Win 10 Upper filter Usb Class driver for USB generic Hub

Hi,

We have a custom device which has a Hub and a inbuilt device attached to it, but device will not be enabled in the beginning. I need to Send Vendor Specific command to my Hub for enabling this device.

My understanding is only way to send Vendor specific command to windows generic hub is through my Usb HUb class Upperfilter driver. Please correct me if i am wrong.

I have following questions with regard to the problem i have.

  1. Can we achieve this using WinUSB userspace app without having to write filter driver or any other simple method?

  2. For former approach How do i install My “USB Hub Class Upperfilter” driver, Inf doesn’t allow me to have ClassInstall32 section becuase WDK 10 complaints that we cannot have this section in Inf for existing class. (I am refering link https://msdn.microsoft.com/en-us/library/windows/hardware/ff547595(v=vs.85).aspx)

  3. Also can I load my class filter driver only for my HUB VID PID and not every hub that attaches to Host?

Thanks,
Patil

You can filter only your hub by installing a device upper filter and matching against your unique hwid (which is composed of your vid/pid). A class upper filter is complete overkill

Sent from my Windows 10 phone

From: xxxxx@yahoo.commailto:xxxxx
Sent: Wednesday, May 18, 2016 3:57 AM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: [ntdev] Win 10 Upper filter Usb Class driver for USB generic Hub

Hi,

We have a custom device which has a Hub and a inbuilt device attached to it, but device will not be enabled in the beginning. I need to Send Vendor Specific command to my Hub for enabling this device.

My understanding is only way to send Vendor specific command to windows generic hub is through my Usb HUb class Upperfilter driver. Please correct me if i am wrong.

I have following questions with regard to the problem i have.
1) Can we achieve this using WinUSB userspace app without having to write filter driver or any other simple method?
2) For former approach How do i install My “USB Hub Class Upperfilter” driver, Inf doesn’t allow me to have ClassInstall32 section becuase WDK 10 complaints that we cannot have this section in Inf for existing class. (I am refering link https://msdn.microsoft.com/en-us/library/windows/hardware/ff547595(v=vs.85).aspx)

3) Also can I load my class filter driver only for my HUB VID PID and not every hub that attaches to Host?

Thanks,
Patil


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:></mailto:xxxxx></mailto:xxxxx>

Thanks Doron for suggesting best approach to the problem.

I am able to load my driver as Upper filter on Windows-USB-Hub-Driver. But when i use functions WdfUsbTargetDeviceCreateWithParameters and WdfUsbTargetDeviceCreate to get USB device, function calls fail in my driver.

Are these function calls allowed for Upper filter driver which is sitting a top windows Hub driver?

Also I added following AddService directive to inf

AddService = usbhub,%SPSVCINST_ASSOCSERVICE%,usbhub_Service_Inst
AddService = HubFilter, HubFilter_Service_Inst –>

This i picked from CDROM filter drv example, To attach my filter driver as upperfilter on Windows Hub driver.

Is this valid Addservice directive for this case?

Thanks,
Patil

The USB apis are not allowed as the fdo below you controls the configuration of the device. It sounds like all you need to do is send a control transfer to the device, the USB apis may be a bit over kill for that

Sent from my Windows 10 phone

From: xxxxx@yahoo.commailto:xxxxx
Sent: Thursday, May 19, 2016 7:24 AM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: RE:[ntdev] Win 10 Upper filter Usb Class driver for USB generic Hub

Thanks Doron for suggesting best approach to the problem.

I am able to load my driver as Upper filter on Windows-USB-Hub-Driver. But when i use functions WdfUsbTargetDeviceCreateWithParameters and WdfUsbTargetDeviceCreate to get USB device, function calls fail in my driver.

Are these function calls allowed for Upper filter driver which is sitting a top windows Hub driver?

Also I added following AddService directive to inf

AddService = usbhub,%SPSVCINST_ASSOCSERVICE%,usbhub_Service_Inst
AddService = HubFilter, HubFilter_Service_Inst –>

This i picked from CDROM filter drv example, To attach my filter driver as upperfilter on Windows Hub driver.

Is this valid Addservice directive for this case?

Thanks,
Patil


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:></mailto:xxxxx></mailto:xxxxx>

Hi Doron,

