使用DeviceIoControl无法使用c#检测USB 3.0端口信息

时间:2017-03-07 15:58:37

标签: c# winapi usb

我尝试通过检查c#应用程序中SuperSpeed的速度来检测USB设备是否连接到USB 3端口。

我设法通过

获得标准的USB连接数据

DeviceIoControl(h,IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX ...

但如果我正在使用

IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2

我总是得到ERROR_INVALID_PARAMETER。

这就是我所做的:

// define consts and structs
const UInt32 IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2 = 0x22045c;

[StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct USB_PROTOCOLS
        {
            UInt32 protocols;

            public bool Usb110 { get { return (this.protocols & 0x01) == 0x01; } }
            public bool Usb200 { get { return (this.protocols & 0x02) == 0x02; } }
            public bool Usb300 { get { return (this.protocols & 0x04) == 0x04; } }

        }

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS
        {
            UInt32 flags;

            public bool DeviceIsOperatingAtSuperSpeedOrHigher
            {
                get { return (this.flags & 0x01) == 0x01; }
            }
            public bool DeviceIsSuperSpeedCapableOrHigher
            {
                get { return (this.flags & 0x02) == 0x02; }
            }
        }

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        struct USB_NODE_CONNECTION_INFORMATION_EX_V2
        {
            public int ConnectionIndex;
            public int Length;
            public USB_PROTOCOLS SupportedUsbProtocols;
            public USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS Flags;
        }


int nBytesReturnedV2;
                        int nBytesV2 = Marshal.SizeOf(typeof(USB_NODE_CONNECTION_INFORMATION_EX_V2));
                        IntPtr ptrNodeConnectionV2 = Marshal.AllocHGlobal(nBytesV2);
                        USB_NODE_CONNECTION_INFORMATION_EX_V2 NodeConnectionV2 = new USB_NODE_CONNECTION_INFORMATION_EX_V2();
                        NodeConnectionV2.ConnectionIndex = i;
                        NodeConnectionV2.Length = Marshal.SizeOf(typeof(USB_NODE_CONNECTION_INFORMATION_EX_V2));
                        Marshal.StructureToPtr(NodeConnectionV2, ptrNodeConnectionV2, true);

// request information
 if (DeviceIoControl(h, (UInt32)IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2, ptrNodeConnectionV2, nBytesV2, ptrNodeConnectionV2, nBytesV2, out nBytesReturnedV2, IntPtr.Zero))
                        {
                            NodeConnectionV2 = (USB_NODE_CONNECTION_INFORMATION_EX_V2)Marshal.PtrToStructure(ptrNodeConnectionV2, typeof(USB_NODE_CONNECTION_INFORMATION_EX_V2));


                        } else
                        {
                            int errCode = Marshal.GetLastWin32Error();
                            Console.WriteLine("Err: " + errCode);
                        }

在这里我总是得到错误87(ERROR_INVALID_PARAMETER)。在我看来,IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2是错误的,但它与我在C ++应用程序中使用的值相同。

2 个答案:

答案 0 :(得分:0)

进入类似的问题:

祝你好运!

答案 1 :(得分:0)

按照我的代码来解决您的问题。它只是用于检测USB端口5的示例代码(您可以首先将USBView用作端口号)

    struct USB_NODE_CONNECTION_INFORMATION_EX_V2
    {
        // one based port number
        public int ConnectionIndex;

        // length of the structure
        public int Length;

        // On input a bitmask that indicates which USB protocols are understood by the caller
        // On output a bitmask that indicates which USB signaling protocols are supported by the port
        //public USB_PROTOCOLS SupportedUsbProtocols;
        public int SupportedUsbProtocols;

        // A bitmask indicating properties of the connected device or port
        //public USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS Flags;
        public int Flags;
    }
//////////////////////////////////////////////////////////////////////////////
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern bool DeviceIoControl(
            IntPtr hDevice,
            int dwIoControlCode,
            IntPtr lpInBuffer,
            int nInBufferSize,
            IntPtr lpOutBuffer,
            int nOutBufferSize,
            out int lpBytesReturned,
            IntPtr lpOverlapped
    );
//////////////////////////////////////////////////////////////////////////////
    private static int CTL_CODE(int dwDeviceType, int dwFunction, int dwMethod, int dwAccess)
    {
        return ((dwDeviceType) << 16) | ((dwAccess) << 14) | ((dwFunction) << 2) | (dwMethod);
    }
///////////////////////////////////////////////////////////////////////////
    private const int USB_GET_NODE_CONNECTION_INFORMATION_EX_V2 = 279;
    private static int IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2 = CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_INFORMATION_EX_V2, METHOD_BUFFERED, FILE_ANY_ACCESS);//IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2 = 0x22045c;
///////////////////////////////////////////////////////////////////////////
    private IntPtr OpenUSB()
    {
        //ouverture en lecture partagAce
        return CreateFile(@"\\.\USB#ROOT_HUB30#4&393adc3c&0&0#{f18a0e88-c30c-11d0-8815-00a0c906bed8}", Convert.ToUInt32(GENERIC_WRITE), Convert.ToInt32(FILE_SHARE_WRITE), IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
    }
/////////////////////////////////////////////////////////////////////
    public void GetUSBProtocol()
    {
        IntPtr pDisplay = OpenUSB();
        if (pDisplay == new IntPtr(-1))
            return;
        int nBytesReturned;
        int nBytesV2 = Marshal.SizeOf(typeof(USB_NODE_CONNECTION_INFORMATION_EX_V2));
        IntPtr ptrNodeConnectionV2 = Marshal.AllocHGlobal(nBytesV2);
        USB_NODE_CONNECTION_INFORMATION_EX_V2 pBrightness = new USB_NODE_CONNECTION_INFORMATION_EX_V2();
        pBrightness.ConnectionIndex = 5;//if you wnat to dectect port 5
        pBrightness.Length = nBytesV2;
        pBrightness.SupportedUsbProtocols = 4;
        Marshal.StructureToPtr(pBrightness, ptrNodeConnectionV2, true);
        DeviceIoControl(pDisplay, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2, ptrNodeConnectionV2, nBytesV2, ptrNodeConnectionV2, nBytesV2, out nBytesReturned, IntPtr.Zero);
        pBrightness = (USB_NODE_CONNECTION_INFORMATION_EX_V2)Marshal.PtrToStructure(ptrNodeConnectionV2, typeof(USB_NODE_CONNECTION_INFORMATION_EX_V2));
        CloseHandle(pDisplay);

        return;
    }