驱动层和应用层的同步通信

首先是同步问题,通过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: %d\n",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 sent\n");

    while(true)

    {



        WaitForSingleObject(m_hEvent,INFINITE);  //等待ring0事件通知

        DeviceIoControl(hDevice,IOCTL_GETINFO,NULL,0,&OutputBuffer,256,&dwOutput,NULL);  //获取数据

        printf("%s\n",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 Error\n"));

                status = STATUS_INVALID_BUFFER_SIZE;

                break;

            }

            hEvent = *(HANDLE*)pInBuffer;



            status = ObReferenceObjectByHandle(hEvent,

                GENERIC_ALL,

                NULL,

                KernelMode,

                &gpEventObject,

                &objHandleInfo);

            KdPrint(("gpEventObject: %x\n",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向驱动层请求数据。
 
 
 
 

你可能感兴趣的:(同步)