zoukankan      html  css  js  c++  java
  • Ring0层创建事件,Ring3层接收

    在学习驱动过程中,一个很重要的内容就是Ring3层与Ring0层的通信,方法有很多种,互斥体,信号量,文件等等,用的比较普遍的,还是事件。所以在学习的过程中,做了一个简单的Demo,主要是体会一下方法。

    在驱动程序下,首先要定义一个事件名,前面的一部分必须是BaseNamedObjects,这其实就是一个目录,后面的部分可以自己起,但不要太过简单和普遍,以免与现有的冲突。

    #define EVENT_NAME   L"\\BaseNamedObjects\\Ring0Event"

    定义两个全局变量

    PKEVENT g_Event;
    HANDLE g_EventHandle;

    NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath)
    {
    NTSTATUS Status = STATUS_SUCCESS;
    PDEVICE_OBJECT DeviceObject = NULL;
    UNICODE_STRING EventName;

    RtlInitUnicodeString(&EventName, EVENT_NAME);     //需要UNICODE_STRING型,所以用RtlInitUnicodeString转换一下
    DriverObject->DriverUnload = DriverUnload;

    //IoCreateNotificationEvent例程创建或打开一个命名的通知事件,用来通知一个或多个线程执行一个事件发生。
    g_Event = IoCreateNotificationEvent(&EventName, &g_EventHandle);  //1参数输入,2参数输出

    return Status;
    }

    VOID DriverUnload(PDRIVER_OBJECT DriverObject)
    {
    DbgPrint("DriverUnload()\r\n");

    if (g_EventHandle != NULL)
    {
    KeClearEvent(g_Event);

    ZwClose(g_EventHandle);   //销毁资源

    g_EventHandle = NULL;
    g_Event = NULL;
    }

    }

    应用层代码

    #include <windows.h>
    #include <iostream>
    using namespace std;

    int main()
    {

    HANDLE EventHandle = NULL;


    while (TRUE)
    {

    //事件名必须与驱动的相同
    EventHandle = OpenEvent(SYNCHRONIZE, FALSE, L"Global\\Ring0Event");

    if (EventHandle == NULL)
    {
    continue;
    }

    break;
    }
    //授信之后输出
    cout << "Ring3等待" << endl;
    while (TRUE)   
    {

    int Index = WaitForSingleObject(EventHandle, 3000);

    Index = Index - WAIT_OBJECT_0;

    if (Index == WAIT_TIMEOUT)   //超时
    {

    //注意这里当驱动卸载并关闭事件时事件对象是不能够得到及时的销毁 因为应用层占用了该对象
    //所以我们长时间等待不到授信 就关闭并重新打开
    if (EventHandle != NULL)
    {
    CloseHandle(EventHandle);
    EventHandle = NULL;
    EventHandle = OpenEvent(SYNCHRONIZE, FALSE, L"Global\\Ring0Event"); //第一参数为访问的事件对象,第二参数为是否继承,名字必须与驱动相同

    if (EventHandle == NULL)
    {
    cout << "对象已经不存在" << endl;
    break;
    }
    }

    continue;
    }

    if (Index == 0)  //成功
    {
    cout << "Ring0触发Ring3" << endl;
    }


    if (Index == WAIT_FAILED)
    {
    break;
    }

    Sleep(1);
    }

    if (EventHandle != NULL)
    {
    CloseHandle(EventHandle);
    EventHandle = NULL;

    }

    getchar();
    return 0;
    }

    上述代码在win7 x86 和win7 x64 的虚拟机下测试成功。

  • 相关阅读:
    EF之POCO应用系列4——延迟加载
    四色原型札记(一)
    HTTP1.1 > HTTP2.0
    【ArangoDB踩坑】字符串查询要加引号
    利用线程池实现多客户端和单服务器端Socket通讯(二):异步编程模型实现
    题目:若干个不重复数,打乱顺序输出
    wtf js(三) number的类型不是number
    wtf js(二)
    算法:给定两个已从小到大排好序的整型数组arrA和arrB,将两个数组合并成arrC,使得arrC也要按从小到大的顺序排好序
    利用线程池实现多客户端和单服务器端Socket通讯(一):同步方式
  • 原文地址:https://www.cnblogs.com/kekoukele987/p/7342105.html
Copyright © 2011-2022 走看看