As you suggested I implemented a Device filter to filter my Hub as a KMDF driver and i want to send vendor command to my device. As you suggested i cannot use framework USB APIs to send vendor command on control pipe so i am following your article

“Formatting a WDFREQUEST for any IRP_MJ code” to send IOCTL_INTERNAL_USB_SUBMIT_URB to Hub driver below.

My Irp request is not succeeding now i am clueless about what is happening.

Please suggest what could have gone wrong here.
------------WinDBg output of My driver----------------------

0: kd> !wdfkd.wdfdriverinfo HubFltUpClsDrv

Default driver image name: HubFltUpClsDrv
WDF library image name: Wdf01000
FxDriverGlobals 0x97580ed8
WdfBindInfo 0xc4db3020
Version v1.15
Library module 0x803fa770
ServiceName \Registry\Machine\System\CurrentControlSet\Services\Wdf01000
ImageName Wdf01000

WDFDRIVER: 0x7bad92e0
Driver logs: !wdflogdump HubFltUpClsDrv.sys -d
Framework logs: !wdflogdump HubFltUpClsDrv.sys -f

!wdfdevice 0x72a14490 ff (Filter)
Pnp/Power State: WdfDevStatePnpStarted, WdfDevStatePowerD0, WdfDevStatePwrPolStartingSucceeded
context: dt 0x8d5ebcf8 HubFltUpClsDrv!DEVICE_CONTEXT (size is 0x1c bytes)

!wdfdevicequeues 0x72a14490

0: kd> !wdfkd.wdfiotarget 76cedbc0
Treating handle as a KMDF handle!

WDFIOTARGET 76cedbc0
=========================
WDFDEVICE: 0x72a14490
Target Device: !devobj 0x91e58028
Target PDO: !devobj 0x8efb2580

Type: Instack target
State: WdfIoTargetStarted

Requests pending: 0

Requests sent: 0

Requests sent with ignore-target-state: 0

0: kd> !devobj 0x91e58028
Device object (91e58028) is for:
00000055 \Driver\usbhub DriverObject 8d50af30
Current Irp 00000000 RefCount 0 Type 00008600 Flags 00002840
Dacl 840caf88 DevExt 91e580e0 DevObjExt 91e5b138
ExtensionFlags (0x00000800) DOE_DEFAULT_SD_PRESENT
Characteristics (0x00000180) FILE_AUTOGENERATED_DEVICE_NAME, FILE_DEVICE_SECURE_OPEN
AttachedDevice (Upper) 89312020 \Driver\HubFltUpClsDrv
AttachedTo (Lower) 8ef3a020 \Driver\ACPI
Device queue is not busy.

------------------WinDbg Output of Irp to send IOCTL_INTERNAL_USB_SUBMIT_URB Hubdriver below ---------------------------
0: kd> !irp 0x8efb7198
Irp is active with 11 stacks 12 is current (= 0x8efb7394)
No Mdl: No System Buffer: Thread 00000000: Irp is completed.
cmd flg cl Device File Completion-Context
[N/A(0), N/A(0)]
0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[N/A(0), N/A(0)]
0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[N/A(0), N/A(0)]
0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[N/A(0), N/A(0)]
0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[N/A(0), N/A(0)]
0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[N/A(0), N/A(0)]
0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[N/A(0), N/A(0)]
0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[N/A(0), N/A(0)]
0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[N/A(0), N/A(0)]
0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[N/A(0), N/A(0)]
0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[N/A(f), N/A(0)]
0 0 00000000 00000000 00000000-00000000

Args: 91c10750 00000000 00220003 00000000

I observe that device parameter is 0x00000 is that the reason why Irp is failing ?
But i think i followed the steps correctly as in article “Formatting a WDFREQUEST for any IRP_MJ code” i don’t understand why device is NULL?

-------------WinDbg output of the WDF messages -----------------------------------------

0: kd> !wdflogdump HubFltUpClsDrv.sys -f
Trace searchpath is:

