Função WdfRequestMarkCancelable (wdfrequest.h)

[Aplica-se a KMDF e UMDF]

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

Sintaxe

void WdfRequestMarkCancelable(
  [in] WDFREQUEST             Request,
  [in] PFN_WDF_REQUEST_CANCEL EvtRequestCancel
);

Parâmetros

[in] Request

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

[in] EvtRequestCancel

Um ponteiro para uma função de retorno de chamada EvtRequestCancel definida pelo driver, que a estrutura chama se cancela a solicitação de E/S.

Retornar valor

Nenhum

Comentários

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

Depois que o driver receber uma solicitação de E/S da estrutura, o driver poderá chamar WdfRequestMarkCancelable ou, começando com KMDF versão 1.9, WdfRequestMarkCancelableEx para tornar a solicitação cancelável.

Ao chamar WdfRequestMarkCancelable, o driver deve especificar uma função de retorno de chamada EvtRequestCancel . A estrutura chamará a função de retorno de chamada se o gerenciador de E/S ou outro driver estiver tentando cancelar a solicitação de E/S.

Escolhendo entre WdfRequestMarkCancelable e WdfRequestMarkCancelableEx

Se o driver usar a sincronização automática da estrutura, o driver poderá chamar WdfRequestMarkCancelable ou WdfRequestMarkCancelableEx.

Se o driver não usar a sincronização automática, ele deverá chamar WdfRequestMarkCancelableEx em vez de WdfRequestMarkCancelable pelos seguintes motivos:

  • Se a solicitação especificada já tiver sido cancelada, WdfRequestMarkCancelable chamará a função de retorno de chamada EvtRequestCancel do driver antes de retornar. Se o driver adquirir um spinlock antes de chamar WdfRequestMarkCancelable e tentar adquirir o mesmo spinlock dentro de EvtRequestCancel, o mesmo thread tentará adquirir o mesmo spinlock duas vezes, causando um deadlock.
  • No entanto, como WdfRequestMarkCancelableEx nunca chama EvtRequestCancel, esse cenário não ocorre. Se a solicitação já tiver sido cancelada, WdfRequestMarkCancelableEx retornará STATUS_CANCELLED. Se o driver adquirir um spinlock (que define o IRQL como DISPATCH_LEVEL) antes de chamar WdfRequestMarkCancelableEx e liberar o spinlock (que define o IRQL como PASSIVE_LEVEL) depois que WdfRequestMarkCancelableEx retornar, a função de retorno de chamada EvtRequestCancel não será chamada antes do spinlock ser lançado. Portanto, um deadlock não ocorre mesmo que a função de retorno de chamada EvtRequestCancel use o mesmo spinlock.

Processando uma solicitação após habilitar o cancelamento

Depois que um driver chama WdfRequestMarkCancelable para habilitar o cancelamento, a solicitação permanece cancelável enquanto o driver possui o objeto de solicitação, a menos que o driver chame WdfRequestUnmarkCancelable.

Se um driver tiver chamado WdfRequestMarkCancelable e se a função de retorno de chamada EvtRequestCancel do driver não tiver sido executada e chamada WdfRequestComplete, o driver deverá chamar WdfRequestUnmarkCancelable antes de chamar WdfRequestComplete fora da função de retorno de chamada EvtRequestCancel .

Se o driver chamar WdfRequestForwardToIoQueue para encaminhar a solicitação para uma fila diferente, as seguintes regras se aplicarão:

  • As solicitações de E/S não podem ser canceladas quando o driver as encaminha para uma fila diferente.

    Em geral, o driver não deve chamar WdfRequestMarkCancelable para habilitar o cancelamento da solicitação antes de chamar WdfRequestForwardToIoQueue. Se o driver tornar a solicitação cancelável, ele deverá chamar WdfRequestUnmarkCancelable para desabilitar o cancelamento antes de chamar WdfRequestForwardToIoQueue.

  • Embora a solicitação esteja na segunda fila, a estrutura a possui e pode cancelá-la sem notificar o driver.

    Se o driver exigir notificação de cancelamento (para que ele possa desalocar todos os recursos que ele possa ter alocado antes de chamar WdfRequestForwardToIoQueue), o driver deverá registrar uma função de retorno de chamada EvtIoCanceledOnQueue e deve usar a memória de contexto específica da solicitação para armazenar informações sobre os recursos da solicitação.

  • Depois que a estrutura tiver desativado a solicitação da segunda fila e entregue-a ao driver, o driver poderá chamar WdfRequestMarkCancelable para habilitar o cancelamento.
Para obter mais informações sobre WdfRequestMarkCancelable, consulte Cancelando solicitações de E/S.

Exemplos

O exemplo de código a seguir mostra partes de duas funções de retorno de chamada:

  • Uma função de retorno de chamada EvtIoRead que executa um trabalho específico da solicitação (como a criação de sub-solicitações para enviar para um destino de E/S) e, em seguida, permite o cancelamento da solicitação de E/S recebida.
  • Uma função de retorno de chamada EvtRequestCancel que cancela uma solicitação de E/S.
O driver deve usar a sincronização automática da estrutura.
VOID
MyEvtIoRead(
    IN WDFQUEUE  Queue,
    IN WDFREQUEST  Request,
    IN size_t  Length
    )
{
...
    // Perform request-specific work here
    // (such as creating subrequests 
    // to send to an I/O target). 
...
    WdfRequestMarkCancelable(
                             Request,
                             MyEvtRequestCancel
                             );
    }
...
}
VOID
MyEvtRequestCancel(
    IN WDFREQUEST  Request
    )
{
    // Remove request-specific work here, because
    // we don't want the work to be done if the
    // request was canceled.

    WdfRequestComplete(
                       Request,
                       STATUS_CANCELLED
                       );
}

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 da DDI DeferredRequestCompleted(kmdf), DriverCreate(kmdf), EvtIoStopCancel(kmdf), InvalidReqAccess(kmdf), InvalidReqAccessLocal(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), MarkCancOnCancReqLocal(kmdf), ReqIsCancOnCancReq(kmdf), ReqMarkCancelableSend(kmdf), ReqNotCanceledLocal(kmdf), RequestCompleted(kmdf), RequestCompletedLocal( kmdf)

Confira também

EvtRequestCancel

WdfRequestComplete

WdfRequestForwardToIoQueue

WdfRequestMarkCancelableEx

WdfRequestUnmarkCancelable