Solved

Communication from VXD to Application!

Posted on 1999-01-11
18
235 Views
Last Modified: 2013-12-03

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!.
0
Comment
Question by:cybernan063098
  • 11
  • 7
18 Comments
 
LVL 32

Accepted Solution

by:
jhance earned 450 total points
ID: 1418502
The normal way to accomplish VxD to application communications is with the DeviceIoControl() Win32 API function.  Of course, this requires that you build a handler into your VxD to receive the DeviceIoControl() command.  

There are many other ways that you might do this but DeviceIoControl() would be the "standard" way.
0
 

Author Comment

by:cybernan063098
ID: 1418503
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!  
0
 
LVL 32

Expert Comment

by:jhance
ID: 1418504
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.
0
 

Author Comment

by:cybernan063098
ID: 1418505
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!


0
 

Author Comment

by:cybernan063098
ID: 1418506
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!
0
 
LVL 32

Expert Comment

by:jhance
ID: 1418507
I don't think you've setup your Control_Dispatch to handle this user function from the Win32 application DeviceIoControl.
0
 

Author Comment

by:cybernan063098
ID: 1418508

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)


0
 

Author Comment

by:cybernan063098
ID: 1418509

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)


0
 

Author Comment

by:cybernan063098
ID: 1418510
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. =(

0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 32

Expert Comment

by:jhance
ID: 1418511
Let me see if I can put together a short example of a VxD that sends data back to an application through DeviceIoControl.  
0
 

Author Comment

by:cybernan063098
ID: 1418512
ok!!  thanks jhance!
please put a short example!

thanks again!
0
 
LVL 32

Expert Comment

by:jhance
ID: 1418513
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;
      }
}


0
 

Author Comment

by:cybernan063098
ID: 1418514
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 !!
0
 
LVL 32

Expert Comment

by:jhance
ID: 1418515
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.
0
 

Author Comment

by:cybernan063098
ID: 1418516
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!
0
 
LVL 32

Expert Comment

by:jhance
ID: 1418517

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

Author Comment

by:cybernan063098
ID: 1418518
Thanks For all!
0
 

Author Comment

by:cybernan063098
ID: 1418519
Thanks your help!
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

This article describes how to add a user-defined command button to the Windows 7 Explorer toolbar.  In the previous article (http://www.experts-exchange.com/A_2172.html), we saw how to put the Delete button back there where it belongs.  "Delete" is …
For most people, the WrapPanel seems like a magic when they switch from WinForms to WPF. Most of us will think that the code that is used to write a control like that would be difficult. However, most of the work is done by the WPF engine, and the W…
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…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

708 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

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now