Compartilhar via


Função WdfRequestUnmarkCancelable (wdfrequest.h)

[Aplica-se a KMDF e UMDF]

O método WdfRequestUnmarkCancelable desabilita o cancelamento de uma solicitação de E/S especificada.

Sintaxe

NTSTATUS WdfRequestUnmarkCancelable(
  [in] WDFREQUEST Request
);

Parâmetros

[in] Request

Um identificador para um objeto de solicitação de estrutura.

Retornar valor

WdfRequestUnmarkCancelable retornará STATUS_SUCCESS se a operação for bem-sucedida. Caso contrário, esse método poderá retornar um dos seguintes valores:

Código de retorno Descrição
STATUS_INVALID_PARAMETER
Um parâmetro de entrada é inválido ou a solicitação já não pode ser cancelada.
STATUS_INVALID_DEVICE_REQUEST
O driver não possui a solicitação.
STATUS_CANCELLED
A solicitação foi cancelada.
 

Esse método também pode retornar outros valores NTSTATUS.

Um bug marcar ocorrerá se o driver fornecer um identificador de objeto inválido.

Comentários

Um driver pode chamar WdfRequestUnmarkCancelable para desabilitar o cancelamento de uma solicitação de E/S, se o driver anteriormente chamado WdfRequestMarkCancelable ou WdfRequestMarkCancelableEx habilitar o cancelamento da solicitação.

Se WdfRequestUnmarkCancelable retornar um valor diferente de STATUS_CANCELLED, a função de retorno de chamada EvtRequestCancel do driver não será chamada para a solicitação.

Se o driver anteriormente chamado WdfRequestMarkCancelable ou WdfRequestMarkCancelableEx, a função de retorno de chamada EvtRequestCancel do driver poderá chamar WdfRequestComplete com um parâmetro Status de STATUS_CANCELLED. A função de retorno de chamada EvtRequestCancel não precisa chamar WdfRequestUnmarkCancelable. Se o driver chamar WdfRequestComplete fora de sua função de retorno de chamada EvtRequestCancel , o driver deverá primeiro chamar WdfRequestUnmarkCancelable.

No entanto, o driver não deve chamar WdfRequestUnmarkCancelable após EvtRequestCancel chamar WdfRequestComplete. Na seção Exemplo a seguir, o exemplo armazena uma cópia local do identificador de solicitação e a limpa quando a função de retorno de chamada EvtRequestCancel chama WdfRequestComplete. O driver não chamará WdfRequestUnmarkCancelable se a cópia local do identificador de solicitação tiver sido limpa. Este exemplo usa a sincronização automática da estrutura para sincronizar as funções de retorno de chamada.

Observe que chamar WdfObjectReference para adicionar uma referência adicional ao objeto de solicitação não permite que o driver chame WdfRequestUnmarkCancelable após a função de retorno de chamada EvtRequestCancel do driver chamar WdfRequestComplete.

Se WdfRequestUnmarkCancelable retornar STATUS_CANCELLED e, em seguida, EvtRequestCancel concluir a solicitação, o driver não deverá usar o objeto de solicitação posteriormente.

Se WdfRequestUnmarkCancelable retornar STATUS_CANCELLED, o driver não deverá concluir a solicitação antes que a estrutura chame EvtRequestCancel. Caso contrário, a estrutura pode chamar evtRequestCancel do driver com uma solicitação inválida. Para obter exemplos de código relacionados, consulte IWDFIoRequest::UnmarkCancelable.

Para obter mais informações sobre WdfRequestUnmarkCancelable, consulte Cancelando solicitações de E/S.

Exemplos

O exemplo de código a seguir fornece versões simplificadas das funções de retorno de chamada EvtIoRead, EvtRequestCancel e EvtTimerFunc que o driver de exemplo ECHO contém. Este exemplo mostra como chamar WdfRequestMarkCancelable, WdfRequestUnmarkCancelable e WdfRequestComplete em um driver que usa a sincronização automática da estrutura. (O exemplo ECHO usa sincronização no nível do dispositivo.)

Se o driver não usar a sincronização automática da estrutura, consulte os dois exemplos em IWDFIoRequest::UnmarkCancelable. Enquanto gravados para um driver UMDF, esses exemplos demonstram técnicas que você pode usar para gerenciar a sincronização entre o retorno de chamada de cancelamento e outro thread que chama a rotina da Dinamarca .

VOID
  EchoEvtIoRead(
    IN WDFQUEUE  Queue,
    IN WDFREQUEST  Request,
    IN size_t  Length
    )
{
    PQUEUE_CONTEXT queueContext = QueueGetContext(Queue);

    // Prepare for read operation here.
    // (See the Echo sample driver for details.) 
 ...
    // Enable cancellation.
    WdfRequestMarkCancelable(
                             Request,
                             EchoEvtRequestCancel
                             );

    // Save the request handle. We'll clear it after
    // we call WdfRequestComplete.
    queueContext->CurrentRequest = Request;
    return
}


VOID
 EchoEvtRequestCancel(
    IN WDFREQUEST  Request
    )
{
    PQUEUE_CONTEXT queueContext = 
        QueueGetContext(WdfRequestGetIoQueue(Request));

    WdfRequestComplete(
                       Request,
                       STATUS_CANCELLED,
     );
    // Clear the request handle so EchEvtTimerFunc will
    // know that we called WdfRequestComplete.
    queueContext->CurrentRequest = NULL;

    return;
}


VOID
  EchoEvtTimerFunc(
    IN WDFTIMER  Timer
    )
{
    NTSTATUS  Status;
    WDFREQUEST  Request;
    WDFQUEUE  queue;
    PQUEUE_CONTEXT  queueContext;

    // Retrieve our saved copy of the request handle.
    queue = WdfTimerGetParentObject(Timer);
    queueContext = QueueGetContext(queue);
    Request = queueContext->CurrentRequest;

    // We cannot call WdfRequestUnmarkCancelable
    // after a request completes, so check here to see
    // if EchoEvtRequestCancel cleared our saved
    // request handle. 
    if( Request != NULL ) {
        Status = WdfRequestUnmarkCancelable(Request);
        if(Status != STATUS_CANCELLED) {
            queueContext->CurrentRequest = NULL;
            Status = queueContext->CurrentStatus;
            WdfRequestComplete(
                               Request,
                               Status
                               );
        }
    }

    return;
}

Requisitos

Requisito Valor
Plataforma de Destino Universal
Versão mínima do KMDF 1.0
Versão mínima do UMDF 2,0
Cabeçalho wdfrequest.h (inclua Wdf.h)
Biblioteca Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF)
IRQL <=DISPATCH_LEVEL
Regras de conformidade de DDI CompleteCanceledReq(kmdf), DeferredRequestCompleted(kmdf), DriverCreate(kmdf), EvtIoStopCancel(kmdf), InvalidReqAccess(kmdf), InvalidReqAccessLocal(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), MarkCancOnCancReqLocal(kmdf), ReqIsCancOnCancReq(kmdf), ReqMarkCancelableSend(kmdf), ReqNotCanceledLocal(kmdf)

Confira também

EvtRequestCancel

WdfRequestComplete

WdfRequestMarkCancelable

WdfRequestMarkCancelableEx