KMD可以设置Win32事件有信号,当KMD内部发生了某些事情,需要Win32来做某些工作时,就可以使用这种手段
步骤
1.KMD内部保存KEVENT对象指针,Win32使用IOCTL方法传递Win32事件句柄
2.KMD转换Win32句柄得到KEVENT对象指针
3.使用KeSetEvent,和KENENT对象指针参数,使Win32事件有信号
4.不需要使用该事件时,KMD要释放KEVENT对象
/*Win32*/ ... g_hDriver= CreateFile("\\\\.\\notify", GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); ... g_hEvent=::CreateEvent(0,0,0,0); ... /*IRP ObReferenceObjectByHandle*/ DeviceIoControl(m_hDriver,IOCTL_IRP_PASSEVENT, &g_hEvent, sizeof(g_hEvent), NULL, 0, &junk, (LPOVERLAPPED) NULL); ... unsigned __stdcall SecondThreadFunc( void* pArguments ) { if(WAIT_OBJECT_0==::WaitForSingleObject(g_hEvent,INFINITE)) { _endthreadex(1); } return 0; } _beginthreadex( NULL, 0, &wait_thread, NULL, 0, &threadid ); ... /*IRP KeSetEvent*/ DeviceIoControl(g_hDriver, IOCTL_IRP_SETEVENT, NULL, 0, // no input buffer NULL, 0, // output buffer &junk, // # bytes returned (LPOVERLAPPED) NULL) // synchronous I/O ... /*IRP ObDereferenceObject*/ DeviceIoControl(g_hDriver, IOCTL_IRP_DELETEEVENT, NULL, 0, // no input buffer NULL, 0, // output buffer &junk, // # bytes returned (LPOVERLAPPED) NULL) ; // synchronous
/*KMD*/ ... /*全局指针,指向转换后的Win32事件*/ PKEVENT g_pEvent=0; ... /*IRP_MJ_DEVICE_CONTROL routine DispatchDeviceControl*/ NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) { PIO_STACK_LOCATION irpStack; NTSTATUS ntStatus; ULONG IoControlCodes; HANDLE hEvent; irpStack=IoGetCurrentIrpStackLocation(Irp); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoControlCodes=irpStack->Parameters.DeviceIoControl.IoControlCode; switch (IoControlCodes) { case IOCTL_IRP_PASSEVENT: hEvent=*(HANDLE*)Irp->AssociatedIrp.SystemBuffer; ntStatus = ObReferenceObjectByHandle(hEvent, EVENT_MODIFY_STATE, *ExEventObjectType, Irp->RequestorMode, (PVOID*) &g_pEvent, NULL); break; case IOCTL_IRP_SETEVENT: KeSetEvent(g_pEvent,0,FALSE); ntStatus=Irp->IoStatus.Status; break; case IOCTL_IRP_DELETEEVENT: ObDereferenceObject(g_pEvent); ntStatus=Irp->IoStatus.Status; DbgPrint("irp3\n"); break; default: ntStatus = STATUS_INVALID_DEVICE_REQUEST; break; } IoCompleteRequest (Irp, IO_NO_INCREMENT); return ntStatus; }