同步傳送 I/O 要求

下表列出驅動程式可以呼叫的 I/O 目標物件方法,以同步傳送 I/O 要求至 I/O 目標。 如需如何使用這些方法的詳細資訊,請參閱方法的參考頁面。

方法 目的

WdfIoTargetSendReadSynchronously

傳送讀取要求

WdfIoTargetSendWriteSynchronously

傳送寫入要求

WdfIoTargetSendIoctlSynchronously

傳送裝置控制要求

WdfIoTargetSendInternalIoctlSynchronously

傳送內部裝置控制要求

WdfIoTargetSendInternalIoctlOthersSynchronously

傳送非標準內部裝置控制要求

您也可以呼叫 WdfRequestSend以同步方式傳送要求,但必須先遵循 非同步傳送 I/O 要求中所述的規則來格式化要求。

以同步方式將 I/O 要求傳送至 I/O 目標比 非同步傳送 I/O 要求更簡單。 不過,您應該使用下列指導方針來協助您決定同步 I/O 是否適合您的驅動程式:

  • 如果您的驅動程式未傳送許多 I/O 要求,而且系統或裝置效能未降低,則可以使用同步 I/O,因為您的驅動程式會等候每個 I/O 要求完成。

  • 如果您的驅動程式必須在短時間內處理許多 I/O 要求,您可能不允許驅動程式等候每個要求完成,再傳送下一個要求。 否則,您的驅動程式可能會遺失資料或降低其裝置 (的效能,也可能是整個系統) 。 在這種情況下,非同步 I/O 可能是更好的選擇。

  • 同步 I/O 適用于處理必須啟動和完成的作業,而不需要額外的並行活動。 這類作業可能包括重設 USB 管道或讀取裝置暫存器。

  • 大部分時候,當驅動程式呼叫同步傳送 I/O 要求的物件方法時,應該指定逾時值。 如果您的驅動程式未指定逾時值,而且如果裝置或較低層級的驅動程式無法回應,您的驅動程式可能會停止。 因此,使用者可以體驗沒有回應的應用程式。 此外,如果您的驅動程式未釋放,其他驅動程式可能無法取得系統資源,例如 工作專案

  • 如果堆疊中的上方和下方的驅動程式需要以同步方式繼續作業,您的驅動程式應該使用同步 I/O。 因此,您應該瞭解可能存在於驅動程式堆疊中的其他驅動程式需求。

下列範例示範如何傳送同步 I/O 控制項 (IOCTL) 要求:

NTSTATUS                status;
    WDF_MEMORY_DESCRIPTOR   inputDesc, outputDesc;
    PWDF_MEMORY_DESCRIPTOR  pInputDesc = NULL, pOutputDesc = NULL;
    ULONG_PTR               bytesReturned;

    UNREFERENCED_PARAMETER(FileObject);

    if (InputBuffer) {
        WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&inputDesc,
                                    InputBuffer,
                                    InputBufferLength);
        pInputDesc = &inputDesc;
    }

    if (OutputBuffer) {
        WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&outputDesc,
                                    OutputBuffer,
                                    OutputBufferLength);
        pOutputDesc = &outputDesc;
    }

    status = WdfIoTargetSendIoctlSynchronously(
                        IoTarget,
                        WDF_NO_HANDLE, // Request
                        IoctlControlCode,
                        pInputDesc,
                        pOutputDesc,
                        NULL, // PWDF_REQUEST_SEND_OPTIONS
                        &bytesReturned);
    if (!NT_SUCCESS(status)) {
         DEBUGP(MP_ERROR,
        ("WdfIoTargetSendIoctlSynchronously failed 0x%x\n",
          status));
    }

    *BytesReadOrWritten = (ULONG)bytesReturned;