Link to home
Start Free TrialLog in
Avatar of cybernan063098
cybernan063098

asked on

Communication from VXD to Application!


Hi Experts!

     I develop a vxd to access my IESA custom card, inside of my hardware interrupt routine I read the port, but Now, I need send this value to my aplication!.I work under Win95 (Win32)
What  can I do??
Any Idea??
Please write a sample skeletor program!

Experts Thanks Again! For All!.
ASKER CERTIFIED SOLUTION
Avatar of jhance
jhance

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
cybernan063098

ASKER

yes!!
in my virtual device declaration in asm , I write to receive the DeviceIOControl command:
..
Control_Dispatch W32_DEVICEIOCONTROL, CVXD_W32_DeviceIOControl, sCall, <ecx, ebx, edx, es>
.

And in my vxd source in C code. I use :
.

DWORD _stdcall CVXD_W32_DeviceIOControl(DWORD dwService,
                                        DWORD dwDDB,
                                        DWORD hDevive,
                                        LPDIOC lpDIOParms){
.
   switch(dwService){
        case DIOC_OPEN
             dwt= 0;
             break;
        case DIOC_CLOSEHANDLE
             dwRetVal= VXD_Cleanup();
             Out_Debug_String("VXD_Cleanup\n\r");
             break;
       .. ...

and in my surce code to load my vxd i use the create file and deviceIOControl ....

I Know communication application to vxd   BUT I have  doubts in the ""communication VXD to aplication"" because under my hardware interrupt routine I need return a value to my aplication,....

what I need do now?

I need see a sample skeletor source code for orient me!.

thanks again!  
You just define your own commands to the VxD that can be called by DeviceIoControl().  You pass in the address of the variable that is to receive the data.  

If you want to poll for the data, it goes something like this:
   switch(dwService){
        case DIOC_OPEN
             dwt= 0;
             break;
        case DIOC_CLOSEHANDLE
             dwRetVal= VXD_Cleanup();
             Out_Debug_String("VXD_Cleanup\n\r");
             break;

        case DIOC_GETPARAMETER  // YOU define this to be whatever
             rwRetVal = XYZ;  // Data you want to send back
             break;


You can also pass in an HWND with DeviceIoControl() and have your VxD send messages back to your application.  You can do this if you don't want to poll for the data.  Using a message is probably the preferred way of doing it.
thanks Jhance  but my vxd is to access my EISA custom card and  my
hardware interrupt routine only read the port ......and I need send this value to my aplication , my vxd is static ....is posible use the CVXD_DeviceIOControl in a vxd static??
I try use this but my vxd fail.!

What can I do?? Please tell me!


thanks Jhance  but my vxd is to access my EISA custom card and  my
hardware interrupt routine only read the port ......and I need send this value to my aplication , my vxd is static ....is posible use the CVXD_DeviceIOControl in a vxd static??
I try use this but my vxd fail.!

What can I do?? Please tell me!

Thanks Again!
I don't think you've setup your Control_Dispatch to handle this user function from the Win32 application DeviceIoControl.

Thanks!!!!

       Jhance I have the Control_Dispatch inside my asm vxd declaraction !!

.......
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
......

What`s up??
What can I do?

Please help me!

thanks Again!



this my vxd in C source code:

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

#define CVXDMSG_COMMUNICATION 10
#define VOLTAM_IRQ 3  //IRQ3 = 3d

typedef DIOCPARAMETERS *LPDIOC;

LPDIOC myLPDIOC;

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

DEVICE_CONTEXT      VOLTAMETRO;

HVM hSysVM;

BOOL OnDeviceInit(VMHANDLE hVM);
void OnSystemExit(VMHANDLE hVM);
DWORD _stdcall CVXD_W32_DeviceIOControl(DWORD, DWORD, DWORD, LPDIOC);
BOOL  _stdcall HwIntProcHandler(VMHANDLE hVM, IRQHANDLE hIRQ, void *Refdata);
VOID  _stdcall EventHandler(VMHANDLE hVM, PVOID Refdata, CRS *pRegs);

void WriteToVoltametro(void);
WORD ProcessHwInt(void);

// functions in asm module
void EventThunk( void );
void HwIntProcThunk( void );
/***************************************************************************
                      CVXD_W32_DeviceIOControl
****************************************************************************/
DWORD _stdcall CVXD_W32_DeviceIOControl(DWORD dwService,
                                        DWORD dwDDB,
                                        DWORD hDevive,
                                        LPDIOC lpDIOParms){
 DWORD dwRetVal= 0;
   switch(dwService){
        case DIOC_OPEN :
             dwRetVal= 0;
             Out_Debug_String("DIOC_OPEN \n\r");
             break;
        case DIOC_CLOSEHANDLE :
             dwRetVal= 0;
             Out_Debug_String("CVXD_Cleanup\n\r");
             break;
        case CVXDMSG_COMMUNICATION :
             dwRetVal= 0;
             Out_Debug_String("CVXDMSG_COMMUNICATION \n\r");
       default :
             dwRetVal= -1; //Message Not Supported
   }
 return (dwRetVal);
}
/***************************************************************************
                     SYS DYNAMIC DEVICE INIT
****************************************************************************/
BOOL OnSysDynamicDeviceInit(VMHANDLE hVM){
   OnDeviceInit( hVM );
   Out_Debug_String("OnSysDynamicDeviceInit\r\n");
   return TRUE;
}
/****************************************************************************
                     SYS DYNAMIC DEVICE EXIT
****************************************************************************/
BOOL OnSysDynamicDeviceExit(void){
   OnSystemExit(Get_Cur_VM_Handle());
   Out_Debug_String("OnSysDynamicDeviceExit\r\n");
   return TRUE;
}
/*****************************************************************************
                         VxD Dynamic ON DEVICE INIT
****************************************************************************/
BOOL OnDeviceInit(VMHANDLE hVM){
        Out_Debug_String("OnDeviceInit Virtualizing Function. \r\n");        
      VOLTAMETRO.descIrq.VID_IRQ_Number = VOLTAM_IRQ;      
      VOLTAMETRO.descIrq.VID_Options = VPICD_OPT_REF_DATA;            
      VOLTAMETRO.descIrq.VID_Hw_Int_Ref = &VOLTAMETRO;
      VOLTAMETRO.descIrq.VID_Hw_Int_Proc = (ULONG)HwIntProcThunk;
      VOLTAMETRO.descIrq.VID_EOI_Proc =       NULL;
      VOLTAMETRO.descIrq.VID_Virt_Int_Proc = NULL;
      VOLTAMETRO.descIrq.VID_Mask_Change_Proc = NULL;
      VOLTAMETRO.descIrq.VID_IRET_Proc = 0;            
      VOLTAMETRO.descIrq.VID_IRET_Time_Out = 500;

      if (!(VOLTAMETRO.hndIrq = VPICD_Virtualize_IRQ(&VOLTAMETRO.descIrq)))
            return FALSE;

        WriteToVoltametro();

      VPICD_Physically_Unmask(VOLTAMETRO.hndIrq);

      return TRUE;
}
/*****************************************************************************
                     VxD SYSTEM EXIT
****************************************************************************/
VOID OnSystemExit(VMHANDLE hVM){
   Cancel_Global_Event(VOLTAMETRO.hEvent);
   VPICD_Physically_Mask(VOLTAMETRO.hndIrq);
   VPICD_Force_Default_Behavior(VOLTAMETRO.hndIrq);
   Out_Debug_String("OnSystemExit\r\n");
}
/***************************************************************************
                  HARDWARE INTERRUPT ROUTINE
****************************************************************************/
BOOL __stdcall HwIntProcHandler(VMHANDLE hVM, IRQHANDLE hIRQ, void *Refdata){

   DEVICE_CONTEXT *pVOLTAMETRO = (DEVICE_CONTEXT *)Refdata;

   PWORD Resultado;  

// THIS VALUE I NEED SEND TO MY APPLICATION!!
   Resultado= (PWORD) myLPDIOC->lpvOutBuffer;

   *Resultado= ProcessHwInt();

   VPICD_Phys_EOI(hIRQ);           // tell VPICD to clear the interrupt

   pVOLTAMETRO->hEvent = Schedule_Global_Event(EventThunk, (ULONG)pVOLTAMETRO);  

   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 *VOLTAMETRO = (DEVICE_CONTEXT *)Refdata;
   VOLTAMETRO->hEvent = 0;
   VOLTAMETRO->EventCounter++;
   Out_Debug_String(" EventHandler");
}
//**********************************************************************
void WriteToVoltametro(void){
// Active select_AD
    _asm{
          cli
          mov dx, 999d
          mov al, 8h
          out dx,al
          sti
    }
  Out_Debug_String("I write to Voltametro !!!\r\n");
}
//******************************************************************
// Read the port 999. Convert A/D
WORD ProcessHwInt(void){  

 BYTE MSB_byte, LSB_byte;
 _asm{      
    cli
    mov dx, 999d
    in al, dx
    mov MSB_byte, al
    in al,dx
    mov LSB_byte, al
    sti
 }
  MSB_byte = MSB_byte << 8; //rota a la Izquiera 8 lugares

  Out_Debug_String("Proccess Hardware Interrupt !!!\r\n");
return (MSB_byte+LSB_byte);
}
 //***   I NEED SEND THIS VALUE TO MY APPLICATION ( MSB_byte+LSB_byte)



Thanks!!!!

       Jhance I have the Control_Dispatch inside my asm vxd declaraction !!

.......
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
......

What`s up??
What can I do?

Please help me!

thanks Again!



this my vxd in C source code:

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

#define CVXDMSG_COMMUNICATION 10
#define VOLTAM_IRQ 3  //IRQ3 = 3d

typedef DIOCPARAMETERS *LPDIOC;

LPDIOC myLPDIOC;

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

DEVICE_CONTEXT      VOLTAMETRO;

HVM hSysVM;

BOOL OnDeviceInit(VMHANDLE hVM);
void OnSystemExit(VMHANDLE hVM);
DWORD _stdcall CVXD_W32_DeviceIOControl(DWORD, DWORD, DWORD, LPDIOC);
BOOL  _stdcall HwIntProcHandler(VMHANDLE hVM, IRQHANDLE hIRQ, void *Refdata);
VOID  _stdcall EventHandler(VMHANDLE hVM, PVOID Refdata, CRS *pRegs);

void WriteToVoltametro(void);
WORD ProcessHwInt(void);

// functions in asm module
void EventThunk( void );
void HwIntProcThunk( void );
/***************************************************************************
                      CVXD_W32_DeviceIOControl
****************************************************************************/
DWORD _stdcall CVXD_W32_DeviceIOControl(DWORD dwService,
                                        DWORD dwDDB,
                                        DWORD hDevive,
                                        LPDIOC lpDIOParms){
 DWORD dwRetVal= 0;
   switch(dwService){
        case DIOC_OPEN :
             dwRetVal= 0;
             Out_Debug_String("DIOC_OPEN \n\r");
             break;
        case DIOC_CLOSEHANDLE :
             dwRetVal= 0;
             Out_Debug_String("CVXD_Cleanup\n\r");
             break;
        case CVXDMSG_COMMUNICATION :
             dwRetVal= 0;
             Out_Debug_String("CVXDMSG_COMMUNICATION \n\r");
       default :
             dwRetVal= -1; //Message Not Supported
   }
 return (dwRetVal);
}
/***************************************************************************
                     SYS DYNAMIC DEVICE INIT
****************************************************************************/
BOOL OnSysDynamicDeviceInit(VMHANDLE hVM){
   OnDeviceInit( hVM );
   Out_Debug_String("OnSysDynamicDeviceInit\r\n");
   return TRUE;
}
/****************************************************************************
                     SYS DYNAMIC DEVICE EXIT
****************************************************************************/
BOOL OnSysDynamicDeviceExit(void){
   OnSystemExit(Get_Cur_VM_Handle());
   Out_Debug_String("OnSysDynamicDeviceExit\r\n");
   return TRUE;
}
/*****************************************************************************
                         VxD Dynamic ON DEVICE INIT
****************************************************************************/
BOOL OnDeviceInit(VMHANDLE hVM){
        Out_Debug_String("OnDeviceInit Virtualizing Function. \r\n");        
      VOLTAMETRO.descIrq.VID_IRQ_Number = VOLTAM_IRQ;      
      VOLTAMETRO.descIrq.VID_Options = VPICD_OPT_REF_DATA;            
      VOLTAMETRO.descIrq.VID_Hw_Int_Ref = &VOLTAMETRO;
      VOLTAMETRO.descIrq.VID_Hw_Int_Proc = (ULONG)HwIntProcThunk;
      VOLTAMETRO.descIrq.VID_EOI_Proc =       NULL;
      VOLTAMETRO.descIrq.VID_Virt_Int_Proc = NULL;
      VOLTAMETRO.descIrq.VID_Mask_Change_Proc = NULL;
      VOLTAMETRO.descIrq.VID_IRET_Proc = 0;            
      VOLTAMETRO.descIrq.VID_IRET_Time_Out = 500;

      if (!(VOLTAMETRO.hndIrq = VPICD_Virtualize_IRQ(&VOLTAMETRO.descIrq)))
            return FALSE;

        WriteToVoltametro();

      VPICD_Physically_Unmask(VOLTAMETRO.hndIrq);

      return TRUE;
}
/*****************************************************************************
                     VxD SYSTEM EXIT
****************************************************************************/
VOID OnSystemExit(VMHANDLE hVM){
   Cancel_Global_Event(VOLTAMETRO.hEvent);
   VPICD_Physically_Mask(VOLTAMETRO.hndIrq);
   VPICD_Force_Default_Behavior(VOLTAMETRO.hndIrq);
   Out_Debug_String("OnSystemExit\r\n");
}
/***************************************************************************
                  HARDWARE INTERRUPT ROUTINE
****************************************************************************/
BOOL __stdcall HwIntProcHandler(VMHANDLE hVM, IRQHANDLE hIRQ, void *Refdata){

   DEVICE_CONTEXT *pVOLTAMETRO = (DEVICE_CONTEXT *)Refdata;

   PWORD Resultado;  

// THIS VALUE I NEED SEND TO MY APPLICATION!!
   Resultado= (PWORD) myLPDIOC->lpvOutBuffer;

   *Resultado= ProcessHwInt();

   VPICD_Phys_EOI(hIRQ);           // tell VPICD to clear the interrupt

   pVOLTAMETRO->hEvent = Schedule_Global_Event(EventThunk, (ULONG)pVOLTAMETRO);  

   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 *VOLTAMETRO = (DEVICE_CONTEXT *)Refdata;
   VOLTAMETRO->hEvent = 0;
   VOLTAMETRO->EventCounter++;
   Out_Debug_String(" EventHandler");
}
//**********************************************************************
void WriteToVoltametro(void){
// Active select_AD
    _asm{
          cli
          mov dx, 999d
          mov al, 8h
          out dx,al
          sti
    }
  Out_Debug_String("I write to Voltametro !!!\r\n");
}
//******************************************************************
// Read the port 999. Convert A/D
WORD ProcessHwInt(void){  

 BYTE MSB_byte, LSB_byte;
 _asm{      
    cli
    mov dx, 999d
    in al, dx
    mov MSB_byte, al
    in al,dx
    mov LSB_byte, al
    sti
 }
  MSB_byte = MSB_byte << 8; //rota a la Izquiera 8 lugares

  Out_Debug_String("Proccess Hardware Interrupt !!!\r\n");
return (MSB_byte+LSB_byte);
}
 //***   I NEED SEND THIS VALUE TO MY APPLICATION ( MSB_byte+LSB_byte)


Please see the Hardware interrupt routine I use the
 PWORD Resultado;  
  // THIS VALUE I NEED SEND TO MY APPLICATION!!
  Resultado= (PWORD) myLPDIOC->lpvOutBuffer;
to send this value to my application
is correct ??or not??

thanks again!!!

Ps:sorry for send 2 times my question my conection fail. =(

Let me see if I can put together a short example of a VxD that sends data back to an application through DeviceIoControl.  
ok!!  thanks jhance!
please put a short example!

thanks again!
First, if you don't have a copy of Karen Hazzah's book "Writing Windows VxDs and Device Drivers" by R&D Books, get a copy ASAP.  It covers all aspects of VxD development.

Since we started down the DeviceIoControl() route with this, it's probably best to continue along this thread.  Here are some examples out of the book:

Here's the ASM setup for handling DeviceIoControl():

BeginProc ControlProc
    Control_Dispatch INIT_COMPLETE, _OnInitComplete, cCall, <ebx>
    Control_Dispatch SYS_DYNAMIC_DEVICE_INIT, _OnSysDynamicDeviceInit, cCall, <ebx>
    Control_Dispatch SYS_DYNAMIC_DEVICE_EXIT, _OnSysDynamicDeviceExit, cCall, <ebx>
    Control_Dispatch W32_DEVICEIOCONTROL, _OnW32Deviceiocontrol, cCall, <esi>
    clc
    ret

EndProc ControlProc

Here's the C part:

DWORD OnW32Deviceiocontrol(PDIOCPARAMETERS p)
{
      DPRINTF1(dbgbuf,"W32DevIoControl code=%x\n", p->dwIoControlCode );

      switch (p->dwIoControlCode)
      {
      case DIOC_GETVERSION:      
      case DIOC_CLOSEHANDLE:       // file closed
            return 0;

      case DMABUF_FUNC_ALLOCBUFFER:
          if (!_Assert_Range( p->lpvInBuffer, sizeof( DMA_BUFFER_DESCRIPTOR ), 0, 0, ASSERT_RANGE_NULL_BAD))
                  return DMABUF_INVALID_PARAMETER;
            else
                  return( AllocBuffer( (DMA_BUFFER_DESCRIPTOR *)p->lpvInBuffer ) );

      case DMABUF_FUNC_FREEBUFFER:
          if (!_Assert_Range( p->lpvInBuffer, sizeof( DMA_BUFFER_DESCRIPTOR ), 0, 0, ASSERT_RANGE_NULL_BAD))
                  return DMABUF_INVALID_PARAMETER;
            else
                  return( FreeBuffer( (DMA_BUFFER_DESCRIPTOR *)p->lpvInBuffer ) );

      default:
            return -1;
      }
}


Thanks again!!

yes in this moment I have the karen hazzan book , but  my problem is
i need load one time my vxd and have commucations vxd aplication any times
my vxd is a ISR and I can´t load any times

what can  i do??

1000 thansk !!
Then go to the section in the book (in my copy page 253) called "VxD PostMessage under Windows 95".  Here, you VxD can send a message to your application any time it wants to.
Thanks jhance but the VXD "PostMessage" Displays a message box using the Windows
shell. but I need get a value of my hardware interrupt routine , send values of my VXD ISR
to my application!!!

Im desperate!!
please what can I do?
Thanks Again!

 
Thanks jhance but the VXD "PostMessage" Displays a message box using the Windows
shell. but I need get a value of my hardware interrupt routine , send values of my VXD ISR
to my application!!!  
 

I don't understand.  PostMessage posts a message to the target window's message queue.  IT'S UP TO YOU DO DECIDE WHAT MESSAGE TO SEND FROM YOUR VxD AND HOW TO HANDLE IT IN YOUR APPLICATION.

Define your own message (say WM_APP+1 or whatever), PostMessage it to your application's window with the value you want to send in lParam or wParam or both, and then write a handler for that message in your app.

>Im desperate!!
>please what can I do?

You can provide more information about what is happening.  For instance:

"PostMessage" Displays a message box using the Windows
shell.

doesn't make sense.  PostMessage doesn't display message boxes, it just posts messages to an application's queue.  Some application must call ::MessageBox() somewhere for a message box to appear.
Thanks For all!
Thanks your help!