Fungsi WdfIoTargetFormatRequestForIoctl (wdfiotarget.h)

[Berlaku untuk KMDF dan UMDF]

Metode WdfIoTargetFormatRequestForIoctl membangun permintaan kontrol perangkat untuk target I/O tetapi tidak mengirim permintaan.

Sintaks

NTSTATUS WdfIoTargetFormatRequestForIoctl(
  [in]           WDFIOTARGET       IoTarget,
  [in]           WDFREQUEST        Request,
  [in]           ULONG             IoctlCode,
  [in, optional] WDFMEMORY         InputBuffer,
  [in, optional] PWDFMEMORY_OFFSET InputBufferOffset,
  [in, optional] WDFMEMORY         OutputBuffer,
  [in, optional] PWDFMEMORY_OFFSET OutputBufferOffset
);

Parameter

[in] IoTarget

Handel ke objek target I/O lokal atau jarak jauh yang diperoleh dari panggilan sebelumnya ke WdfDeviceGetIoTarget atau WdfIoTargetCreate, atau dari metode yang disediakan target I/O khusus.

[in] Request

Handel ke objek permintaan kerangka kerja. Untuk informasi selengkapnya, lihat bagian Keterangan berikut ini.

[in] IoctlCode

Kode kontrol I/O (IOCTL) yang didukung target I/O.

[in, optional] InputBuffer

Handel ke objek memori kerangka kerja. Objek ini mewakili buffer yang berisi data yang akan dikirim ke target I/O. Untuk informasi selengkapnya, lihat bagian Keterangan berikut ini.

[in, optional] InputBufferOffset

Penunjuk ke struktur WDFMEMORY_OFFSET yang dialokasikan penelepon yang memasok nilai offset dan panjang byte opsional. Kerangka kerja menggunakan nilai-nilai ini untuk menentukan alamat dan panjang awal, dalam buffer input, untuk transfer data. Jika pointer ini NULL, transfer data dimulai di awal buffer input, dan ukuran transfer adalah ukuran buffer.

[in, optional] OutputBuffer

Handel ke objek memori kerangka kerja. Objek ini mewakili buffer yang akan menerima data dari target I/O. Untuk informasi selengkapnya, lihat bagian Keterangan berikut ini.

[in, optional] OutputBufferOffset

Penunjuk ke struktur WDFMEMORY_OFFSET yang dialokasikan penelepon yang memasok nilai offset dan panjang byte opsional. Kerangka kerja menggunakan nilai-nilai ini untuk menentukan alamat dan panjang awal, dalam buffer output, untuk transfer data. Jika pointer ini ADALAH NULL, transfer data dimulai di awal buffer output, dan ukuran transfer adalah ukuran buffer.

Nilai kembali

WdfIoTargetFormatRequestForIoctl mengembalikan STATUS_SUCCESS jika operasi berhasil. Jika tidak, metode ini mungkin mengembalikan salah satu nilai berikut:

Menampilkan kode Deskripsi
STATUS_INVALID_PARAMETER
Parameter yang tidak valid terdeteksi.
STATUS_INVALID_DEVICE_REQUEST
Panjang transfer lebih besar dari panjang buffer, atau permintaan I/O sudah diantrekan ke target I/O.
STATUS_INSUFFICIENT_RESOURCES
Kerangka kerja tidak dapat mengalokasikan sumber daya sistem (biasanya memori).
STATUS_REQUEST_NOT_ACCEPTED
Paket permintaan I/O (IRP) yang diwakili parameter Permintaan tidak menyediakan struktur IO_STACK_LOCATION yang cukup untuk memungkinkan driver meneruskan permintaan.
 

Metode ini juga dapat mengembalikan nilai NTSTATUS lainnya.

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

Keterangan

Gunakan metode WdfIoTargetFormatRequestForIoctl , diikuti oleh metode WdfRequestSend , untuk mengirim permintaan kontrol perangkat baik secara sinkron atau asinkron. Atau, gunakan metode WdfIoTargetSendIoctlSynchronously untuk mengirim permintaan kontrol perangkat secara sinkron.

Untuk informasi selengkapnya tentang permintaan kontrol perangkat, lihat Menggunakan Kode Kontrol I/O.

Anda dapat meneruskan permintaan kontrol perangkat yang diterima driver Anda dalam antrean I/O, atau Anda dapat membuat dan mengirim permintaan baru. Dalam kedua kasus, kerangka kerja memerlukan objek permintaan dan beberapa ruang buffer.

