close

在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;
}



arrow
arrow
    全站熱搜

    skyuxxx 發表在 痞客邦 留言(0) 人氣()