通过WDK获取设备的VID-PID、网卡原生MAC地址、硬盘序列号
2010-05-01 15:54
543 查看
开发语言:C/C++
开发工具:
Visual Studio 2010
Windows Driver Kit Version 7600.16385.1
支持平台:Windows
实现功能:
通过WDK获取设备的VID-PID、网卡原生MAC地址、硬盘序列号
下载地址:
WDK_DeviceQuery.zip
版本历史:
V1.3 2010年05月22日
增加获取硬盘序列号(需要系统管理员权限)。
V1.2 2010年05月20日
更新接口函数。
增加获取网卡原生MAC地址。
V1.1 2010年04月27日
优化代码。
V1.0 2010年04月15日
完成正式版本。获取设备的VID-PID。
接口函数:
WDK_DeviceQuery_Property
WDK_DeviceQuery_VIDPID
接口文件:WDK_DeviceQuery.h
实现代码:WDK_DeviceQuery.cpp
开发工具:
Visual Studio 2010
Windows Driver Kit Version 7600.16385.1
支持平台:Windows
实现功能:
通过WDK获取设备的VID-PID、网卡原生MAC地址、硬盘序列号
下载地址:
WDK_DeviceQuery.zip
版本历史:
V1.3 2010年05月22日
增加获取硬盘序列号(需要系统管理员权限)。
V1.2 2010年05月20日
更新接口函数。
增加获取网卡原生MAC地址。
V1.1 2010年04月27日
优化代码。
V1.0 2010年04月15日
完成正式版本。获取设备的VID-PID。
接口函数:
WDK_DeviceQuery_Property
WDK_DeviceQuery_VIDPID
接口文件:WDK_DeviceQuery.h
/* ---------------------------------------------------------- 文件名称:WDK_DeviceQuery.h 作者:秦建辉 MSN:splashcn@msn.com 版本历史: V1.3 2010年05月22日 增加获取硬盘序列号(需要系统管理员权限)。 V1.2 2010年05月20日 更新接口函数。 增加获取网卡原生MAC地址。 V1.1 2010年04月27日 优化代码。 V1.0 2010年04月15日 完成正式版本。获取设备的VID-PID。 功能描述: 基于WDK获取设备属性值。 接口函数: WDK_DeviceQuery_Property WDK_DeviceQuery_VIDPID ------------------------------------------------------------ */ #pragma once #include <windows.h> #ifndef MACRO_T_DEVICE_PROPERTY #define MACRO_T_DEVICE_PROPERTY #define PROPERTY_MAX_LEN 128 // 属性字段最大长度 typedef struct _T_DEVICE_PROPERTY { TCHAR szProperty[PROPERTY_MAX_LEN]; } T_DEVICE_PROPERTY; #endif #define WDK_QUERY_TYPENUM 4 // WDK查询支持的类型数 #ifndef MACRO_HIDD_VIDPID #define MACRO_HIDD_VIDPID typedef struct _HIDD_VIDPID { USHORT VendorID; USHORT ProductID; } HIDD_VIDPID; #endif #ifdef __cplusplus extern "C" { #endif /* 功能:基于WDK获取设备属性值 参数说明: iQueryType:需要查询的设备属性 0:人机交互设备的VID-PID 1:网卡原生MAC地址(包含USB网卡) 2:网卡原生MAC地址(剔除USB网卡) 3:硬盘序列号(需要系统管理员权限) properties:存储设备属性值 iSize:可存储的最大设备数 返回值: -1:获取设备信息表失败 -2:不支持的查询类型 >=0:实际获取的设备数 */ INT WDK_DeviceQuery_Property( INT iQueryType, T_DEVICE_PROPERTY *properties, INT iSize ); /* 功能:获取指定设备接口类相关设备的VID和PID 参数说明: pGuid:指向设备接口类GUID pVIDPID:存储设备的VID和PID iSize:可存储的最大设备数 返回值: -1:获取设备信息表失败 >=0:实际获取的设备数 */ INT WDK_DeviceQuery_VIDPID( const GUID* pGuid, HIDD_VIDPID* pVIDPID, INT iSize ); #ifdef __cplusplus } #endif
实现代码:WDK_DeviceQuery.cpp
#include "WDK_DeviceQuery.h" #include <tchar.h> #include <strsafe.h> #include <setupapi.h> #include <ntddndis.h> #include <ntdddisk.h> #include <algorithm> #ifdef __cplusplus extern "C" { #endif #include <hidsdi.h> #ifdef __cplusplus } #endif #pragma comment (lib, "Setupapi.lib") #pragma comment (lib, "hid.lib") const GUID GUID_QUERYSET[] = { // 人机交互设备VID-PID {0x4D1E55B2, 0xF16F, 0x11CF, 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30}, // 网卡原生MAC地址(包含USB网卡) {0xAD498944, 0x762F, 0x11D0, 0x8D, 0xCB, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C}, // 网卡原生MAC地址(剔除USB网卡) {0xAD498944, 0x762F, 0x11D0, 0x8D, 0xCB, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C}, // 硬盘序列号 {0x53F56307, 0xB6BF, 0x11D0, 0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B}, }; // 获取设备的VID-PID static BOOL WDK_GetVIDPID( TCHAR* DevicePath, TCHAR* szProperty, UINT uSize ) { HANDLE hDeviceFile; BOOL isOK = FALSE; // 获取设备句柄 hDeviceFile = CreateFile( DevicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if( hDeviceFile != INVALID_HANDLE_VALUE ) { // 获取设备属性 HIDD_ATTRIBUTES Attributes; Attributes.Size = sizeof(HIDD_ATTRIBUTES); isOK = HidD_GetAttributes( hDeviceFile, &Attributes ); if( isOK ) { if( szProperty != NULL ) { StringCchPrintf( szProperty, uSize, TEXT("%04X-%04X"), Attributes.VendorID, Attributes.ProductID ); } } CloseHandle( hDeviceFile ); } return isOK; } // 获取网卡原生MAC地址 static BOOL WDK_GetMacAddress( TCHAR* DevicePath, TCHAR* szProperty, UINT uSize, BOOL isIncludeUSB ) { HANDLE hDeviceFile; BOOL isOK = FALSE; // 剔除虚拟网卡 if( _tcsnicmp( DevicePath + 4, TEXT("root"), 4 ) == 0 ) { return FALSE; } if( !isIncludeUSB ) { // 剔除USB网卡 if( _tcsnicmp( DevicePath + 4, TEXT("usb"), 4 ) == 0 ) { return FALSE; } } // 获取设备句柄 hDeviceFile = CreateFile( DevicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if( hDeviceFile != INVALID_HANDLE_VALUE ) { ULONG dwID; BYTE ucData[8]; DWORD dwByteRet; // 获取原生MAC地址 dwID = OID_802_3_PERMANENT_ADDRESS; isOK = DeviceIoControl( hDeviceFile, IOCTL_NDIS_QUERY_GLOBAL_STATS, &dwID, sizeof(dwID), ucData, sizeof(ucData), &dwByteRet, NULL ); if( isOK ) { if( szProperty != NULL ) { // 将字节数组转换成16进制字符串 for( DWORD i = 0; i < dwByteRet; i++ ) { StringCchPrintf( szProperty + (i << 1), uSize - (i << 1), TEXT("%02X"), ucData[i] ); } } } CloseHandle( hDeviceFile ); } return isOK; } // 获取硬盘序列号(需要系统管理员权限) static BOOL WDK_GetHarddiskSerialNumberWithAdminRights( TCHAR* DevicePath, TCHAR* szProperty, UINT uSize ) { HANDLE hDeviceFile; BOOL isOK = FALSE; // 获取设备句柄 hDeviceFile = CreateFile( DevicePath, GENERIC_READ | GENERIC_WRITE, // 注意:需要系统管理员权限才能执行读写操作 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if( hDeviceFile != INVALID_HANDLE_VALUE ) { GETVERSIONINPARAMS VersionInParams; DWORD dwByteRet; // 获取硬盘属性 isOK = DeviceIoControl( hDeviceFile, SMART_GET_VERSION, NULL, 0, &VersionInParams, sizeof(GETVERSIONINPARAMS), &dwByteRet, NULL ); if( isOK ) { isOK = FALSE; if( VersionInParams.fCapabilities & CAP_ATA_ID_CMD ) { BYTE abSCIP[sizeof(SENDCMDINPARAMS) - 1] = {0}; BYTE abSCOP[sizeof(SENDCMDOUTPARAMS) - 1 + 512] = {0}; SENDCMDINPARAMS *scip = reinterpret_cast<SENDCMDINPARAMS*>(abSCIP); SENDCMDOUTPARAMS *scop = reinterpret_cast<SENDCMDOUTPARAMS*>(abSCOP); // 设置输入参数 scip->irDriveRegs.bCommandReg = ID_CMD; // 设置输出参数 scop->cBufferSize = 512; // 获取硬盘详细信息 isOK = DeviceIoControl( hDeviceFile, SMART_RCV_DRIVE_DATA, scip, sizeof(abSCIP), scop, sizeof(abSCOP), &dwByteRet, NULL ); if( isOK ) { if( szProperty != NULL ) { // 提取硬盘序列号 for( UINT i = 0; i < 20; i += 2 ) { // 颠倒高低位字节 szProperty[i] = scop->bBuffer[i+21]; szProperty[i + 1] = scop->bBuffer[i+20]; } szProperty[20] = TEXT('/0'); // 去掉空格 std::remove( szProperty, szProperty + _tcslen(szProperty) + 1, L' ' ); } } } } CloseHandle( hDeviceFile ); } return isOK; } static BOOL WDK_GetProperty( TCHAR* DevicePath, INT iQueryType, TCHAR* szProperty, UINT uSize ) { BOOL isOK = FALSE; switch( iQueryType ) { case 0: // 获取设备的VID-PID isOK = WDK_GetVIDPID( DevicePath, szProperty, uSize ); break; case 1: // 网卡原生MAC地址(包含USB网卡) isOK = WDK_GetMacAddress( DevicePath, szProperty, uSize, TRUE ); break; case 2: // 网卡原生MAC地址(剔除USB网卡) isOK = WDK_GetMacAddress( DevicePath, szProperty, uSize, FALSE ); break; case 3: // 硬盘序列号(需要系统管理员权限) isOK = WDK_GetHarddiskSerialNumberWithAdminRights( DevicePath, szProperty, uSize ); break; default: break; } return isOK; } INT WDK_DeviceQuery_Property( INT iQueryType, T_DEVICE_PROPERTY *properties, INT iSize ) { HDEVINFO hDevInfo; DWORD MemberIndex, RequiredSize; SP_DEVICE_INTERFACE_DATA DeviceInterfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData; INT iTotal = 0; // 判断查询类型是否支持 if( (iQueryType < 0) || (iQueryType >= sizeof(GUID_QUERYSET)/sizeof(GUID)) ) { return -2; // 查询类型不支持 } // 获取设备信息集 hDevInfo = SetupDiGetClassDevs( GUID_QUERYSET + iQueryType, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE ); if( hDevInfo == INVALID_HANDLE_VALUE ) { return -1; } // 枚举设备信息集中所有设备 DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); for( MemberIndex = 0; ((properties == NULL) || (iTotal < iSize)); MemberIndex++ ) { // 获取设备接口 if( !SetupDiEnumDeviceInterfaces( hDevInfo, NULL, GUID_QUERYSET + iQueryType, MemberIndex, &DeviceInterfaceData ) ) { // 设备枚举完毕 break; } // 获取接收缓冲区大小,函数返回值为FALSE,GetLastError()=ERROR_INSUFFICIENT_BUFFER SetupDiGetDeviceInterfaceDetail( hDevInfo, &DeviceInterfaceData, NULL, 0, &RequiredSize, NULL ); // 申请接收缓冲区 DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc( RequiredSize ); DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); // 获取设备细节信息 if( SetupDiGetDeviceInterfaceDetail( hDevInfo, &DeviceInterfaceData, DeviceInterfaceDetailData, RequiredSize, NULL, NULL ) ) { if( properties != NULL ) { if( WDK_GetProperty( DeviceInterfaceDetailData->DevicePath, iQueryType, properties[iTotal].szProperty, PROPERTY_MAX_LEN ) ) { if( iTotal > 0 ) { // 剔除重复设备 if( _tcscmp( properties[iTotal].szProperty, properties[iTotal - 1].szProperty ) != 0 ) { iTotal++; } } else { iTotal++; } } } else { iTotal++; } } free( DeviceInterfaceDetailData ); } SetupDiDestroyDeviceInfoList( hDevInfo ); return iTotal; } INT WDK_DeviceQuery_VIDPID( const GUID* pGuid, HIDD_VIDPID* pVIDPID, INT iSize ) { HDEVINFO hDevInfo; DWORD MemberIndex, RequiredSize; SP_DEVICE_INTERFACE_DATA DeviceInterfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData; INT iTotal = 0; // 获取设备信息集 hDevInfo = SetupDiGetClassDevs( pGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE ); if( hDevInfo == INVALID_HANDLE_VALUE ) { return -1; } // 枚举设备信息集中所有设备 DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); for( MemberIndex = 0; ((pVIDPID == NULL) || (iTotal < iSize)); MemberIndex++ ) { // 获取设备接口 if( !SetupDiEnumDeviceInterfaces( hDevInfo, NULL, pGuid, MemberIndex, &DeviceInterfaceData ) ) { // 设备枚举完毕 break; } // 获取接收缓冲区大小,函数返回值为FALSE,GetLastError()=ERROR_INSUFFICIENT_BUFFER SetupDiGetDeviceInterfaceDetail( hDevInfo, &DeviceInterfaceData, NULL, 0, &RequiredSize, NULL ); // 申请接收缓冲区 DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc( RequiredSize ); DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); // 获取设备细节信息 if( SetupDiGetDeviceInterfaceDetail( hDevInfo, &DeviceInterfaceData, DeviceInterfaceDetailData, RequiredSize, NULL, NULL ) ) { // 获取设备句柄 HANDLE hDeviceFile; hDeviceFile = CreateFile( DeviceInterfaceDetailData->DevicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if( hDeviceFile != INVALID_HANDLE_VALUE ) { // 获取设备属性 HIDD_ATTRIBUTES Attributes; Attributes.Size = sizeof(HIDD_ATTRIBUTES); if( HidD_GetAttributes( hDeviceFile, &Attributes ) ) { if( pVIDPID != NULL ) { pVIDPID[iTotal].VendorID = Attributes.VendorID; pVIDPID[iTotal].ProductID = Attributes.ProductID; if( iTotal > 0 ) { // 剔除重复设备 if( (pVIDPID[iTotal].VendorID != pVIDPID[iTotal - 1].VendorID) || (pVIDPID[iTotal].ProductID != pVIDPID[iTotal - 1].ProductID) ) { iTotal++; } } else { iTotal++; } } else { iTotal++; } } CloseHandle( hDeviceFile ); } } free( DeviceInterfaceDetailData ); } SetupDiDestroyDeviceInfoList( hDevInfo ); return iTotal; }
相关文章推荐
- 通过Windows注册表获取U盘、移动硬盘和USB读卡器等设备的PID、VID和序列号
- 通过Windows注册表获取U盘、移动硬盘和USB读卡器等设备的PID、VID和序列号
- 通过WMI获取网卡MAC地址、硬盘序列号、主板序列号、CPU ID、BIOS序列号
- 通过WDK获取网卡原生MAC地址和当前MAC地址
- 通过WMI获取网卡MAC地址、硬盘序列号、主板序列号、CPU ID、BIOS序列号
- 通过WDK获取网卡原生MAC地址和当前MAC地址。
- 通过WMI获取网卡MAC地址、硬盘序列号、主板序列号、CPU ID、BIOS序列号
- (转)通过WMI获取网卡MAC地址、硬盘序列号、主板序列号、CPU ID、BIOS序列号
- 通过WMI获取网卡MAC地址、硬盘序列号、主板序列号、CPU ID、BIOS序列号
- 通过WMI获取网卡MAC地址、硬盘序列号、主板序列号、CPU ID、BIOS序列号
- 获取cpu序列号,硬盘ID,网卡MAC地址
- unity3d 获取cpu序列号,硬盘ID,网卡MAC地址等硬件可用于加密
- vc通过usb获取手机设备vidpid
- 基于硬件指纹的软件加密和注册技术--获取硬盘物理序列号、CPU序列号、网卡MAC地址、BIOS序列号、主板序列号
- C#应用:获取cpu序列号,硬盘ID,网卡MAC地址[编程联盟]
- C# 获取CPU序列号、网卡MAC地址、硬盘序列号封装类,用于软件绑定电脑
- C# 获取CPU序列号、网卡MAC地址、硬盘序列号封装类,用于软件绑定电脑
- windows平台下获取网卡MAC地址、硬盘序列号、主板序列号、CPU ID、BIOS序列号
- 通过WMI获得硬盘Id和CPU的物理序列号网卡的Mac地址
- 获取cpu序列号,硬盘ID,网卡MAC地址-老童