Trace format prefix is: %7!u!: %!FUNC! -
Trying to extract TMF information from - C:\ProgramData\dbg\sym\Wdf01000.pdb\0BAEE654C9F84345921DBEFADFDFCAB71\Wdf01000.pdb
Gather log: Please wait, this may take a moment (reading 4032 bytes).
% read so far … 10, 20, 100
There are 24 log entries
— start of log —
1: FxIFRStart - FxIFR logging started
2: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x72A14490 !devobj 0x89312020 entering PnP State WdfDevStatePnpInit from WdfDevStatePnpObjectCreated
3: FxPkgPnp::Dispatch - WDFDEVICE 0x72A14490 !devobj 0x89312020, IRP_MJ_PNP, 0x00000000(IRP_MN_START_DEVICE) IRP 0x8EEB4008
4: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x72A14490 !devobj 0x89312020 entering PnP State WdfDevStatePnpInitStarting from WdfDevStatePnpInit
5: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x72A14490 !devobj 0x89312020 entering PnP State WdfDevStatePnpHardwareAvailable from WdfDevStatePnpInitStarting
6: FxPkgPnp::NotPowerPolicyOwnerEnterNewState - WDFDEVICE 0x72A14490 !devobj 0x89312020 entering not power policy owner state WdfDevStatePwrPolStarting from WdfDevStatePwrPolObjectCreated
7: FxPkgPnp::PowerEnterNewState - WDFDEVICE 0x72A14490 !devobj 0x89312020 entering Power State WdfDevStatePowerStartingCheckDeviceType from WdfDevStatePowerObjectCreated
8: FxPkgPnp::PowerEnterNewState - WDFDEVICE 0x72A14490 !devobj 0x89312020 entering Power State WdfDevStatePowerD0Starting from WdfDevStatePowerStartingCheckDeviceType
9: FxPkgPnp::PowerEnterNewState - WDFDEVICE 0x72A14490 !devobj 0x89312020 entering Power State WdfDevStatePowerD0StartingConnectInterrupt from WdfDevStatePowerD0Starting
10: FxPkgPnp::PowerEnterNewState - WDFDEVICE 0x72A14490 !devobj 0x89312020 entering Power State WdfDevStatePowerD0StartingDmaEnable from WdfDevStatePowerD0StartingConnectInterrupt
11: FxPkgPnp::PowerEnterNewState - WDFDEVICE 0x72A14490 !devobj 0x89312020 entering Power State WdfDevStatePowerD0StartingStartSelfManagedIo from WdfDevStatePowerD0StartingDmaEnable
12: FxPkgIo::ResumeProcessingForPower - Power resume all queues of WDFDEVICE 0x72A14490
13: FxPkgPnp::PowerEnterNewState - WDFDEVICE 0x72A14490 !devobj 0x89312020 entering Power State WdfDevStatePowerDecideD0State from WdfDevStatePowerD0StartingStartSelfManagedIo
14: FxPkgPnp::PowerEnterNewState - WDFDEVICE 0x72A14490 !devobj 0x89312020 entering Power State WdfDevStatePowerD0 from WdfDevStatePowerDecideD0State
15: FxPkgPnp::NotPowerPolicyOwnerEnterNewState - WDFDEVICE 0x72A14490 !devobj 0x89312020 entering not power policy owner state WdfDevStatePwrPolStarted from WdfDevStatePwrPolStarting
16: FxPkgPnp::NotPowerPolicyOwnerEnterNewState - WDFDEVICE 0x72A14490 !devobj 0x89312020 entering not power policy owner state WdfDevStatePwrPolStartingSucceeded from WdfDevStatePwrPolStarted
17: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x72A14490 !devobj 0x89312020 entering PnP State WdfDevStatePnpEnableInterfaces from WdfDevStatePnpHardwareAvailable
18: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x72A14490 !devobj 0x89312020 entering PnP State WdfDevStatePnpStarted from WdfDevStatePnpEnableInterfaces
19: FxPkgPnp::Dispatch - WDFDEVICE 0x72A14490 !devobj 0x89312020, IRP_MJ_PNP, 0x00000014(IRP_MN_QUERY_PNP_DEVICE_STATE) IRP 0x8C1378A8
20: FxPkgFdo::HandleQueryPnpDeviceStateCompletion - WDFDEVICE 0x72A14490 !devobj 0x89312020 returning PNP_DEVICE_STATE 0x0 IRP 0x8C1378A8
21: FxPkgPnp::Dispatch - WDFDEVICE 0x72A14490 !devobj 0x89312020, IRP_MJ_PNP, 0x00000007(IRP_MN_QUERY_DEVICE_RELATIONS) type BusRelations IRP 0x8C1378A8
22: FxPkgPnp::Dispatch - WDFDEVICE 0x72A14490 !devobj 0x89312020, IRP_MJ_PNP, 0x00000007(IRP_MN_QUERY_DEVICE_RELATIONS) type BusRelations IRP 0x9719E3C8
23: imp_WdfRequestSend - WDFREQUEST 7BB28D00 must be a WDFQUEUE presented request
24: FxPkgPnp::Dispatch - WDFDEVICE 0x72A14490 !devobj 0x89312020 IRP_MJ_POWER, 0x00000000(IRP_MN_WAIT_WAKE) IRP 0x97ECCD98 for PowerSystemUnspecified (S-1)
---- end of log ----

