using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; namespace POSV.HWiNFO { [StructLayout(LayoutKind.Sequential)] public struct T_VIDPID { public ushort VendorID; // 供应商标识 public ushort ProductID; // 产品编号 } /// /// 基于WDK获取系统设备的VIDPID /// public static partial class HWiNFO { /// /// 结合设备安装类GUID和设备接口类GUID获取设备VIDPID /// /// 设备安装类GUID,Empty忽视 /// 设备接口类GUID,Empty忽视 /// 设备VIDPID列表 /// /// 优点:直接通过设备实例ID提取VIDPID,从而无需获取设备路径来读写IO /// public static T_VIDPID[] WDK_QueryVidPid(Guid SetupClassGuid, Guid InterfaceClassGuid) { // 根据设备安装类GUID创建空的设备信息集合 IntPtr DeviceInfoSet; if (SetupClassGuid.Equals(Guid.Empty)) { DeviceInfoSet = SetupApi.SetupDiCreateDeviceInfoList(IntPtr.Zero, IntPtr.Zero); } else { DeviceInfoSet = SetupApi.SetupDiCreateDeviceInfoList(ref SetupClassGuid, IntPtr.Zero); } if (DeviceInfoSet == Kernel32.INVALID_HANDLE_VALUE) return null; // 根据设备接口类GUID创建新的设备信息集合 IntPtr hDevInfo; if (InterfaceClassGuid.Equals(Guid.Empty)) { hDevInfo = SetupApi.SetupDiGetClassDevsEx( IntPtr.Zero, null, IntPtr.Zero, SetupApi.DIGCF.DIGCF_ALLCLASSES | SetupApi.DIGCF.DIGCF_INTERFACEDEVICE | SetupApi.DIGCF.DIGCF_PRESENT, DeviceInfoSet, null, IntPtr.Zero); } else { hDevInfo = SetupApi.SetupDiGetClassDevsEx( ref InterfaceClassGuid, null, IntPtr.Zero, SetupApi.DIGCF.DIGCF_INTERFACEDEVICE | SetupApi.DIGCF.DIGCF_PRESENT, DeviceInfoSet, null, IntPtr.Zero); } if (hDevInfo == Kernel32.INVALID_HANDLE_VALUE) { SetupApi.SetupDiDestroyDeviceInfoList(DeviceInfoSet); // 删除设备信息集 return null; } // 枚举所有设备 List DeviceList = new List(); // 存储设备实例ID StringBuilder DeviceInstanceId = new StringBuilder(256); // 获取设备信息数据 uint DeviceIndex = 0; SetupApi.SP_DEVINFO_DATA DeviceInfoData = SetupApi.SP_DEVINFO_DATA.Empty; while (SetupApi.SetupDiEnumDeviceInfo(hDevInfo, DeviceIndex++, ref DeviceInfoData)) { // 获取设备实例ID if (SetupApi.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) { T_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); } } } SetupApi.SetupDiDestroyDeviceInfoList(hDevInfo); if (DeviceList.Count == 0) return null; else return DeviceList.ToArray(); } /// /// 验证设备的VIDPID /// /// 设备VID /// 设备PID /// 设备安装类GUID,Empty忽视 /// 设备接口类GUID,Empty忽视 /// /// true:匹配成功 /// false:匹配失败 /// public static bool WDK_VIDPIDMatch(ushort VendorID, ushort ProductID, Guid SetupClassGuid, Guid InterfaceClassGuid) { // 根据设备安装类GUID创建空的设备信息集合 IntPtr DeviceInfoSet; if (SetupClassGuid.Equals(Guid.Empty)) { DeviceInfoSet = SetupApi.SetupDiCreateDeviceInfoList(IntPtr.Zero, IntPtr.Zero); } else { DeviceInfoSet = SetupApi.SetupDiCreateDeviceInfoList(ref SetupClassGuid, IntPtr.Zero); } if (DeviceInfoSet == Kernel32.INVALID_HANDLE_VALUE) return false; // 根据设备接口类GUID创建新的设备信息集合 IntPtr hDevInfo; if (InterfaceClassGuid.Equals(Guid.Empty)) { hDevInfo = SetupApi.SetupDiGetClassDevsEx( IntPtr.Zero, null, IntPtr.Zero, SetupApi.DIGCF.DIGCF_ALLCLASSES | SetupApi.DIGCF.DIGCF_INTERFACEDEVICE | SetupApi.DIGCF.DIGCF_PRESENT, DeviceInfoSet, null, IntPtr.Zero); } else { hDevInfo = SetupApi.SetupDiGetClassDevsEx( ref InterfaceClassGuid, null, IntPtr.Zero, SetupApi.DIGCF.DIGCF_INTERFACEDEVICE | SetupApi.DIGCF.DIGCF_PRESENT, DeviceInfoSet, null, IntPtr.Zero); } if (hDevInfo == Kernel32.INVALID_HANDLE_VALUE) { SetupApi.SetupDiDestroyDeviceInfoList(DeviceInfoSet); // 删除设备信息集 return false; } // 存储设备实例ID StringBuilder DeviceInstanceId = new StringBuilder(256); // 获取设备信息数据 uint DeviceIndex = 0; SetupApi.SP_DEVINFO_DATA DeviceInfoData = SetupApi.SP_DEVINFO_DATA.Empty; while (SetupApi.SetupDiEnumDeviceInfo(hDevInfo, DeviceIndex++, ref DeviceInfoData)) { // 获取设备实例ID if (SetupApi.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) { // 供应商标识 if (VendorID == Convert.ToUInt16(match.Value.Substring(4, 4), 16)) { // 产品编号 if (ProductID == Convert.ToUInt16(match.Value.Substring(13, 4), 16)) { SetupApi.SetupDiDestroyDeviceInfoList(hDevInfo); return true; } } } } } SetupApi.SetupDiDestroyDeviceInfoList(hDevInfo); return false; } /// /// 输出VIDPID信息到指定INI文件 /// /// 要保存的ini文件名 /// /// true:成功 /// false:失败 /// public static bool WDK_VIDPIDPrint(string iniFileName) { if (string.IsNullOrEmpty(iniFileName)) return false; LINQToINI iniFile = new LINQToINI(); // VIDPID T_VIDPID[] Properties = WDK_QueryVidPid(Guid.Empty, Guid.Empty); if (Properties != null) { for (int i = 0; i < Properties.Length; i++) { iniFile.WriteProfileString("VIDPID", i.ToString(), Properties[i].VendorID.ToString("X4") + "-" + Properties[i].ProductID.ToString("X4")); } } iniFile.Save(iniFileName); return true; } /// /// 通过WDK获取网卡原生MAC地址 /// /// 是否包含USB网卡,默认不包含USB网卡 /// 获取到的网卡原生MAC地址集合 public static string[] WDK_QueryMacAddress(bool isIncludeUSB = false) { // 获取设备信息集 Guid DeviceInterfaceClass = new Guid(0xAD498944, 0x762F, 0x11D0, 0x8D, 0xCB, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C); IntPtr hDevInfo = SetupApi.SetupDiGetClassDevs(ref DeviceInterfaceClass, null, IntPtr.Zero, SetupApi.DIGCF.DIGCF_PRESENT | SetupApi.DIGCF.DIGCF_INTERFACEDEVICE); if (hDevInfo == Kernel32.INVALID_HANDLE_VALUE) return null; // 枚举设备信息集中所有设备 List DeviceList = new List(); SetupApi.SP_DEVICE_INTERFACE_DATA DeviceInterfaceData = SetupApi.SP_DEVICE_INTERFACE_DATA.Empty; for (uint MemberIndex = 0; ; MemberIndex++) { // 获取设备接口 if (!SetupApi.SetupDiEnumDeviceInterfaces(hDevInfo, null, ref DeviceInterfaceClass, MemberIndex, ref DeviceInterfaceData)) { // 设备枚举完毕 break; } // 获取设备细节信息 SetupApi.SP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData = new SetupApi.SP_DEVICE_INTERFACE_DETAIL_DATA(); if (IntPtr.Size == 8) DeviceInterfaceDetailData.cbSize = 8; else DeviceInterfaceDetailData.cbSize = 4 + Marshal.SystemDefaultCharSize; if (SetupApi.SetupDiGetDeviceInterfaceDetail(hDevInfo, ref DeviceInterfaceData, ref DeviceInterfaceDetailData, Marshal.SizeOf(DeviceInterfaceDetailData), IntPtr.Zero, IntPtr.Zero)) { // 剔除虚拟网卡 if (string.Compare(DeviceInterfaceDetailData.DevicePath, 4, "root", 0, 4, StringComparison.OrdinalIgnoreCase) == 0) continue; if (isIncludeUSB) { // 剔除USB网卡 if (string.Compare(DeviceInterfaceDetailData.DevicePath, 4, "usb", 0, 3, StringComparison.OrdinalIgnoreCase) == 0) continue; } string PermanentAddress = GetPermanentAddressByDevicePath(DeviceInterfaceDetailData.DevicePath); if (!string.IsNullOrEmpty(PermanentAddress) && !DeviceList.Contains(PermanentAddress)) DeviceList.Add(PermanentAddress); } } SetupApi.SetupDiDestroyDeviceInfoList(hDevInfo); if (DeviceList.Count == 0) return null; else return DeviceList.ToArray(); } /// /// 通过设备路径获取网卡原生MAC地址 /// /// 设备路径 /// 网卡原生MAC地址 private static string GetPermanentAddressByDevicePath(string DevicePath) { // 获取设备句柄 IntPtr DeviceHandle = Kernel32.CreateFile(DevicePath, NativeFileAccess.SPECIAL, NativeFileShare.FILE_SHARE_READ | NativeFileShare.FILE_SHARE_WRITE, IntPtr.Zero, NativeFileMode.OPEN_EXISTING, IntPtr.Zero, IntPtr.Zero); if (DeviceHandle != Kernel32.INVALID_HANDLE_VALUE) { byte[] ucData = new byte[8]; int nBytesReturned; // 获取原生MAC地址 const int IOCTL_NDIS_QUERY_GLOBAL_STATS = 0x00170002; uint OID_802_3_PERMANENT_ADDRESS = 0x01010101; bool isOK = Kernel32.DeviceIoControl(DeviceHandle, IOCTL_NDIS_QUERY_GLOBAL_STATS, ref OID_802_3_PERMANENT_ADDRESS, Marshal.SizeOf(OID_802_3_PERMANENT_ADDRESS), ucData, ucData.Length, out nBytesReturned, IntPtr.Zero); Kernel32.CloseHandle(DeviceHandle); if (isOK) { StringBuilder sb = new StringBuilder(nBytesReturned << 1); for (int i = 0; i < nBytesReturned; i++) { sb.Append(ucData[i].ToString("X2")); } return sb.ToString(); } } return null; } /// /// 获取硬盘序列号 /// /// 获取到的硬盘序列号集合 public static string[] WDK_QueryDiskDrive() { // 获取设备信息集 Guid DeviceInterfaceClass = new Guid(0x53F56307, 0xB6BF, 0x11D0, 0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B); IntPtr hDevInfo = SetupApi.SetupDiGetClassDevs(ref DeviceInterfaceClass, null, IntPtr.Zero, SetupApi.DIGCF.DIGCF_PRESENT | SetupApi.DIGCF.DIGCF_INTERFACEDEVICE); if (hDevInfo == Kernel32.INVALID_HANDLE_VALUE) return null; // 枚举设备信息集中所有设备 List DeviceList = new List(); SetupApi.SP_DEVICE_INTERFACE_DATA DeviceInterfaceData = SetupApi.SP_DEVICE_INTERFACE_DATA.Empty; for (uint MemberIndex = 0; ; MemberIndex++) { // 获取设备接口 if (!SetupApi.SetupDiEnumDeviceInterfaces(hDevInfo, null, ref DeviceInterfaceClass, MemberIndex, ref DeviceInterfaceData)) { // 设备枚举完毕 break; } // 获取设备细节信息 SetupApi.SP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData = new SetupApi.SP_DEVICE_INTERFACE_DETAIL_DATA(); if (IntPtr.Size == 8) DeviceInterfaceDetailData.cbSize = 8; else DeviceInterfaceDetailData.cbSize = 4 + Marshal.SystemDefaultCharSize; if (SetupApi.SetupDiGetDeviceInterfaceDetail(hDevInfo, ref DeviceInterfaceData, ref DeviceInterfaceDetailData, Marshal.SizeOf(DeviceInterfaceDetailData), IntPtr.Zero, IntPtr.Zero)) { string SerialNumber = GetHarddiskSerialNumberWithZeroRights(DeviceInterfaceDetailData.DevicePath); if (!string.IsNullOrEmpty(SerialNumber) && !DeviceList.Contains(SerialNumber)) DeviceList.Add(SerialNumber); } } SetupApi.SetupDiDestroyDeviceInfoList(hDevInfo); if (DeviceList.Count == 0) return null; else return DeviceList.ToArray(); } /// /// 通过设备路径获取硬盘序列号 /// /// 设备路径 /// 硬盘序列号 private static string GetHarddiskSerialNumberWithZeroRights(string DevicePath) { const uint IOCTL_STORAGE_QUERY_PROPERTY = 0x2D1400; // 控制代码 string SerialNumber = null; // 获取硬盘句柄 IntPtr hDeviceFile = Kernel32.CreateFile(DevicePath, NativeFileAccess.FILE_SPECIAL, NativeFileShare.FILE_SHARE_READ | NativeFileShare.FILE_SHARE_WRITE, IntPtr.Zero, NativeFileMode.OPEN_EXISTING, IntPtr.Zero, IntPtr.Zero); if (hDeviceFile != Kernel32.INVALID_HANDLE_VALUE) { STORAGE_PROPERTY_QUERY PropertyQuery; PropertyQuery.PropertyId = STORAGE_PROPERTY_ID.StorageDeviceProperty; PropertyQuery.QueryType = STORAGE_QUERY_TYPE.PropertyStandardQuery; PropertyQuery.AdditionalParameters = 0; STORAGE_DESCRIPTOR_HEADER DescriptorHeader = new STORAGE_DESCRIPTOR_HEADER(); int dwBytesReturned; if (Kernel32.DeviceIoControl(hDeviceFile, IOCTL_STORAGE_QUERY_PROPERTY, ref PropertyQuery, Marshal.SizeOf(PropertyQuery), ref DescriptorHeader, Marshal.SizeOf(DescriptorHeader), out dwBytesReturned, IntPtr.Zero)) { IntPtr DescriptorBuffer = Marshal.AllocHGlobal(DescriptorHeader.Size); if (Kernel32.DeviceIoControl(hDeviceFile, IOCTL_STORAGE_QUERY_PROPERTY, ref PropertyQuery, Marshal.SizeOf(PropertyQuery), DescriptorBuffer, DescriptorHeader.Size, out dwBytesReturned, IntPtr.Zero)) { STORAGE_DEVICE_DESCRIPTOR DeviceDescriptor = (STORAGE_DEVICE_DESCRIPTOR)Marshal.PtrToStructure(DescriptorBuffer, typeof(STORAGE_DEVICE_DESCRIPTOR)); if (DeviceDescriptor.SerialNumberOffset != 0) { SerialNumber = ProcessHardDiskSerialNumber(Marshal.PtrToStringAnsi(IntPtr.Add(DescriptorBuffer, DeviceDescriptor.SerialNumberOffset))); } } Marshal.FreeHGlobal(DescriptorBuffer); } Kernel32.CloseHandle(hDeviceFile); } return SerialNumber; } /// /// 查看系统中是否存在指定标识的硬件设备 /// /// 处理器标识,可以为空 /// 硬盘序列号,可以为空 /// 网卡MAC地址(已剔除虚拟网卡和USB网卡),可以为空 /// /// true:匹配成功 /// false:匹配失败 /// /// /// 说明: /// 对设备标识不区分大小写 /// 空项不做判断,非空项必须全部满足 /// public static bool WDK_DeviceMatch(string CPUID, string HardDiskSerialNumber, string MacAddress) { // CPU ID if (!string.IsNullOrEmpty(CPUID)) { // 基于WMI查询 string[] Properties = WMI_DeviceQuery(4); if (Properties == null) return false; bool IsExist = false; foreach (string Item in Properties) { if (CPUID.Equals(Item, StringComparison.OrdinalIgnoreCase)) { IsExist = true; break; } } if (!IsExist) return false; } // 硬盘序列号 if (!string.IsNullOrEmpty(HardDiskSerialNumber)) { // 基于WMI查询 string[] Properties = WDK_QueryDiskDrive(); if (Properties == null) return false; bool IsExist = false; foreach (string Item in Properties) { if (HardDiskSerialNumber.Equals(Item, StringComparison.OrdinalIgnoreCase)) { IsExist = true; break; } } if (!IsExist) return false; } // 网卡原生MAC地址 if (!string.IsNullOrEmpty(MacAddress)) { // 基于WDK查询 string[] Properties = WDK_QueryMacAddress(); if (Properties == null) return false; bool IsExist = false; foreach (string Item in Properties) { if (MacAddress.Equals(Item, StringComparison.OrdinalIgnoreCase)) { IsExist = true; break; } } if (!IsExist) return false; } // 判断程序是否是在VMware虚拟机中运行 if (WDK_IsVMware()) return false; else return true; } /// /// 输出硬件信息到指定INI文件 /// /// 要保存的ini文件名 /// /// true:成功 /// false:失败 /// public static bool WDK_DeviceInfoPrint(string iniFileName) { if (string.IsNullOrEmpty(iniFileName)) return false; LINQToINI iniFile = new LINQToINI(); // 网卡原生MAC地址 string[] Properties = WDK_QueryMacAddress(); if (Properties != null) { for (int i = 0; i < Properties.Length; i++) { iniFile.WriteProfileString("MacAddress", i.ToString(), Properties[i]); } } // 硬盘序列号 Properties = WDK_QueryDiskDrive(); if (Properties != null) { for (int i = 0; i < Properties.Length; i++) { iniFile.WriteProfileString("HardDiskSerialNumber", i.ToString(), Properties[i]); } } // CPU ID Properties = WMI_DeviceQuery(4); if (Properties != null) { for (int i = 0; i < Properties.Length; i++) { iniFile.WriteProfileString("CPUID", i.ToString(), Properties[i]); } } iniFile.Save(iniFileName); return true; } /// /// 判断程序是否在VMware虚拟机中运行 /// /// /// true:程序是在VMware虚拟机中运行 /// false:程序不是在VMware虚拟机中运行 /// public static bool WDK_IsVMware() { const uint IOCTL_STORAGE_QUERY_PROPERTY = 0x2D1400; // 控制代码 bool IsOK = false; // 获取硬盘句柄 IntPtr hDeviceFile = Kernel32.CreateFile(@"\\.\PhysicalDrive0", NativeFileAccess.FILE_SPECIAL, NativeFileShare.FILE_SHARE_READ | NativeFileShare.FILE_SHARE_WRITE, IntPtr.Zero, NativeFileMode.OPEN_EXISTING, IntPtr.Zero, IntPtr.Zero); if (hDeviceFile != Kernel32.INVALID_HANDLE_VALUE) { STORAGE_PROPERTY_QUERY PropertyQuery; PropertyQuery.PropertyId = STORAGE_PROPERTY_ID.StorageDeviceProperty; PropertyQuery.QueryType = STORAGE_QUERY_TYPE.PropertyStandardQuery; PropertyQuery.AdditionalParameters = 0; STORAGE_DESCRIPTOR_HEADER DescriptorHeader = new STORAGE_DESCRIPTOR_HEADER(); int dwBytesReturned; if (Kernel32.DeviceIoControl(hDeviceFile, IOCTL_STORAGE_QUERY_PROPERTY, ref PropertyQuery, Marshal.SizeOf(PropertyQuery), ref DescriptorHeader, Marshal.SizeOf(DescriptorHeader), out dwBytesReturned, IntPtr.Zero)) { IntPtr DescriptorBuffer = Marshal.AllocHGlobal(DescriptorHeader.Size); if (Kernel32.DeviceIoControl(hDeviceFile, IOCTL_STORAGE_QUERY_PROPERTY, ref PropertyQuery, Marshal.SizeOf(PropertyQuery), DescriptorBuffer, DescriptorHeader.Size, out dwBytesReturned, IntPtr.Zero)) { STORAGE_DEVICE_DESCRIPTOR DeviceDescriptor = (STORAGE_DEVICE_DESCRIPTOR)Marshal.PtrToStructure(DescriptorBuffer, typeof(STORAGE_DEVICE_DESCRIPTOR)); if (DeviceDescriptor.VendorIdOffset != 0) { string vendorId = Marshal.PtrToStringAnsi(IntPtr.Add(DescriptorBuffer, DeviceDescriptor.VendorIdOffset)); if (!string.IsNullOrEmpty(vendorId) && vendorId.IndexOf("VMware") >= 0) { IsOK = true; } } } Marshal.FreeHGlobal(DescriptorBuffer); } Kernel32.CloseHandle(hDeviceFile); } return IsOK; } } }