reactos/sdk/lib/drivers/wdf/shared/targets/usb/fxusbinterfaceapi.cpp
Victor Perevertkin 8a978a179f
[WDF] Add Windows Driver Framework files
Takern from Microsoft GitHub repo:
d9c6040fe9

Licensed under MIT
2020-11-03 00:06:26 +03:00

498 lines
12 KiB
C++

/*++
Copyright (c) Microsoft Corporation
Module Name:
FxUsbInterfaceAPI.cpp
Abstract:
Author:
Environment:
Both kernel and user mode
Revision History:
--*/
#include "fxusbpch.hpp"
extern "C" {
#include "FxUsbInterfaceAPI.tmh"
}
//
// Extern "C" all APIs
//
extern "C" {
_Must_inspect_result_
__drv_maxIRQL(PASSIVE_LEVEL)
NTSTATUS
WDFAPI
WDFEXPORT(WdfUsbInterfaceSelectSetting)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBINTERFACE UsbInterface,
__in_opt
PWDF_OBJECT_ATTRIBUTES PipesAttributes,
__in
PWDF_USB_INTERFACE_SELECT_SETTING_PARAMS Params
)
/*++
Routine Description:
Selects an alternate setting on a given interface number
Arguments:
UsbInterface - the interface whose setting will be selected
PipesAttributes - Attributes to apply to each of the new pipes on the setting
Params - Strucutre indicating how to select a new setting
Return Value:
NTSTATUS
--*/
{
DDI_ENTRY();
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxUsbInterface* pUsbInterface;
NTSTATUS status;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
UsbInterface,
FX_TYPE_USB_INTERFACE,
(PVOID*) &pUsbInterface,
&pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, Params);
status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL);
if (!NT_SUCCESS(status)) {
return status;
}
if (Params->Size != sizeof(WDF_USB_INTERFACE_SELECT_SETTING_PARAMS)) {
status = STATUS_INFO_LENGTH_MISMATCH;
DoTraceLevelMessage(
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
"Params size %d, expected %d %!STATUS!", Params->Size,
sizeof(WDF_USB_INTERFACE_SELECT_SETTING_PARAMS), status);
return status;
}
status = FxValidateObjectAttributes(pFxDriverGlobals,
PipesAttributes,
FX_VALIDATE_OPTION_PARENT_NOT_ALLOWED);
if (!NT_SUCCESS(status)) {
return status;
}
#if (FX_CORE_MODE == FX_CORE_USER_MODE)
if (Params->Type != WdfUsbInterfaceSelectSettingTypeSetting) {
FX_VERIFY_WITH_NAME(INTERNAL, TRAPMSG("UMDF may only select settings by index."),
DriverGlobals->DriverName);
}
#endif
switch (Params->Type) {
case WdfUsbInterfaceSelectSettingTypeDescriptor:
if (Params->Types.Descriptor.InterfaceDescriptor == NULL) {
status = STATUS_INVALID_PARAMETER;
DoTraceLevelMessage(
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
"InterfaceDescriptor passed in is NULL %!STATUS!", status);
}
else {
status = pUsbInterface->SelectSettingByDescriptor(
PipesAttributes,
Params->Types.Descriptor.InterfaceDescriptor
);
}
break;
case WdfUsbInterfaceSelectSettingTypeSetting:
status = pUsbInterface->SelectSettingByIndex(
PipesAttributes,
Params->Types.Interface.SettingIndex
);
break;
case WdfUsbInterfaceSelectSettingTypeUrb:
if (Params->Types.Urb.Urb == NULL ||
Params->Types.Urb.Urb->UrbHeader.Function != URB_FUNCTION_SELECT_INTERFACE ||
(Params->Types.Urb.Urb->UrbHeader.Length <
sizeof(struct _URB_SELECT_INTERFACE) - sizeof(USBD_PIPE_INFORMATION)) ) {
status = STATUS_INVALID_PARAMETER;
DoTraceLevelMessage(
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
"URB or URB fields passed in are invalid Urb 0x%p %!STATUS!",
Params->Types.Urb.Urb, status);
}
else {
status = pUsbInterface->SelectSetting(PipesAttributes,
Params->Types.Urb.Urb);
}
break;
default:
status = STATUS_INVALID_PARAMETER;
break;
}
return status;
}
__drv_maxIRQL(DISPATCH_LEVEL)
BYTE
WDFAPI
WDFEXPORT(WdfUsbInterfaceGetInterfaceNumber)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBINTERFACE UsbInterface
)
/*++
Routine Description:
Returns the interface number of the given interface. The interface number
is not necessarily the same as the index of the interface. Once is specified
by the device, the other is where it is located within an internal array.
Arguments:
UsbInterface - Interace whose number will be returned
Return Value:
interface number
--*/
{
DDI_ENTRY();
FxUsbInterface * pUsbInterface;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
UsbInterface,
FX_TYPE_USB_INTERFACE,
(PVOID*) &pUsbInterface);
return pUsbInterface->GetInterfaceNumber();
}
__drv_maxIRQL(DISPATCH_LEVEL)
BYTE
WDFAPI
WDFEXPORT(WdfUsbInterfaceGetNumEndpoints)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBINTERFACE UsbInterface,
__in
UCHAR SettingIndex
)
/*++
Routine Description:
Returns the number of endpoints (not configured) for a given setting on the
given interface.
Arguments:
UsbInterface - interface whose number of endpoints will be returned
SettingsIndex - the index into the alternate setting array
Return Value:
Number of endpoints
--*/
{
DDI_ENTRY();
FxUsbInterface * pUsbInterface;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
UsbInterface,
FX_TYPE_USB_INTERFACE ,
(PVOID*) &pUsbInterface);
return pUsbInterface->GetNumEndpoints(SettingIndex);
}
__drv_maxIRQL(DISPATCH_LEVEL)
VOID
WDFAPI
WDFEXPORT(WdfUsbInterfaceGetEndpointInformation)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBINTERFACE UsbInterface,
__in
UCHAR SettingIndex,
__in
UCHAR EndpointIndex,
__out
PWDF_USB_PIPE_INFORMATION EndpointInfo
)
/*++
Routine Description:
Returns information on a given endpoint (unconfigured) for an interface +
alternate setting index.
Arguments:
UsbInterface - interface which contains the endpoint
SettingIndex - alternate setting index
EndpointIndex - index into the endpoint array contained by interface+setting
EndpointInfo - structure to be filled in with the info of the endpoint
Return Value:
None
--*/
{
DDI_ENTRY();
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxUsbInterface * pUsbInterface;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
UsbInterface,
FX_TYPE_USB_INTERFACE,
(PVOID*) &pUsbInterface,
&pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, EndpointInfo);
if (EndpointInfo->Size != sizeof(WDF_USB_PIPE_INFORMATION)) {
DoTraceLevelMessage(
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
"EndpointInfo Size %d incorrect, expected %d, %!STATUS!",
EndpointInfo->Size, sizeof(WDF_USB_PIPE_INFORMATION),
STATUS_INFO_LENGTH_MISMATCH);
FxVerifierDbgBreakPoint(pFxDriverGlobals);
return;
}
pUsbInterface->GetEndpointInformation(SettingIndex,
EndpointIndex,
EndpointInfo);
}
__drv_maxIRQL(DISPATCH_LEVEL)
BYTE
WDFEXPORT(WdfUsbInterfaceGetNumSettings)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBINTERFACE UsbInterface
)
/*++
Routine Description:
Returns the number of settings available on an interface.
Arguments:
UsbInterface - the usb interface being queried
Return Value:
Number of settings as described by the config descriptor
--*/
{
DDI_ENTRY();
FxUsbInterface * pUsbInterface;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
UsbInterface,
FX_TYPE_USB_INTERFACE,
(PVOID*) &pUsbInterface);
return pUsbInterface->GetNumSettings();
}
__drv_maxIRQL(DISPATCH_LEVEL)
VOID
WDFAPI
WDFEXPORT(WdfUsbInterfaceGetDescriptor)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBINTERFACE UsbInterface,
__in
UCHAR SettingIndex,
__out
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
)
/*++
Routine Description:
Returns the underlying USB interface descriptor for the given WDF handle
Arguments:
UsbInterface - interface whose descriptor will be returned
SettingIndex - alternatve setting whose interface should be returned
InterfaceDescriptor - Pointer which will receive the descriptor
--*/
{
DDI_ENTRY();
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxUsbInterface * pUsbInterface;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
UsbInterface,
FX_TYPE_USB_INTERFACE,
(PVOID*) &pUsbInterface,
&pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, InterfaceDescriptor);
pUsbInterface->GetDescriptor(InterfaceDescriptor, SettingIndex);
}
__drv_maxIRQL(DISPATCH_LEVEL)
BYTE
WDFAPI
WDFEXPORT(WdfUsbInterfaceGetConfiguredSettingIndex)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBINTERFACE UsbInterface
)
/*++
Routine Description:
Returns the alternate setting index which is currently configured
Arguments:
UsbInterface - interfase whose configured setting is being queried
Return Value:
The current setting or 0 on failure
--*/
{
DDI_ENTRY();
FxUsbInterface * pUsbInterface;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
UsbInterface,
FX_TYPE_USB_INTERFACE ,
(PVOID*) &pUsbInterface);
return pUsbInterface->GetConfiguredSettingIndex();
}
__drv_maxIRQL(DISPATCH_LEVEL)
BYTE
WDFAPI
WDFEXPORT(WdfUsbInterfaceGetNumConfiguredPipes)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBINTERFACE UsbInterface
)
/*++
Routine Description:
Returns the number of configured pipes on a given interface.
Arguments:
UsbInterface - the configured interface
Return Value:
Number of configured pipes or 0 on error
--*/
{
DDI_ENTRY();
FxUsbInterface * pUsbInterface;
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
UsbInterface,
FX_TYPE_USB_INTERFACE ,
(PVOID*) &pUsbInterface);
return pUsbInterface->GetNumConfiguredPipes();
}
__drv_maxIRQL(DISPATCH_LEVEL)
WDFUSBPIPE
WDFAPI
WDFEXPORT(WdfUsbInterfaceGetConfiguredPipe)(
__in
PWDF_DRIVER_GLOBALS DriverGlobals,
__in
WDFUSBINTERFACE UsbInterface,
__in
UCHAR PipeIndex,
__out_opt
PWDF_USB_PIPE_INFORMATION PipeInfo
)
/*++
Routine Description:
Returns the WDFUSBPIPE handle for the configured interface + pipe index.
Optionally, information about the pipe is also returned.
Arguments:
UsbInterface - configured interface
PipeIndex - index into the number of pipes on the interface
PipeInfo - information to be returned on the pipe
Return Value:
valid WDFUSBPIPE or NULL on error
--*/
{
DDI_ENTRY();
PFX_DRIVER_GLOBALS pFxDriverGlobals;
FxUsbInterface * pUsbInterface;
NTSTATUS status;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
UsbInterface,
FX_TYPE_USB_INTERFACE,
(PVOID*) &pUsbInterface,
&pFxDriverGlobals);
if (PipeInfo != NULL && PipeInfo->Size != sizeof(WDF_USB_PIPE_INFORMATION)) {
status = STATUS_INFO_LENGTH_MISMATCH;
DoTraceLevelMessage(
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
"PipeInfo Size %d incorrect, expected %d, %!STATUS!",
PipeInfo->Size, sizeof(WDF_USB_PIPE_INFORMATION), status);
FxVerifierDbgBreakPoint(pFxDriverGlobals);
return NULL;
}
return pUsbInterface->GetConfiguredPipe(PipeIndex, PipeInfo);
}
} // extern "C"