WdfRequestStopAcknowledge 函数 (wdfrequest.h)

[适用于 KMDF 和 UMDF]

WdfRequestStopAcknowledge 方法通知框架驱动程序已停止处理指定的 I/O 请求。

语法

void WdfRequestStopAcknowledge(
  [in] WDFREQUEST Request,
  [in] BOOLEAN    Requeue
);

参数

[in] Request

框架请求对象的句柄。

[in] Requeue

一个布尔值,如果 为 TRUE,则会导致框架将请求重新排队到队列中,以便框架再次将其传递给驱动程序。 如果 为 FALSE,则框架不会重新排队请求。 有关更多信息,请参见下面的“备注”部分。

返回值

备注

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

如果驱动程序为 I/O 队列注册 EvtIoStop 回调函数,则当队列的基础设备离开其工作 (D0) 状态时,框架会调用它。 框架针对驱动程序尚未完成的每个 I/O 请求调用 EvtIoStop 回调函数,包括驱动程序拥有的请求以及它已转发到 I/O 目标的请求。 驱动程序必须通过执行以下操作之一完成、取消或推迟每个请求的处理:

  • 如果驱动程序拥有请求,则可以调用 WdfRequestComplete 来完成或取消请求。
  • 如果驱动程序已将请求转发到 I/O 目标,则可以调用 WdfRequestCancelSentRequest 来尝试取消请求。
  • 如果驱动程序推迟处理请求,则必须调用 WdfRequestStopAcknowledge
如果驱动程序调用 WdfRequestStopAcknowledge,则必须从其 EvtIoStop 回调函数中调用此方法。

在驱动程序完成、取消或推迟 EvtIoStop 回调函数收到的每个请求之前,框架不允许设备保持其工作 (D0) 状态。 这种不作为可能会阻止系统进入其休眠状态或其他低系统电源状态。

当驱动程序的 EvtIoStop 回调函数调用 WdfRequestStopAcknowledge 时,它可以将 Requeue 参数设置为 TRUEFALSE

  • “重新排队” 设置为 TRUE 会导致框架将请求放回其 I/O 队列。

    当基础设备返回到其工作 (D0) 状态时,框架将向驱动程序重新发出请求。

  • “重新排队” 设置为 FALSE 会导致框架不重新排队请求。 如果驱动程序 拥有 请求,则所有权仍归驱动程序所有。 如果驱动程序已转发请求,则驱动程序负责在请求完成后处理请求。 驱动程序必须停止执行任何需要硬件访问的 I/O 处理。

    当基础设备返回到其工作 (D0) 状态时,框架将调用驱动程序的 EvtIoResume 回调函数,以便驱动程序可以继续处理请求。

如果驱动程序之前已调用 WdfRequestMarkCancelableWdfRequestMarkCancelableEx,则必须在调用 WdfRequestStopAcknowledge 之前调用 WdfRequestUnmarkCancelable,并且 Requeue 设置为 TRUE

在调用 WdfRequestStopAcknowledge 之前,驱动程序的 EvtIoStop 回调函数必须停止对需要访问基础设备的 I/O 请求的所有处理,因为设备即将进入低功耗状态。

有关 WdfRequestStopAcknowledge 方法的详细信息,请参阅 使用 Power-Managed I/O 队列

示例

如果驱动程序调用 WdfRequestStopAcknowledge重新排队 设置为 TRUE,则必须先调用 WdfRequestUnmarkCancelable

下面的代码示例是一个 EvtIoStop 回调函数,该函数检查收到的请求是否可取消,如果可取消,则调用 WdfRequestUnmarkCancelable。 如果 WdfRequestUnmarkCancelable 返回STATUS_CANCELLED,则示例仅返回,因为驱动程序的 EvtRequestCancel 回调函数将处理请求。 否则,该示例调用 WdfRequestStopAcknowledge 并指定 TRUE ,以便框架在基础设备返回到其工作 (D0) 状态时重新排队请求。

VOID
MyEvtIoStop(
    IN WDFQUEUE  Queue,
    IN WDFREQUEST  Request,
    IN ULONG  ActionFlags
    )
{
    NTSTATUS status;

    // TODO: Take steps here to suspend and, if necessary, roll back any processing that has already occurred on this request

    if (ActionFlags & WdfRequestStopRequestCancelable) {
        status = WdfRequestUnmarkCancelable(Request);
        if (status == STATUS_CANCELLED) {
            return;
        }
    }

    // Inform framework that driver is postponing processing, cause framework to redeliver request when device returns to D0

    WdfRequestStopAcknowledge(Request, TRUE);
}

通常,如果驱动程序调用 WdfRequestStopAcknowledgeRequeue 设置为 FALSE,则会使请求可取消。

下面的代码示例是一个 EvtIoStop 回调函数,该函数调用 WdfRequestStopAcknowledge 并指定 FALSE ,以便框架最终调用驱动程序的 EvtIoResume 回调函数,其中驱动程序恢复处理请求。

如果可以接受的是停止处理特定请求并稍后继续处理,而不是重新发出请求并从头开始重启处理,则可以使用此类代码。

VOID
MyEvtIoStop(
    IN WDFQUEUE  Queue,
    IN WDFREQUEST  Request,
    IN ULONG  ActionFlags
    )
{

    //TODO: Take steps here to suspend processing of the request so it can be resumed when power returns
	 
    // Acknowledge the stop, but leave the request under driver's ownership.
    // Provide a corresponding EvtIoResume handler to resume processing when power returns

    WdfRequestStopAcknowledge(Request, FALSE);
}

要求

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

另请参阅

EvtIoStop

EvtRequestCancel

WdfRequestComplete