libusb_open returns 'LIBUSB_ERROR_NOT_SUPPORTED' on Windows 7
Asked Answered
W

5

11

I have been developing USB drivers using LibUSB on Linux, but now I want to have one of my drivers compiled for Windows (this is the first time I am doing it).

My environment

I am working on Windows 7 using the MinGW compiler (also using Dev-cpp IDE), and I am using a pre-compiled libusb library downloaded from this link.

My device: It's a HID touch device. So no drivers are required for Windows. I have an additional endpoint to get certain debug data.

My code:

I have compiled code to list all the devices and USB devices connected to my machine, and the code works. Now I add code to open the device so that I get a device handle and start communication. But the function returns -12 That is, LIBUSB_ERROR_NOT_SUPPORTED.

How can I fix this problem?

I searched through the Internet and did not find a definite solution for this problem. While it's code which works beautifully on Linux.

P.S.: I have added the whole code below. The DoList(); function works fine, but the GetTRSDevice(); function fails at libusb_open(dev, &handle);.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libusb.h>


libusb_device_handle* deviceHandle = NULL;

int DoList();
libusb_device_handle* GetTRSDevice(void);

int main()
{
    int ret = libusb_init(NULL);
    if (ret < 0) {
        printf("Failed to init libusb");
        return ret;
    }

    DoList();
    deviceHandle = GetTRSDevice();
    if(!deviceHandle) {
        printf("Failed to locate device");
        goto fail_dev_open;
    }

    printf("Device opened");

    libusb_close(deviceHandle);
    fail_dev_open:
        libusb_exit(NULL);

    return(ret);
}

int DoList()
{
    libusb_device **devs;
    ssize_t cnt;


    cnt = libusb_get_device_list(NULL, &devs);
    if (cnt < 0)
        return (int) cnt;

    libusb_device *dev;
    int i = 0;

    while ((dev = devs[i++]) != NULL) {
        struct libusb_device_descriptor desc;
        int r = libusb_get_device_descriptor(dev, &desc);
        if (r < 0) {
            fprintf(stderr, "failed to get device descriptor");
            return(-1);
        }

        printf("%04x:%04x (bus %d, device %d)\n",
               desc.idVendor, desc.idProduct,
               libusb_get_bus_number(dev), libusb_get_device_address(dev));
    }
    libusb_free_device_list(devs, 1);
    return 0;
}

libusb_device_handle* GetTRSDevice(void)
{
    int i = 0;
    ssize_t cnt;
    libusb_device *dev;
    libusb_device **devs;
    libusb_device_handle* handle = NULL;

    cnt = libusb_get_device_list(NULL, &devs);
    if (cnt < 0) {
        printf("Failed libusb_get_device_list");
        return(0);
    }

    while ((dev = devs[i++]) != NULL) {
        struct libusb_device_descriptor desc;
        int ret = libusb_get_device_descriptor(dev, &desc);
        if (ret < 0) {
            printf("Failed libusb_get_device_descriptor");
            continue;
        }
        if(desc.idVendor == 0X238f && desc.idProduct == 1) {
            int ret = libusb_open(dev, &handle);
            if (ret < 0) {
                printf("Failed libusb_open: %d\n\r",ret);
                break;
            }
            #ifndef WIN32
                libusb_detach_kernel_driver(handle, 0);
            #endif
            ret = libusb_claim_interface(handle,0);
            if (ret < 0) {
                libusb_close(handle);
                handle=NULL;
                break;
            }
            break;
        }
    }
    libusb_free_device_list(devs, 1);
    return(handle);
}
Wakerife answered 27/6, 2013 at 18:1 Comment(0)
S
11

It seems you need to install the winusb driver - libusb can get information about devices without this driver, but it cannot open them.

http://libusb.6.n5.nabble.com/LIBUSB-ERROR-NOT-SUPPORTED-td5617169.html:

On Wed, Apr 4, 2012 at 11:52 PM, Quân Phạm Minh <[hidden email]> wrote:

although I never install winusb driver but I use libusb to get information of my usb (kingston usb, and already recognize by system)

Yes that is possible. But you can not open the device and do further things. That is the confusing part for new users with regard to libusb Windows backend, and similarly for Mac OS X as well. libusb can get some basic information for device with a non-proper driver (e.g.: USB mass storage device), but will not be able to open the device without changing the driver to a supported one.

-- Xiaofan

