Driver Problems? Questions? Issues?
Put OSR's experience to work for you! Contact us for assistance with:
  • Creating the right design for your requirements
  • Reviewing your existing driver code
  • Analyzing driver reliability/performance issues
  • Custom training mixed with consulting and focused directly on your specific areas of interest/concern.
Check us out. OSR, the Windows driver experts.

OSR Seminars


Go Back   OSR Online Lists > ntdev
Welcome, Guest
You must login to post to this list
  Message 1 of 7  
25 May 18 07:11
Rui Abreu
xxxxxx@protonmail.com
Join Date: 25 May 2018
Posts To This List: 3
Getting USB descriptors from a class filter

Hi all, I have few questions related to an USB class filtering. - I shouldn't send URBs from a class filter to a PDO, but why? I mean, if a have the PDO of a USB device, why is not safe to ask for the device descriptor, for example, after the device is started? - Is a reasonable approach to wait for URBs sent by the system to complete succesfully and then read the information from them? I guess... with lower filter? - Is there any way to get the descriptors from an (upper or lower) USB class filter? Thanks in advance, Rui
  Message 2 of 7  
25 May 18 10:59
Peter Viscarola
xxxxxx@osr.com
Join Date:
Posts To This List: 6183
List Moderator
Getting USB descriptors from a class filter

<quote> why is not safe to ask for the device descriptor, for example, after the device is started? </quote> Who says it's NOT safe? It sounds perfectly reasonable to me. <quote> Is a reasonable approach to wait for URBs sent by the system to complete succesfully and then read the information from them </quote> Well... "it depends" -- I don't TYPICALLY like *any* synchronous "wait for it to complete" approach, when it's used generically in the path to a controller. Rather, I'd like to see you send the request asynchronously and get the results in a Completion Callback. All using WDF, of course. Peter OSR @OSRDrivers
  Message 3 of 7  
25 May 18 13:01
Tim Roberts
xxxxxx@probo.com
Join Date: 28 Jan 2005
Posts To This List: 11955
Getting USB descriptors from a class filter

xxxxx@protonmail.com wrote: > > I have few questions related to an USB class filtering. I would caution that the term "USB class filtering" can have several different meanings.  What "class" are you filtering? > - I shouldn't send URBs from a class filter to a PDO, but why? I mean, > if a have the PDO of a USB device, why is not safe to ask for the > device descriptor, for example, after the device is started?  It is safe, although typically it's not necessary, because you can intercept the device descriptor request from the driver you're filtering and snaggle its output.  You will typically need to monitor many of the standard requests, so you can learn which interfaces are selected, for example. > - Is a reasonable approach to wait for URBs sent by the system to > complete succesfully and then read the information from them? I > guess... with lower filter? Absolutely.  I do it all the time. > - Is there any way to get the descriptors from an (upper or lower) USB > class filter? Monitoring as a lower filter is easy.  From an upper filter, you'd need to send your own request.  Note that, as an upper filter, you won't know which interfaces are selected, or which alternate settings are chosen.  A USB upper filter typically doesn't deal in URBs very much; you deal in whatever interface is spoken out the top end of the driver you're filtering. -- Tim Roberts, xxxxx@probo.com Providenza & Boekelheide, Inc.
  Message 4 of 7  
26 May 18 14:36
Rui Abreu
xxxxxx@protonmail.com
Join Date: 25 May 2018
Posts To This List: 3
Getting USB descriptors from a class filter

Peter, Tim, thank you. Your help is really appreciated. After reading your answers I realized there are things (even more) I dont understand properly enough to write the filter. I have been reading a bit more... and I have new basic doubts. - According to MSDN the USB class includes USB host controllers and USB hubs, but not USB peripherals. What does "but not USB peripherals" really mean? I can see USB enumerated devices (\USB\VID_*)... and monitor the IRPs before and after arriving the FDO. Is it something like not all USB devices are going to be informed in my AddDevice function? - The fact that Peter suggests using WDF...implies that I was wrong about something very basic. As I expected to monitor URBs I wrongly thought the filter is considered a bus filter. Ok, so after reading the forum, I guess the next move is to rewrite it using KMDF, isn't it? Every class filter can be written with KMDF regardless the class? - Regardless the framework used, and although this WDM filter is going to the end up in the Recycle Bin... is my code BSODing in (Windows Server 2012, IRQL is PASSIVE_LEVEL) because the approach? It *seemed* to work OK in XP, what I do is: 1. Install a completion routine on IRP_MN_START_DEVICE 2. If the start is successful, I try to get the class of the device to save it in my device descriptor by: 2.1 Declare URB & USB_DEVICE_DESCRIPTOR structs in the stack 2.2 Init the URB with UsbBuildGetDescriptorRequest 2.3 Create an IRP with IoBuildDeviceIoControlRequest with an event to wait in case is pended 2.4 Setup the stack location with the address of the URB 2.5 Call IoCallDriver with the PDO 2.6 If needed, wait until the IRP is completed 2.7 Parse the device descriptor in case of success Should this approach work? If I move it to WDF, isn't it this, more or less, what would happen under the hood? Thank you again. Rui
  Message 5 of 7  