In Above message what does "23: imp_WdfRequestSend - WDFREQUEST 7BB28D00 must be a WDFQUEUE presented request " mean am i doing anything wrong here ?

Thanks

xxxxx@yahoo.com wrote:

As you suggested I implemented a Device filter to filter my Hub as a KMDF driver and i want to send vendor command to my device. As you suggested i cannot use framework USB APIs to send vendor command on control pipe so i am following your article

“Formatting a WDFREQUEST for any IRP_MJ code” to send IOCTL_INTERNAL_USB_SUBMIT_URB to Hub driver below.

My Irp request is not succeeding now i am clueless about what is happening.

“Not succeeding” could mean anything. Are you getting an error back
from WdfRequestSend? Which error? Are you getting an error in the
completion?

Please suggest what could have gone wrong here.

We can’t really tell anything without seeing your code. Please, show us
the whole routine. There are a hundred ways to do this incorrectly.
Are you using WdfIoTargetFormatRequestForInternalIoctlOthers? How are
you telling the hub which device is supposed to receive the vendor command?

------------------WinDbg Output of Irp to send IOCTL_INTERNAL_USB_SUBMIT_URB Hubdriver below ---------------------------
0: kd> !irp 0x8efb7198
Irp is active with 11 stacks 12 is current (= 0x8efb7394)
No Mdl: No System Buffer: Thread 00000000: Irp is completed.
cmd flg cl Device File Completion-Context

[N/A(f), N/A(0)]
0 0 00000000 00000000 00000000-00000000

Args: 91c10750 00000000 00220003 00000000

I observe that device parameter is 0x00000 is that the reason why Irp is failing ?
But i think i followed the steps correctly as in article “Formatting a WDFREQUEST for any IRP_MJ code” i don’t understand why device is NULL?

It could be that the request has been partially prepared but not sent.
When you create a new IRP, you fill in that final stack entry prior to
sending it. Not all of the fields are required at every step.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Thanks Tim for analyzing the WinDbg output of my driver. I have attached the code below. I went through the code again and again to understand if there are any issues here i am clueless now.

NTSTATUS SendUrb(WDFDEVICE Device)

{

WDF_OBJECT_ATTRIBUTES woa;
WDFREQUEST Request;
WDFIOTARGET target;

NTSTATUS status;
WDFMEMORY memory;
PURB Urb;
PUCHAR buffer = NULL;

WDF_OBJECT_ATTRIBUTES_INIT(&woa);

//Create request oject
target = WdfDeviceGetIoTarget(Device);

status = WdfRequestCreate(

WDF_NO_OBJECT_ATTRIBUTES, target, &Request);

if (!NT_SUCCESS(status)) {

TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, “URb Req Create Failed”);
return status;

}

woa.ParentObject = Request;

status = WdfMemoryCreate(WDF_NO_OBJECT_ATTRIBUTES,

NonPagedPool,

0,

sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST)+50,//sizeof(XRB),

&memory,

(PVOID*)&Urb);

if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, “Urb Mem Create failed”);
return status;

}

buffer = ExAllocatePoolWithTag(NonPagedPoolNx, 50, ‘durb’);

//Initialize buffer with random data
if (buffer != NULL)
{
for (int i = 0; i < 50; i++)
buffer[i] = 0xaa;
}

