Solved

Accessing EISA custom card under Win9x.

Posted on 1998-12-11
6
257 Views
Last Modified: 2013-12-03
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    
0
Comment
Question by:cybernan063098
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
6 Comments
 
LVL 32

Expert Comment

by:jhance
ID: 1417080
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.
0
 
LVL 2

Accepted Solution

by:
ivi earned 600 total points
ID: 1417081
You should not touch a PIC registers directly, it is
prohibited! For example, your code contains:
    //enable IRQs 0 to 6.
    _asm{
     xor al, al
     mov dx, 0x21
     mov al, 0x80
     out dx, al
    }
and

VPICD_Physically_Unmask(rtc.hndIrq);

== Use VPICD_Physicall_Unmask only! ==

Also in your interrupt handler contains:
)
   // Commando EOI (end of interrupt) Rehabilita
  _asm{
    mov dx, 0x20
    mov al, 0x20
    out dx, al
  }
The same error - use VPICD_Phys_EOI only!


0
 

Author Comment

by:cybernan063098
ID: 1417082
Thanks ivi......
but my whole system dies...
Im desesperate!
What Can I do??
       please help meeeee!!!!!!!!



0
Salesforce Has Never Been Easier

Improve and reinforce salesforce training & adoption using WalkMe's digital adoption platform. Start saving on costly employee training by creating fast intuitive Walk-Thrus for Salesforce. Claim your Free Account Now

 

Author Comment

by:cybernan063098
ID: 1417083
Thanks ivi......
but my whole system dies...
Im desesperate!
What Can I do??
       please help meeeee!!!!!!!!



0
 
LVL 2

Expert Comment

by:ivi
ID: 1417084
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

0
 

Author Comment

by:cybernan063098
ID: 1417085
Thanks IVI!!!!!!!
0

Featured Post

Salesforce Made Easy to Use

On-screen guidance at the moment of need enables you & your employees to focus on the core, you can now boost your adoption rates swiftly and simply with one easy tool.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this article, I will show how to use the Ribbon IDs Tool Window to assign the built-in Office icons to a ribbon button.  This tool will help us to find the OfficeImageId that corresponds to our desired built-in Office icon. The tool is part of…
After several hours of googling I could not gather any information on this topic. There are several ways of controlling the USB port connected to any storage device. The best example of that is by changing the registry value of "HKEY_LOCAL_MACHINE\S…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
In this video, viewers will be given step by step instructions on adjusting mouse, pointer and cursor visibility in Microsoft Windows 10. The video seeks to educate those who are struggling with the new Windows 10 Graphical User Interface. Change Cu…

734 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question