概述
首先是同步问题,通过Ring3创建事件,并将该事件传递给Ring0,同时Ring3创建监控线程,等待Ring0发起事件。
监控到事件(通知)
Ring0(监控)----------------------------------------------------------------> Ring3
应用层得到事件通知后,向驱动层发起数据获取请求。由Ring3主动发起,Ring0被动接受。
询问(CTL_CODE)
Ring3 ---------------------------------------------------------------- > Ring0
回答(通过OUT参数)
Ring3 <---------------------------------------------------------------- Ring0
具体实现:
应用层:
HANDLE hDevice = CreateFile("\\.\PRMonitor", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL); //打开设备 if(hDevice==INVALID_HANDLE_VALUE) { printf("Failed to obtain device with error code: %dn",GetLastError()); getchar(); return; } DWORD dwOutput; char* OutputBuffer[256]; HANDLE m_hEvent = CreateEvent(NULL,FALSE,FALSE,NULL); //创建事件 DeviceIoControl(hDevice,IOCTL_STARTHOOK,&m_hEvent,sizeof(HANDLE),NULL,0,&dwOutput,NULL); //发事件给ring0 printf("IoControl code sentn"); while(true) { WaitForSingleObject(m_hEvent,INFINITE); //等待ring0事件通知 DeviceIoControl(hDevice,IOCTL_GETINFO,NULL,0,&OutputBuffer,256,&dwOutput,NULL); //获取数据 printf("%sn",OutputBuffer); ResetEvent(m_hEvent); //重置事件 }
驱动层:
PRKEVENT gpEventObject;
POBJECT_HANDLE_INFORMATION objHandleInfo;
NTSTATUS DevDispatch(PDEVICE_OBJECT DeviceObject,PIRP Irp) { PVOID pInBuffer; ULONG pInbufferSize; PVOID pOutBuffer; ULONG pOutbufferSize; NTSTATUS status; PIO_STACK_LOCATION ps = IoGetCurrentIrpStackLocation(Irp); switch(ps->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_STARTHOOK: //传送事件 if(!bProcMon) { ……
pInBuffer = Irp->AssociatedIrp.SystemBuffer; pInbufferSize = ps->Parameters.DeviceIoControl.InputBufferLength; if(pInBuffer == NULL || pInbufferSize < sizeof(HANDLE)) { KdPrint(("Set Event Errorn")); status = STATUS_INVALID_BUFFER_SIZE; break; } hEvent = *(HANDLE*)pInBuffer; status = ObReferenceObjectByHandle(hEvent, GENERIC_ALL, NULL, KernelMode, &gpEventObject, &objHandleInfo); KdPrint(("gpEventObject: %xn",gpEventObject)); } break; case IOCTL_GETINFO: //传送数据 pOutBuffer = Irp->AssociatedIrp.SystemBuffer; pOutbufferSize = ps->Parameters.DeviceIoControl.OutputBufferLength; RtlCopyMemory(pOutBuffer,output,sizeof(output)); Irp->IoStatus.Information = pOutbufferSize; break; } // Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp,IO_NO_INCREMENT); return STATUS_SUCCESS; }
在需要通知应用层事件的地方(比如监控到某一事件时)加上这一句
KeSetEvent(gpEventObject,0,FALSE);
这时应用层程序就会通过DeviceIoControl向驱动层请求数据。
转载于:https://www.cnblogs.com/dflower/archive/2009/04/17/1438066.html
最后
以上就是勤恳大雁为你收集整理的驱动层和应用层的同步通信的全部内容,希望文章能够帮你解决驱动层和应用层的同步通信所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复