在Driver中常會遇到一個狀況
在IRQL 為DISPATCH_LEVEL 時要執行一個必須為PASSIVE_LEVEL才能執行的function
此時就可以利用workitem來達成
Example Code:
typedef struct _XXX_WORK_ITEM {
PVOID DeviceContext;
WORK_QUEUE_ITEM WorkItem;
} XXX_WORK_ITEM, *PXXX_WORK_ITEM;
VOID
ReadDefRegValueWorkItem(
IN PVOID DeviceContext
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PXXX_WORK_ITEM workitem = (PXXX_WORK_ITEM)DeviceContext;
// read effect reg value
ntStatus = ReadDefRegValue(workitem->DeviceContext);
// free memory for workitem
ExFreePool(workitem);
}
NTSTATUS
ReadDefRegValue(
IN PTASCCAM_DEVICE_CONTEXT DeviceContext)
{
KIRQL irql;
NTSTATUS ntStatus = STATUS_SUCCESS;
PXXX_WORK_ITEM workitem;
irql = KeGetCurrentIrql();
if (irql == PASSIVE_LEVEL){
ntStatus = ReadDefRegValue(DeviceContext);
}else{
// queue a workitem to do the job
workitem = ExAllocatePool(NonPagedPool, sizeof(XXX_WORK_ITEM));
if (workitem){
ExInitializeWorkItem(&workitem->WorkItem, ReadDefRegValueWorkItem, workitem);
workitem->DeviceContext = DeviceContext;
ExQueueWorkItem(&workitem->WorkItem, DelayedWorkQueue);
ntStatus = STATUS_PENDING;
} else {
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
}
return ntStatus;
}
留言列表