Testing KMDF USBSamp driver

In order to test the USBSamp driver (WDK 6000), I modified the VID/PID pair in the INF file to match the IDs advertised by my USB device. So far so good. I also see the device and the driver correctly hooked up in the DebugView.
Now when I build the testapp.c (in the exe) folder and run the same, with “usbsamp rwbuild -u” command line, the rw_dev function fails at DeviceIoControl with error code 1 (Incorrect Function). Similarly the “usbsamp -r 0” fails in the open_file function at CreateFile with same error code.
I am not sure what i am missing here. Any help in the regard would be highly appreciated.
Regards,
Mohit

Did you debug the appropriate functions in the driver? To debug the failure of open_File, set a bp on UsbSamp_EvtDeviceFileCreate and step through it. If it can’t find the pipe based on the file name, it will return STATUS_INVALID_DEVICE_REQUEST (which maps to ERROR_INVALID_FUNCTION (e.g. 1)) so I would guess you will have to look at the pipes on the device (!wdfkd.wdfusbinterface and !wdfkd.wdfusbdevice will help you see the current config in the debugger).

As for DeviceIoControl failing, set a bp on UsbSamp_EvtIoDeviceControl and step through it as well.

d

Dear Doron,
Thanks for you response. Based on your suggestion, I tried to debug the driver code and found that the WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE call sets the number of configured pipes to 0 in SelectInterface function (device.c). Because of this the WdfUsbInterfaceGetConfiguredPipe call in GetPipeFromName function (queue.c) returns NULL causing the UsbSamp_EvtDeviceFileCreate to return with STATUS_INVALID_DEVICE_REQUEST status.
Can you please guide me as to how do I configure the pipes.

Regards,
Mohit

I assume you are referring to this code

//
// The device has only 1 interface.
//
WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE( &configParams);

status = WdfUsbTargetDeviceSelectConfig(pDeviceContext->WdfUsbTargetDevice,
WDF_NO_OBJECT_ATTRIBUTES,
&configParams);

if (NT_SUCCESS(status) &&
WdfUsbTargetDeviceGetNumInterfaces(pDeviceContext->WdfUsbTargetDevice) > 0) {

pDeviceContext->UsbInterface =
configParams.Types.SingleInterface.ConfiguredUsbInterface;

pDeviceContext->NumberConfiguredPipes =
configParams.Types.SingleInterface.NumberConfiguredPipes;
}

If so, WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE sets the number of configured pipes to zero b/c this is an output parameter and the structure is being zero initliazed. The important function call is WdfUsbTargetDeviceSelectConfig and the values of the configParams.Types.SingleInterface structure after it has successfully returned. What is the return value for this function for your device and the output of

dt configParams Types.SingleInterface.

in the debugger after a successful call?

d

Are you actually calling WdfUsbTargetDeviceSelectConfig() or just setting up the struct with that macro? You won’t get any pipes until you actually select a config. What’s the physical configuration of your device?

Dear Doron,
Yes, I am referring to the same code and after a successful call to the WdfUsbTargetDeviceSelectConfig I get configParams.Types.SingleInterface.NumberConfiguredPipes = 0 and WdfUsbTargetDeviceGetNumInterfaces(pDeviceContext->WdfUsbTargetDevice) returns 1 i.e. I have 1 interface and 0 pipes.

get the WDFUSBINTERFACE handle value from configParams.Types.SingleInterface.ConfiguredUsbInterface and pass it as a parameter to !wdfkd.wdfusbinterface [handle value] and send the output. Does your interface have any endpoints on it to begin with?

d

Dear Doron,
The kd output is :
lkd> !wdfkd.wdfusbinterface 7a51af10
WDFUSBINTERFACE 7a51af10
Interface Number 0x00 Class 0xff, SubClass 0x00, Protocol 0x00
Alt Setting 0, Num Endpoints 0, Interface Desc 859bc369, Selected

As for the endpoints, I am not sure how to confirm that as I am using the usbsamp sample code “as is” (only change is that of VID/PID).

Regards,
Mohit

This says it all:

WDFUSBINTERFACE 7a51af10
Interface Number 0x00 Class 0xff, SubClass 0x00, Protocol 0x00
Alt Setting 0, Num Endpoints 0, Interface Desc 859bc369, Selected

You have no endpoings on your interface, you need to fix your config descriptor first to declare the endpoints.

d

Dear Doron,
I would really appreciate if you could guide me towards the probable code/article portion i should look into. I went thru UsbSamp__EvtDeviceAdd and UsbSamp_EvtDevicePrepareHardware but was not able to find anything out of place. Also, the ConfigureDevice function seems to be creating the config descriptor in accordance to the WDK documentation.