Subcommittee answered 27/6, 2013 at 18:23 Comment(7)
Thanks for the reply. So as i understand from you if i develop this driver and distribute it as part of an application. Then do the people using my application needs to install this driver.Wakerife
It would seem so, but I've only ever done usb in Windows with native win32 api. FYI, if you have the device info and you want to be able to open it to write to it in win32, call CreateFileEx on the device 'path', which is usually something like \.\MyHidDevice (since it's in the Windows Object Manager space). Play with WinObj if you're curious.Subcommittee
I find libusb in windows is a grey area can anybody kindly please share me some tutorial, links etc, for getting started. The sad part is it just takes a few minutes to get libusb working on Linux and people assume the same on windowsWakerife
It's uh, complicated. SetupDI, HidD_, HidP_ functions are where you should start. HidD_GetHidGuid, SetupDiGetClassDevs, SetupDIEnumDeviceInterfaces, SetupDiGetDeviceInterfaceDetail are what you're looking for.Subcommittee
I already have a couple of tested and released driver which works well on Linux with libusb. I am not having enough time to rewrite the driver in Windows also. So can any body please suggest me the best method forward. The libusb in windows reminds me of Pandora's box.Wakerife
It should be possible to configure an installer to get the right drivers installed to make it work on windows.Subcommittee
Just to add. I have a driver installed for the hardware and i am not able to make the system override the driver for the new winusb driver as mentioned. If anybody has faced this problem kindly add your experience hereWakerife
W
12

You can easily install the WinUSB driver or the other drivers which libusb supports (libusb-win32 and libusbK) through the use of Zadig, an application that was developed just to solve this problem. See https://zadig.akeo.ie.

One thing to keep in mind, though, is that if you replace a Mass Storage driver or HID driver (which Windows installs automatically) with WinUSB, you will only be able to access your device through libusb and won't be able to access your device as Mass Storage or HID until you uninstall the WinUSB driver.

Finally, if you have control of the firmware for your device, it is also possible to create devices that will automatically install the WinUSB driver on Vista or later, so that users don't have to go through a manual driver installation (this may require a connection to Windows Update for Windows 7 or earlier, but should work even without an internet connection for Windows 8 or later). See https://github.com/pbatard/libwdi/wiki/WCID-Devices.

[DISCLAIMER] I am the author of Zadig/libwi, the WCID wiki pages as well as a contributor to the libusb Windows backend.

Wary answered 19/7, 2014 at 15:14 Comment(4)
Can i get a digitizer or a mouse also working on this driver?Wakerife
Zadig worked great. One gotcha for me was that I had disabled the "Windows Update" service. Zadig needs this service running to install WinUSB on your device.Call
When I click on the link to download Zadig, a virus is detected: You are not permitted to transfer the file "zadig-2.4.exe" because it is infected with the virus "W32/Agent.QWHDAR!tr".Nerynesbit
I'm afraid that's a false positive. If you get a human person from the Antivirus vendor you are using to confirm that there is a virus, you will find them to ultimately indicate that it was a false positive on their side. At any rate, if you do believe that the file you are trying to download is infected, you should definitely contact your AV vendor so that they either confirm or retract it.Wary
S
11

It seems you need to install the winusb driver - libusb can get information about devices without this driver, but it cannot open them.

http://libusb.6.n5.nabble.com/LIBUSB-ERROR-NOT-SUPPORTED-td5617169.html:

On Wed, Apr 4, 2012 at 11:52 PM, Quân Phạm Minh <[hidden email]> wrote:

although I never install winusb driver but I use libusb to get information of my usb (kingston usb, and already recognize by system)

Yes that is possible. But you can not open the device and do further things. That is the confusing part for new users with regard to libusb Windows backend, and similarly for Mac OS X as well. libusb can get some basic information for device with a non-proper driver (e.g.: USB mass storage device), but will not be able to open the device without changing the driver to a supported one.

-- Xiaofan

Subcommittee answered 27/6, 2013 at 18:23 Comment(7)
Thanks for the reply. So as i understand from you if i develop this driver and distribute it as part of an application. Then do the people using my application needs to install this driver.Wakerife
It would seem so, but I've only ever done usb in Windows with native win32 api. FYI, if you have the device info and you want to be able to open it to write to it in win32, call CreateFileEx on the device 'path', which is usually something like \.\MyHidDevice (since it's in the Windows Object Manager space). Play with WinObj if you're curious.Subcommittee
I find libusb in windows is a grey area can anybody kindly please share me some tutorial, links etc, for getting started. The sad part is it just takes a few minutes to get libusb working on Linux and people assume the same on windowsWakerife
It's uh, complicated. SetupDI, HidD_, HidP_ functions are where you should start. HidD_GetHidGuid, SetupDiGetClassDevs, SetupDIEnumDeviceInterfaces, SetupDiGetDeviceInterfaceDetail are what you're looking for.Subcommittee
I already have a couple of tested and released driver which works well on Linux with libusb. I am not having enough time to rewrite the driver in Windows also. So can any body please suggest me the best method forward. The libusb in windows reminds me of Pandora's box.Wakerife
It should be possible to configure an installer to get the right drivers installed to make it work on windows.Subcommittee
Just to add. I have a driver installed for the hardware and i am not able to make the system override the driver for the new winusb driver as mentioned. If anybody has faced this problem kindly add your experience hereWakerife
H
0

