0x00 函数
组合1
IoAllocateWorkItem() //分配一个工作项
IoQueueWorkItem() //将WorkItem例程与工作项关联,并将工作项插入队列中,供系统工作线程稍后处理。 -> 工作项、回调函数、队列类型、参数进行关联
IoFreeWorkItem() //释放一个由IoAllocateWorkItem分配的工作项
组合2
IoInitializeWorkItem() //初始化调用方已经分配的工作项。参数2必须从非分页池分配内存
IoQueueWorkItem() //将WorkItem例程与工作项关联,并将工作项插入队列中,供系统工作线程稍后处理。 -> 工作项、回调函数、队列类型、参数进行关联
IoUninitializeWorkItem() //释放一个由IoInitializeWorkItem初始化的工作项
组合3
ExInitializeWorkItem() //使用调用方提供的上下文和回调例程初始化工作队列项,以便在系统工作线程获得控制时排队执行。 参数1必须从非分页池分配此结构 -> 工作项、回调函数、参数进行关联
ExQueueWorkItem() // 将给定的工作项插入到队列中,系统工作线程从中删除该项,并将控制权授予调用者提供给ExInitializeWorkItem的例程 -> 工作项、队列类型进行关联.(ExInitializeWorkItem已经将工作项、回调函数、参数进行了关联)
注意:
设备驱动程序必须使用IoQueueWorkItem而不是ExQueueWorkItem。只有在指定的工作项与设备对象或设备堆栈没有关联的情况下,驱动程序才应使用ExQueueWorkItem和关联的ExInitializeWorkItem。在所有其他情况下,驱动程序应该使用IoAllocateWorkItem、IoFreeWorkItem和IoQueueWorkItem,因为只有这些例程才能确保与指定工作项关联的设备对象在处理完工作项之前保持可用。
多看文档,多看文档....
0x01 代码
#include <wdm.h>
PIO_WORKITEM IoWorkItem = NULL;
VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
DbgPrint("DriverUnload");
if (IoWorkItem != NULL)
{
/*
//方法2
DbgPrint("DriverUnload -> IoUninitializeWorkItem | ExFreePool");
IoUninitializeWorkItem(IoWorkItem); //只销毁当前未排队的工作项
ExFreePool(IoWorkItem);
*/
//IoFreeWorkItem = IoUninitializeWorkItem + ExFreePool
//IoFreeWorkItem -> 只释放当前未排队的工作项。可以在WorkItem或WorkItemEx中调用IoFreeWorkItem来释放未排队的工作项
//方法3
DbgPrint("DriverUnload -> IoFreeWorkItem");
IoFreeWorkItem(IoWorkItem);
}
return;
}
//方法1
//WORK_QUEUE_ITEM Item = { 0 };
//void Routine(PVOID Parameter)
//{
// DbgPrint("Routine");
//}
VOID WorkerRoutine(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PVOID Context)
{
DbgPrint("WorkerRoutine");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
NTSTATUS status = STATUS_SUCCESS;
DriverObject->DriverUnload = DriverUnload;
//方法1
//初始化WorkItem -> 必须从非分页池分配此结构
//ExInitializeWorkItem(&Item,Routine,0);
//插入到工作项队列
//ExQueueWorkItem(&Item, DelayedWorkQueue);
// IoAllocateWorkItem = ExAllocatePool + IoInitializeWorkItem
/*
//方法2
IoWorkItem = ExAllocatePool(NonPagedPool, IoSizeofWorkItem());
if (IoWorkItem == NULL)
{
DbgPrint("DriverEntry -> ExAllocatePool failed");
return STATUS_NO_MEMORY;
}
IoInitializeWorkItem(DriverObject,IoWorkItem);
*/
//方法3
IoWorkItem = IoAllocateWorkItem(DriverObject);
if (IoWorkItem == NULL)
{
DbgPrint("DriverEntry -> IoAllocateWorkItem failed");
return STATUS_NO_MEMORY;
}
//将工作项加入工作项队列
IoQueueWorkItem(IoWorkItem,WorkerRoutine, CriticalWorkQueue,0);
DbgPrint("DriverEntry Success");
return status;
}