Fungsi IoBuildAsynchronousFsdRequest (wdm.h)

Rutinitas IoBuildAsynchronousFsdRequest mengalokasikan dan menyiapkan IRP untuk dikirim ke driver tingkat bawah.

Sintaks

__drv_aliasesMem PIRP IoBuildAsynchronousFsdRequest(
  [in]           ULONG            MajorFunction,
  [in]           PDEVICE_OBJECT   DeviceObject,
  [in, out]      PVOID            Buffer,
  [in, optional] ULONG            Length,
  [in, optional] PLARGE_INTEGER   StartingOffset,
  [in, optional] PIO_STATUS_BLOCK IoStatusBlock
);

Parameter

[in] MajorFunction

Kode fungsi utama yang akan diatur dalam IRP. Kode ini dapat IRP_MJ_PNP, IRP_MJ_READ, IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS, atau IRP_MJ_SHUTDOWN.

[in] DeviceObject

Penunjuk ke objek perangkat driver berikutnya yang lebih rendah. Objek ini mewakili perangkat target untuk operasi baca, tulis, hapus, atau matikan.

[in, out] Buffer

Penunjuk ke buffer tempat data dibaca atau dari mana data ditulis. Nilai argumen ini adalah NULL untuk permintaan flush dan shutdown.

[in, optional] Length

Panjangnya, dalam byte, dari buffer yang diacu oleh Buffer. Untuk perangkat seperti disk, nilai ini harus berupa kelipatan bilangan bulat dari ukuran sektor. Dimulai dengan Windows 8, ukuran sektor bisa 4.096 atau 512 byte. Di versi Windows sebelumnya, ukuran sektor selalu 512 byte. Parameter ini diperlukan untuk permintaan baca dan tulis, tetapi harus nol untuk permintaan flush dan shutdown.

[in, optional] StartingOffset

Penunjuk ke offset awal pada media input/output. Nilai argumen ini adalah nol untuk permintaan flush dan shutdown.

[in, optional] IoStatusBlock

Penunjuk ke alamat blok status I/O tempat driver yang akan dipanggil mengembalikan status akhir tentang operasi yang diminta.

Nilai kembali

IoBuildAsynchronousFsdRequest mengembalikan pointer ke IRP, atau penunjuk NULL jika IRP tidak dapat dialokasikan.

Keterangan

Driver tingkat menengah atau tertinggi dapat memanggil IoBuildAsynchronousFsdRequest untuk menyiapkan RUN untuk permintaan yang dikirim ke driver tingkat bawah. Driver panggilan harus menyediakan rutinitas IoCompletion untuk IRP, sehingga IRP dapat dialokasikan dengan IoFreeIrp. Untuk informasi selengkapnya tentang dealokasi IRP, lihat Contoh.

IRP yang dibangun hanya berisi informasi yang cukup untuk memulai operasi dan untuk menyelesaikan IRP. Tidak ada informasi konteks lain yang dilacak karena permintaan asinkron tidak bergantung pada konteks.

Driver tingkat bawah mungkin memberlakukan pembatasan pada parameter yang disediakan untuk rutinitas ini. Misalnya, driver disk mungkin mengharuskan nilai yang disediakan untuk Panjang dan StartingOffset adalah kelipatan bilangan bulat dari ukuran sektor perangkat.

Driver tingkat menengah atau tertinggi juga dapat memanggil IoBuildDeviceIoControlRequest, IoAllocateIrp, atau IoBuildSynchronousFsdRequest untuk menyiapkan permintaan yang dikirimnya ke driver tingkat bawah. Hanya driver tingkat tertinggi yang dapat memanggil IoMakeAssociatedIrp.

Selama panggilan IoBuildAsynchronousFsdRequest , manajer I/O mengatur anggota Tail.Overlay.Thread dari struktur IRP untuk menunjuk ke objek utas pemanggil, tetapi tidak mengambil referensi yang dihitung ke objek utas atas nama pemanggil. Setelah penelepon mengirim IRP ke driver untuk perangkat target, driver ini mungkin menggunakan anggota Tail.Overlay.Thread untuk mengakses objek utas. Misalnya, driver penyimpanan mungkin memanggil rutinitas IoSetHardErrorOrVerifyDevice dan menyediakan pointer ke IRP sebagai parameter input. Selama panggilan ini, IoSetHardErrorOrVerifyDevice menggunakan anggota Tail.Overlay.Thread untuk mengakses objek utas. Ketika objek utas diakses dengan cara ini, driver yang disebut IoBuildAsynchronousFsdRequest untuk mengalokasikan IRP bertanggung jawab untuk memastikan bahwa objek utas tetap valid saat IRP sedang ditangani.

