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 的虚拟机下测试成功。

  • 相关阅读:
    mysql 高效分页控件及c#调用实例
    sql server高效分页控件及c#调用实例
    Log4net从下载到使用例子
    Nlog从下载到使用例子
    使用httpClient调用接口,参数用map封装或者使用JSON参数,并转换返回结果
    Pool thread stack traces: Thread[C3P0PooledConnectionPoolManager[identityToken->原因解决办法
    使用spring的aop监听所有controller或者action日志
    ActiveMQ监听消息并进行转发,监听不同的mq服务器和不同的队列
    zookeeper集群查看状态时报错Error contacting service. It is probably not running的一些坑以及解决办法
    AopProxyUtils.getSingletonTarget(Ljava/lang/Object;)Ljava/lang/Object;大坑
  • 原文地址:https://www.cnblogs.com/kekoukele987/p/7342105.html
Copyright © 2011-2022 走看看