mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 19:26:32 +00:00
[SDK][WDFLDR] Add kmdf loader driver [SDK][WDF] Add kmdf drver init static library [SDK][WDF] Modify kmdf driver for working with wdfldr driver [SDK][CDROM] Cdrom driver dynamically linking with kmdf [SDK][WDF] Add kmdfdriver module type [SDK][WDF][USBDEX][NTOSKRNL_VISTA] Fully enable KMDF [KMDF][WDFLDR][WDF01000] Fix Windows 10 Compatibility WDFLDR and WDF01000 [WDF01000] NO_KERNEL_LIST_ENTRY_CHECKS for wdf01000 3rd party code This PR is an accumulation of three peoples work, with the goal of the trying to get WDF to work like it should. This has been tested in combination with some extra NT6+ ntoskrnl against multiple drivers. --------- Co-authored-by: Max Korostil <[email protected]> Co-authored-by: Victor Perevertkin <[email protected]> Co-authored-by: Adam Słaboń <[email protected]> Co-authored-by: Hermès BÉLUSCA - MAÏTO <[email protected]>
1448 lines
40 KiB
C++
1448 lines
40 KiB
C++
/*++
|
|
|
|
Copyright (c) Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
FxUsbDeviceAPI.cpp
|
|
|
|
Abstract:
|
|
|
|
|
|
Author:
|
|
|
|
Environment:
|
|
|
|
Both kernel and user mode
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "fxusbpch.hpp"
|
|
|
|
extern "C" {
|
|
#if defined(EVENT_TRACING)
|
|
#include "FxUsbDeviceAPI.tmh"
|
|
#endif
|
|
}
|
|
|
|
//
|
|
// Extern "C" all APIs
|
|
//
|
|
extern "C" {
|
|
|
|
_Must_inspect_result_
|
|
__drv_maxIRQL(PASSIVE_LEVEL)
|
|
NTSTATUS
|
|
WDFAPI
|
|
FxUsbTargetDeviceCreate(
|
|
__in
|
|
PFX_DRIVER_GLOBALS FxDriverGlobals,
|
|
__in
|
|
FxDeviceBase* Device,
|
|
__in
|
|
ULONG USBDClientContractVersion,
|
|
__in_opt
|
|
PWDF_OBJECT_ATTRIBUTES Attributes,
|
|
__out
|
|
WDFUSBDEVICE* UsbDevice
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Creates a WDFUSBDEVICE handle for the client.
|
|
|
|
Arguments:
|
|
|
|
Device - FxDeviceBase object
|
|
|
|
USBDClientContractVersion - The USBD Client Contract version of the client driver
|
|
|
|
UsbDevice - Pointer which will receive the created handle
|
|
|
|
Return Value:
|
|
STATUS_SUCCESS - success
|
|
STATUS_INSUFFICIENT_RESOURCES - no memory available
|
|
...
|
|
|
|
--*/
|
|
{
|
|
FxUsbDevice* pUsbDevice;
|
|
NTSTATUS status;
|
|
|
|
//
|
|
// Basic parameter validation
|
|
//
|
|
|
|
FxPointerNotNull(FxDriverGlobals, UsbDevice);
|
|
*UsbDevice = NULL;
|
|
|
|
status = FxVerifierCheckIrqlLevel(FxDriverGlobals, PASSIVE_LEVEL);
|
|
if (!NT_SUCCESS(status)) {
|
|
return status;
|
|
}
|
|
|
|
status = FxValidateObjectAttributes(FxDriverGlobals,
|
|
Attributes,
|
|
FX_VALIDATE_OPTION_PARENT_NOT_ALLOWED);
|
|
if (!NT_SUCCESS(status)) {
|
|
return status;
|
|
}
|
|
|
|
pUsbDevice = new(FxDriverGlobals, Attributes) FxUsbDevice(FxDriverGlobals);
|
|
if (pUsbDevice == NULL) {
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
//
|
|
// Perform all init and handle creation functions. Check for error at the
|
|
// end and clean up there.
|
|
//
|
|
status = pUsbDevice->Init(Device);
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
WDFOBJECT device;
|
|
|
|
device = NULL;
|
|
|
|
status = pUsbDevice->InitDevice(USBDClientContractVersion);
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
status = pUsbDevice->CreateInterfaces();
|
|
}
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
status = Device->AddIoTarget(pUsbDevice);
|
|
}
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
status = pUsbDevice->Commit(Attributes, &device, Device);
|
|
}
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
*UsbDevice = (WDFUSBDEVICE) device;
|
|
}
|
|
}
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
//
|
|
// And now free it
|
|
//
|
|
pUsbDevice->DeleteFromFailedCreate();
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
_Must_inspect_result_
|
|
__drv_maxIRQL(PASSIVE_LEVEL)
|
|
NTSTATUS
|
|
WDFAPI
|
|
NTAPI
|
|
WDFEXPORT(WdfUsbTargetDeviceCreate)(
|
|
__in
|
|
PWDF_DRIVER_GLOBALS DriverGlobals,
|
|
__in
|
|
WDFDEVICE Device,
|
|
__in_opt
|
|
PWDF_OBJECT_ATTRIBUTES Attributes,
|
|
__out
|
|
WDFUSBDEVICE* UsbDevice
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Creates a WDFUSBDEVICE handle for the client.
|
|
|
|
Arguments:
|
|
Device - WDFDEVICE handle to which we are attaching the WDFUSBDEVICE handle
|
|
to
|
|
PUsbDevice - Pointer which will receive the created handle
|
|
|
|
Return Value:
|
|
STATUS_SUCCESS - success
|
|
STATUS_INSUFFICIENT_RESOURCES - no memory available
|
|
...
|
|
|
|
--*/
|
|
{
|
|
DDI_ENTRY();
|
|
|
|
PFX_DRIVER_GLOBALS pFxDriverGlobals;
|
|
FxDeviceBase* pDevice;
|
|
|
|
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
|
|
Device,
|
|
FX_TYPE_DEVICE_BASE,
|
|
(PVOID*)&pDevice,
|
|
&pFxDriverGlobals);
|
|
|
|
return FxUsbTargetDeviceCreate(pFxDriverGlobals,
|
|
pDevice,
|
|
USBD_CLIENT_CONTRACT_VERSION_INVALID,
|
|
Attributes,
|
|
UsbDevice);
|
|
}
|
|
|
|
__checkReturn
|
|
__drv_maxIRQL(PASSIVE_LEVEL)
|
|
NTSTATUS
|
|
WDFAPI
|
|
NTAPI
|
|
WDFEXPORT(WdfUsbTargetDeviceCreateWithParameters)(
|
|
__in
|
|
PWDF_DRIVER_GLOBALS DriverGlobals,
|
|
__in
|
|
WDFDEVICE Device,
|
|
__in
|
|
PWDF_USB_DEVICE_CREATE_CONFIG Config,
|
|
__in_opt
|
|
PWDF_OBJECT_ATTRIBUTES Attributes,
|
|
__out
|
|
WDFUSBDEVICE* UsbDevice
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Creates a WDFUSBDEVICE handle for the client.
|
|
|
|
Arguments:
|
|
Device - WDFDEVICE handle to which we are attaching the WDFUSBDEVICE handle
|
|
to
|
|
PUsbDevice - Pointer which will receive the created handle
|
|
|
|
Return Value:
|
|
STATUS_SUCCESS - success
|
|
STATUS_INSUFFICIENT_RESOURCES - no memory available
|
|
...
|
|
|
|
--*/
|
|
{
|
|
DDI_ENTRY();
|
|
|
|
PFX_DRIVER_GLOBALS pFxDriverGlobals;
|
|
FxDeviceBase* pDevice;
|
|
NTSTATUS status;
|
|
|
|
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
|
|
Device,
|
|
FX_TYPE_DEVICE_BASE,
|
|
(PVOID*)&pDevice,
|
|
&pFxDriverGlobals);
|
|
|
|
FxPointerNotNull(pFxDriverGlobals, Config);
|
|
|
|
if (Config->Size != sizeof(WDF_USB_DEVICE_CREATE_CONFIG)) {
|
|
status = STATUS_INFO_LENGTH_MISMATCH;
|
|
|
|
DoTraceLevelMessage(
|
|
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
|
|
"WDF_USB_DEVICE_CREATE_CONFIG Size 0x%x, expected 0x%x, %!STATUS!",
|
|
Config->Size, sizeof(WDF_USB_DEVICE_CREATE_CONFIG), status);
|
|
|
|
return status;
|
|
}
|
|
|
|
return FxUsbTargetDeviceCreate(pFxDriverGlobals,
|
|
pDevice,
|
|
Config->USBDClientContractVersion,
|
|
Attributes,
|
|
UsbDevice);
|
|
}
|
|
|
|
_Must_inspect_result_
|
|
__drv_maxIRQL(DISPATCH_LEVEL)
|
|
NTSTATUS
|
|
WDFAPI
|
|
NTAPI
|
|
WDFEXPORT(WdfUsbTargetDeviceRetrieveInformation)(
|
|
__in
|
|
PWDF_DRIVER_GLOBALS DriverGlobals,
|
|
__in
|
|
WDFUSBDEVICE UsbDevice,
|
|
__out
|
|
PWDF_USB_DEVICE_INFORMATION Information
|
|
)
|
|
{
|
|
DDI_ENTRY();
|
|
|
|
PFX_DRIVER_GLOBALS pFxDriverGlobals;
|
|
FxUsbDevice* pUsbDevice;
|
|
NTSTATUS status;
|
|
|
|
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
|
|
UsbDevice,
|
|
FX_TYPE_IO_TARGET_USB_DEVICE,
|
|
(PVOID*) &pUsbDevice,
|
|
&pFxDriverGlobals);
|
|
|
|
FxPointerNotNull(pFxDriverGlobals, Information);
|
|
|
|
if (Information->Size != sizeof(WDF_USB_DEVICE_INFORMATION)) {
|
|
status = STATUS_INFO_LENGTH_MISMATCH;
|
|
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
|
|
"Information size %d, expected %d %!STATUS!",
|
|
Information->Size, sizeof(WDF_USB_DEVICE_INFORMATION),
|
|
status);
|
|
return status;
|
|
}
|
|
|
|
pUsbDevice->GetInformation(Information);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
__drv_maxIRQL(PASSIVE_LEVEL)
|
|
VOID
|
|
WDFAPI
|
|
NTAPI
|
|
WDFEXPORT(WdfUsbTargetDeviceGetDeviceDescriptor)(
|
|
__in
|
|
PWDF_DRIVER_GLOBALS DriverGlobals,
|
|
__in
|
|
WDFUSBDEVICE UsbDevice,
|
|
__out
|
|
PUSB_DEVICE_DESCRIPTOR UsbDeviceDescriptor
|
|
)
|
|
{
|
|
DDI_ENTRY();
|
|
|
|
PFX_DRIVER_GLOBALS pFxDriverGlobals;
|
|
FxUsbDevice* pUsbDevice;
|
|
NTSTATUS status;
|
|
|
|
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
|
|
UsbDevice,
|
|
FX_TYPE_IO_TARGET_USB_DEVICE,
|
|
(PVOID*) &pUsbDevice,
|
|
&pFxDriverGlobals);
|
|
|
|
FxPointerNotNull(pFxDriverGlobals, UsbDeviceDescriptor);
|
|
|
|
status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL);
|
|
if (!NT_SUCCESS(status)) {
|
|
return;
|
|
}
|
|
|
|
pUsbDevice->CopyDeviceDescriptor(UsbDeviceDescriptor);
|
|
}
|
|
|
|
_Must_inspect_result_
|
|
__drv_maxIRQL(PASSIVE_LEVEL)
|
|
NTSTATUS
|
|
WDFAPI
|
|
NTAPI
|
|
WDFEXPORT(WdfUsbTargetDeviceRetrieveConfigDescriptor)(
|
|
__in
|
|
PWDF_DRIVER_GLOBALS DriverGlobals,
|
|
__in
|
|
WDFUSBDEVICE UsbDevice,
|
|
__out_bcount_part_opt(*ConfigDescriptorLength, *ConfigDescriptorLength)
|
|
PVOID ConfigDescriptor,
|
|
__inout
|
|
PUSHORT ConfigDescriptorLength
|
|
)
|
|
{
|
|
DDI_ENTRY();
|
|
|
|
PFX_DRIVER_GLOBALS pFxDriverGlobals;
|
|
FxUsbDevice* pUsbDevice;
|
|
NTSTATUS status;
|
|
|
|
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
|
|
UsbDevice,
|
|
FX_TYPE_IO_TARGET_USB_DEVICE,
|
|
(PVOID*) &pUsbDevice,
|
|
&pFxDriverGlobals);
|
|
|
|
FxPointerNotNull(pFxDriverGlobals, ConfigDescriptorLength);
|
|
|
|
status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL);
|
|
if (!NT_SUCCESS(status)) {
|
|
return status;
|
|
}
|
|
|
|
return pUsbDevice->GetConfigDescriptor(ConfigDescriptor,
|
|
ConfigDescriptorLength);
|
|
}
|
|
|
|
_Must_inspect_result_
|
|
__drv_maxIRQL(PASSIVE_LEVEL)
|
|
NTSTATUS
|
|
WDFAPI
|
|
NTAPI
|
|
WDFEXPORT(WdfUsbTargetDeviceQueryString)(
|
|
__in
|
|
PWDF_DRIVER_GLOBALS DriverGlobals,
|
|
__in
|
|
WDFUSBDEVICE UsbDevice,
|
|
__in_opt
|
|
WDFREQUEST Request,
|
|
__in_opt
|
|
PWDF_REQUEST_SEND_OPTIONS RequestOptions,
|
|
__out_ecount_opt(*NumCharacters)
|
|
PUSHORT String,
|
|
__inout
|
|
PUSHORT NumCharacters,
|
|
__in
|
|
UCHAR StringIndex,
|
|
__in_opt
|
|
USHORT LangID
|
|
)
|
|
{
|
|
DDI_ENTRY();
|
|
|
|
PFX_DRIVER_GLOBALS pFxDriverGlobals;
|
|
FxUsbDevice* pUsbDevice;
|
|
NTSTATUS status;
|
|
|
|
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
|
|
UsbDevice,
|
|
FX_TYPE_IO_TARGET_USB_DEVICE,
|
|
(PVOID*) &pUsbDevice,
|
|
&pFxDriverGlobals);
|
|
|
|
FxPointerNotNull(pFxDriverGlobals, NumCharacters);
|
|
|
|
status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL);
|
|
if (!NT_SUCCESS(status)) {
|
|
return status;
|
|
}
|
|
|
|
status = FxValidateRequestOptions(pFxDriverGlobals, RequestOptions);
|
|
if (!NT_SUCCESS(status)) {
|
|
return status;
|
|
}
|
|
|
|
status = pUsbDevice->GetString(String,
|
|
NumCharacters,
|
|
StringIndex,
|
|
LangID,
|
|
Request,
|
|
RequestOptions);
|
|
|
|
return status;
|
|
}
|
|
|
|
_Must_inspect_result_
|
|
__drv_maxIRQL(PASSIVE_LEVEL)
|
|
NTSTATUS
|
|
WDFAPI
|
|
NTAPI
|
|
WDFEXPORT(WdfUsbTargetDeviceAllocAndQueryString)(
|
|
__in
|
|
PWDF_DRIVER_GLOBALS DriverGlobals,
|
|
__in
|
|
WDFUSBDEVICE UsbDevice,
|
|
__in_opt
|
|
PWDF_OBJECT_ATTRIBUTES StringMemoryAttributes,
|
|
__out
|
|
WDFMEMORY* StringMemory,
|
|
__out_opt
|
|
PUSHORT NumCharacters,
|
|
__in
|
|
UCHAR StringIndex,
|
|
__in_opt
|
|
USHORT LangID
|
|
)
|
|
{
|
|
DDI_ENTRY();
|
|
|
|
PFX_DRIVER_GLOBALS pFxDriverGlobals;
|
|
WDFMEMORY hMemory;
|
|
FxUsbDevice* pUsbDevice;
|
|
NTSTATUS status;
|
|
USHORT numChars = 0;
|
|
|
|
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
|
|
UsbDevice,
|
|
FX_TYPE_IO_TARGET_USB_DEVICE,
|
|
(PVOID*) &pUsbDevice,
|
|
&pFxDriverGlobals);
|
|
|
|
FxPointerNotNull(pFxDriverGlobals, StringMemory);
|
|
|
|
*StringMemory = NULL;
|
|
if (NumCharacters != NULL) {
|
|
*NumCharacters = 0;
|
|
}
|
|
|
|
status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL);
|
|
if (!NT_SUCCESS(status)) {
|
|
return status;
|
|
}
|
|
|
|
status = FxValidateObjectAttributes(pFxDriverGlobals, StringMemoryAttributes);
|
|
if (!NT_SUCCESS(status)) {
|
|
return status;
|
|
}
|
|
|
|
status = pUsbDevice->GetString(NULL, &numChars, StringIndex, LangID);
|
|
|
|
if (NT_SUCCESS(status) && numChars > 0) {
|
|
FxMemoryObject* pBuffer;
|
|
|
|
status = FxMemoryObject::_Create(pFxDriverGlobals,
|
|
StringMemoryAttributes,
|
|
NonPagedPool,
|
|
pFxDriverGlobals->Tag,
|
|
numChars * sizeof(WCHAR),
|
|
&pBuffer);
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
status = pBuffer->Commit(StringMemoryAttributes,
|
|
(WDFOBJECT*)&hMemory);
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
status = pUsbDevice->GetString((PUSHORT) pBuffer->GetBuffer(),
|
|
&numChars,
|
|
StringIndex,
|
|
LangID);
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
if (NumCharacters != NULL) {
|
|
*NumCharacters = numChars;
|
|
}
|
|
*StringMemory = hMemory;
|
|
}
|
|
}
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
//
|
|
// There can only be one context on this object right now,
|
|
// so just clear out the one.
|
|
//
|
|
pBuffer->DeleteFromFailedCreate();
|
|
}
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
_Must_inspect_result_
|
|
__drv_maxIRQL(DISPATCH_LEVEL)
|
|
NTSTATUS
|
|
NTAPI
|
|
WDFEXPORT(WdfUsbTargetDeviceFormatRequestForString)(
|
|
__in
|
|
PWDF_DRIVER_GLOBALS DriverGlobals,
|
|
__in
|
|
WDFUSBDEVICE UsbDevice,
|
|
__in
|
|
WDFREQUEST Request,
|
|
__in
|
|
WDFMEMORY Memory,
|
|
__in_opt
|
|
PWDFMEMORY_OFFSET Offset,
|
|
__in
|
|
UCHAR StringIndex,
|
|
__in_opt
|
|
USHORT LangID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Formats a request so that it can be used to query for a string from the
|
|
device.
|
|
|
|
Arguments:
|
|
UsbDevice - device to be queried
|
|
|
|
Request - request to format
|
|
|
|
Memory - memory to write the string into
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
DDI_ENTRY();
|
|
|
|
PFX_DRIVER_GLOBALS pFxDriverGlobals;
|
|
IFxMemory* pMemory;
|
|
FxUsbDevice* pUsbDevice;
|
|
FxRequestBuffer buf;
|
|
FxRequest* pRequest;
|
|
NTSTATUS status;
|
|
size_t bufferSize;
|
|
|
|
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
|
|
UsbDevice,
|
|
FX_TYPE_IO_TARGET_USB_DEVICE,
|
|
(PVOID*) &pUsbDevice,
|
|
&pFxDriverGlobals);
|
|
|
|
DoTraceLevelMessage(
|
|
pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
|
|
"WDFUSBDEVICE %p, WDFREQUEST %p, WDFMEMORY %p, StringIndex %d, LandID 0x%x",
|
|
UsbDevice, Request, Memory, StringIndex, LangID);
|
|
|
|
FxObjectHandleGetPtr(pFxDriverGlobals,
|
|
Memory,
|
|
IFX_TYPE_MEMORY,
|
|
(PVOID*) &pMemory);
|
|
|
|
FxObjectHandleGetPtr(pFxDriverGlobals,
|
|
Request,
|
|
FX_TYPE_REQUEST,
|
|
(PVOID*) &pRequest);
|
|
|
|
status = pMemory->ValidateMemoryOffsets(Offset);
|
|
if (!NT_SUCCESS(status)) {
|
|
return status;
|
|
}
|
|
|
|
buf.SetMemory(pMemory, Offset);
|
|
|
|
bufferSize = buf.GetBufferLength();
|
|
|
|
//
|
|
// the string descriptor is array of WCHARs so the buffer being used must be
|
|
// of an integral number of them.
|
|
//
|
|
if ((bufferSize % sizeof(WCHAR)) != 0) {
|
|
status = STATUS_INVALID_PARAMETER;
|
|
|
|
DoTraceLevelMessage(
|
|
pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
|
|
"WDFMEMORY %p length must be even number of WCHARs, but is %I64d in "
|
|
"length, %!STATUS!",
|
|
Memory, bufferSize, status);
|
|
|
|
return status;
|
|
}
|
|
|
|
//
|
|
// While the length in the descriptor (bLength) is a byte, so the requested
|
|
// buffer cannot be bigger then that, do not check the bufferSize < 0xFF.
|
|
// We don't check because the driver can be using the WDFMEMORY as a part
|
|
// of a larger structure.
|
|
//
|
|
|
|
//
|
|
// Format the request
|
|
//
|
|
status = pUsbDevice->FormatStringRequest(pRequest, &buf, StringIndex, LangID);
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
FxUsbDeviceStringContext* pContext;
|
|
|
|
pContext = (FxUsbDeviceStringContext*) pRequest->GetContext();
|
|
pContext->m_UsbParameters.Parameters.DeviceString.Buffer = Memory;
|
|
pContext->m_UsbParameters.Parameters.DeviceString.StringIndex = StringIndex;
|
|
pContext->m_UsbParameters.Parameters.DeviceString.LangID = LangID;
|
|
}
|
|
|
|
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
|
|
"WDFUSBDEVICE %p, WDFREQUEST %p, WDFMEMORY %p, %!STATUS!",
|
|
UsbDevice, Request, Memory, status);
|
|
|
|
return status;
|
|
}
|
|
|
|
_Must_inspect_result_
|
|
__drv_maxIRQL(PASSIVE_LEVEL)
|
|
NTSTATUS
|
|
WDFAPI
|
|
NTAPI
|
|
WDFEXPORT(WdfUsbTargetDeviceSelectConfig)(
|
|
__in
|
|
PWDF_DRIVER_GLOBALS DriverGlobals,
|
|
__in
|
|
WDFUSBDEVICE UsbDevice,
|
|
__in_opt
|
|
PWDF_OBJECT_ATTRIBUTES PipesAttributes,
|
|
__inout
|
|
PWDF_USB_DEVICE_SELECT_CONFIG_PARAMS Params
|
|
)
|
|
{
|
|
DDI_ENTRY();
|
|
|
|
PFX_DRIVER_GLOBALS pFxDriverGlobals;
|
|
FxUsbDevice* pUsbDevice;
|
|
NTSTATUS status;
|
|
|
|
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
|
|
UsbDevice,
|
|
FX_TYPE_IO_TARGET_USB_DEVICE,
|
|
(PVOID*) &pUsbDevice,
|
|
&pFxDriverGlobals);
|
|
|
|
FxPointerNotNull(pFxDriverGlobals, Params);
|
|
|
|
status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL);
|
|
if (!NT_SUCCESS(status)) {
|
|
return status;
|
|
}
|
|
|
|
if (Params->Size != sizeof(WDF_USB_DEVICE_SELECT_CONFIG_PARAMS)) {
|
|
status = STATUS_INFO_LENGTH_MISMATCH;
|
|
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
|
|
"Params size %d, expected %d %!STATUS!",
|
|
Params->Size, sizeof(WDF_USB_DEVICE_SELECT_CONFIG_PARAMS),
|
|
status);
|
|
return status;
|
|
}
|
|
|
|
//
|
|
// Sanity check the Type value as well to be in range.
|
|
//
|
|
if (Params->Type < WdfUsbTargetDeviceSelectConfigTypeDeconfig
|
|
||
|
|
Params->Type > WdfUsbTargetDeviceSelectConfigTypeUrb) {
|
|
|
|
status = STATUS_INVALID_PARAMETER;
|
|
|
|
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
|
|
"Params Type %d not a valid value, %!STATUS!",
|
|
Params->Size, status);
|
|
|
|
return status;
|
|
}
|
|
|
|
#if (FX_CORE_MODE == FX_CORE_USER_MODE)
|
|
if ((Params->Type == WdfUsbTargetDeviceSelectConfigTypeDeconfig) ||
|
|
(Params->Type == WdfUsbTargetDeviceSelectConfigTypeUrb) ||
|
|
(Params->Type == WdfUsbTargetDeviceSelectConfigTypeInterfacesDescriptor)) {
|
|
status = STATUS_NOT_SUPPORTED;
|
|
|
|
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
|
|
"Params Type %d not supported for UMDF, %!STATUS!",
|
|
Params->Type, status);
|
|
|
|
return status;
|
|
|
|
}
|
|
#endif
|
|
|
|
status = FxValidateObjectAttributes(pFxDriverGlobals,
|
|
PipesAttributes,
|
|
FX_VALIDATE_OPTION_PARENT_NOT_ALLOWED);
|
|
if (!NT_SUCCESS(status)) {
|
|
return status;
|
|
}
|
|
|
|
if (pUsbDevice->HasMismatchedInterfacesInConfigDescriptor()) {
|
|
//
|
|
// Config descriptor reported zero interfaces, but we found an
|
|
// interface descriptor in it.
|
|
//
|
|
status = STATUS_INVALID_DEVICE_REQUEST;
|
|
|
|
DoTraceLevelMessage(
|
|
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
|
|
"WDFUSBDEVICE %p number of interfaces found in the config descriptor "
|
|
"does not match bNumInterfaces in config descriptor, failing config "
|
|
"operation %!WdfUsbTargetDeviceSelectConfigType!, %!STATUS!",
|
|
UsbDevice, Params->Type, status);
|
|
|
|
return status;
|
|
}
|
|
else if (pUsbDevice->GetNumInterfaces() == 0) {
|
|
//
|
|
// Special case the zero interface case and exit early
|
|
//
|
|
status = STATUS_SUCCESS;
|
|
|
|
DoTraceLevelMessage(
|
|
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
|
|
"WDFUSBDEVICE %p succeeding config operation "
|
|
"%!WdfUsbTargetDeviceSelectConfigType! on zero interfaces "
|
|
"immediately, %!STATUS!", UsbDevice, Params->Type, status);
|
|
|
|
return status;
|
|
}
|
|
|
|
switch (Params->Type) {
|
|
|
|
#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
|
|
|
|
case WdfUsbTargetDeviceSelectConfigTypeDeconfig:
|
|
status = pUsbDevice->Deconfig();
|
|
break;
|
|
|
|
case WdfUsbTargetDeviceSelectConfigTypeInterfacesDescriptor:
|
|
if (Params->Types.Descriptor.InterfaceDescriptors == NULL ||
|
|
Params->Types.Descriptor.NumInterfaceDescriptors == 0) {
|
|
status = STATUS_INVALID_PARAMETER;
|
|
DoTraceLevelMessage(
|
|
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
|
|
"Either InterfaceDescriptor is NULL or NumInterfaceDescriptors is zero "
|
|
"WDFUSBDEVICE %p InterfaceDescriptor %p NumInterfaceDescriptors 0x%x"
|
|
"%!WdfUsbTargetDeviceSelectConfigType! %!STATUS!", UsbDevice,
|
|
Params->Types.Descriptor.InterfaceDescriptors,
|
|
Params->Types.Descriptor.NumInterfaceDescriptors,
|
|
Params->Type,
|
|
status);
|
|
|
|
}
|
|
else {
|
|
status = pUsbDevice->SelectConfigDescriptor(
|
|
PipesAttributes,
|
|
Params);
|
|
}
|
|
break;
|
|
|
|
case WdfUsbTargetDeviceSelectConfigTypeUrb:
|
|
//
|
|
// Since the USBD macro's dont include the USBD_PIPE_INFORMATION for 0 EP's,
|
|
// make the length check to use
|
|
// sizeof(struct _URB_SELECT_CONFIGURATION) - sizeof(USBD_PIPE_INFORMATION)
|
|
//
|
|
if (Params->Types.Urb.Urb == NULL ||
|
|
Params->Types.Urb.Urb->UrbHeader.Function != URB_FUNCTION_SELECT_CONFIGURATION ||
|
|
Params->Types.Urb.Urb->UrbHeader.Length <
|
|
(sizeof(struct _URB_SELECT_CONFIGURATION) - sizeof(USBD_PIPE_INFORMATION))) {
|
|
status = STATUS_INVALID_PARAMETER;
|
|
DoTraceLevelMessage(
|
|
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
|
|
"Either URB passed in was NULL or the URB Function or Length was invalid "
|
|
" WDFUSBDEVICE %p Urb 0x%p "
|
|
"%!WdfUsbTargetDeviceSelectConfigType!"
|
|
" %!STATUS!", UsbDevice,
|
|
Params->Types.Urb.Urb,
|
|
Params->Type,
|
|
status);
|
|
|
|
}
|
|
else {
|
|
status = pUsbDevice->SelectConfig(
|
|
PipesAttributes,
|
|
Params->Types.Urb.Urb,
|
|
FxUrbTypeLegacy,
|
|
NULL);
|
|
}
|
|
break;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
case WdfUsbTargetDeviceSelectConfigTypeInterfacesPairs:
|
|
if (Params->Types.MultiInterface.Pairs == NULL) {
|
|
status = STATUS_INVALID_PARAMETER;
|
|
|
|
DoTraceLevelMessage(
|
|
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
|
|
"WDFUSBDEVICE %p SettingPairs Array passed is NULL, %!STATUS!",
|
|
pUsbDevice->GetHandle(),status);
|
|
|
|
break;
|
|
}
|
|
else if (Params->Types.MultiInterface.NumberInterfaces !=
|
|
pUsbDevice->GetNumInterfaces()) {
|
|
status = STATUS_INVALID_PARAMETER;
|
|
|
|
DoTraceLevelMessage(
|
|
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
|
|
"WDFUSBDEVICE %p MultiInterface.NumberInterfaces %d != %d "
|
|
"(reported num interfaces), %!STATUS!",
|
|
pUsbDevice->GetHandle(),
|
|
Params->Types.MultiInterface.NumberInterfaces,
|
|
pUsbDevice->GetNumInterfaces(), status);
|
|
|
|
break;
|
|
}
|
|
|
|
// || || Fall through || ||
|
|
// \/ \/ \/ \/
|
|
case WdfUsbTargetDeviceSelectConfigTypeMultiInterface:
|
|
|
|
//
|
|
// Validate SettingIndexes passed-in
|
|
//
|
|
for (ULONG i = 0;
|
|
i < Params->Types.MultiInterface.NumberInterfaces;
|
|
i++) {
|
|
|
|
PWDF_USB_INTERFACE_SETTING_PAIR pair;
|
|
FxUsbInterface * pUsbInterface;
|
|
UCHAR numSettings;
|
|
|
|
pair = &(Params->Types.MultiInterface.Pairs[i]);
|
|
|
|
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
|
|
pair->UsbInterface,
|
|
FX_TYPE_USB_INTERFACE,
|
|
(PVOID*) &pUsbInterface);
|
|
|
|
numSettings = pUsbInterface->GetNumSettings();
|
|
|
|
if (pair->SettingIndex >= numSettings) {
|
|
status = STATUS_INVALID_PARAMETER;
|
|
|
|
DoTraceLevelMessage(
|
|
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
|
|
"WDFUSBDEVICE %p SettingPairs contains invalid SettingIndex"
|
|
" for WDFUSBINTERFACE %p. Setting index passed in: %d, "
|
|
"max index: %d, returning %!STATUS!",
|
|
pUsbDevice->GetHandle(),
|
|
pair->UsbInterface,
|
|
pair->SettingIndex,
|
|
pUsbInterface->GetNumSettings() - 1,
|
|
status);
|
|
|
|
return status;
|
|
}
|
|
}
|
|
|
|
status = pUsbDevice->SelectConfigMulti(
|
|
PipesAttributes,
|
|
Params);
|
|
break;
|
|
|
|
case WdfUsbTargetDeviceSelectConfigTypeSingleInterface:
|
|
status = pUsbDevice->SelectConfigSingle( //vm changed name from SelectConfigAuto
|
|
PipesAttributes,
|
|
Params);
|
|
break;
|
|
|
|
default:
|
|
status = STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
__drv_maxIRQL(DISPATCH_LEVEL)
|
|
UCHAR
|
|
WDFAPI
|
|
NTAPI
|
|
WDFEXPORT(WdfUsbTargetDeviceGetNumInterfaces)(
|
|
__in
|
|
PWDF_DRIVER_GLOBALS DriverGlobals,
|
|
__in
|
|
WDFUSBDEVICE UsbDevice
|
|
)
|
|
{
|
|
DDI_ENTRY();
|
|
|
|
FxUsbDevice* pUsbDevice;
|
|
|
|
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
|
|
UsbDevice,
|
|
FX_TYPE_IO_TARGET_USB_DEVICE,
|
|
(PVOID*) &pUsbDevice);
|
|
|
|
return pUsbDevice->GetNumInterfaces();
|
|
}
|
|
|
|
|
|
__drv_maxIRQL(DISPATCH_LEVEL)
|
|
USBD_CONFIGURATION_HANDLE
|
|
WDFAPI
|
|
NTAPI
|
|
WDFEXPORT(WdfUsbTargetDeviceWdmGetConfigurationHandle)(
|
|
__in
|
|
PWDF_DRIVER_GLOBALS DriverGlobals,
|
|
__in
|
|
WDFUSBDEVICE UsbDevice
|
|
)
|
|
{
|
|
DDI_ENTRY();
|
|
|
|
FxUsbDevice* pUsbDevice;
|
|
|
|
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
|
|
UsbDevice,
|
|
FX_TYPE_IO_TARGET_USB_DEVICE,
|
|
(PVOID*) &pUsbDevice);
|
|
|
|
return pUsbDevice->GetConfigHandle();
|
|
}
|
|
|
|
_Must_inspect_result_
|
|
__drv_maxIRQL(PASSIVE_LEVEL)
|
|
NTSTATUS
|
|
NTAPI
|
|
WDFEXPORT(WdfUsbTargetDeviceSendControlTransferSynchronously)(
|
|
__in
|
|
PWDF_DRIVER_GLOBALS DriverGlobals,
|
|
__in
|
|
WDFUSBDEVICE UsbDevice,
|
|
__in_opt
|
|
WDFREQUEST Request,
|
|
__in_opt
|
|
PWDF_REQUEST_SEND_OPTIONS RequestOptions,
|
|
__in
|
|
PWDF_USB_CONTROL_SETUP_PACKET SetupPacket,
|
|
__in_opt
|
|
PWDF_MEMORY_DESCRIPTOR MemoryDescriptor,
|
|
__out_opt
|
|
PULONG BytesTransferred
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Synchronously sends a control transfer to the default control pipe on the
|
|
device.
|
|
|
|
Arguments:
|
|
UsbDevice - the target representing the device
|
|
|
|
Request - Request whose PIRP to use
|
|
|
|
RequestOptions - options to use when sending the request
|
|
|
|
SetupPacket - control setup packet to be used in the transfer
|
|
|
|
MemoryDescriptor - memory to use in the transfer after the setup packet
|
|
|
|
BytesTransferred - number of bytes sent to or by the device
|
|
|
|
Return Value:
|
|
NTSTATUS
|
|
|
|
--*/
|
|
{
|
|
DDI_ENTRY();
|
|
|
|
PFX_DRIVER_GLOBALS pFxDriverGlobals;
|
|
FxUsbDevice* pUsbDevice;
|
|
NTSTATUS status;
|
|
FxRequestBuffer buf;
|
|
|
|
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
|
|
UsbDevice,
|
|
FX_TYPE_IO_TARGET_USB_DEVICE,
|
|
(PVOID*) &pUsbDevice,
|
|
&pFxDriverGlobals);
|
|
|
|
FxUsbDeviceControlContext context(FxUrbTypeLegacy);
|
|
|
|
FxSyncRequest request(pFxDriverGlobals, &context, Request);
|
|
|
|
//
|
|
// FxSyncRequest always succeesds for KM but can fail for UM.
|
|
//
|
|
status = request.Initialize();
|
|
if (!NT_SUCCESS(status)) {
|
|
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
|
|
"Failed to initialize FxSyncRequest");
|
|
return status;
|
|
}
|
|
|
|
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
|
|
"WDFUSBDEVICE %p control transfer sync", UsbDevice);
|
|
|
|
FxPointerNotNull(pFxDriverGlobals, SetupPacket);
|
|
|
|
status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL);
|
|
if (!NT_SUCCESS(status)) {
|
|
return status;
|
|
}
|
|
|
|
status = FxValidateRequestOptions(pFxDriverGlobals, RequestOptions);
|
|
if (!NT_SUCCESS(status)) {
|
|
return status;
|
|
}
|
|
|
|
status = buf.ValidateMemoryDescriptor(
|
|
pFxDriverGlobals,
|
|
MemoryDescriptor,
|
|
MemoryDescriptorNullAllowed | MemoryDescriptorNoBufferAllowed
|
|
);
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
return status;
|
|
}
|
|
|
|
status = pUsbDevice->FormatControlRequest(request.m_TrueRequest,
|
|
SetupPacket,
|
|
&buf);
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
DoTraceLevelMessage(
|
|
pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
|
|
"WDFUSBDEVICE %p, WDFREQUEST %p being submitted",
|
|
UsbDevice, request.m_TrueRequest->GetTraceObjectHandle());
|
|
|
|
status = pUsbDevice->SubmitSync(request.m_TrueRequest, RequestOptions);
|
|
|
|
if (BytesTransferred != NULL) {
|
|
if (NT_SUCCESS(status)) {
|
|
#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
|
|
*BytesTransferred = context.m_Urb->TransferBufferLength;
|
|
#elif (FX_CORE_MODE == FX_CORE_USER_MODE)
|
|
*BytesTransferred = context.m_UmUrb.UmUrbControlTransfer.TransferBufferLength;
|
|
#endif
|
|
}
|
|
else {
|
|
*BytesTransferred = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
|
|
"WDFUSBDEVICE %p, %!STATUS!", UsbDevice, status);
|
|
|
|
return status;
|
|
}
|
|
|
|
_Must_inspect_result_
|
|
__drv_maxIRQL(DISPATCH_LEVEL)
|
|
NTSTATUS
|
|
NTAPI
|
|
WDFEXPORT(WdfUsbTargetDeviceFormatRequestForControlTransfer)(
|
|
__in
|
|
PWDF_DRIVER_GLOBALS DriverGlobals,
|
|
__in
|
|
WDFUSBDEVICE UsbDevice,
|
|
__in
|
|
WDFREQUEST Request,
|
|
__in
|
|
PWDF_USB_CONTROL_SETUP_PACKET SetupPacket,
|
|
__in_opt
|
|
WDFMEMORY TransferMemory,
|
|
__in_opt
|
|
PWDFMEMORY_OFFSET TransferOffset
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Formats a request so that a control transfer can be sent to the device
|
|
after this call returns successfully.
|
|
|
|
Arguments:
|
|
UsbDevice - the target representing the device
|
|
|
|
Request - Request to format
|
|
|
|
SetupPacket - control setup packet to be used in the transfer
|
|
|
|
TransferMemory - memory to use in the transfer after the setup packet
|
|
|
|
TransferOffset - offset into TransferMemory and size override for transfer
|
|
length
|
|
|
|
Return Value:
|
|
NTSTATUS
|
|
|
|
--*/
|
|
{
|
|
DDI_ENTRY();
|
|
|
|
PFX_DRIVER_GLOBALS pFxDriverGlobals;
|
|
IFxMemory* pMemory;
|
|
FxUsbDevice* pUsbDevice;
|
|
FxRequestBuffer buf;
|
|
FxRequest* pRequest;
|
|
NTSTATUS status;
|
|
|
|
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
|
|
UsbDevice,
|
|
FX_TYPE_IO_TARGET_USB_DEVICE,
|
|
(PVOID*) &pUsbDevice,
|
|
&pFxDriverGlobals);
|
|
|
|
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
|
|
"WDFUSBDEVICE %p, WDFREQUEST %p, WDFMEMORY %p",
|
|
UsbDevice, Request, TransferMemory);
|
|
|
|
FxPointerNotNull(pFxDriverGlobals, SetupPacket);
|
|
|
|
if (TransferMemory != NULL) {
|
|
FxObjectHandleGetPtr(pFxDriverGlobals,
|
|
TransferMemory,
|
|
IFX_TYPE_MEMORY,
|
|
(PVOID*) &pMemory);
|
|
|
|
status = pMemory->ValidateMemoryOffsets(TransferOffset);
|
|
if (!NT_SUCCESS(status)) {
|
|
return status;
|
|
}
|
|
|
|
buf.SetMemory(pMemory, TransferOffset);
|
|
}
|
|
else {
|
|
pMemory = NULL;
|
|
}
|
|
|
|
FxObjectHandleGetPtr(pFxDriverGlobals,
|
|
Request,
|
|
FX_TYPE_REQUEST,
|
|
(PVOID*) &pRequest);
|
|
|
|
status = pUsbDevice->FormatControlRequest(pRequest, SetupPacket, &buf);
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
FxUsbDeviceControlContext* pContext;
|
|
|
|
pContext = (FxUsbDeviceControlContext*) pRequest->GetContext();
|
|
|
|
RtlCopyMemory(
|
|
&pContext->m_UsbParameters.Parameters.DeviceControlTransfer.SetupPacket,
|
|
SetupPacket,
|
|
sizeof(*SetupPacket)
|
|
);
|
|
|
|
if (pMemory != NULL) {
|
|
pContext->m_UsbParameters.Parameters.DeviceControlTransfer.Buffer =
|
|
TransferMemory;
|
|
}
|
|
}
|
|
|
|
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGIOTARGET,
|
|
"format control request WDFUSBDEVICE %p, WDFREQWUEST %p, WDFMEMORY %p, %!STATUS!",
|
|
UsbDevice, Request, TransferMemory, status);
|
|
|
|
return status;
|
|
}
|
|
|
|
_Must_inspect_result_
|
|
__drv_maxIRQL(PASSIVE_LEVEL)
|
|
NTSTATUS
|
|
WDFAPI
|
|
NTAPI
|
|
WDFEXPORT(WdfUsbTargetDeviceResetPortSynchronously)(
|
|
__in
|
|
PWDF_DRIVER_GLOBALS DriverGlobals,
|
|
__in
|
|
WDFUSBDEVICE UsbDevice
|
|
)
|
|
{
|
|
DDI_ENTRY();
|
|
|
|
PFX_DRIVER_GLOBALS pFxDriverGlobals;
|
|
FxUsbDevice* pUsbDevice;
|
|
NTSTATUS status;
|
|
|
|
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
|
|
UsbDevice,
|
|
FX_TYPE_IO_TARGET_USB_DEVICE,
|
|
(PVOID*) &pUsbDevice,
|
|
&pFxDriverGlobals);
|
|
|
|
status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL);
|
|
if (!NT_SUCCESS(status)) {
|
|
return status;
|
|
}
|
|
|
|
status = pUsbDevice->Reset();
|
|
|
|
return status;
|
|
}
|
|
|
|
#pragma warning(disable:28285)
|
|
__checkReturn
|
|
__drv_maxIRQL(DISPATCH_LEVEL)
|
|
NTSTATUS
|
|
WDFAPI
|
|
NTAPI
|
|
WDFEXPORT(WdfUsbTargetDeviceCreateIsochUrb)(
|
|
__in
|
|
PWDF_DRIVER_GLOBALS DriverGlobals,
|
|
__in
|
|
WDFUSBDEVICE UsbDevice,
|
|
__in_opt
|
|
PWDF_OBJECT_ATTRIBUTES Attributes,
|
|
__in
|
|
ULONG NumberOfIsochPackets,
|
|
__out
|
|
WDFMEMORY* UrbMemory,
|
|
__deref_opt_out_bcount(GET_ISOCH_URB_SIZE(NumberOfIsochPackets))
|
|
PURB* Urb
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Creates a WDFUSBDEVICE handle for the client.
|
|
|
|
Arguments:
|
|
Attributes - Attributes associated with this object
|
|
|
|
NumberOfIsochPacket - Maximum number of Isoch packets that will be programmed into this Urb
|
|
|
|
UrbMemory - The returned handle to the caller for the allocated Urb
|
|
|
|
Urb - (opt) Pointer to the associated urb buffer.
|
|
|
|
Return Value:
|
|
STATUS_INVALID_PARAMETER - any required parameters are not present/invalid
|
|
|
|
STATUS_INVALID_DEVICE_STATE - If the client did not specify a client contract verion while
|
|
creating the WDFUSBDEVICE
|
|
|
|
STATUS_INSUFFICIENT_RESOURCES - could not allocated the object that backs
|
|
the handle
|
|
|
|
STATUS_SUCCESS - success
|
|
|
|
...
|
|
|
|
--*/
|
|
{
|
|
DDI_ENTRY();
|
|
|
|
PFX_DRIVER_GLOBALS pFxDriverGlobals;
|
|
FxUsbDevice* pUsbDevice;
|
|
NTSTATUS status;
|
|
|
|
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
|
|
UsbDevice,
|
|
FX_TYPE_IO_TARGET_USB_DEVICE,
|
|
(PVOID*) &pUsbDevice,
|
|
&pFxDriverGlobals);
|
|
|
|
//
|
|
// Basic parameter validation
|
|
//
|
|
FxPointerNotNull(pFxDriverGlobals, UrbMemory);
|
|
|
|
if (pUsbDevice->GetUSBDHandle() == NULL) {
|
|
status = STATUS_INVALID_DEVICE_STATE;
|
|
|
|
DoTraceLevelMessage(
|
|
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
|
|
"USBDEVICE Must have been created with Client Contract Verion Info, %!STATUS!",
|
|
status);
|
|
|
|
return status;
|
|
}
|
|
|
|
status = pUsbDevice->CreateIsochUrb(Attributes,
|
|
NumberOfIsochPackets,
|
|
UrbMemory,
|
|
Urb);
|
|
|
|
return status;
|
|
}
|
|
|
|
__drv_maxIRQL(DISPATCH_LEVEL)
|
|
WDFUSBINTERFACE
|
|
WDFAPI
|
|
NTAPI
|
|
WDFEXPORT(WdfUsbTargetDeviceGetInterface)(
|
|
__in
|
|
PWDF_DRIVER_GLOBALS DriverGlobals,
|
|
__in
|
|
WDFUSBDEVICE UsbDevice,
|
|
__in
|
|
UCHAR InterfaceIndex
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
DDI_ENTRY();
|
|
|
|
PFX_DRIVER_GLOBALS pFxDriverGlobals;
|
|
FxUsbDevice* pUsbDevice;
|
|
FxUsbInterface *pUsbInterface;
|
|
|
|
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
|
|
UsbDevice,
|
|
FX_TYPE_IO_TARGET_USB_DEVICE,
|
|
(PVOID*) &pUsbDevice,
|
|
&pFxDriverGlobals);
|
|
|
|
pUsbInterface = pUsbDevice->GetInterfaceFromIndex(InterfaceIndex);
|
|
|
|
if (pUsbInterface != NULL) {
|
|
return pUsbInterface->GetHandle();
|
|
}
|
|
else {
|
|
DoTraceLevelMessage(
|
|
pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET,
|
|
"WDFUSBDEVICE %p has %d interfaces, index %d requested, returning "
|
|
"NULL handle",
|
|
UsbDevice, pUsbDevice->GetNumInterfaces(), InterfaceIndex);
|
|
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
_Must_inspect_result_
|
|
__drv_maxIRQL(PASSIVE_LEVEL)
|
|
NTSTATUS
|
|
WDFAPI
|
|
NTAPI
|
|
WDFEXPORT(WdfUsbTargetDeviceQueryUsbCapability)(
|
|
__in
|
|
PWDF_DRIVER_GLOBALS DriverGlobals,
|
|
__in
|
|
WDFUSBDEVICE UsbDevice,
|
|
__in
|
|
CONST GUID* CapabilityType,
|
|
__in
|
|
ULONG CapabilityBufferLength,
|
|
__drv_when(CapabilityBufferLength == 0, __out_opt)
|
|
__drv_when(CapabilityBufferLength != 0 && ResultLength == NULL, __out_bcount(CapabilityBufferLength))
|
|
__drv_when(CapabilityBufferLength != 0 && ResultLength != NULL, __out_bcount_part_opt(CapabilityBufferLength, *ResultLength))
|
|
PVOID CapabilityBuffer,
|
|
__out_opt
|
|
__drv_when(ResultLength != NULL,__deref_out_range(<=,CapabilityBufferLength))
|
|
PULONG ResultLength
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Queries USB capability for the device. Such capabilities are available
|
|
only with USB 3.0 stack. On earlier stacks this API will fail with
|
|
STATUS_NOT_IMPLEMENTED
|
|
|
|
Arguments:
|
|
UsbDevice - Device whose capability is to be queried.
|
|
|
|
CapabilityType - Type of capability as defined by
|
|
IOCTL_INTERNAL_USB_GET_USB_CAPABILITY
|
|
|
|
CapabilityBufferLength - Length of Capability buffer
|
|
|
|
CapabilityBuffer - Buffer for capability. Can be NULL if
|
|
CapabilitiyBufferLength is 0
|
|
|
|
ResultLength - Actual length of the capability. This parameter is optional.
|
|
|
|
Return Value:
|
|
STATUS_SUCCESS - success
|
|
STATUS_NOT_IMPLEMENTED - Capabilties are not supported by USB stack
|
|
STATUS_INSUFFICIENT_RESOURCES - no memory available
|
|
...
|
|
|
|
--*/
|
|
{
|
|
DDI_ENTRY();
|
|
|
|
NTSTATUS status;
|
|
PFX_DRIVER_GLOBALS pFxDriverGlobals;
|
|
FxUsbDevice* pUsbDevice;
|
|
|
|
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
|
|
UsbDevice,
|
|
FX_TYPE_IO_TARGET_USB_DEVICE,
|
|
(PVOID*) &pUsbDevice,
|
|
&pFxDriverGlobals);
|
|
|
|
if (CapabilityBufferLength > 0) {
|
|
FxPointerNotNull(pFxDriverGlobals, CapabilityBuffer);
|
|
}
|
|
|
|
status = pUsbDevice->QueryUsbCapability(CapabilityType,
|
|
CapabilityBufferLength,
|
|
CapabilityBuffer,
|
|
ResultLength);
|
|
return status;
|
|
}
|
|
|
|
} // extern "C"
|