Untuk meneruskan permintaan kontrol perangkat yang diterima driver Anda dalam antrean I/O:

  1. Tentukan handel permintaan yang diterima untuk parameter Permintaan metode WdfIoTargetFormatRequestForIoctl.
  2. Gunakan buffer input permintaan yang diterima untuk parameter InputBuffer metode WdfIoTargetFormatRequestForIoctl.

    Driver harus memanggil WdfRequestRetrieveInputMemory untuk mendapatkan handel ke objek memori kerangka kerja yang mewakili buffer input permintaan, dan harus menggunakan handel tersebut sebagai nilai untuk InputBuffer.

  3. Gunakan buffer output permintaan yang diterima untuk parameter OutputBuffer metode WdfIoTargetFormatRequestForIoctl.

    Driver harus memanggil WdfRequestRetrieveOutputMemory untuk mendapatkan handel ke buffer output permintaan, dan harus menggunakan handel tersebut sebagai nilai untuk OutputBuffer.

Untuk informasi selengkapnya tentang meneruskan permintaan I/O, lihat Meneruskan Permintaan I/O.

Driver sering membagi permintaan I/O yang diterima menjadi permintaan yang lebih kecil yang mereka kirim ke target I/O, sehingga driver Anda mungkin membuat permintaan baru.

Untuk membuat permintaan I/O baru:

  1. Buat objek permintaan baru dan berikan handelnya untuk parameter Permintaan metode WdfIoTargetFormatRequestForIoctl.

    Panggil WdfRequestCreate untuk melakukan pra-alokasi satu atau beberapa objek permintaan. Anda dapat menggunakan kembali objek permintaan ini dengan memanggil WdfRequestReuse. Fungsi panggilan balik EvtDriverDeviceAdd driver Anda dapat melakukan pra-alokasi objek permintaan untuk perangkat.

  2. Sediakan ruang buffer, dan berikan handel buffer untuk parameter InputBuffer dan OutputBuffer metode WdfIoTargetFormatRequestForIoctl.

    Driver Anda harus menentukan ruang buffer ini sebagai handel WDFMEMORY ke memori yang dikelola kerangka kerja. Driver Anda dapat melakukan salah satu hal berikut:

    Perhatikan bahwa jika driver Anda memanggil WdfRequestRetrieveInputMemory atau WdfRequestRetrieveOutputMemory dan meneruskan handel memori ke WdfIoTargetFormatRequestForIoctl, driver tidak boleh menyelesaikan permintaan I/O yang diterima sampai setelah driver menghapus, menggunakan kembali, atau memformat ulang objek permintaan baru yang dibuat driver. (WdfIoTargetFormatRequestForIoctl menaikkan jumlah referensi objek memori. Menghapus, menggunakan kembali, atau memformat ulang objek permintaan mengurangi jumlah referensi objek memori.)
Setelah driver memanggil WdfIoTargetFormatRequestForIoctl untuk memformat permintaan kontrol perangkat, driver harus memanggil WdfRequestSend untuk mengirim permintaan (baik secara sinkron atau asinkron) ke target I/O.

Beberapa panggilan ke WdfIoTargetFormatRequestForIoctl yang menggunakan permintaan yang sama tidak menyebabkan alokasi sumber daya tambahan. Oleh karena itu, untuk mengurangi kemungkinan WdfRequestCreate akan mengembalikan STATUS_INSUFFICIENT_RESOURCES, fungsi panggilan balik EvtDriverDeviceAdd driver Anda dapat memanggil WdfRequestCreate untuk melakukan pra-alokasi satu atau beberapa objek permintaan untuk perangkat. Driver kemudian dapat menggunakan kembali (panggil WdfRequestReuse), reformat (panggil WdfIoTargetFormatRequestForIoctl), dan mengirim ulang (panggil WdfRequestSend) setiap objek permintaan tanpa mempertaruhkan nilai pengembalian STATUS_INSUFFICIENT_RESOURCES dari panggilan selanjutnya ke WdfRequestCreate. Semua panggilan berikutnya ke WdfIoTargetFormatRequestForIoctl untuk objek permintaan yang digunakan kembali akan mengembalikan STATUS_SUCCESS, jika nilai parameter tidak berubah. (Jika driver tidak memanggil metode pemformatan permintaan yang sama setiap kali, sumber daya tambahan mungkin dialokasikan. Selain itu, jika kode kontrol I/O menentukan jenis transfer METHOD_BUFFERED, kerangka kerja harus mengalokasikan buffer sistem untuk setiap permintaan dan alokasi tersebut dapat gagal karena sumber daya memori yang tidak mencukupi.)

