Windows ExCreateCallback多驱动间通信

//sender
 
#include <ntifs.h>
 
 
#define CALLBACKNAME L"\\Callback\\driverStart"
 
VOID UnloadDriver(PDRIVER_OBJECT driver);
 
VOID MyThread(PVOID context);
 
BOOLEAN gbSuccess = 0;
//线程句柄
HANDLE ghThread = NULL;
//回调指针
PCALLBACK_OBJECT gpObjCallback = NULL;
KEVENT gEvent;
 
extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING registry)
{
    UNREFERENCED_PARAMETER(registry);
 
    NTSTATUS status;
    OBJECT_ATTRIBUTES objAttri;
    driver->DriverUnload = UnloadDriver;
    //初始化通知事件
    KeInitializeEvent(&gEvent, SynchronizationEvent, FALSE);
 
    UNICODE_STRING uniCallbackName = RTL_CONSTANT_STRING(CALLBACKNAME);
    //这里必须指定OBJ_PERMANENT属性,否则会失败
    InitializeObjectAttributes(&objAttri, &uniCallbackName, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, NULL);
 
    //注册回调对象
    status = ExCreateCallback(&gpObjCallback, &objAttri, TRUE, TRUE);
    if (!NT_SUCCESS(status))
    {
        KdPrint(("[sysTest] ExCreateCallback error code:(0x%x).\n", status));
        return status;
    }
    //注册成功
    gbSuccess = 1;
    //创建线程,定期发送 ExNotifyCallback
    status = PsCreateSystemThread(&ghThread, THREAD_ALL_ACCESS, NULL, NULL, NULL, MyThread, NULL);
    if (!NT_SUCCESS(status))
    {
        KdPrint(("[sysTest] PsCreateSystemThread error code:(0x%x).\n", status));
        return status;
    }
 
    status = STATUS_SUCCESS;
    return status;
 
}
 
VOID MyThread(PVOID context)
{
    UNREFERENCED_PARAMETER(context);
 
    NTSTATUS status;
    ULONG type = 1;
    //ULONG ulData = 0;
    const char* ulData = "hello";
    LARGE_INTEGER tick = { 0 };
    //时间间隔是定位2秒
    tick = RtlConvertLongToLargeInteger(-10 * 1000 * 1000 * 2);
 
    while (tick.QuadPart != 0)
    {
        //等待3秒
        status = KeWaitForSingleObject(&gEvent, Executive, KernelMode, FALSE, &tick);
        if (STATUS_TIMEOUT != status)
        {
            break;
        }
        //通知
        ExNotifyCallback(gpObjCallback, &type, (PVOID)ulData);
        KdPrint(("[sysTest] send.\n"));
    }
 
    KdPrint(("[sysTest] thread ended.\n"));
    PsTerminateSystemThread(STATUS_SUCCESS);
}
 
VOID UnloadDriver(PDRIVER_OBJECT driver)
{
    UNREFERENCED_PARAMETER(driver);
     
    KeSetEvent(&gEvent, 0, TRUE);  
    if (NULL != ghThread)
    {
        ZwWaitForSingleObject(ghThread, FALSE, NULL);
        ZwClose(ghThread);
        ghThread = NULL;
    }
    if (gbSuccess)
    {
        ObDereferenceObject(gpObjCallback);
    }
 
    KdPrint(("[sysTest] driver stoped.\n"));
}
//receiver
 
#include <ntifs.h>
 
#define CALLBACKNAME L"\\Callback\\driverStart"
 
VOID UnloadDriver(_In_ PDRIVER_OBJECT driver);
VOID CALLBACK_FUNC(
    _In_ PVOID CallbackContext,
    _In_ PVOID Argument1,
    _In_ PVOID Argument2);
 
PCALLBACK_OBJECT gpObjCallback = NULL;
BOOLEAN gbSuccess = 0;
PVOID gpCookie = NULL;
 
 
extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING registry)
{
    UNREFERENCED_PARAMETER(registry);
     
    driver->DriverUnload = UnloadDriver;
 
    NTSTATUS status;
    UNICODE_STRING uniName = RTL_CONSTANT_STRING(CALLBACKNAME);
    OBJECT_ATTRIBUTES objAttri;
 
    InitializeObjectAttributes(&objAttri, &uniName, OBJ_CASE_INSENSITIVE, NULL, NULL);
 
    status = ExCreateCallback(&gpObjCallback, &objAttri, FALSE, TRUE);
    if (!NT_SUCCESS(status))
    {
        KdPrint(("[sysRecv1] ExCreateCallback error code:(0x%x).\n", status));
        return status;
    }
    gbSuccess = 1;
     
    gpCookie = ExRegisterCallback(gpObjCallback, CALLBACK_FUNC, NULL);
    if (NULL == gpCookie)
    {
        KdPrint(("[sysRecv1] ExRegisterCallback error.\n"));
        return STATUS_UNSUCCESSFUL;
    }
 
    status = STATUS_SUCCESS;
 
    return status;
}
 
 
 
VOID UnloadDriver(_In_ PDRIVER_OBJECT driver)
{
    UNREFERENCED_PARAMETER(driver);
 
    if (NULL != gpCookie)
    {
        ExUnregisterCallback(gpCookie);
    }
    KdPrint(("[sysRecv1] Drvier unloaded.\n"));
}
 
 
VOID CALLBACK_FUNC(
    _In_ PVOID CallbackContext,
    _In_ PVOID Argument1,
    _In_ PVOID Argument2)
{
    UNREFERENCED_PARAMETER(CallbackContext);
     
    ULONG ulType;
    PCHAR ulValue;
    ulType = *(ULONG*)Argument1;
    ulValue = (PCHAR)Argument2;
 
    KdPrint(("[sysRecv1]:get notify ulType:(%d)\tulValue:(%s)\n", ulType, ulValue));
}
1