这段代码是用来实现虚拟com口通讯用的。
采用TI公司的MSP430TUSB3410做USB到UMP的转换,驱动都已经打上,范例程序也已通过。现在在C# winForm下 作通讯程序,为了查找到虚拟的com口(该虚拟com口FriendlyName不确定,可能是COM9,也可能是COM11或者其他),需要枚举系统的COM类设备信息,得到其接口信息。
            int dwNeeded = 0; IntPtr pidd = IntPtr.Zero;
            Externs.SP_DEVINFO_DATA devinfo = new Externs.SP_DEVINFO_DATA();
            IntPtr g_hdi = IntPtr.Zero;            Guid myGuid = new Guid("4D36E978-E325-11CE-BFC1-08002BE10318");  //驱动文件中的ClassGUID
                 //("86E0D1E0-8089-11D0-9CE4-08003E301F73");  //范例程序中的GUiD
                     
            // Open new enumeration if needed 首次查找释放所有该类设备及其内存
            if (index == 0)
            {
                // Close open device interface enum set if any
                if (g_hdi != IntPtr.Zero)
                    Externs.SetupDiDestroyDeviceInfoList(g_hdi);
                g_hdi = Externs.SetupDiGetClassDevs(ref myGuid, 0, IntPtr.Zero, Externs.DIGCF_ALLCLASSES | Externs.DIGCF_PRESENT);  //C#下得到g_hdi = 17556736
                if (g_hdi == IntPtr.Zero)
                    return Externs.GetLastError();
            }
            // Get next device interface data 
            Externs.SP_DEVICE_INTERFACE_DATA did = new Externs.SP_DEVICE_INTERFACE_DATA();
            did.cbSize = Marshal.SizeOf(did);
            did.InterfaceClassGuid = System.Guid.Empty;
            did.Flags = 0;
            did.RESERVED =  IntPtr.Zero;
            if (!Externs.SetupDiEnumDeviceInterfaces(g_hdi,IntPtr.Zero,ref myGuid,(uint)index,ref did))
            {
                return Externs.GetLastError(); 
            }
/// <summary>
        /// 获取一个指定类别或全部类别的所有已安装设备的信息
        /// </summary>
        /// <param name="gClass"></param>
        /// <param name="iEnumerator"></param>
        /// <param name="hParent"></param>
        /// <param name="nFlags"></param>
        /// <returns></returns>
        [DllImport("setupapi.dll", SetLastError = true)]
        public static extern IntPtr SetupDiGetClassDevs(ref Guid gClass, UInt32 iEnumerator, IntPtr hParent, UInt32 nFlags);        /// <summary>
        /// 销毁一个设备信息集合,并且释放所有关联的内存
        /// </summary>
        /// <param name="lpInfoSet"></param>
        /// <returns></returns>
        [DllImport("setupapi.dll", SetLastError = true)]
        public static extern int SetupDiDestroyDeviceInfoList(IntPtr lpInfoSet);
        /// <summary>
        /// 枚举一个设备信息集合的设备接口
        /// </summary>
        /// <param name="lpInfoSet"></param>
        /// <param name="ptrDeviceInfoData"></param>
        /// <param name="ptrInterfaceClassGuid"></param>
        /// <param name="MemberIndex"></param>
        /// <param name="SP_DEVICE_INTERFACE_DATA"></param>
        [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SetupDiEnumDeviceInterfaces(IntPtr lpInfoSet, IntPtr ptrDeviceInfoData,
                        ref Guid ptrInterfaceClassGuid, UInt32 MemberIndex, ref  SP_DEVICE_INTERFACE_DATA ptrDeviceInterfaceData);        /// <summary>
        /// 设备接口信息
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public class SP_DEVICE_INTERFACE_DATA
        {
            public int cbSize;
            public Guid InterfaceClassGuid;
            public int Flags;
            public IntPtr RESERVED;
        }范例程序中的代码和执行情况:  const TCHAR szHardwareIDUmp[] = "umpport\\VID_0451_BEEF_com";
  static HDEVINFO g_hdi = INVALID_HANDLE_VALUE; // Setup API enum handle
  SP_DEVICE_INTERFACE_DATA did;  // Open new enumeration if needed
  if (dwIndex == 0) // dwIndex为传入的参数,实际上是枚举的该类设备的编号
  {
    // Close open device interface enum set if any
    if (g_hdi != INVALID_HANDLE_VALUE)
      SetupDiDestroyDeviceInfoList(g_hdi);  //销毁一个设备信息集合,并且释放所有关联的内存          // Enumerate all devices present (DIGCF_PRESENT)
  // 使用此函数,需要包含头文件setupapi.h。在project setting中的link页面需要添加setupapi.lib。
  // 查询所有设备,并返回与指定参数匹配的所有已安装设备的设备信息结构的句柄
    g_hdi = (HDEVINFO)SetupDiGetClassDevs((CONST LPGUID)&GUID_CLASS_COMPORT,
      NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);  
          //查看g_hdi值,“CXX0017:ERROR:symbol ‘g_hdi’nod found!”,这是什么?
          //这里的GUID_CLASS_COMPORT “86E0D1E0-8089-11D0-9CE4-08003E301F73” 同样是这个,放入c#还是不行
 
    if (g_hdi == INVALID_HANDLE_VALUE)
    {
      return GetLastError();
    }
  }  // Get next device interface data ('dwIndex')
  did.cbSize = sizeof(did);  if (!SetupDiEnumDeviceInterfaces(g_hdi, NULL,
      (CONST LPGUID)&GUID_CLASS_COMPORT, dwIndex, &did))
  {
    return GetLastError();
  }
  //返回正确,&did = 
  //{cbsize = 28}
  //{interfaceClassGuid = {86E0D1E0-8089-11D0-9CE4-08003E301F73}} 
  //{Flags =1}
  //{reserved = 1450704}
查询了很多资料,有的说是ClassGuid与SetupDiEnumDeviceInterfaces所需的参数interface GUID不一致,但是按照方法去找只能找到C#中现在用的那个,还是不行。
现在怀疑是SetupDiGetClassDevs得到的句柄不对,在范例程序跟踪 g_hdi ,总是“CXX0017:ERROR:symbol ‘g_hdi’nod found!”,在C#中却能得到一个g_hdi = 17556736,什么都不一致啊!!

求高手解疑!