26 May 18 20:54
Tim Roberts
xxxxxx@probo.com
Join Date: 28 Jan 2005
Posts To This List: 11955
Getting USB descriptors from a class filter

On May 26, 2018, at 11:34 AM, xxxxx@protonmail.com <xxxxx@lists.osr.com> wrote: > > - According to MSDN the USB class includes USB host controllers and USB hubs, but not USB peripherals. What does "but not USB peripherals" really mean? I can see USB enumerated devices (\USB\VID_*)... and monitor the IRPs before and after arriving the FDO. Is it something like not all USB devices are going to be informed in my AddDevice function? The situation is not straightforward, in part because the term "class" is heavily overloaded. We have the device install class, which is the Class and ClassGUID specified in the INF file. In this case, the USB class has a GUID that starts 36fc9e60. This class is intended for USB host controllers and hubs. However, because there was no other convenient place, many people making USB devices put them in Class=USB, just because the name was so tempting. Microsoft added the USBDevice class (which starts 88bae032) in Windows 10 to solve that problem, but there are a lot of old driver packages out there. Microsoft also uses the term "class" to refer to device interfaces, which are PnP concepts that are managed at run-time, not specified in the INF file. There is a device interface class for USB devices as well, and I believe the hubs create that interface for any subdivide that they create. A "class filter driver" is ordinarily filtering based on the device install class. That means anything that appears in Device Manager under "Universal Serial Bus Controllers", which might include devices that are not actually USB controllers. > - The fact that Peter suggests using WDF...implies that I was wrong about something very basic. As I expected to monitor URBs I wrongly thought the filter is considered a bus filter. Ok, so after reading the forum, I guess the next move is to rewrite it using KMDF, isn't it? Every class filter can be written with KMDF regardless the class? No, URBs are sent by individual devices. A straight device filter or class filter can grab those. Being a bus filter is more about watching complicated PnP interactions. If all you need are URBs, that's a straight filter. Filter drivers are trivially easy in KMDF. There is NO reason to write a filter driver in straight WDM any more. > - Regardless the framework used, and although this WDM filter is going to the end up in the Recycle Bin... is my code BSODing in (Windows Server 2012, IRQL is PASSIVE_LEVEL) because the approach? It *seemed* to work OK in XP, what I do is: > > 1. Install a completion routine on IRP_MN_START_DEVICE > 2. If the start is successful, I try to get the class of the device to save it in my device descriptor by: > 2.1 Declare URB & USB_DEVICE_DESCRIPTOR structs in the stack > 2.2 Init the URB with UsbBuildGetDescriptorRequest > 2.3 Create an IRP with IoBuildDeviceIoControlRequest with an event to wait in case is pended > 2.4 Setup the stack location with the address of the URB > 2.5 Call IoCallDriver with the PDO <...excess quoted lines suppressed...> As long as you are doing this in the completion routine, this should be OK. Where do you get the blue screen? ??? Tim Roberts, xxxxx@probo.com Providenza & Boekelheide, Inc.
  Message 6 of 7  
27 May 18 17:41
Rui Abreu
xxxxxx@protonmail.com
Join Date: 25 May 2018
Posts To This List: 3
Getting USB descriptors from a class filter

