WinUSB_Initialize function occurs INVALID_FUNCTION (0x1) Error

2

Why does the WinUSB_Initialize function occur INVALID_FUNCTION (0x1) Error? This is a function from the winusb.dll which returns an interface handle.

I would like to get an Interface handle. I already have a Device handle.

internal struct devInfo
        {
            internal SafeFileHandle deviceHandle;
            internal IntPtr winUsbHandle;
            internal Byte bulkInPipe;
            internal Byte bulkOutPipe;
            internal Byte interruptInPipe;
            internal Byte interruptOutPipe;
            internal UInt32 devicespeed;
        }

    internal const Int32 FILE_ATTRIBUTE_NORMAL = 0X80;
        internal const Int32 FILE_FLAG_OVERLAPPED = 0X40000000;
        internal const Int32 FILE_SHARE_READ = 1;
        internal const Int32 FILE_SHARE_WRITE = 2;
        internal const UInt32 GENERIC_READ = 0X80000000;
        internal const UInt32 GENERIC_WRITE = 0X40000000;
        internal const Int32 OPEN_EXISTING = 3;

        [DllImport("winusb.dll", SetLastError = true)]
        internal static extern Boolean WinUsb_Initialize
        (SafeFileHandle DeviceHandle,
        ref IntPtr InterfaceHandle);

        internal devInfo myDevInfo; // = new devInfo();

        public IntPtr Get_WinUSB_handle()
        {

            Guid myGuid = Get_HID_GUID();
            IntPtr deviceInfoSet = Get_Device_Info_Set(myGuid);
            SP_DEVICE_INTERFACE_DATA MyDeviceInterfaeData = Get_Device_Interface_Data(deviceInfoSet, myGuid);
            IntPtr detailDataBuffer = Get_Structure_with_Device_PathName(deviceInfoSet, ref MyDeviceInterfaeData);
            string devicePathName = Get_Device_PathName(detailDataBuffer);

           myDevInfo.deviceHandle= CreateFile(devicePathName,
           (GENERIC_WRITE | GENERIC_READ),
           FILE_SHARE_READ | FILE_SHARE_WRITE,
           IntPtr.Zero,
           OPEN_EXISTING,
           FILE_FLAG_OVERLAPPED,
           0);

               Boolean success;
               success = WinUsb_Initialize(myDevInfo.deviceHandle, ref myDevInfo.winUsbHandle);
               System.Console.WriteLine(Marshal.GetLastWin32Error());
               System.Console.WriteLine(success);


            return myDevInfo.winUsbHandle;

        }
c#
usb
asked on Stack Overflow Feb 26, 2014 by Szilvia Lázár • edited Jun 12, 2018 by Cœur

2 Answers

3

I believe you are connecting to a device that is not actually using winusb.sys as one of its drivers. To other people who might read this, you can check if a device uses winusb.sys by double-clicking it in the Device Manager, going to the "Driver" tab, and clicking on "Driver Details". If you don't see winusb.sys there then this is not a WinUSB device.

To have a WinUSB device, you need to write a proper INF file and then tell Windows to use it one way or another.

It looks like you are trying to access an HID. Instead of using WinUSB I would recommend HIDAPI.

answered on Stack Overflow Feb 27, 2014 by David Grayson • edited Aug 13, 2020 by David Grayson
3
       success = WinUsb_Initialize(...);
       System.Console.WriteLine(Marshal.GetLastWin32Error());

This kind of error checking is wrong. It is only valid to call Marshal.GetLastWin32Error() when a winapi function failed. So a rock-hard requirement is to check success first. Calling GetLastWin32Error() anyway produces an arbitrary garbage value if the function actually succeeded. ERROR_INVALID_FUNCTION certainly has a high garbage value.

The code is also fairly broken when there actually is an error, it doesn't nearly make enough noise and the client code can easily ignore the invalid handle value. Proper code is:

       bool success = WinUsb_Initialize(...);
       if (!success) throw new System.ComponentModel.Win32Exception();

The exception constructor already calls Marshal.GetLastWin32Error() and will produce an appropriate localized error message.

answered on Stack Overflow Feb 27, 2014 by Hans Passant • edited Feb 12, 2018 by Hans Passant

User contributions licensed under CC BY-SA 3.0