用事件Event在kernal mode与user mode之间进行通信,我们一般的做法是在kernal mode中定义Event,标记上名字,然后在user mode中打开这个Event,代码如下:
kernal mode:
UNICODE_STRING EventName=NDIS_STRING_CONST("beauty");
PKEVENT pEvent;
HANDLE pEvnetHandle;
pEvent=IoCreateNotificationEvent(&EventName,&pEventHandle);
///使用的时候必须是下面两个函数一起使用,因为在user mode是不能改动pEvent
keSetEvent(pEvent,0,FALSE);
KeClearEvent(pEvent);
我最近看到一种新的方法,在user mode 定义Event ,这样在该Event就可以被kernal mode与user mode两种状态下修改。代码如下:
user mode:
HANDLE m_hCommEvent = CreateEvent(NULL, false, false, NULL);
// m_hCommDevice is the device object DeviceIoControl(m_hCommDevice, IO_REFERENCE_EVENT, (LPVOID) m_hCommEvent, 0, NULL, 0, dwReturn, NULL);
///.........
while(true) { WaitForSingleObject(m_hCommEvent, INFINITE); // After this function, the event is set to // non signaled. Get information and deal with it. }kernal mode:case IO_REFERENCE_EVENT: hEvent = (HANDLE) irpStack-> Parameters.DeviceIoControl.Type3InputBuffer; status = ObReferenceObjectByHandle(hEvent, GENERIC_ALL, NULL, KernelMode, &gpEventObject, &objHandleInfo);
/直接使Event受信 KeSetEvent(gpEventObject, 0, FALSE);
///使用完后
case IO_DEREFERENCE_EVENT: if(gpEventObject) ObDereferenceObject(gpEventObject);如有问题望大家斧正!