Share via


EVT_UFX_DEVICE_ENDPOINT_ADD función de devolución de llamada (ufxclient.h)

Implementación del controlador de cliente para crear un objeto de punto de conexión predeterminado.

Sintaxis

EVT_UFX_DEVICE_ENDPOINT_ADD EvtUfxDeviceEndpointAdd;

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

Parámetros

[in] unnamedParam1

Identificador de un objeto de dispositivo USB que el controlador cliente recibió en una llamada anterior a UfxDeviceCreate.

[in] unnamedParam2

Puntero a una estructura de USB_ENDPOINT_DESCRIPTOR que contiene datos de descriptor.

[in, out] unnamedParam3

Puntero a una estructura UFXENDPOINT_INIT opaca que contiene el descriptor de punto de conexión necesario para crear un objeto de punto de conexión.

Valor devuelto

Si la operación se realiza correctamente, la función de devolución de llamada debe devolver STATUS_SUCCESS u otro valor de estado para el que NT_SUCCESS(status) es igual a TRUE. De lo contrario, debe devolver un valor de estado para el que NT_SUCCESS(status) es igual a FALSE.

Comentarios

El controlador de cliente para el controlador host de función registra su implementación de EVT_UFX_DEVICE_ENDPOINT_ADD con la extensión de clase de función USB (UFX) llamando al método UfxDeviceCreate .

Para crear el punto de conexión, se espera que el controlador de cliente inicialice los atributos de las colas de comandos y transferencia del punto de conexión y, a continuación, llame a UfxEndpointCreate para crear el punto de conexión.

El controlador cliente indica la finalización de este evento llamando al método UfxDeviceEventComplete .

Ejemplos

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 - Cosntant 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 appropirate 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;
}

Requisitos

Requisito Value
Plataforma de destino Windows
Versión mínima de KMDF 1.0
Versión mínima de UMDF 2.0
Encabezado ufxclient.h
IRQL PASSIVE_LEVEL

Consulte también

UfxDeviceCreate

UfxDeviceEventComplete