我是靠谱客的博主 勤恳大雁,最近开发中收集的这篇文章主要介绍驱动层和应用层的同步通信,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

首先是同步问题,通过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

最后

以上就是勤恳大雁为你收集整理的驱动层和应用层的同步通信的全部内容,希望文章能够帮你解决驱动层和应用层的同步通信所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(40)

评论列表共有 0 条评论

立即
投稿
返回
顶部