EVT_UFX_DEVICE_ENDPOINT_ADD コールバック関数 (ufxclient.h)

既定のエンドポイント オブジェクトを作成するためのクライアント ドライバーの実装。

構文

EVT_UFX_DEVICE_ENDPOINT_ADD EvtUfxDeviceEndpointAdd;

NTSTATUS EvtUfxDeviceEndpointAdd(
  [in]      UFXDEVICE unnamedParam1,
  [in]      const PUSB_ENDPOINT_DESCRIPTOR unnamedParam2,
  [in, out] PUFXENDPOINT_INIT unnamedParam3
)
{...}

パラメーター

[in] unnamedParam1

UfxDeviceCreate の前回の呼び出しでクライアント ドライバーが受信した USB デバイス オブジェクトへのハンドル。

[in] unnamedParam2

記述子データを含む USB_ENDPOINT_DESCRIPTOR 構造体へのポインター。

[in, out] unnamedParam3

エンドポイント オブジェクトの作成に必要なエンドポイント記述子を含む、UFXENDPOINT_INIT不透明な構造体へのポインター。

戻り値

操作が成功した場合、コールバック関数は STATUS_SUCCESS、または NT_SUCCESS(status) が TRUE に等しい別の状態値を返す必要があります。 それ以外の場合は、NT_SUCCESS(status) が FALSE である状態値を返す必要があります。

注釈

関数ホスト コントローラーのクライアント ドライバーは、UfxDeviceCreate メソッドを呼び出して、そのEVT_UFX_DEVICE_ENDPOINT_ADD実装を USB 関数クラス拡張機能 (UFX) に登録します。

エンドポイントを作成するには、クライアント ドライバーがエンドポイントの転送キューとコマンド キューの属性を初期化し、 UfxEndpointCreate を呼び出してエンドポイントを作成することが想定されています。

クライアント ドライバーは、 UfxDeviceEventComplete メソッドを呼び出すことによって、このイベントの完了を示します。

EVT_UFX_DEVICE_ENDPOINT_ADD UfxDevice_EvtDeviceEndpointAdd;

NTSTATUS
UfxDevice_EvtDeviceEndpointAdd (
    _In_ UFXDEVICE UfxDevice,
    _In_ const PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor,
    _Inout_ PUFXENDPOINT_INIT EndpointInit
    )
/*++

Routine Description:

    EvtDeviceEndpointAdd handler for the UFXDEVICE object.
    Creates UFXENDPOINT object corresponding to the newly reported endpoint.

Arguments:

    UfxDevice - UFXDEVICE object representing the device.

    EndpointDescriptor - Constant Pointer to Endpoint descriptor for the
        newly reported endpoint.

    EndpointInit - Pointer to the Opaque UFXENDPOINT_INIT object

Return Value:

    STATUS_SUCCESS on success, or an appropriate NTSTATUS message on failure.

--*/
{
    NTSTATUS Status;
    WDF_OBJECT_ATTRIBUTES Attributes;
    WDF_IO_QUEUE_CONFIG TransferQueueConfig;
    WDF_OBJECT_ATTRIBUTES TransferQueueAttributes;
    WDF_IO_QUEUE_CONFIG CommandQueueConfig;
    WDF_OBJECT_ATTRIBUTES CommandQueueAttributes;
    UFXENDPOINT Endpoint;
    PUFXENDPOINT_CONTEXT EpContext;
    PUFXDEVICE_CONTEXT DeviceContext;
    UFX_ENDPOINT_CALLBACKS Callbacks;
    PENDPOINT_QUEUE_CONTEXT QueueContext;
    WDFQUEUE Queue;

    TraceEntry();


    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&Attributes, UFXENDPOINT_CONTEXT);
    Attributes.ExecutionLevel = WdfExecutionLevelPassive;
    Attributes.EvtCleanupCallback = UfxEndpoint_Cleanup;

    //
    // Note: Execution level needs to be passive to avoid deadlocks with WdfRequestComplete.
    //
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&TransferQueueAttributes, ENDPOINT_QUEUE_CONTEXT);
    TransferQueueAttributes.ExecutionLevel = WdfExecutionLevelPassive;
    
    WDF_IO_QUEUE_CONFIG_INIT(&TransferQueueConfig, WdfIoQueueDispatchManual);
    TransferQueueConfig.AllowZeroLengthRequests = TRUE;
    TransferQueueConfig.EvtIoStop = EndpointQueue_EvtIoStop;

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&CommandQueueAttributes, ENDPOINT_QUEUE_CONTEXT);
    CommandQueueAttributes.ExecutionLevel = WdfExecutionLevelPassive;

    WDF_IO_QUEUE_CONFIG_INIT(&CommandQueueConfig, WdfIoQueueDispatchSequential);
    CommandQueueConfig.EvtIoInternalDeviceControl = EvtEndpointCommandQueue;

    UFX_ENDPOINT_CALLBACKS_INIT(&Callbacks);
    UfxEndpointInitSetEventCallbacks(EndpointInit, &Callbacks);

    Status = UfxEndpointCreate(
                 Device,
                 EndpointInit,
                 &Attributes,
                 &TransferQueueConfig,
                 &TransferQueueAttributes,
                 &CommandQueueConfig,
                 &CommandQueueAttributes,
                 &Endpoint);


    Status = WdfCollectionAdd(DeviceContext->Endpoints, Endpoint);


    EpContext = UfxEndpointGetContext(Endpoint);
    EpContext->UfxDevice = Device;
    EpContext->WdfDevice = DeviceContext->FdoWdfDevice;
    RtlCopyMemory(&EpContext->Descriptor, Descriptor, sizeof(*Descriptor));

    Queue = UfxEndpointGetTransferQueue(Endpoint);
    QueueContext = EndpointQueueGetContext(Queue);
    QueueContext->Endpoint = Endpoint;

    Queue = UfxEndpointGetCommandQueue(Endpoint);
    QueueContext = EndpointQueueGetContext(Queue);
    QueueContext->Endpoint = Endpoint;

    //
    // This can happen if we're handling a SetInterface command.
    //
    if (DeviceContext->UsbState == UsbfnDeviceStateConfigured) {
        UfxEndpointConfigure(Endpoint);
    }

    Status = WdfIoQueueReadyNotify(
                 UfxEndpointGetTransferQueue(Endpoint),
                 TransferReadyNotify,
                 Endpoint);

End:
    TraceExit();
    return Status;
}

要件

要件
対象プラットフォーム Windows
最小 KMDF バージョン 1.0
最小 UMDF バージョン 2.0
Header ufxclient.h
IRQL PASSIVE_LEVEL

こちらもご覧ください

UfxDeviceCreate

UfxDeviceEventComplete