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 |
---|---|
|
Um parâmetro de entrada é inválido ou a solicitação já não pode ser cancelada. |
|
O driver não possui a solicitação. |
|
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) |