Link to home
Start Free TrialLog in
Avatar of cybernan063098
cybernan063098

asked on

Accessing EISA custom card under Win9x.

Dear Experts.

I am trying to develop a vxd to access my EISA custom card, I need to virtualize the IRQ3.
I am using the DDK, Visual C , MASM 6.11c, all running under Win95.
I am writing my source code in assembly and C language and I think that this source is correct. My vxd source code compiles correctly, but when I load my dynamic vxd , my computer dies: the mouse pointer, the keyboard, the whole system dies.
I don't get any error messages, it's just that my computer dies, and I must reset it !! =(

What could the problem be??
Why is my vxd incorrect??  
What can I do??

Thanks Again to all.
Please Help me! I`m desesperate. =(


This is my Source Code:

The vxd in C source code:

#define WANTVXDWRAPS
#include <basedef.h>
#include <vmm.h>
#include <debug.h>
#include <vxdwraps.h>
#include <vpicd.h>
#include <vxdcall.h>
#include <wrappers.h>
#include <intrinsi.h>
#include <vwin32.h>
#include <winerror.h>
#include "puertos.h"

#define CVXD_VERSION 0x0001
#define CVXDMSG_COMMUNICATION 0x00A
#define RTC_IRQ 0xB  //IRQ3 == 0xB

typedef struct{
   VPICD_IRQ_DESCRIPTOR      descIrq;      
   IRQHANDLE              hndIrq;
   EVENTHANDLE             hEvent;                  
   DWORD       EventCounter;
} DEVICE_CONTEXT;

DEVICE_CONTEXT      rtc;

typedef struct{
         DWORD   myData[3];
      } TRANSFERDATA, *LPTRANSFERDATA;
 
  LPTRANSFERDATA  lpTransferData, lpTransferDATA;
  typedef DIOCPARAMETERS *LPDIOC;
  band= 0;
BOOL OnDeviceInit(VMHANDLE hVM);
void OnSystemExit(VMHANDLE hVM);
BOOL _stdcall HwIntProcHandler(VMHANDLE hVM, IRQHANDLE hIRQ, void *Refdata);
VOID _stdcall EventHandler(VMHANDLE hVM, PVOID Refdata, CRS *pRegs);
DWORD _stdcall CVXD_W32_DeviceIOControl(DWORD, DWORD, DWORD, LPDIOC);
DWORD _stdcall CVXD_CleanUp(void);

// functions in asm module
void EventThunk( void );
void HwIntProcThunk( void );

/*******************************************************
                  CVXD_W32_DeviceIOControl
*********************************************************/
DWORD _stdcall CVXD_W32_DeviceIOControl(DWORD  dwService,
                                        DWORD  dwDDB,
                                        DWORD  hDevice,
                                        LPDIOC lpDIOCParms){
          DWORD dwRetVal= 0;
          switch( dwService ){
              case DIOC_OPEN:
                   Out_Debug_String(" supported here!\n\r");                    dwRetVal= 0;
              case DIOC_CLOSEHANDLE:
                   dwRetVal= CVXD_CleanUp();
               Out_Debug_String("Close Handle.\n\r");
              case CVXDMSG_COMMUNICATION:
               Out_Debug_String("API Communication.r");    
                lpTransferData = (LPTRANSFERDATA)lpDIOCParms->lpvOutBuffer;
          lpTransferData->myData[0]= Get_Sys_VM_Handle();
          lpTransferData->myData[1]= 102;
          lpTransferData->myData[2]= 31;
          lpTransferData->myData[3]= 89;
           dwRetVal= 0;
          default:
               dwRetVal= -1; // Message not supported.
         }
return(dwRetVal);
}
/*********************************************************
                         VxD Dynamic Init
***********************************************************/
BOOL OnDeviceInit(VMHANDLE hVM){
 DWORD Lbyte,Hbyte,myTime;
 int i, cont=0 ;
 BYTE VectON;
      rtc.descIrq.VID_IRQ_Number = RTC_IRQ;      
      rtc.descIrq.VID_Options = VPICD_OPT_REF_DATA;      
      rtc.descIrq.VID_Hw_Int_Ref = &rtc;
      rtc.descIrq.VID_Hw_Int_Proc = (ULONG)HwIntProcThunk;
      rtc.descIrq.VID_EOI_Proc =       NULL;
      rtc.descIrq.VID_Virt_Int_Proc = NULL;
      rtc.descIrq.VID_Mask_Change_Proc = NULL;
      rtc.descIrq.VID_IRET_Proc = 0;            
      rtc.descIrq.VID_IRET_Time_Out = 500;

if (!(rtc.hndIrq = VPICD_Virtualize_IRQ(&rtc.descIrq)))
     return FALSE;
        //VectorON= inp(0x21)      
         _asm{
              xor al, al
              in al, 0x21
              mov VectON, al
            }
        //enable IRQs 0 to 6.
        _asm{
             xor al, al
             mov dx, 0x21
             mov al, 0x80
             out dx, al
          }
        for(i=1; i<11; i++){
           _asm{
                mov dx, select_AD
                mov al, 11
                out dx, al
            }
             do{
               cont++;
            }while(band == 0);
        }  
      rtc.EventCounter = 0;

      VPICD_Physically_Unmask(rtc.hndIrq);
        Out_Debug_String("OnDeviceInit\r\n");
      return TRUE;
}
/********************************************************
                     VxD SYS DYNAMIC DEVICE INIT
**********************************************************/
BOOL OnSysDynamicDeviceInit(VMHANDLE hVM){
   OnDeviceInit( hVM );
   Out_Debug_String("OnSysDynamicDeviceInit\r\n");
   return TRUE;
}
/***********************************************************
                     VxD DYNAMIC EXIT
***********************************************************/
BOOL OnSysDynamicDeviceExit(void){
   OnSystemExit(Get_Cur_VM_Handle());
   Out_Debug_String("OnSysDynamicDeviceExit\r\n");
   return TRUE;
}
/*********************************************************
                     VxD SYSTEM EXIT
**********************************************************/
VOID OnSystemExit(VMHANDLE hVM){
   Cancel_Global_Event(rtc.hEvent);
   VPICD_Physically_Mask(rtc.hndIrq);
   VPICD_Force_Default_Behavior(rtc.hndIrq);
   Out_Debug_String("OnSystemExit\r\n");
}
/*******************************************************
                  HARDWARE INTERRUPT ROUTINE
********************************************************/
BOOL __stdcall HwIntProcHandler(VMHANDLE hVM, IRQHANDLE hIRQ, void *Refdata){
   int  dato, Vlr;
   BYTE MSB_byte, LSB_byte;
   DEVICE_CONTEXT *pRtc = (DEVICE_CONTEXT *)Refdata;    
   VPICD_Phys_EOI(hIRQ);           // tell VPICD to clear the interrupt
  pRtc->hEvent = Schedule_Global_Event(EventThunk, (ULONG)pRtc );        
        // MSB_byte= inp(select_AD)
        _asm{
             xor al, al
             mov dx, select_AD
             in al, dx
             mov MSB_byte, al
         }
         // LSB_byte= inp(select_AD)
        _asm{
             xor al, al
             mov dx, select_AD
             in  al, dx
             mov LSB_byte, al
         }
         dato= (MSB_byte << 8 ) + LSB_byte;
         if(dato > 4095 ){
            dato= ((255-MSB_byte) << 8) + (255-LSB_byte);
            Vlr= -1 * (dato/4096*5);
         }
         else{
            Vlr= dato/4096*5;
            band= 1;
            // inp(0x20, 0x20)
            // Commando EOI (end of interrupt) Rehabilita
           _asm{
                mov dx, 0x20
                mov al, 0x20
                out dx, al
            }
         }
        Out_Debug_String("My ISR Runing!!!\r\n");
      return TRUE;                      // thunk will clear carry
}
/**********************************************************
                   EVENT HANDLER
**********************************************************/

VOID __stdcall EventHandler(VMHANDLE hVM, PVOID Refdata, CRS* pRegs){
   DEVICE_CONTEXT *rtc = (DEVICE_CONTEXT *)Refdata;
   rtc->hEvent = 0;
   rtc->EventCounter++;
   Out_Debug_String(" EventHandler");
}
/**********************************************************
                         VxD CleanUp
**********************************************************/
DWORD _stdcall CVXD_CleanUp(void){
    Out_Debug_String("Cleaning Up\n\r");
    return(VXD_SUCCESS);
}
//*******************************************************
This is my ASM source code:

PAGE 58,132
;********************************************************
TITLE CONTROL -  UADY
;*********************************************************
  .386p
;**********************************************************
;                I N C L U D E S
;**********************************************************    .xlist
    include vmm.inc
    include debug.inc
   .list
CVXD_DEVICE_ID EQU Undefined_Device_ID

;=========================================================
;  V I R T U A L   D E V I C E   D E C L A R A T I O N
;=========================================================
DECLARE_VIRTUAL_DEVICE    VCIRD, 1, 0, ControlProc, CVXD_DEVICE_ID, \
                        UNDEFINED_INIT_ORDER, ,
VxD_LOCKED_CODE_SEG
ifdef _VXD_SERVICES
extrn _CVXD_Get_Version:near
endif

BeginProc ControlProc
  Control_Dispatch DEVICE_INIT, _OnDeviceInit, cCall, <ebx>
  Control_Dispatch SYSTEM_EXIT, _OnSystemExit, cCall, <ebx>
  Control_Dispatch SYS_DYNAMIC_DEVICE_INIT,  _OnSysDynamicDeviceInit, cCall, <ebx>
  Control_Dispatch SYS_DYNAMIC_DEVICE_EXIT, _OnSysDynamicDeviceExit, cCall    
 Control_Dispatch W32_DEVICEIOCONTROL,  CVXD_W32_DeviceIOControl, sCall, <ecx, ebx, edx, esi>
    clc
    ret
EndProc ControlProc

PUBLIC _HwIntProcThunk
       _HwIntProcThunk PROC NEAR        
         sCall HwIntProcHandler, <ebx, eax, edx>
         or ax, ax
         jnz clearc
         stc
         ret
      clearc:
         clc
         ret
      _HwIntProcThunk ENDP
VxD_LOCKED_CODE_ENDS
VxD_CODE_SEG
  BeginProc _EventThunk
      sCall EventHandler, <ebx,edx,ebp>
      ret
  EndProc _EventThunk
VXD_CODE_ENDS
    END
My C source code to load my vxd.

#include <stdio.h>
#include <windows.h>
#include <vmm.h>
#include <vxdldr.h>

#define CVXDMSG_COMMUNICATION 0x000A
typedef struct{
    DWORD myData[3];
}TRANSFERDATA, *LPTRANSFERDATA;

TRANSFERDATA TransferData;
int main(){
  HANDLE myVxDHandle= 0;
  DWORD  xBytesReturned;
  DWORD  xErrorCode;
  myVxDHandle= CreateFile("\\\\.\\VCIRD.VXD",0,0,0,   CREATE_NEW,FILE_FLAG_DELETE_ON_CLOSE,0);
  if( myVxDHandle == INVALID_HANDLE_VALUE){
     xErrorCode= GetLastError();
     if( xErrorCode == ERROR_NOT_SUPPORTED)
       printf("Error: Unable to load vxd\n");  
   else
     printf("Error: VXD \n  Code Error: %lx\n", xErrorCode);  }
else{  
  if (DeviceIoControl(myVxDHandle,CVXDMSG_COMMUNICATION,
                NULL, 0,
               &TransferData, sizeof(TransferData),
                &xBytesReturned, NULL) )
       printf("Sistema: %lx,%lx,%lx,%lx,%lx \n",        TransferData.myData[0],    TransferData.myData[1],TransferData.myData[2],TransferData.myData[3]);
      else
         printf("Device no soporta Solicitud API\n");      
    CloseHandle(myVxDHandle);
    }  
   return(0);
}

my DEF file source code:

VXD VCIRD DYNAMIC

SEGMENTS
_LPTEXT      CLASS 'LCODE'   PRELOAD NONDISCARDABLE
_LTEXT      CLASS 'LCODE'   PRELOAD NONDISCARDABLE
_LDATA      CLASS 'LCODE'   PRELOAD NONDISCARDABLE
_TEXT      CLASS 'LCODE'   PRELOAD NONDISCARDABLE
_DATA      CLASS 'LCODE'   PRELOAD NONDISCARDABLE
CONST      CLASS 'LCODE'   PRELOAD NONDISCARDABLE
_TLS      CLASS 'LCODE'   PRELOAD NONDISCARDABLE
_BSS      CLASS 'LCODE'   PRELOAD NONDISCARDABLE
_ITEXT      CLASS 'ICODE'   DISCARDABLE
_IDATA      CLASS 'ICODE'   DISCARDABLE
_PTEXT      CLASS 'PCODE'   NONDISCARDABLE
_PDATA      CLASS 'PDATA'   NONDISCARDABLE SHARED
_STEXT      CLASS 'SCODE'   RESIDENT
_SDATA      CLASS 'SCODE'   RESIDENT
_DBOSTART CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING
_DBOCODE CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING _DBODATA CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING
_16ICODE CLASS '16ICODE' PRELOAD DISCARDABLE
_RCODE      CLASS 'RCODE'
 EXPORTS
        VCIRD_DDB @1

My MAKEFILE source Code:

CFLAGS = -DWIN32 -DCON -Di386 -D_X86_ -D_NTWIN -W3 -Gs -D_DEBUG -Zi
CVXDFLAGS  = -Zdp -Gs -c -DIS_32 -Zl -DDEBLEVEL=1 -DDEBUG
LFLAGS  = -machine:i386 -debug:notmapped,full -debugtype:cv -subsystem:console kernel32.lib
AFLAGS  = -coff -DBLD_COFF -DIS_32 -W2 -Zd -c -Cx -DMASM6 -DDEBLEVEL=1 -DDEBUG

all:  winapi.exe vcird.vxd

vcird.obj: vcird.c
        cl $(CVXDFLAGS) -Fo$@ %s

vcirdasm.obj: vcirdasm.asm
        ml $(AFLAGS) -Fo$@ %s

vcird.vxd: vcird.obj vcirdasm.obj \
                  vcird.def
        echo >NUL @<<vcird.crf
-MACHINE:i386 -DEBUG:NONE -PDB:NONE
-DEF:vcird.def -OUT:vcird.vxd -MAP:vcird.map
-VXD vxdwraps.clb wrappers.clb vcird.obj vcirdasm.obj
<<
        link @vcird.crf        
        mapsym vcird
        ...
winapi.obj: winapi.c
        cl $(CFLAGS) -c -Fo$@ %s

winapi.exe: winapi.obj
        echo >NUL @<<winapi.crf
$(LFLAGS)
-PDB:NONE -OUT:winapi.exe -MAP:winapi.map winapi.obj
<<
        link @winapi.crf

Thanks Dear Experts    
Avatar of jhance
jhance

I don't have an answer to this specific question, but I have a recommendation.  It's inconceivable that you would attempt to develop anything but the most trivial VxD without a first class debugger.  I can recommend SoftICE from NuMega/Compuware (www.numega.com).  As far as I know, it's the only debugger on the market that allows debugging of VxDs.
ASKER CERTIFIED SOLUTION
Avatar of ivi
ivi

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of cybernan063098

ASKER

Thanks ivi......
but my whole system dies...
Im desesperate!
What Can I do??
       please help meeeee!!!!!!!!



Thanks ivi......
but my whole system dies...
Im desesperate!
What Can I do??
       please help meeeee!!!!!!!!



How can I help you? Maybe to write a driver instead of you? :)
Seriously. As the first step I reccomend you to remove
almost all code from the interrupt handler. Try debug it
in simple variant, with the counter only. Later you can add a code to the handler again.
BTW, have you the Karen's Hazzah book about VxD?
You can write me directly to tools@entechtaiwan.com

Thanks IVI!!!!!!!