Communication between GUI APP and Device Driver

Environment: Visual C++ 6, NT4 SP3/2K/XP
Background
Recently I read a good article, in which the author wrote a device driver and a GUI program, and he want to notify the GUI App when some event happened in device driver. In his article, when a new process was created, a callback function in his driver would be called, it would notify the GUI App and display some information about the new process immediately. In device driver, the author create a named event and opened it in GUI App, when an event happened, his codes like this:
KeSetEvent(Event, 0, FALSE); KeClearEvent(Event);
At this time, the GUI App was waiting for the event. Between the interval of the two functions, the App must got information of the new process. It works, but I don't think it's a good solution.
Why does the author code like this? Because, if we create an event in kernel mode, we can't modify its state in user mode, we only can check its state. But normally, we want the GUI App modify the event to non signaled, and it can wait the event again. I think this is the eligible IPC model to deal with this question.
About my solution
Kernel mode has higher priority than user mode. In kernel mode we can modify data in user mode conveniently. So I create an event object in user mode, and refer it in kernel mode. Now both device driver and GUI App can check and modify the state of the event object.
How to integrate it into your application
In your App, you must open the device object firstly, then code like this:
1 - Create an event object and down it into driver.
HANDLE m_hCommEvent = CreateEvent(NULL,
false,
false,
NULL);
// download event object to device driver,
// m_hCommDevice is the device object
DeviceIoControl(m_hCommDevice,
IO_REFERENCE_EVENT,
(LPVOID) m_hCommEvent,
0,
NULL,
0,
dwReturn,
NULL);
2 - Wait the event object to be signaled.
while(true)
{
WaitForSingleObject(m_hCommEvent, INFINITE);
// After this function, the event is set to
// non signaled. Get information and deal with it.
}
In device driver, codes like this:
1 - In IRP_MJ_DEVICE_CONTROL major routine:
case IO_REFERENCE_EVENT:
hEvent = (HANDLE) irpStack->
Parameters.DeviceIoControl.Type3InputBuffer;
status = ObReferenceObjectByHandle(hEvent,
GENERIC_ALL,
NULL,
KernelMode,
&gpEventObject,
&objHandleInfo);
the gpEventObject is a PRKEVENT object, so we can use KeEventXXX and KeWaitForXXX to operate it.
2 - When the object event happened
KeSetEvent(gpEventObject, 0, FALSE);
3 - When we don't need it, we should dereference it:
case IO_DEREFERENCE_EVENT:
if(gpEventObject)
ObDereferenceObject(gpEventObject);
I have tested my solution in a personal firewall product. It works well. When my IP Filter Driver got an IP packet, it check the IP header as my security rules. If the packet will be intercepted, report to my GUI App.
The sample project file includes two projects: GUI app and device driver. The GUI App is a dialog based MFC application. It has a log window which can register the operations on event object. The device driver is only a very simple kernel mode device driver. It can operate the event object as GUI App asked. I you want to run this demo, you must install and start the driver firstly. Because there are so many tools can install and start device deriver, so I don't include code to do these works.
If you have any problems and advices, Please notify me. It's welcome.

Comments
More on the subject...
Posted by Legacy on 02/05/2004 12:00amOriginally posted by: Bogdan
http://www.microsoft.com/msj/0799/nerd/nerd0799.aspx
Reply
interested in devicedriver programming
Posted by Legacy on 07/25/2003 12:00amOriginally posted by: naresh
sir
i am naresh doing final year M.C.A i am interested in kernel side programming and devicedriver programming can u just help me in this regard
Replythanx
in advance
naresh
code of device driver
Posted by Legacy on 02/17/2003 12:00amOriginally posted by: amit gupta
sir ,
Replymy name is amit i m student of mca in final year
& i m really intreasted in creating device driver in vc++
so please send me a mail
amit
Nice idea, but...
Posted by Legacy on 10/12/2002 12:00amOriginally posted by: Paul
I think this is a good idea as a method of communicating with a kernal mode driver however i do see one problem. In the original article if the application failed then the driver would not be effected. However this way the device driver is using user mode memory, so if the app fails then that memory will no longer be valid and when the device driver accesses it it will also fail (very likely bringing the system down with it). I new to this so i could be wrong?
ReplyI think perhaps you know it,please help me!
Posted by Legacy on 07/25/2002 12:00amOriginally posted by: XieMin
My driver is a virtual device driver,and I need send I/O control to the real device,so I make a new IRP and send it to the real device.
The problem is if the real device is not a PNP device ,it is success(Such as COM1),but if I use a PNP device(such as USB modem),it is fail.Is there difference between the real
COM port and the COM port which is created by the PNP device?
The problem is urgent,please help me,thanks a lot!
ReplyHow to get filename in device driver?
Posted by Legacy on 06/01/2002 12:00amOriginally posted by: Le Hoang Dung
I was wrote a IO device driver, but I want to get filename of IRP request at IRP_MJ_CREATE. Can you help me?
ReplyI want to say the meaning is:
Posted by Legacy on 03/29/2002 12:00amOriginally posted by: zhang2798
Hi,
ReplyIt is possible that I did not say clearly tomorrow.The mean is that my program can run first without the scanner's triggering.when my program is invoking,It's Icon is in the system tray and the window is minmized.At this time,when I do with the scanner,my program is invoked secondly and the second Icon of my program appears in the system tray.so I want to resolve the problem.when my program is invoking,
then if I do with my scanner,my program can be triggered and invoke some function of my program such as:ImageScan(),and there is not the second instance is invoked,only one instance:the first running instance.How can I do?
Thank very much for you help!
I have a problem.
Posted by Legacy on 03/28/2002 12:00amOriginally posted by: zhang2798
Hello,
ReplyI wrote a program with vc++,it is a virtual scanner,the scanner driver is like that you say in the text.My program use some functions to register itself,and when the scanner is being done,such as:scan,my program can receive the eventname:scan GUID(The driver have registered it in the regedit),and running itself to scan through the twain interface and save the file as a bmp to open with the Kodakimg.(that is to say:my program can scan as a scanner with the function Imagescan()that I wrote.).but now I have a problem:when my program is running,and the scaner is being done,my program responds the scaner and running secondly,that is:have two *.exe is runing,I want my
program is running only once and can respond the scanner using some functions of my program in any case.
Thanks very much for you help!
I hope you can tell me the solution in detail,thanks.
My mail is:zhangyhi@sohu.com
Original Article
Posted by Legacy on 03/27/2002 12:00amOriginally posted by: Mark Zhang
Hi,zhiwei, could you post the original article,
Thanks,
ReplyHow to open the event created by device driver in GUI
Posted by Legacy on 03/25/2002 12:00amOriginally posted by: Mike
I have seen your code, you pass the event created by GUI to driver through ioctl. but my question is how to open the event created by driver. still use ioctl? Or all the events are system variables?
thanks
Reply