Thanks a lot for the feedback. This is a stack trace in Windows XP, which seems reasonable, during a succesful processing of the IRP: kd> kb ChildEBP RetAddr Args to Child bad07680 ba49ff14 45447367 8ac8ef20 bad077f0 USBPORT!USBPORT_SCT_GetSetDescriptor+0x46 <- Get Descriptor makes sense... bad076ac ba4a5088 89b3c618 89b8d028 000000b0 USBPORT!USBPORT_ProcessURB+0x3f4 bad076cc ba48e3d2 89b3c618 8ac8ef20 89b3c618 USBPORT!USBPORT_PdoInternalDeviceControlIrp+0x7e bad076f0 804ee119 8ac8efd8 89b3c770 806d22e8 USBPORT!USBPORT_Dispatch+0x148 bad07700 8064d628 8ac8ef20 bad077f0 89c83e38 nt!IopfCallDriver+0x31 bad07724 baa5859c bad0774c baa5c82d 8ac8ef20 nt!IovCallDriver+0xa0 bad0772c baa5c82d 8ac8ef20 89b3c618 8ac8ef20 usbhub!USBH_PassIrp+0x18 bad0774c baa5d0ae 89cdd1d8 8ac8ef20 89c83d80 usbhub!USBH_PdoUrbFilter+0xbd bad07768 baa5a5e4 bad077f0 8ac8ef20 bad077ac usbhub!USBH_PdoDispatch+0x202 bad07778 804ee119 89c83d80 8ac8ef20 806d22e8 usbhub!USBH_HubDispatch+0x48 bad07788 8064d628 8b022ed8 bad07908 8b022fb4 nt!IopfCallDriver+0x31 bad077ac ba58308d bad07dcc 00040000 00000000 nt!IovCallDriver+0xa0 bad077dc ba583160 89c83d80 bad077f0 89c83d80 MyDriver!UsbSendUrb+0x6d <- Send the URB bad07850 ba57c262 89c83d80 bad07860 01100112 MyDriver!UsbReadDeviceDescriptor+0x50 bad07880 8064d830 89c82678 8b022ed8 00000000 MyDriver!StartDeviceCompleted+0x202 <- Completion routine, sending URB... <<<<<< bad078a4 804f069e 89c82678 8b022ed8 bad07908 nt!IovpLocalCompletionRoutine+0xb4 bad078d4 8064dcb8 8996ae90 89c84030 8b022e00 nt!IopfCompleteRequest+0xa2 bad07940 babce03f ffffffff ffffffff 00000000 nt!IovCompleteRequest+0x9a bad07988 babc85e5 89c840e8 8b022ed8 0000001b usbccgp!USBC_PnP+0x29f bad079c4 804ee119 89c84030 8b022ed8 806d22e8 usbccgp!USBC_Dispatch+0x195 bad079d4 8064d628 89c82678 89d884d0 8b022e00 nt!IopfCallDriver+0x31 bad079f8 ba57c459 89c82730 00000000 8b022fd8 nt!IovCallDriver+0xa0 bad07a0c 804ee119 89c82678 8b022ed8 806d22e8 MyDriver!DispatchPnP+0x139 <- IRP_MN_START_DEVICE recieved, set the completion routine <<<<< bad07a1c 8064d628 8b022ffc bad07aac 8b022ed8 nt!IopfCallDriver+0x31 bad07a40 80587fc9 bad07aac 89c83d80 00000000 nt!IovCallDriver+0xa0 bad07a6c 80588047 89c82678 bad07a88 00000000 nt!IopSynchronousCall+0xb7 bad07ab0 804f514c 89c83d80 89c164e0 00000001 nt!IopStartDevice+0x4d bad07acc 805876f7 89c83d80 89c16401 00000000 nt!PipProcessStartPhase1+0x4e bad07d24 80587bca 89d8fee8 00000001 00000000 nt!PipProcessDevNodeTree+0x1db bad07d4c 804f58d6 00000003 80552040 8055b0fc nt!PiProcessStartSystemDevices+0x3a bad07d74 80534c02 00000000 00000000 89da1da8 nt!PipDeviceActionWorker+0x166 bad07dac 805c6160 00000000 00000000 00000000 nt!ExpWorkerThread+0x100 bad07ddc 80541dd2 80534b02 00000001 00000000 nt!PspSystemThreadStartup+0x34 00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16 ################################################################################# # Now the crash in Windows Server 2012: To test the filter, I attach to every device in AddDevice() and then I try to do the same. The first devices that appear are root hubs: USB\ROOT_HUB, USB\ROOT_HUB20 and USB\ROOT_HUB30 which I suspect correspond to UHCI, EHCI and xHCI. For the first two root hubs, the IoCallDriver() call fails with STATUS_NO_SUCH_DEVICE which maybe make sense for root hubs, I don't know yet, but USBview is showing device descriptors only for generic hubs connected to root hubs, but not for root hubs. Anyways the third one does not return an error, it just crashes with bugcheck KERNEL_MODE_EXCEPTION_NOT_HANDLED. kd> !analyze -v ******************************************************************************* * * * Bugcheck Analysis * * * ******************************************************************************* SYSTEM_THREAD_EXCEPTION_NOT_HANDLED (7e) This is a very common bugcheck. Usually the exception address pinpoints the driver/function that caused the problem. Always note this address as well as the link date of the driver/image that contains this address. Arguments: Arg1: ffffffffc0000005, The exception code that was not handled Arg2: fffff8000040f066, The address that the exception occurred at Arg3: ffffd0002078c488, Exception Record Address Arg4: ffffd0002078bc90, Context Record Address Debugging Details: ------------------ EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%p referenced memory at 0x%p. The memory could not be %s. FAULTING_IP: Wdf01000!imp_WdfObjectGetTypedContextWorker+26 fffff800`0040f066 4c8b5010 mov r10,qword ptr [rax+10h] EXCEPTION_RECORD: ffffd0002078c488 -- (.exr 0xffffd0002078c488) ExceptionAddress: fffff8000040f066 (Wdf01000!imp_WdfObjectGetTypedContextWorker+0x0000000000000026) ExceptionCode: c0000005 (Access violation) ExceptionFlags: 00000000 NumberParameters: 2 Parameter[0]: 0000000000000000 Parameter[1]: 0000307ffee7b438 Attempt to read from address 0000307ffee7b438 CONTEXT: ffffd0002078bc90 -- (.cxr 0xffffd0002078bc90) rax=0000307ffee7b428 rbx=0000000000000000 rcx=0000000000000000 rdx=ffffcf8001184bd0 rsi=0000000000000000 rdi=ffffd0002078ca40 rip=fffff8000040f066 rsp=ffffd0002078c6c0 rbp=000000000000000b r8=fffff80001bb00b0 r9=fffff801ea1156b0 r10=ffffe0000518fc70 r11=0000000000000000 r12=0000000000000021 r13=0000000000000000 r14=00001ffffae70858 r15=ffffcf800111ed30 iopl=0 nv up ei pl zr na po nc cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010246 Wdf01000!imp_WdfObjectGetTypedContextWorker+0x26: fffff800`0040f066 4c8b5010 mov r10,qword ptr [rax+10h] ds:002b:0000307f`fee7b438=???????????????? Resetting default scope DEFAULT_BUCKET_ID: VISTA_DRIVER_FAULT PROCESS_NAME: System CURRENT_IRQL: 0 ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%p referenced memory at 0x%p. The memory could not be %s. EXCEPTION_PARAMETER1: 0000000000000000 EXCEPTION_PARAMETER2: 0000307ffee7b438 READ_ADDRESS: 0000307ffee7b438 FOLLOWUP_IP: ucx01000!Urb_USBPORTStyle_ProcessURB+98 fffff800`01ba3a84 4533db xor r11d,r11d BUGCHECK_STR: 0x7E LAST_CONTROL_TRANSFER: from fffff80001ba3a84 to fffff8000040f066 STACK_TEXT: ffffd000`2078c6c0 fffff800`01ba3a84 : 00000000`00000000 fffff801`ea473de9 ffffe000`00e6b330 fffff801`ea472368 : Wdf01000!imp_WdfObjectGetTypedContextWorker+0x26 ffffd000`2078c710 fffff800`01b99e20 : 00001fff`fae70858 ffffcf80`0111ed30 ffffd000`2078c7d0 ffffcf80`0111ef68 : ucx01000!Urb_USBPORTStyle_ProcessURB+0x98 ffffd000`2078c770 fffff800`00414d43 : ffffcf80`0111ed30 ffffe000`00341818 00000000`0000000f ffffe000`0518f7a0 : ucx01000!RootHub_Pdo_EvtInternalDeviceControlIrpPreprocessCallback+0x448 <<<< Maybe this calls to the preprocess callbacks I have been reading about (WDF). I guess makes sense because URB is sent via IRP_MJ_INTERNAL_DEVICE_CONTROL ffffd000`2078c800 fffff801`ea465911 : ffffe000`00e6bed0 00000000`00000002 fffff801`e9f1c04c ffffe000`05190710 : Wdf01000!FxDevice::DispatchWithLock+0xb01 ffffd000`2078c8e0 fffff800`0031a989 : ffffcf80`0111ed30 fffff800`01071def fffff801`e9f1c04c ffffe000`00e6be30 : nt!IovCallDriver+0x3cd ffffd000`2078c930 fffff800`01071def : fffff801`ea0ae880 ffffe000`05433040 ffffe000`0544ae50 00000000`00000000 : VerifierExt!IofCallDriver_internal_wrapper+0x71 ffffd000`2078c970 fffff800`01071f18 : ffffe000`05190710 ffffd000`2078ca40 00000000`00000000 fffff801`ea0ae890 : MyDriver!UsbSendUrb+0xaf ffffd000`2078ca20 fffff800`0106949d : ffffe000`05190710 ffffd000`2078cb48 ffffe000`0544ae50 ffffe000`00e81010 : MyDriver!UsbReadDeviceDescriptor+0x78=20 ffffd000`2078cb00 fffff801`ea4726a6 : ffffe000`05433d20 ffffcf80`01184bd0 00000000`00000000 fffff801`e9e02000 : MyDriver!StartDeviceCompleted+0x25d <- Completion routine, sending URB... <<<<<<<<<< ffffd000`2078cb70 fffff801`ea4729e4 : fffff801`ea0ae890 fffff801`ea0ae880 00000000`00000080 ffffe000`001e4040 : nt!ViPendingCompleteAfterWait+0xda ffffd000`2078cbc0 fffff801`e9ee9664 : 0072a845`c7202444 740069ac`45c70074 006f0069`b045c700 c7000000`6eb445c7 : nt!ViPendingWorkerThread+0x2c ffffd000`2078cc00 fffff801`e9f586c6 : fffff801`ea0f3180 ffffe000`001e4040 ffffe000`001e3880 000001b9`41402454 : nt!PspSystemThreadStartup+0x58 ffffd000`2078cc60 00000000`00000000 : ffffd000`2078d000 ffffd000`20787000 00000000`00000000 00000000`00000000 : nt!KxStartSystemThread+0x16 SYMBOL_STACK_INDEX: 1 SYMBOL_NAME: ucx01000!Urb_USBPORTStyle_ProcessURB+98 FOLLOWUP_NAME: MachineOwner MODULE_NAME: ucx01000 IMAGE_NAME: ucx01000.sys DEBUG_FLR_IMAGE_TIMESTAMP: 5215f7fc STACK_COMMAND: .cxr 0xffffd0002078bc90 ; kb FAILURE_BUCKET_ID: X64_0x7E_VRF_ucx01000!Urb_USBPORTStyle_ProcessURB+98 BUCKET_ID: X64_0x7E_VRF_ucx01000!Urb_USBPORTStyle_ProcessURB+98 Followup: MachineOwner --------- Any idea of what could be happening? Kind regards, Rui
  Message 7 of 7  
