C#:结合设备安装类GUID和设备接口类GUID获取设备VIDPID
2011-09-10 18:58
435 查看
前言:
VID和PID常被用于厂家的软件加密,只有在系统中检测到某VID和PID的设备时,软件才能运行。因此获取某一类型设备或者全部设备的VID和PID集合至关重要。获取设备VID和PID的一般流程是通过设备接口类GUID创建设备信息集,然后从设备接口详细信息中获取设备路径,再调用HidD_GetAttributes从属性中读取VID和PID。该方法的缺点是需要事先知道设备接口类GUID,且每次只能获取一个设备接口类的VID和PID集合。本方法既可以指定设备安装类GUID和/或设备接口类GUID,也可以两者都不指定而直接创建设备信息集,然后通过设备信息数据获取设备实例ID,并直接从设备实例ID中提取出VID和PID,巧妙地避开了对设备IO的读写。
下载:
WDK_VidPidQuery.zip
源代码:
WDKVidPidQuery.cs
SetupApi.cs
VID和PID常被用于厂家的软件加密,只有在系统中检测到某VID和PID的设备时,软件才能运行。因此获取某一类型设备或者全部设备的VID和PID集合至关重要。获取设备VID和PID的一般流程是通过设备接口类GUID创建设备信息集,然后从设备接口详细信息中获取设备路径,再调用HidD_GetAttributes从属性中读取VID和PID。该方法的缺点是需要事先知道设备接口类GUID,且每次只能获取一个设备接口类的VID和PID集合。本方法既可以指定设备安装类GUID和/或设备接口类GUID,也可以两者都不指定而直接创建设备信息集,然后通过设备信息数据获取设备实例ID,并直接从设备实例ID中提取出VID和PID,巧妙地避开了对设备IO的读写。
下载:
WDK_VidPidQuery.zip
源代码:
WDKVidPidQuery.cs
/* ---------------------------------------------------------- 文件名称:WDKVidPidQuery.cs 作者:秦建辉 MSN:splashcn@msn.com QQ:36748897 博客:http://blog.csdn.net/jhqin 开发环境: Visual Studio V2010 .NET Framework 4 Client Profile 版本历史: V1.0 2011年09月10日 结合设备安装类GUID和设备接口类GUID获取设备VIDPID ------------------------------------------------------------ */ using System; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; namespace Splash.IO.PORTS { public struct HIDD_VIDPID { public UInt16 VendorID; // 供应商标识 public UInt16 ProductID; // 产品编号 } /// <summary> /// 基于WDK获取系统设备的VIDPID /// </summary> public partial class USB { /// <summary> /// 获取系统所有设备的VIDPID /// </summary> public static HIDD_VIDPID[] AllVidPid { get { return WhoVidPid(Guid.Empty, Guid.Empty); } } /// <summary> /// 结合设备安装类GUID和设备接口类GUID获取设备VIDPID /// </summary> /// <param name="setupClassGuid">设备安装类GUID,Empty忽视</param> /// <param name="interfaceClassGuid">设备接口类GUID,Empty忽视</param> /// <returns>设备VIDPID列表</returns> /// <remarks> /// 优点:直接通过设备实例ID提取VIDPID,从而无需获取设备路径来读写IO /// </remarks> public static HIDD_VIDPID[] WhoVidPid(Guid setupClassGuid, Guid interfaceClassGuid, String Enumerator = null) { // 根据设备安装类GUID创建空的设备信息集合 IntPtr DeviceInfoSet; if (setupClassGuid == Guid.Empty) { DeviceInfoSet = SetupDiCreateDeviceInfoList(IntPtr.Zero, IntPtr.Zero); } else { DeviceInfoSet = SetupDiCreateDeviceInfoList(ref setupClassGuid, IntPtr.Zero); } if (DeviceInfoSet == new IntPtr(-1)) return null; // 根据设备接口类GUID创建新的设备信息集合 IntPtr hDevInfo; if (interfaceClassGuid == Guid.Empty) { hDevInfo = SetupDiGetClassDevsEx( IntPtr.Zero, Enumerator, IntPtr.Zero, DIGCF.DIGCF_ALLCLASSES | DIGCF.DIGCF_DEVICEINTERFACE | DIGCF.DIGCF_PRESENT, DeviceInfoSet, null, IntPtr.Zero); } else { hDevInfo = SetupDiGetClassDevsEx( ref interfaceClassGuid, null, IntPtr.Zero, DIGCF.DIGCF_DEVICEINTERFACE | DIGCF.DIGCF_PRESENT, DeviceInfoSet, null, IntPtr.Zero); } if (hDevInfo == new IntPtr(-1)) return null; // 枚举所有设备 List<HIDD_VIDPID> DeviceList = new List<HIDD_VIDPID>(); // 存储设备实例ID StringBuilder DeviceInstanceId = new StringBuilder(256); // 获取设备信息数据 UInt32 DeviceIndex = 0; SP_DEVINFO_DATA DeviceInfoData = SP_DEVINFO_DATA.Empty; while (SetupDiEnumDeviceInfo(hDevInfo, DeviceIndex++, ref DeviceInfoData)) { // 获取设备实例ID if (SetupDiGetDeviceInstanceId(hDevInfo, ref DeviceInfoData, DeviceInstanceId, DeviceInstanceId.Capacity, IntPtr.Zero)) { String PNPDeviceID = DeviceInstanceId.ToString(); Match match = Regex.Match(PNPDeviceID, "VID_[0-9|A-F]{4}&PID_[0-9|A-F]{4}"); if (match.Success) { HIDD_VIDPID Entity; Entity.VendorID = Convert.ToUInt16(match.Value.Substring(4, 4), 16); // 供应商标识 Entity.ProductID = Convert.ToUInt16(match.Value.Substring(13, 4), 16); // 产品编号 if (!DeviceList.Contains(Entity)) DeviceList.Add(Entity); } } } SetupDiDestroyDeviceInfoList(hDevInfo); if (DeviceList.Count == 0) return null; else return DeviceList.ToArray(); } /// <summary> /// 从搜索列表中提取出存在于系统中的VIDPID /// </summary> /// <param name="searchList">搜索列表</param> /// <returns>系统中存在的VIDPID列表</returns> public static HIDD_VIDPID[] WhoVidPid(HIDD_VIDPID[] searchList) { // 获取系统所有设备的VIDPID集合 HIDD_VIDPID[] DeviceCollection = AllVidPid; if (DeviceCollection == null) return null; List<HIDD_VIDPID> ValidList = new List<HIDD_VIDPID>(); foreach (HIDD_VIDPID VidPid in searchList) { if (Array.IndexOf(DeviceCollection, VidPid) != -1) { ValidList.Add(VidPid); } } if (ValidList.Count == 0) return null; else return ValidList.ToArray(); } } }
SetupApi.cs
/* ---------------------------------------------------------- 文件名称:SetupApi.cs 作者:秦建辉 MSN:splashcn@msn.com QQ:36748897 博客:http://blog.csdn.net/jhqin 开发环境: Visual Studio V2010 .NET Framework 4 Client Profile 版本历史: V1.0 2011年09月05日 实现对setupapi.dll接口的PInvoke 参考资料: http://www.pinvoke.net/ ------------------------------------------------------------ */ using System; using System.Runtime.InteropServices; using System.Text; namespace Splash.IO.PORTS { /// <summary> /// SetupApi.dll的PInvoke /// </summary> public partial class USB { #region ENUM [Flags] private enum DIGCF { DIGCF_DEFAULT = 0x00000001, DIGCF_PRESENT = 0x00000002, DIGCF_ALLCLASSES = 0x00000004, // 设备安装类 DIGCF_PROFILE = 0x00000008, DIGCF_DEVICEINTERFACE = 0x00000010, // 设备接口类 } #endregion #region STRUCT [StructLayout(LayoutKind.Sequential)] private struct SP_DEVINFO_DATA { public static readonly SP_DEVINFO_DATA Empty = new SP_DEVINFO_DATA(Marshal.SizeOf(typeof(SP_DEVINFO_DATA))); public UInt32 cbSize; public Guid ClassGuid; public UInt32 DevInst; public IntPtr Reserved; private SP_DEVINFO_DATA(int size) { cbSize = (UInt32)size; ClassGuid = Guid.Empty; DevInst = 0; Reserved = IntPtr.Zero; } } [StructLayout(LayoutKind.Sequential)] private struct SP_DEVICE_INTERFACE_DATA { public static readonly SP_DEVICE_INTERFACE_DATA Empty = new SP_DEVICE_INTERFACE_DATA(Marshal.SizeOf(typeof(SP_DEVICE_INTERFACE_DATA))); public UInt32 cbSize; public Guid InterfaceClassGuid; public UInt32 Flags; public UIntPtr Reserved; private SP_DEVICE_INTERFACE_DATA(int size) { cbSize = (uint)size; InterfaceClassGuid = Guid.Empty; Flags = 0; Reserved = UIntPtr.Zero; } } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] private struct SP_DEVICE_INTERFACE_DETAIL_DATA { public UInt32 cbSize; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public String DevicePath; } #endregion #region API #region SetupDiGetClassDevs [DllImport("setupapi.dll", CharSet = CharSet.Auto)] private static extern IntPtr SetupDiGetClassDevs( ref Guid ClassGuid, [MarshalAs(UnmanagedType.LPTStr)] String Enumerator, IntPtr hwndParent, DIGCF Flags ); [DllImport("setupapi.dll", CharSet = CharSet.Auto)] private static extern IntPtr SetupDiGetClassDevs( IntPtr ClassGuid, // null String Enumerator, IntPtr hwndParent, DIGCF Flags ); #endregion #region SetupDiGetClassDevsEx [DllImport("setupapi.dll", CharSet = CharSet.Auto)] private static extern IntPtr SetupDiGetClassDevsEx( ref Guid ClassGuid, [MarshalAs(UnmanagedType.LPTStr)] String Enumerator, IntPtr hwndParent, DIGCF Flags, IntPtr DeviceInfoSet, [MarshalAs(UnmanagedType.LPTStr)] String MachineName, IntPtr Reserved ); [DllImport("setupapi.dll", CharSet = CharSet.Auto)] private static extern IntPtr SetupDiGetClassDevsEx( IntPtr ClassGuid, [MarshalAs(UnmanagedType.LPTStr)] String Enumerator, IntPtr hwndParent, DIGCF Flags, IntPtr DeviceInfoSet, [MarshalAs(UnmanagedType.LPTStr)] String MachineName, IntPtr Reserved ); #endregion #region SetupDiEnumDeviceInterfaces [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern Boolean SetupDiEnumDeviceInterfaces( IntPtr hDevInfo, ref SP_DEVINFO_DATA devInfo, ref Guid interfaceClassGuid, UInt32 memberIndex, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData ); [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern Boolean SetupDiEnumDeviceInterfaces( IntPtr hDevInfo, [MarshalAs(UnmanagedType.AsAny)] Object devInfo, ref Guid interfaceClassGuid, UInt32 memberIndex, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData ); #endregion #region SetupDiGetDeviceInterfaceDetail [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern Boolean SetupDiGetDeviceInterfaceDetail( IntPtr hDevInfo, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData, ref SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData, Int32 deviceInterfaceDetailDataSize, out Int32 requiredSize, ref SP_DEVINFO_DATA deviceInfoData ); [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern Boolean SetupDiGetDeviceInterfaceDetail( IntPtr hDevInfo, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData, ref SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData, Int32 deviceInterfaceDetailDataSize, out Int32 requiredSize, [MarshalAs(UnmanagedType.AsAny)] object deviceInfoData // null ); [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern Boolean SetupDiGetDeviceInterfaceDetail( IntPtr hDevInfo, ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData, ref SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData, Int32 deviceInterfaceDetailDataSize, IntPtr requiredSize, // null [MarshalAs(UnmanagedType.AsAny)] object deviceInfoData // null ); #endregion #region SetupDiCreateDeviceInfoList [DllImport("setupapi.dll", SetLastError = true)] private static extern IntPtr SetupDiCreateDeviceInfoList(ref Guid ClassGuid, IntPtr hwndParent); [DllImport("setupapi.dll", SetLastError = true)] private static extern IntPtr SetupDiCreateDeviceInfoList(IntPtr ClassGuid, IntPtr hwndParent); #endregion [DllImport("setupapi.dll", SetLastError = true)] private static extern Boolean SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet); [DllImport("setupapi.dll", SetLastError = true)] private static extern Boolean SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, UInt32 MemberIndex, ref SP_DEVINFO_DATA DeviceInfoData); #region SetupDiGetDeviceInstanceId [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern Boolean SetupDiGetDeviceInstanceId( IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, StringBuilder DeviceInstanceId, Int32 DeviceInstanceIdSize, out Int32 RequiredSize ); [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern Boolean SetupDiGetDeviceInstanceId( IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, StringBuilder DeviceInstanceId, Int32 DeviceInstanceIdSize, IntPtr RequiredSize ); #endregion #endregion } }
相关文章推荐
- VC++:结合设备安装类GUID和设备接口类GUID获取设备VIDPID
- 结合设备安装类GUID和设备接口类GUID获取设备VIDPID
- VC++:结合设备安装类GUID和设备接口类GUID获取设备VIDPID
- VC++:结合设备安装类GUID和设备接口类GUID获取设备VIDPID
- 获取输入设备的vid和pid
- 知道设备的GUID,和VidPid,如何知道设备是否已经连接到计算机?
- 关于Mac获取usb设备pid,vid,locationID的使用
- vc通过usb获取手机设备vidpid
- 通过Windows注册表获取U盘、移动硬盘和USB读卡器等设备的PID、VID和序列号
- 通过Windows注册表获取U盘、移动硬盘和USB读卡器等设备的PID、VID和序列号
- 获取usb设备的vid,pid
- libusb获取usb设备的idVendor(vid),idProduct(pid),以及Serial Number
- 【VC】 获取电脑USB设备VID和PID等信息。
- Android下USB设备VID与PID获取及ADB设置
- 根据VID PID获取USB设备路径
- 获取输入设备的vid和pid
- 通过GUID获取pid,vid
- 获取电脑USB设备VID和PID等信息。
- 获取指定USB设备的VID PID和SerialNumber
- 通过WDK获取设备的VID-PID、网卡原生MAC地址、硬盘序列号