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 (状态) 等於 TRUE 的另一個狀態值。 否則,它必須傳回狀態值,NT_SUCCESS (状态) 等於 FALSE。
備註
函式主控制器的用戶端驅動程式會藉由呼叫 UfxDeviceCreate 方法,向 USB 函式類別延伸模組 (UFX) 註冊其EVT_UFX_DEVICE_ENDPOINT_ADD實作。
若要建立端點,用戶端驅動程序預期會初始化端點傳輸和命令佇列的屬性,然後呼叫 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 |
標頭 | ufxclient.h |
IRQL | PASSIVE_LEVEL |