Untuk informasi tentang mendapatkan informasi status setelah permintaan I/O selesai, lihat Mendapatkan Informasi Penyelesaian.

Untuk informasi selengkapnya tentang WdfIoTargetFormatRequestForIoctl, lihat Mengirim Permintaan I/O ke Target I/O Umum.

Untuk informasi selengkapnya tentang target I/O, lihat Menggunakan Target I/O.

Contoh

Kode berikut menggunakan kembali objek permintaan yang telah dialokasikan sebelumnya dan objek memori yang telah dialokasikan sebelumnya. Contoh menetapkan buffer input dan output ke objek memori, memformat objek permintaan, mendaftarkan fungsi panggilan balik CompletionRoutine , dan mengirim permintaan ke target I/O.

NTSTATUS
NICSendOidRequestToTargetAsync(
    IN WDFIOTARGET  IoTarget,
    IN WDFREQUEST  Request,
    IN PFILE_OBJECT  FileObject,
    IN ULONG  IoctlControlCode,
    IN OUT PVOID  InputBuffer,
    IN ULONG  InputBufferLength,
    IN OUT PVOID  OutputBuffer,
    IN ULONG  OutputBufferLength,
    OUT PULONG  BytesReadOrWritten
    )
{
    NTSTATUS  status;
    PREQUEST_CONTEXT  reqContext;
    WDF_REQUEST_REUSE_PARAMS  params;
    WDFMEMORY  inputMem, outputMem;
 
    WDF_REQUEST_REUSE_PARAMS_INIT(
                                  &params, 
                                  WDF_REQUEST_REUSE_NO_FLAGS, 
                                  STATUS_SUCCESS
                                  );
    status = WdfRequestReuse(Request, &params);
    if (!NT_SUCCESS(status)){
        return status;
    }

    reqContext = GetRequestContext(Request);

    inputMem = outputMem = NULL;
 
    if (InputBuffer != NULL) {
        status = WdfMemoryAssignBuffer(
                                       reqContext->InputMemory,
                                       InputBuffer, 
                                       InputBufferLength
                                       );
        if (!NT_SUCCESS(status)) {
             return status;
        }
        inputMem = reqContext->InputMemory;
    }

    if (OutputBuffer != NULL) {
        status = WdfMemoryAssignBuffer(
                                       reqContext->OutputMemory,
                                       OutputBuffer, 
                                       OutputBufferLength
                                       );
        if (!NT_SUCCESS(status)) {
            return status;
        }
        outputMem = reqContext->OutputMemory;
    }

    status = WdfIoTargetFormatRequestForIoctl(
                                              IoTarget,
                                              Request,
                                              IoctlControlCode,
                                              inputMem,
                                              NULL,
                                              outputMem,
                                              NULL
                                              );
    if (!NT_SUCCESS(status)) {
        return status;
    }

    WdfRequestSetCompletionRoutine(
                                   Request,
                                   NICSendOidRequestToTargetAsyncCompletionRoutine,
                                   BytesReadOrWritten
                                   );

    if (WdfRequestSend(
                       Request,
                       IoTarget,
                       WDF_NO_SEND_OPTIONS
                       ) == FALSE) {
        status = WdfRequestGetStatus(Request);
    }
    return status;
}

Persyaratan

Persyaratan Nilai
Target Platform Universal
Versi KMDF minimum 1,0
Versi UMDF minimum 2.0
Header wdfiotarget.h (termasuk Wdf.h)
Pustaka Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF)
IRQL <=DISPATCH_LEVEL
Aturan kepatuhan DDI DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), RequestFormattedValid(kmdf), RequestSendAndForgetNoFormatting(kmdf), RequestSendAndForgetNoFormatting2(kmdf)

Lihat juga

EvtDriverDeviceAdd

WDFMEMORY_OFFSET

WdfDeviceGetIoTarget

WdfIoTargetBuat

WdfIoTargetFormatRequestForInternalIoctl

WdfIoTargetSendIoctlSynchronously

WdfMemoryCreate

WdfMemoryCreatePreallocated

WdfRequestCreate

WdfRequestRetrieveInputMemory

WdfRequestRetrieveOutputMemory

WdfRequestReuse

WdfRequestSend