UfxEndpointCreate 関数 (ufxclient.h)

エンドポイント オブジェクトを作成します。

構文

NTSTATUS UfxEndpointCreate(
  [in]           UFXDEVICE              UfxDevice,
  [in, out]      PUFXENDPOINT_INIT      EndpointInit,
  [in, optional] PWDF_OBJECT_ATTRIBUTES Attributes,
  [in]           PWDF_IO_QUEUE_CONFIG   TransferQueueConfig,
  [in, optional] PWDF_OBJECT_ATTRIBUTES TransferQueueAttributes,
  [in]           PWDF_IO_QUEUE_CONFIG   CommandQueueConfig,
  [in, optional] PWDF_OBJECT_ATTRIBUTES CommandQueueAttributes,
  [out]          UFXENDPOINT            *UfxEndpoint
);

パラメーター

[in] UfxDevice

ドライバーが UfxDeviceCreate を呼び出して作成した UFX デバイス オブジェクトへのハンドル。

[in, out] EndpointInit

EVT_UFX_DEVICE_ENDPOINT_ADDまたはEVT_UFX_DEVICE_DEFAULT_ENDPOINT_ADDの呼び出しで UFX によって渡される不透明な構造体。

[in, optional] Attributes

呼び出し元によって割り当てられた WDF_OBJECT_ATTRIBUTES 構造体へのポインター。 この構造体は、 WDF_OBJECT_ATTRIBUTES_INIT または WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPEで初期化する必要があります。 このパラメーターは省略可能であり、 WDF_NO_OBJECT_ATTRIBUTESできます。

[in] TransferQueueConfig

構造体に割り当てられた呼び出し元 へのポインター WDF_IO_QUEUE_CONFIG 。 この構造体は 、WDF_IO_QUEUE_CONFIG_INITで初期化する必要があります。

[in, optional] TransferQueueAttributes

呼び出し元によって割り当てられた WDF_OBJECT_ATTRIBUTES 構造体へのポインター。 この構造体は、 WDF_OBJECT_ATTRIBUTES_INIT または WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPEで初期化する必要があります。 このパラメーターは省略可能であり、 WDF_NO_OBJECT_ATTRIBUTESできます。

[in] CommandQueueConfig

構造体に割り当てられた呼び出し元 へのポインター WDF_IO_QUEUE_CONFIG 。 この構造体は 、WDF_IO_QUEUE_CONFIG_INITで初期化する必要があります。

[in, optional] CommandQueueAttributes

呼び出し元によって割り当てられた WDF_OBJECT_ATTRIBUTES 構造体へのポインター。 この構造体は、 WDF_OBJECT_ATTRIBUTES_INIT または WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPEで初期化する必要があります。 このパラメーターは省略可能であり、 WDF_NO_OBJECT_ATTRIBUTESできます。

[out] UfxEndpoint

UFXENDPOINT オブジェクトへのハンドルを受け取る場所へのポインター。

戻り値

操作が成功した場合、メソッドは STATUS_SUCCESS、または NT_SUCCESS(status) が TRUE である別の状態値を返します。 それ以外の場合は、NT_SUCCESS(status) が FALSE である状態値を返します。

注釈

転送キューは、エンドポイント転送に関連する次の IOCTL を処理します。

コマンド キューは、次の IOCTL を処理します。

次の例は、UFXENDPOINT オブジェクトを作成し、そのコンテキストを初期化する方法を示しています。
NTSTATUS
UfxEndpointAdd (
    _In_ UFXDEVICE Device,
    _In_ PUSB_ENDPOINT_DESCRIPTOR Descriptor,
    _Inout_ PUFXENDPOINT_INIT EndpointInit
    )
/*++
Routine Description:

    Creates a UFXENDPOINT object, and initializes its contexts.

Parameters Description:

    Device - UFXDEVICE associated with the endpoint.

    Descriptor - Endpoint descriptor for this endpoint.

    EndpointInit - Opaque structure from UFX.

Return Value:

    STATUS_SUCCESS if successful, appropriate NTSTATUS message otherwise.
--*/
{
    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();

    DeviceContext = UfxDeviceGetContext(Device);

    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);
    CHK_NT_MSG(Status, "Failed to create ufxendpoint!");

    Status = WdfCollectionAdd(DeviceContext->Endpoints, Endpoint);
    CHK_NT_MSG(Status, "Failed to add endpoint to collection!");

    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;

    Status = TransferInitialize(Endpoint);
    CHK_NT_MSG(Status, "Failed to initialize endpoint transfers");
    
    //
    // This can happen if we're handling a SetInterface command.
    //
    if (DeviceContext->UsbState == UsbfnDeviceStateConfigured) {
        UfxEndpointConfigure(Endpoint);
    }

    Status = WdfIoQueueReadyNotify(
                 UfxEndpointGetTransferQueue(Endpoint),
                 TransferReadyNotify,
                 Endpoint);
    CHK_NT_MSG(Status, "Failed to register ready notify");

End:
    TraceExit();
    return Status;
}

要件

要件
サポートされている最小のクライアント Windows 10
対象プラットフォーム Windows
ヘッダー ufxclient.h
Library ufxstub.lib
IRQL PASSIVE_LEVEL