注册IRP_MJ_SHUTDOWN事件 基于ReactOS0303

Posted Yuri800

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了注册IRP_MJ_SHUTDOWN事件 基于ReactOS0303相关的知识,希望对你有一定的参考价值。

    系统关闭时,会向注册SHUTDOWN事件的设备驱动发送IRP_MJ_SHUTDOWN事件。

NTSTATUS STDCALL
NtShutdownSystem(IN SHUTDOWN_ACTION Action)
{
    if (Action > ShutdownPowerOff)
     return STATUS_INVALID_PARAMETER;
   Status = PsCreateSystemThread(&ThreadHandle,
                                 THREAD_ALL_ACCESS,
                                 NULL,
                                 NULL,
                                 NULL,
                                 ShutdownThreadMain,
                                 (PVOID)Action);
}

VOID STDCALL
ShutdownThreadMain(PVOID Context)
{
    ioshutdownRegisteredDevices();
}


VOID
NTAPI
IoShutdownRegisteredDevices(VOID)
{
    ListEntry = ExInterlockedRemoveHeadList(&ShutdownListHead,
                                            &ShutdownListLock);
    while (ListEntry)
    {
        /* Get the shutdown entry */
        ShutdownEntry = CONTAINING_RECORD(ListEntry,
                                          SHUTDOWN_ENTRY,
                                          ShutdownList);

        /* Get the attached device */
        DeviceObject = IoGetAttachedDevice(ShutdownEntry->DeviceObject);

        /* Build the shutdown IRP and call the driver */
        Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SHUTDOWN,
                                           DeviceObject,
                                           NULL,
                                           0,
                                           NULL,
                                           &Event,
                                           &StatusBlock);
        Status = IoCallDriver(DeviceObject, Irp);
        if (Status == STATUS_PENDING)
        {
            /* Wait on the driver */
            KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
        }

        /* Free the shutdown entry and reset the event */
        ExFreePool(ShutdownEntry);
        KeClearEvent(&Event);

        /* Go to the next entry */
        ListEntry = ExInterlockedRemoveHeadList(&ShutdownListHead,
                                                &ShutdownListLock);
     }
}
    调用Native API NtShutdownSystem时会遍历ShutdownListHead队列,取出每个元素,这个元素的结构中包含设备对象:

typedef struct _SHUTDOWN_ENTRY
{
    LIST_ENTRY ShutdownList;
    PDEVICE_OBJECT DeviceObject;
} SHUTDOWN_ENTRY, *PSHUTDOWN_ENTRY;
    之后获得这个设备的设备栈深度并以此建立一个类型为IRP_MJ_SHUTDOWN的IRP请求包,以同步的方式发向设备栈的最上层设备。 设备栈中的设备驱动如果注册了IRP_MJ_SHUTDOWN事件那就调用相应的回调,如果没有注册就按默认的方式完成请求或者下发请求。

    联系驱动程序注册IRP_MJ_SHUTDOWN事件和IoShutdownRegisteredDevices函数的是IoRegisterShutdownNotification---注册关机通知函数。这个函数新建SHUTDOWN_ENTRY结构,并填入设备对象,然后把SHUTDOWN_ENTRY结构挂入ShutdownListHead队列。

/*
 * @implemented
 */
NTSTATUS
NTAPI
IoRegisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
{
    PSHUTDOWN_ENTRY Entry;

    /* Allocate the shutdown entry */
    Entry = ExAllocatePoolWithTag(NonPagedPool,
                                  sizeof(SHUTDOWN_ENTRY),
                                  TAG_SHUTDOWN_ENTRY);
    if (!Entry) return STATUS_INSUFFICIENT_RESOURCES;

    Entry->DeviceObject = DeviceObject;

    /* Insert it into the list */
    ExInterlockedInsertHeadList(&ShutdownListHead,
                                &Entry->ShutdownList,
                                &ShutdownListLock);

    
    DeviceObject->Flags |= DO_SHUTDOWN_REGISTERED;
    return STATUS_SUCCESS;
}

    驱动入口以如下的方式注册关闭通知:

DriverEntry(pDriverObject,pRegistryPath)
{
    pDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = Shutdown;
    IoRegisterShutdownNotification(pDriverObject);
}



以上是关于注册IRP_MJ_SHUTDOWN事件 基于ReactOS0303的主要内容,如果未能解决你的问题,请参考以下文章

对比高性能I/O设计模式-Reactor/Proactor

对比高性能I/O设计模式-Reactor/Proactor

libevent & Reactor模式

epoll高度封装reactor,几乎所有可见服务器的底层框架

完整的基于PHP的登录/注册系统、档案系统、聊天室、论坛系统和博客/民意调查/事件管理系统。

为啥 jQuery 单击事件侦听器未在 WooCommerce 按钮上注册?