Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Çerçeve isteği nesnesini izlemek zor olduğundan ertelenen yordam çağrıları (DPC) Statik Sürücü Doğrulayıcı'ya (SDV) yönelik güçlükler sunar. Bir zorluk, isteğin genellikle kuyruk bağlamından veya bir iş öğesinden küresel bir işaretçiden geri çağrılması gerektiğidir. Statik Sürücü Doğrulayıcı bu zorluğu aşmak için iki işlev sağlar: __sdv_save_request ve __sdv_retrieve_request. Bu işlevler ertelenen isteği SDV'nin izleyebileceği bir istekle eşler.
__sdv_save_request ve __sdv_retrieve_request işlevleri aşağıdaki söz dizimine sahiptir:
__sdv_save_request( request )
__sdv_retrieve_request( request )
Burada istek , herhangi bir çerçeve isteği nesnesinin tanıtıcısı olabilir.
Bu işlevler yalnızca statik çözümleme araçları tarafından kullanılır. Fonksiyonlar derleyici tarafından yoksayılır.
Aşağıdaki kod örneği , __sdv_save_request ve __sdv_retrieve_request işlevlerinin, SDV'nin ertelenen isteği eşleyebilmesi için SDV'ye yol göstermek için nasıl kullanıldığını gösterir. SDV, DeferredRequestCompleted kuralını doğrulamak için bu eşlemeyi kullanabilir. DeferredRequestCompleted kuralı, kodunuzda __sdv_save_request ve __sdv_retrieve_request gösterilmesini gerektirir. __sdv_save_request ve __sdv_retrieve_request işlevlerinin varlığını arayan iki sürücü özelliği kuralı (AliasWithinDispatch, AliasWithinTimerDpc) vardır.
Aşağıdaki kod örneğinde EchoEvtIoRead işlevi, tanıtıcıyı kuyruk bağlam alanındaki çerçeve isteği nesnesine kaydeden bir EvtIoRead olay geri çağırma işlevidir. EchoEvtTimerFunc işlevi, onu alan bir EvtTimerFunc olay geri çağırma işlevidir.
VOID
EchoEvtIoRead(
)in WDFQUEUE Queue,
__in WDFREQUEST Request,
__in size_t Length
)
{
/* ..................... */
// Mark the request as cancelable
WdfRequestMarkCancelable(Request, EchoEvtRequestCancel);
// Defer the completion to another thread from the timer DPC and save the handle to the framework request object by using the __sdv_save_request function.
queueContext->CurrentRequest = Request;
__sdv_save_request(Request);
queueContext->CurrentStatus = Status;
return;
}
Aşağıda verilen kod örneği, `__sdv_retrieve_request` işlevinin SDV'nin bir talebin tamamlanmasını takip edebilmesi için var olan bir talebi nasıl eşlediğini gösterir.
VOID
EchoEvtTimerFunc(
IN WDFTIMER Timer
)
{...................................................
queue = WdfTimerGetParentObject(Timer);
queueContext = QueueGetContext(queue);
//
// The DPC is automatically synchronized to the queue lock,
// so this prevents race conditions from occurring without explicit driver-managed locking. The __sdv_retrieve_request function is used so that SDV can restore the deferred request in the timer DPC. Because we know that this deferred request is valid (because it has been previously saved), the __analysis_assume function is used to suppress false defects that might otherwise result in this code path.
//
__sdv_retrieve_request(queueContext->CurrentRequest);
Request = queueContext->CurrentRequest;
__analysis_assume(Request != NULL);
if( Request != NULL ) {
//
// Try to remove cancel status from the request.
//
// The request is not completed if it is already canceled
// because the EchoEvtIoCancel function has run, or is about to run,
// and we are racing with it.
Status = WdfRequestUnmarkCancelable(Request);
// Because we know that the request is not NULL in this code path and that the request is no longer marked cancelable, we can use the __analysis_assume function to suppress the reporting of a false defect.
__analysis_assume(Status != STATUS_CANCELLED);
if( Status != STATUS_CANCELLED ) {
queueContext->CurrentRequest = NULL;
Status = queueContext->CurrentStatus;
KdPrint(("CustomTimerDPC Completing request 0x%p, Status 0x%x \n", Request,Status));
WdfRequestComplete(Request, Status);
}
else {
KdPrint(("CustomTimerDPC Request 0x%p is STATUS_CANCELLED, not completing\n",
Request));
}
}
return;
}