I had this same issue and it was not solved by installing WinUSB drivers with Zadig.

Consistently I found that libusb_open() returns LIBUSB_ERROR_NOT_SUPPORTED if and only if I have a Logitech Unifying Receiver plugged into another USB port. This causes the pyusb libusb1 backend to raise an exception like "NotImplementedError: Operation not supported or unimplemented on this platform".

I have removed the Logitech receiver (so I am using a wired keyboard) and the problem is solved for me. I would love to know why or how the Logitech receiver can cause this error on another USB port, but I don't.

Harryharsh answered 11/2, 2020 at 9:18 Comment(0)
F
0

I had the same issue with Zadig not working. I fixed it my connection the device directly to my laptop not through a USB-C hub

Fournier answered 5/1, 2021 at 11:58 Comment(0)
C
0

I had the same issue. But to my surprize, ignoring the error and continuing the execution of the rest of the code, send the data as normal. So the device was supported and could communicate as normal. And for some reason, libUSB-1.0 thought it could not support the device.

My code example:

#include <libusb.h>
#include <stdio.h>
#include <unistd.h>
libusb_context* context = NULL;


int main(void)
{
int kernelDriverDetached = 0;  /* Set to 1 if kernel driver detached*/
uint8_t buffer[64];                /* 64 byte transfer buffer */

int numBytes = 0;  /* Actual bytes transferred. */

libusb_device_handle* handle = NULL;
int res = libusb_init(&context); //initialize the library using libusb_init

if (res != 0)
{
  fprintf(stderr, "Error initialising libusb.\n");

}


/* Get the first device with the matching Vendor ID and Product ID.If
* intending to allow multiple demo boards to be connected at once,you
* will need to use libusb_get_device_list() instead. Refer to the libusb
* documentation for details. */
handle = libusb_open_device_with_vid_pid(0, 0x1cbe, 0x0003);

if (!handle)
{
    fprintf(stderr, "Unable to open device.\n");

}

       /* Check whether a kernel driver is attached to interface #0. If so, we'll
  * need to detach it.*/
 if (libusb_kernel_driver_active(handle, 0))
 {
    res = libusb_detach_kernel_driver(handle, 0);
    if (res == 0)
    {
       kernelDriverDetached = 1;
    }
    else
    {
       fprintf(stderr, "Error detaching kernel driver. %s\n", libusb_error_name(res));
    }
}

   /* Claim interface #0. */
res = libusb_claim_interface(handle, 0);
if (res != 0)
{
   fprintf(stderr, "Error claiming interface.\n");

}

memset(buffer, 0, 12);
buffer[0] = 0x55;
buffer[1] = 0xAA;
buffer[2] = 0x01;
buffer[3] = 0x00;
buffer[4] = 0x00;
buffer[5] = 0x00;
buffer[6] = 0x00;
buffer[7] = 0x00;
buffer[8] = 0x01;
buffer[9] = 0x00;
buffer[10] = 0x01;
buffer[11] = 0x01;

res = libusb_bulk_transfer(handle, 0x01, buffer, 12, &numBytes, 100);
if (res == 0)
{
   printf("%d bytes transmitted successfully.\n", numBytes);
}
else
{
  fprintf(stderr, "Error during send message: %s\n",libusb_error_name(res));
}

memset(buffer, 0, 12);

 res = libusb_bulk_transfer(handle, 0x81, buffer, 12, &numBytes, 100);
 if (res == 0)
 {
    printf("%d bytes receibed successfully.\n", numBytes);
 }
 else
 {
    fprintf(stderr, "Error during receibe response:%s\n",libusb_error_name(res));
 }



/* Release interface #0. */
res = libusb_release_interface(handle, 0);
if (0 != res)
{
   fprintf(stderr, "Error releasing interface.\n");
}

/* If we detached a kernel driver from interface #0 earlier, we'll now
* need to attach it again.  */
if (kernelDriverDetached)
{
  libusb_attach_kernel_driver(handle, 0);
}

/* Shutdown libusb. */
libusb_exit(0);
system("pause");
return 0;
}
Casern answered 20/7, 2022 at 8:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.