C# 将DeviceIoControl调用返回值结构从C映射到C时出现问题#

C# 将DeviceIoControl调用返回值结构从C映射到C时出现问题#,c#,c,winapi,C#,C,Winapi,我正在修改一些查询设备树并报告设备功能的代码,特别是USB端口及其速度。我正在从DeviceIoControl调用中获取_USB_节点_连接_信息_EX对象,但它错误地将USB 3.0报告为高速。进一步的研究表明,我需要从DeviceIoControl获取_USB_NODE_CONNECTION_INFORMATION_EX_V2 struct以适应USB 3.0。我试图将新结构从C映射到C,但对于如何处理作为新(ish)USB节点连接信息EX V2结构成员存在的两个C联合,我有点困惑 我在大学

我正在修改一些查询设备树并报告设备功能的代码,特别是USB端口及其速度。我正在从DeviceIoControl调用中获取_USB_节点_连接_信息_EX对象,但它错误地将USB 3.0报告为高速。进一步的研究表明,我需要从DeviceIoControl获取_USB_NODE_CONNECTION_INFORMATION_EX_V2 struct以适应USB 3.0。我试图将新结构从C映射到C,但对于如何处理作为新(ish)USB节点连接信息EX V2结构成员存在的两个C联合,我有点困惑

我在大学里得了C,比如说,差不多20年前。我职业生涯的大部分时间都在Powerbuilder(别笑,那是很久以前的事了)、Java(别笑,那是很久以前的事了),但主要是C。有哪位C大师能帮我将这些带并集的结构映射到C#结构中,并可能给我一个如何将它们编组的线索?注意,我已经映射了USB\uNode\uConnection\uEx\uV2,但不知道如何处理USB\uProtocols和USB\uNode\uConnection\uEx\uV2\uFlags结构。最好将_USB_PROTOCOLS结构映射到C#Flags枚举中,这样我也可以使用按位and和or

下面的代码显示了注释掉的C typedef和我在C#中对应的结构(未注释和…嗯,未完成:()。提前感谢大家

//typedef struct _USB_NODE_CONNECTION_INFORMATION_EX_V2
    //{
    //    ULONG ConnectionIndex;
    //    ULONG Length;
    //    USB_PROTOCOLS SupportedUsbProtocols;
    //    USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS Flags;
    //}
    //USB_NODE_CONNECTION_INFORMATION_EX_V2, *PUSB_NODE_CONNECTION_INFORMATION_EX_V2;

    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;
    }

    //typedef union _USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS {
    //  ULONG ul;
    //        struct {
    //    ULONG DeviceIsOperatingAtSuperSpeedOrHigher  :1;
    //        ULONG DeviceIsSuperSpeedCapableOrHigher  :1;
    //        ULONG ReservedMBZ  :30;
    //    };
    //}
    //USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS, * PUSB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS;
    struct USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS
    {

    }

    //typedef union _USB_PROTOCOLS {
    //  ULONG ul;
    //        struct {
    //        ULONG Usb110  :1;
    //        ULONG Usb200  :1;
    //        ULONG Usb300  :1;
    //        ULONG ReservedMBZ  :29;
    //    };
    //}
    //USB_PROTOCOLS, * PUSB_PROTOCOLS;
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    struct USB_PROTOCOLS
    {

    }

USB_协议
是一个联合结构,它只是包装一个32位整数,其中位0是Usb110,位1是Usb200,位2是Usb300。定义如下:

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; } }

}
USB\u节点\u连接\u信息\u EX\u V2\u标志的故事大致相同,但为了完整性:

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; }
    }
}
或者,您可以使用
Flags
属性将这两个属性都定义为枚举

[Flags]
public enum USB_PROTOCOLS : uint
{
    Usb110 = 0x01,
    Usb200 = 0x02,
    Usb300 = 0x04,
}

[Flags]
public enum USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS : uint // nice short type name
{
    DeviceIsOperatingAtSuperSpeedOrHigher = 0x01,
    DeviceIsSuperSpeedCapableOrHigher = 0x02,
}
或者,由于三个选项优于两个选项,您还可以将第一个结构的定义更改为:

struct USB_NODE_CONNECTION_INFORMATION_EX_V2
{
    public int ConnectionIndex;
    public int Length;
    public uint SupportedUsbProtocols;
    public uint Flags;
}
自己动手做一些小动作

<>我是如何做到的?我在VisualStudio中打开了一个C++控制台应用程序,并编写了以下程序,然后在调试器中逐步通过:

#include <usbioctl.h>

int size = sizeof(USB_PROTOCOLS); // size = 4
USB_PROTOCOLS proto = { 0 }; 
proto.Usb110 = 1;
unsigned int val = *((unsigned int*)(&proto)); // val = 1
proto.Usb110 = 0;
proto.Usb200 = 1;
val = *((unsigned int*)(&proto)); // val = 2
proto.Usb200 = 0;
proto.Usb300 = 1;
val = *((unsigned int*)(&proto)); // val = 4

size = sizeof(USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS); // size = 4
USB_NODE_CONNECTION_INFORMATION_EX_V2_FLAGS flags = { 0 };
flags.DeviceIsOperatingAtSuperSpeedOrHigher = 1;
val = *((unsigned int*)(&flags)); // val = 1
flags.DeviceIsOperatingAtSuperSpeedOrHigher = 0;
flags.DeviceIsSuperSpeedCapableOrHigher = 1;
val = *((unsigned int*)(&flags)); // val = 2
#包括
int size=sizeof(USB_协议);//size=4
USB_协议协议proto={0};
proto.Usb110=1;
unsigned int val=*((unsigned int*)(&proto));//val=1
proto.Usb110=0;
proto.Usb200=1;
val=*((无符号int*)(&proto));//val=2
proto.Usb200=0;
proto.Usb300=1;
val=*((无符号int*)(&proto));//val=4
size=sizeof(USB_节点_连接_信息_EX_V2_标志);//size=4
USB_节点_连接_信息_EX_V2_标志={0};
flags.DeviceIsOperatingAtSuperSpeedOrHigher=1;
val=*((unsigned int*)(&flags));//val=1
flags.DeviceIsOperatingAtSuperSpeedOrHigher=0;
flags.deviceissuperspeedcapable或更高版本=1;
val=*((unsigned int*)(&flags));//val=2