Bagikan melalui


Fungsi WdfRequestMarkCancelable (wdfrequest.h)

[Berlaku untuk KMDF dan UMDF]

Metode WdfRequestMarkCancelable memungkinkan pembatalan permintaan I/O tertentu.

Sintaks

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

Parameter

[in] Request

Handel ke objek permintaan kerangka kerja.

[in] EvtRequestCancel

Penunjuk ke fungsi panggilan balik EvtRequestCancel yang ditentukan driver, yang dipanggil kerangka kerja jika membatalkan permintaan I/O.

Nilai kembali

Tidak ada

Keterangan

Pemeriksaan bug terjadi jika driver menyediakan handel objek yang tidak valid.

Setelah driver Anda menerima permintaan I/O dari kerangka kerja, driver dapat memanggil WdfRequestMarkCancelable atau, dimulai dengan KMDF versi 1.9, WdfRequestMarkCancelableEx untuk membuat permintaan dapat dibatalkan.

Saat memanggil WdfRequestMarkCancelable, driver Anda harus menentukan fungsi panggilan balik EvtRequestCancel . Kerangka kerja memanggil fungsi panggilan balik jika manajer I/O atau driver lain mencoba membatalkan permintaan I/O.

Memilih antara WdfRequestMarkCancelable dan WdfRequestMarkCancelableEx

Jika driver Anda menggunakan sinkronisasi otomatis kerangka kerja, driver dapat memanggil WdfRequestMarkCancelable atau WdfRequestMarkCancelableEx.

Jika driver tidak menggunakan sinkronisasi otomatis, driver harus memanggil WdfRequestMarkCancelableEx alih-alih WdfRequestMarkCancelable karena alasan berikut:

  • Jika permintaan yang ditentukan telah dibatalkan, WdfRequestMarkCancelable memanggil fungsi panggilan balik EvtRequestCancel driver sebelum kembali. Jika driver memperoleh spinlock sebelum memanggil WdfRequestMarkCancelable dan mencoba untuk memperoleh spinlock yang sama di dalam EvtRequestCancel, utas yang sama mencoba untuk memperoleh spinlock yang sama dua kali, menyebabkan kebuntuan.
  • Namun, karena WdfRequestMarkCancelableEx tidak pernah memanggil EvtRequestCancel, skenario ini tidak terjadi. Jika permintaan telah dibatalkan, WdfRequestMarkCancelableEx mengembalikan STATUS_CANCELLED. Jika driver Anda memperoleh spinlock (yang mengatur IRQL ke DISPATCH_LEVEL) sebelum memanggil WdfRequestMarkCancelableEx dan melepaskan spinlock (yang mengatur IRQL ke PASSIVE_LEVEL) setelah WdfRequestMarkCancelableEx kembali, fungsi panggilan balik EvtRequestCancel tidak akan dipanggil sebelum spinlock dirilis. Oleh karena itu, kebuntuan tidak terjadi bahkan jika fungsi panggilan balik EvtRequestCancel menggunakan spinlock yang sama.

Memproses permintaan setelah mengaktifkan pembatalan

Setelah driver memanggil WdfRequestMarkCancelable untuk mengaktifkan pembatalan, permintaan tetap dapat dibatalkan sementara driver memiliki objek permintaan, kecuali driver memanggil WdfRequestUnmarkCancelable.

Jika driver telah memanggil WdfRequestMarkCancelable, dan jika fungsi panggilan balik EvtRequestCancel driver belum dijalankan dan disebut WdfRequestComplete, driver harus memanggil WdfRequestUnmarkCancelable sebelum memanggil WdfRequestComplete di luar fungsi panggilan balik EvtRequestCancel .

Jika driver memanggil WdfRequestForwardToIoQueue untuk meneruskan permintaan ke antrean yang berbeda, aturan berikut berlaku:

  • Permintaan I/O tidak dapat dibatalkan ketika driver Anda meneruskannya ke antrean yang berbeda.

    Umumnya, driver Anda tidak boleh memanggil WdfRequestMarkCancelable untuk mengaktifkan pembatalan permintaan sebelum memanggil WdfRequestForwardToIoQueue. Jika driver membuat permintaan dapat dibatalkan, driver harus memanggil WdfRequestUnmarkCancelable untuk menonaktifkan pembatalan sebelum memanggil WdfRequestForwardToIoQueue.

  • Saat permintaan berada dalam antrean kedua, kerangka kerja memilikinya dan dapat membatalkannya tanpa memberi tahu driver.

    Jika driver memerlukan pemberitahuan pembatalan (sehingga dapat membatalkan alokasi sumber daya apa pun yang mungkin telah dialokasikan sebelum memanggil WdfRequestForwardToIoQueue), driver harus mendaftarkan fungsi panggilan balik EvtIoCanceledOnQueue , dan harus menggunakan memori konteks khusus permintaan untuk menyimpan informasi tentang sumber daya permintaan.

  • Setelah kerangka kerja menghapus antrean permintaan dari antrean kedua dan mengirimkannya ke driver, driver dapat memanggil WdfRequestMarkCancelable untuk mengaktifkan pembatalan.
Untuk informasi selengkapnya tentang WdfRequestMarkCancelable, lihat Membatalkan Permintaan I/O.

Contoh

Contoh kode berikut menunjukkan bagian dari dua fungsi panggilan balik:

  • Fungsi panggilan balik EvtIoRead yang melakukan pekerjaan khusus permintaan (seperti membuat subkueri untuk dikirim ke target I/O), lalu mengaktifkan pembatalan permintaan I/O yang diterima.
  • Fungsi panggilan balik EvtRequestCancel yang membatalkan permintaan I/O.
Driver harus menggunakan sinkronisasi otomatis kerangka kerja.
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
                       );
}

Persyaratan

Persyaratan Nilai
Target Platform Universal
Versi KMDF minimum 1,0
Versi UMDF minimum 2.0
Header wdfrequest.h (termasuk Wdf.h)
Pustaka Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF)
IRQL <=DISPATCH_LEVEL
Aturan kepatuhan 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)

Lihat juga

EvtRequestCancel

WdfRequestComplete

WdfRequestForwardToIoQueue

WdfRequestMarkCancelableEx

WdfRequestUnmarkCancelable