28 May 18 00:07
Tim Roberts
xxxxxx@probo.com
Join Date: 28 Jan 2005
Posts To This List: 11955
Getting USB descriptors from a class filter

On May 27, 2018, at 2:39 PM, xxxxx@protonmail.com <xxxxx@lists.osr.com> wrote: > > Thanks a lot for the feedback. > ,,, > FAULTING_IP: > Wdf01000!imp_WdfObjectGetTypedContextWorker+26 > fffff800`0040f066 4c8b5010 mov r10,qword ptr [rax+10h] > ,,, > rax=0000307ffee7b428 rbx=0000000000000000 rcx=0000000000000000 > rdx=ffffcf8001184bd0 rsi=0000000000000000 rdi=ffffd0002078ca40 > rip=fffff8000040f066 rsp=ffffd0002078c6c0 rbp=000000000000000b <...excess quoted lines suppressed...> In this case, it's using a KMDF handle as if it were an address. Is it possible you accidentally inserted a KMDF handle into one of the IRP fields? That seems really unlikely. > ffffd000`2078c770 fffff800`00414d43 : ffffcf80`0111ed30 ffffe000`00341818 00000000`0000000f ffffe000`0518f7a0 : ucx01000!RootHub_Pdo_EvtInternalDeviceControlIrpPreprocessCallback+0x448 <<<< Maybe this calls to the preprocess callbacks I have been reading about (WDF). I guess makes sense because URB is sent via IRP_MJ_INTERNAL_DEVICE_CONTROL It does that in case the call came from user mode. It needs to be able to grab pointers from user-mode memory, and that requires preprocessing. ??? Tim Roberts, xxxxx@probo.com Providenza & Boekelheide, Inc.
Posting Rules  
You may not post new threads
You may not post replies
You may not post attachments
You must login to OSR Online AND be a member of the ntdev list to be able to post.

All times are GMT -5. The time now is 23:39.


Copyright ©2015, OSR Open Systems Resources, Inc.
Based on vBulletin Copyright ©2000 - 2005, Jelsoft Enterprises Ltd.
Modified under license