WdfWorkItemEnqueue 函数 (wdfworkitem.h)

[适用于 KMDF 和 UMDF]

WdfWorkItemEnqueue 方法将指定的框架工作项对象添加到系统的工作项队列。

语法

void WdfWorkItemEnqueue(
  [in] WDFWORKITEM WorkItem
);

参数

[in] WorkItem

框架工作项对象的句柄,该对象是从上一次调用 WdfWorkItemCreate 获取的

返回值

备注

如果驱动程序提供无效的对象句柄,则会发生 bug 检查。

驱动程序调用 WdfWorkItemCreate 以创建工作项后,驱动程序必须调用 WdfWorkItemEnqueue 以将工作项添加到系统的工作项队列。 系统工作线程随后从队列中删除工作项,并调用工作项的 EvtWorkItem 回调函数。 系统按工作项添加到队列的顺序删除这些工作项。

在驱动程序调用 WdfWorkItemEnqueue 之前,它们通常使用工作项对象的上下文内存来存储有关工作项的信息。 EvtWorkItem 回调函数使用此信息来确定它必须执行的操作。

对于 1.7 及更高版本的 KMDF,如果驱动程序重用其工作项对象,则驱动程序可以在系统工作线程取消工作项排队并随后调用驱动程序的 EvtWorkItem 回调函数之前再次为同一工作项调用 WdfWorkItemEnqueue 但是,KMDF 不会将工作项添加到队列(如果已存在)。 因此, EvtWorkItem 回调函数必须在每次调用它时处理所有排队的工作。

驱动程序还可以在 EvtWorkItem 回调函数运行时调用 WdfWorkItemEnqueue,以将另一个工作项排队。 第二个工作项的 EvtWorkItem 回调甚至可以在第一个工作项完成之前运行。

在 1.7 版之前的 KMDF 版本中,如果驱动程序重复使用其工作项对象,则在系统工作线程取消对工作项的排队并调用其 EvtWorkItem 回调函数之前,它不得针对同一工作项再次调用 WdfWorkItemEnqueue

有关工作项的详细信息,请参阅 使用框架工作项

示例

本部分包含两个示例。 第一个示例演示如何将工作项添加到 KMDF 版本 1.7 及更高版本的队列。 第二个示例演示如何将工作项添加到 1.7 版之前的 KMDF 版本的队列

示例 1:KMDF 版本 1.7 及更高版本

下面的代码示例调用一个本地例程,该例程返回指向工作项对象的上下文内存的指针。 该示例在对象的上下文内存中设置信息,然后调用 WdfWorkItemEnqueue。 驱动程序的 EvtWorkItem 回调函数稍后将从工作项对象检索信息。

PMY_CONTEXT_TYPE context;

context = GetWorkItemContext(hWorkItem);
context->FdoData = FdoData;
context->Argument1 = Context1;
context->Argument2 = Context2;

WdfWorkItemEnqueue(hWorkItem);

驱动程序的 EvtWorkItem 回调函数包含以下代码。

MyWorkItemCallback (
    IN WDFWORKITEM hWorkItem
    )
{
    PMY_CONTEXT_TYPE context;

    context = GetWorkItemContext(hWorkItem);

    //
    // Do work here.
    //
    ...
    //
    return;
}

示例 2:1.7 之前的 KMDF 版本

下面的代码示例调用一个本地例程,该例程返回指向工作项对象的上下文内存的指针。 该示例在对象的上下文内存中设置信息,将状态变量设置为“busy”,然后调用 WdfWorkItemEnqueue。 驱动程序的 EvtWorkItem 回调函数稍后将从工作项对象检索信息。

typedef enum _WORKITEM_STATE {
    WORKITEM_STATE_FREE =0,
    WORKITEM_STATE_BUSY = 1
} WORKITEM_STATE;
...
PMY_CONTEXT_TYPE context;

context = GetWorkItemContext(hWorkItem);
context->FdoData = FdoData;
context->Argument1 = Context1;
context->Argument2 = Context2;

if (InterlockedCompareExchange(
                               (PLONG)&context->WorkItemState,
                               WORKITEM_STATE_BUSY,
                               WORKITEM_STATE_FREE
                               ) == WORKITEM_STATE_FREE) {
 WdfWorkItemEnqueue(hWorkItem);
}

驱动程序的 EvtWorkItem 回调函数包含以下代码。 在 return 语句之前,代码将工作项对象的状态变量设置为“free”,以便驱动程序可以再次将对象排队。

MyWorkItemCallback (
    IN WDFWORKITEM hWorkItem
    )
{
    PMY_CONTEXT_TYPE context;
    LONG result;

    context = GetWorkItemContext(hWorkItem);

    //
    // Do work here.
    //
    ...
    //
    // Reset object state.
    //
    result = InterlockedExchange(
                                 (PLONG)&context->WorkItemState,
                                 WORKITEM_STATE_FREE
                                 );
    ASSERT(result == WORKITEM_STATE_BUSY);
    return;
}

要求

要求
目标平台 通用
最低 KMDF 版本 1.0
最低 UMDF 版本 2.0
标头 wdfworkitem.h (包括 Wdf.h)
Library Wdf01000.sys (KMDF) ;WUDFx02000.dll (UMDF)
IRQL <= DISPATCH_LEVEL
DDI 符合性规则 DeferredRequestCompleted (kmdf) DriverCreate (kmdf) KmdfIrql (kmdf) KmdfIrql2 (kmdf) 、 KmdfIrqlExplicit (kmdf) , RequestCompleted (kmdf) RequestCompletedLocal (kmdf)

另请参阅

EvtWorkItem

InterlockedCompareExchange

InterlockedExchange

WdfWorkItemCreate