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(상태)이 TRUE인 다른 상태 값을 반환합니다. 그렇지 않으면 NT_SUCCESS(상태)이 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
라이브러리 ufxstub.lib
IRQL PASSIVE_LEVEL