// [?Format the URB?]
UsbBuildVendorRequest(Urb,
URB_FUNCTION_CLASS_INTERFACE,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
USBD_TRANSFER_DIRECTION_OUT,
0,
0,//RequestCode,
0,
0xABCD,
buffer,//(Urb+1),//TransferBuffer,
NULL,
50,//TransferBufferLength,
0);

// Parameters.Others.Argument3 is used by the IOCTL value

status = WdfIoTargetFormatRequestForInternalIoctlOthers(

WdfDeviceGetIoTarget(Device),

Request,

IOCTL_INTERNAL_USB_SUBMIT_URB,

memory, NULL, // Parameters.Others.Argument1

WDF_NO_HANDLE, NULL, // Parameters.Others.Argument2

WDF_NO_HANDLE, NULL // Parameters.Others.Argument4

);

if (NT_SUCCESS(status)) {

WdfRequestSetCompletionRoutine(Request, UrbCompletionRoutine, NULL);

WDF_REQUEST_SEND_OPTIONS_INIT(&options,
WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET);

TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, “Urb send WdfDeviceGetIoTarget=0x%llx”,(unsigned __int64)target);
// send async

if (WdfRequestSend(Request,

WdfDeviceGetIoTarget(Device),

&options) == FALSE) {

status = WdfRequestGetStatus(Request);
// send failed
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, “Urb send failed Status=0x%x”, status);
WdfObjectDelete(memory);
}
else {

status = STATUS_PENDING;
}
}

if (!NT_SUCCESS(status)) {

WdfObjectDelete(memory);
}

return status;

}

Thanks,
Patil

xxxxx@yahoo.com wrote:

Thanks Tim for analyzing the WinDbg output of my driver. I have attached the code below. I went through the code again and again to understand if there are any issues here i am clueless now.

status = WdfMemoryCreate(WDF_NO_OBJECT_ATTRIBUTES,
NonPagedPool,
0,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST)+50,//sizeof(XRB),
&memory,
(PVOID*)&Urb);

Why allocate 50 extra bytes? Superstition? Or were you planning to use
the rest for your buffer?

If you’re sending the URB synchronously, you can just put the URB on the
stack. You don’t really need dynamic memory.

buffer = ExAllocatePoolWithTag(NonPagedPoolNx, 50, ‘durb’);

//Initialize buffer with random data
if (buffer != NULL)
{
for (int i = 0; i < 50; i++)
buffer[i] = 0xaa;
}

RtlFillMemory( buffer, 50, 0xaa );

// [?Format the URB?]
UsbBuildVendorRequest(Urb,
URB_FUNCTION_CLASS_INTERFACE,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
USBD_TRANSFER_DIRECTION_OUT,
0,
0,//RequestCode,
0,
0xABCD,
buffer,//(Urb+1),//TransferBuffer,
NULL,
50,//TransferBufferLength,
0);

OK, there are two related problems here. You have used
URB_FUNCTION_CLASS_INTERFACE. You are saying “this is a request that is
identified in one of the existing USB class specifications”, and it
means “this request is targeted at a specific interface”.

Request code 0 is GET_STATUS, but for a hub, GET_STATUS is only valid to
a device, or to other. There is no GET_STATUS to an interface. I’m
pretty sure you didn’t really want GET_STATUS anyway – I’m just using
this to build up to my final point.

More importantly, when you send a control request to an interface, the
wIndex value must have the target interface number. You have passed
0xABCD. Windows will reject this request if your device does not have
an interface 0xCD.

If you want to send arbitrary values for bRequest, wValue and wIndex,
then you must use a “vendor” request aimed at either the “device” or at
"other. That means URB_FUNCTION_VENDOR_DEVICE or
URB_FUNCTION_VENDOR_OTHER. Note that there must be code in the device
that is expecting to receive this request.

Now, there ARE a set of well-defined class-specific requests for hubs,
identified in chapter 11 of the USB spec. It’s possible you could
convince yourself that your task fits into SET_FEATURE for the feature
PORT_ENABLE, but in that case you’d need to use
URB_FUNCTION_CLASS_OTHER, and wIndex would have the port number to control.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Thanks Tim,

As you ponited out there are mistakes in URB packet parameters. Also after removing SEND_FORGET send option now i can see that URB is reaching my device though it is malformed.

As you mentioned there are mistakes in the packet formation.
I have to correct them.

Once again Thanks Tim.

Patil