I am listing the USB configuration dump for your review:

START: open_dev
START: OpenUsbDevice
Going to OpenOneDevice
Going to SetupDiGetDeviceInterfaceDetail
Completed SetupDiGetDeviceInterfaceDetail
Attempting to open \?\usb#vid_0f8b&pid_0310#5ac003e4#{7d42d66c-6c5b-48cb-93a4-b7a3d0b25592}
OpenOneDevice success
END: OpenUsbDevice
DeviceName = (\?\usb#vid_0f8b&pid_0310#5ac003e4#{7d42d66c-6c5b-48cb-93a4-b7a3d0b25592})
END: open_dev
START: dumpUsbConfig
START: rw_dev
request complete, success = 1 nBytes = 18
STATUS: DeviceIoControl successful

===================
USB_CONFIGURATION_DESCRIPTOR
bLength = 0x9, decimal 9
INSIDE: usbDescriptorTypeString
bDescriptorType = 0x2 ( USB_CONFIGURATION_DESCRIPTOR_TYPE )
wTotalLength = 0x12, decimal 18
bNumInterfaces = 0x1, decimal 1
bConfigurationValue = 0x1, decimal 1
iConfiguration = 0x0, decimal 0
INSIDE: usbConfigAttributesString
bmAttributes = 0x80 ( USB_CONFIG_BUS_POWERED )
MaxPower = 0x1c, decimal 28


USB_INTERFACE_DESCRIPTOR #0
bLength = 0x9
INSIDE: usbDescriptorTypeString
bDescriptorType = 0x4 ( USB_INTERFACE_DESCRIPTOR_TYPE )
bInterfaceNumber = 0x0
bAlternateSetting = 0x0
bNumEndpoints = 0x0
bInterfaceClass = 0xff
bInterfaceSubClass = 0x0
bInterfaceProtocol = 0x0
bInterface = 0x0
END: rw_dev
END: dumpUsbConfig

your config descriptor has 2 problems

  1. You do not have an endpoint descriptor after your interface descriptor
  2. you interface descriptor says it has no endpoints, bNumEndpoints = 0x0

d

xxxxx@hcl.in wrote:

Dear Doron,
I would really appreciate if you could guide me towards the probable code/article portion i should look into. I went thru UsbSamp__EvtDeviceAdd and UsbSamp_EvtDevicePrepareHardware but was not able to find anything out of place. Also, the ConfigureDevice function seems to be creating the config descriptor in accordance to the WDK documentation.

The problem is not with the driver. The problem is in the hardware.
Your USB device has no endpoints. You should be able to do transfers on
the control endpoint (endpoint 0), which is always present, but nothing
else.

What kind of a device is this supposed to be?


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

Dear Tim,
The Device is a dongle (on USB port) which acts as a hardware lock. The device principally needs to read/write the security key to lock/unlock the software.

Regards,
Mohit

xxxxx@hcl.in wrote:

Dear Tim,
The Device is a dongle (on USB port) which acts as a hardware lock. The device principally needs to read/write the security key to lock/unlock the software.

Is this a device you are building, or a third-party device you are
attempting to use? Do you have specifications for the device? How are
you supposed to talk to it? Are you supposed to send all of the data as
vendor commands to the control pipe?


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

I would really appreciate if you can proivde me some guidance about how to modify the usbsamp driver code to write onto the control endpoint (endpoint 0) incase there any no endpoints?

As for the device, its a third party device which i am using in order to learn the device driver development and unfortunately, i do not have access to the tech specs of the device though i am trying to get them.

To communicate on the control endpoint, use WdfUsbTargetDeviceSendControlTransferSynchronously or WdfUsbTargetDeviceFormatRequestForControlTransfer (for async i/o), but without the technical specs for your device, it is a non starter since you don’t know how to format the control setup packet and what the data format is.

If you want to learn how to write a usb driver and gain experience with USB devices, get the OSR FX2 device. It is an awesome little test board that you can install usbsamp on and learn everything you want.

d

xxxxx@hcl.in wrote:

I would really appreciate if you can proivde me some guidance about how to modify the usbsamp driver code to write onto the control endpoint (endpoint 0) incase there any no endpoints?

The rather verbose API
WdfUsbTargetDeviceSendControlTransferSynchronously will do this.

As for the device, its a third party device which i am using in order to learn the device driver development and unfortunately, i do not have access to the tech specs of the device though i am trying to get them.

Without the specs, how can you possibly know what commands to send? You
can’t just send random bytes. What if you accidentally send it the
self-destruct code?


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