Agar objek utas tetap valid, driver yang memanggil IoBuildAsynchronousFsdRequest dapat mengambil referensi yang dihitung pada objek utas sebelum mengirim IRP. Misalnya, driver ini dapat memanggil rutinitas dan pasokan ObReferenceObjectByPointerWithTag , sebagai parameter Objek , penunjuk objek dari anggota Tail.Overlay.Thread dari struktur IRP . Nantinya, rutinitas penyelesaian driver ini dapat mendereferensikan objek dengan memanggil rutinitas seperti ObDereferenceObjectWithTag.

Driver mungkin memanggil IoBuildAsynchronousFsdRequest dalam satu utas, dan mengirim IRP yang dialokasikan oleh panggilan ini di utas lain. Sebelum mengirim IRP, driver ini harus mengatur anggota Tail.Overlay.Thread dari IRP untuk menunjuk ke objek utas untuk utas pengirim. Biasanya, driver memanggil rutinitas PsGetCurrentThread untuk mendapatkan penunjuk objek utas.

Driver yang memanggil IoBuildAsynchronousFsdRequest untuk mengalokasikan IRP tidak selalu perlu mengambil referensi yang dihitung pada objek utas yang ditunjukkan oleh anggota Tail.Overlay.Thread dari IRP. Driver mungkin menggunakan teknik lain untuk menjamin bahwa objek utas ini tetap valid saat IRP sedang ditangani. Misalnya, jika driver membuat utas, utas dapat menunggu sampai IRP selesai untuk mengakhiri dirinya sendiri.

Contoh

Sebelum memanggil IoFreeIrp, langkah tambahan diperlukan untuk membebaskan buffer untuk IRP yang dibangun oleh IoBuildAsynchronousFsdRequest jika semuanya benar:

  • Buffer dialokasikan dari kumpulan memori sistem.

  • Di objek perangkat untuk perangkat target, bendera DO_DIRECT_IO diatur di bidang DeviceObject-Flags>.

  • Bidang Irp-MdlAddress> bukan NULL.

Sebelum membebaskan buffer untuk IRP ini, panggil rutinitas MmUnlockPages dengan Irp-MdlAddress> sebagai nilai parameter. Panggilan ini mengurangi jumlah referensi tambahan yang ditambahkan IoBuildAsynchronousFsdRequest ke halaman kumpulan di MDL. Jika tidak, panggilan berikutnya ke IoFreeMdl akan diperiksa bug karena jumlah referensi untuk halaman kumpulan ini akan menjadi 2, bukan 1. Contoh kode berikut menunjukkan panggilan MmUnlockPages, IoFreeMdl, dan IoFreeIrp untuk kasus ini:

if (((DeviceObject->Flags & DO_DIRECT_IO) == DO_DIRECT_IO) &&
    (Irp->MdlAddress != NULL))
{
    MmUnlockPages(Irp->MdlAddress);
}

IoFreeMdl(Irp->MdlAddress);
IoFreeIrp(Irp);

Persyaratan

Persyaratan Nilai
Target Platform Universal
Header wdm.h (termasuk Wdm.h, Ntddk.h, Ntifs.h)
Pustaka NtosKrnl.lib
DLL NtosKrnl.exe
IRQL IRQL <= APC_LEVEL
Aturan kepatuhan DDI ForwardedAtBadIrqlFsdAsync(wdm), HwStorPortProhibitedDDIs(storport), IoBuildFsdComplete(wdm), IoBuildFsdForward(wdm), IoBuildFsdFree(wdm)

Lihat juga

IO_STACK_LOCATION

IRP

IoAllocateIrp

IoBuildDeviceIoControlRequest

IoBuildSynchronousFsdRequest

IoCallDriver

IoFreeIrp

IoFreeMdl

IoMakeAssociatedIrp

IoSetCompletionRoutine

IoSetHardErrorOrVerifyDevice

MmUnlockPages

ObDereferenceObjectWithTag

ObReferenceObjectByPointerWithTag

PsGetCurrentThread