I’ve spent some time working with USB communications and I seem to be stuck. What I wish to do is have a block of code I can use to communicate with USB devices which works on XP, Vista and Win-7.
Currently I can enumerate all the USB devices attached to my machine and obtain the configuration descriptor , interface descriptor and endpoint descriptors. But the device descriptor escapes me? As many others I am relatively new to driver development and so I’m on the learning curve . I’ve downloaded the DDK and built up a few drivers, installed a few, played around with understanding the relavant registry entries. Read through every thing USB I could find on the web and in the last 2 months of this forum.
But I digress what I want to know for now is how to get a hold of the device descriptor without throwing out what I currently have working for a drastically different way of working with the USB. (I will get there eventually but I just want to put a close on my current enumeration test code before I move on to a straight forward WinUSB implementation of communication with my companies devices)
So currently I
// Get a handle for the Plug and Play node and request currently active USB devices
// Get a handle to the device information set by passing the device interface GUID
// that you defined in the INF
// In this case we are using the generic WinUSB GUID
// The function returns an HDEVINFO handle
PnPHandle := SetupDiGetClassDevs(@GUID, nil, 0, DIGCF_PRESENT or DIGCF_DEVICEINTERFACE);
AND THEN LOOP THROUGH INCREMENTING THE DEVICE NUMBER TILL IT NO LONGER WORKS
// Call SetupDiEnumDeviceInterfaces to enumerate the system?s device interfaces
// and obtain information on your device interface
// Pass the HDEVINFO handle from above, the device interface GUID, and a reference to
// the initialized SP_DEVICE_INTERFACE_DATA structure
Success := SetupDiEnumDeviceInterfaces(PnPHandle, nil, Guid, DeviceNumber, DeviceInterfaceData);
I GET THE SIZE OF THE BUFFER WHICH IS NEEDED
// Call SetupDiGetDeviceInterfaceDetail to get detailed data for the device interface.
// The information is returned in a SP_DEVICE_INTERFACE_DETAIL_DATA structure
// Because the size of the SP_DEVICE_INTERFACE_DETAIL_DATA structure varies, you
// must first obtain the correct buffer size by calling SetupDiGetDeviceInterfaceDetail with
// the DeviceInterfaceDetailData parameter set to NULL
// The function returns the correct buffer size in the requiredlength parameter. Use that
// value to correctly allocate memory for a SP_DEVICE_INTERFACE_DETAIL_DATA
// structure
SetupDiGetDeviceInterfaceDetail(PnPHandle, @DeviceInterfaceData, nil, 0, BytesReturned, @DevData);
THEN I BUILD UP A LIST OF DEVICE PATHS
// Call SetupDiGetDeviceInterfaceDetail again and pass it a reference to the initialized
// structure. When the function returns, the structure contains detailed information about
// the interface
if SetupDiGetDeviceInterfaceDetail(PnPHandle, @DeviceInterfaceData,
FunctionClassDeviceData, BytesReturned, BytesReturned, @DevData) then
begin
// The device path is in the SP_DEVICE_INTERFACE_DETAIL_DATA structure?s
// DevicePath member
ListOfUSBDevices.Add(PChar(@FunctionClassDeviceData.DevicePath));
SO AT THIS POINT I HAVE A LIST OF DEVICE PATHS LIKE:
‘\?\usb#vid_0930&pid_6545#001d92a85eaab911e3360016#{a5dcbf10-6530-11d2-901f-00c04fb951ed}’
// Get a handle to the USB device
handle := CreateFile(PChar(DeviceName),GENERIC_WRITE or GENERIC_READ,FILE_SHARE_WRITE or FILE_SHARE_READ, nil,OPEN_EXISTING,0,0);
// Safety First
if (handle = INVALID_HANDLE_VALUE) then exit;
// Figure out the magic number the device driver will respond to
FunctionNumber := CTL_CODE($22, 0, 0, 0);
// Query the Driver passing in the handle and function (Magic Number)
if Windows.DeviceIoControl(handle, FunctionNumber, @InBuffer, InSize, @InBuffer,OutSize, BytesReturned, nil) = true then
begin
then
this gives me my devices and I have obtained all the configuration, interface and endpoint information (not all shown here for brevity)
USB Devices Found = 5
1 Vendor(04D8) = Microchip, PID Product(000A) = Pic 18F AVB Box
HID
2 Vendor(0930) = Toshiba Product(6545) = 8G Memory Stick
Failure The request is not supported
3 Vendor(1448) = BioSystems Product(8278) = MultiPro
USB_CONFIGURATION_DESCRIPTOR
Descriptor Length = 9
Descriptor Type = 2
Total Length = 46
Interfaces = 1
ConfigID = 1
Description Index = 0
Attributes = 128
Max Power = 112
…
…
4 Vendor(413C) = Dell Computer Corp Product(2003) = Keyboard
HID
5 Vendor(413C) = Dell Computer Corp Product(3012) = Mouse
HID
so is it the case that I only need to figure out a new magic number to get the device descriptor
// This one came from the // IOCTL_BULKUSB_GET_CONFIG_DESCRIPTOR;
// and appears to work the same for the winusb driver
// FunctionNumber := 2228224;
or do I need to pass in some info to
Windows.DeviceIoControl
to get it to respond with the device descriptor