//不记得从哪儿看到的,觉得不错,就贴下来了
#include <stdafx.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <TCHAR.H>
#include <SetupAPI.h>
#include <cfgmgr32.h> // cfgmgr32.h 在Microsoft Windows 2000 DDK 中.
#include <regstr.h>
#pragma comment(lib,"setupapi.lib")
#define UNKNOWNDEVICE _T("<Unknown Device>")
typedef struct _DEVICE_INFO
{
SP_DEVINFO_DATA DevInfoData; //设备信息包括实例句柄和设备类的GUID
DWORD DevID; //在此次全局的枚举中设备ID
TCHAR *lpszDevName; //设备的名称
ULONG ulDevNameLen; //设备名称的长度
BOOL bDisableable; //是否可以被禁用
BOOL bDisabled; //是否已经被禁用
struct _DEVICE_INFO *pNextDevInfo; //下一个结构块
}
DEVICE_INFO,*LPDEVICE_INFO;
DEVICE_INFO DevInfo; //设备链表头
BOOL IsDisableable(DWORD dwDevID, HDEVINFO hDevInfo) ;
BOOL IsDisabled(DWORD dwDevID, HDEVINFO hDevInfo) ;
BOOL StateChange( DWORD dwNewState, DWORD dwDevID, HDEVINFO hDevInfo) ;
//
// 获得设备注册表中的内容
//
BOOL GetRegistryProperty( HDEVINFO DeviceInfoSet,
PSP_DEVINFO_DATA DeviceInfoData,
ULONG Property,
PVOID Buffer,
PULONG Length )
{
while ( !SetupDiGetDeviceRegistryProperty( DeviceInfoSet,
DeviceInfoData,
Property,
NULL,
(BYTE *)*(TCHAR **)Buffer,
*Length,
Length))
{
// 长度不够则重新分配缓冲区
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
if (*(LPTSTR *)Buffer)
LocalFree(*(LPTSTR *)Buffer);
*(LPTSTR *)Buffer = (PCHAR)LocalAlloc(LPTR,*Length);
}
else
{
return false;
}
}
return (BOOL)(*(LPTSTR *)Buffer)[0];
}
BOOL EnableDevice(DWORD dwDevID, HDEVINFO hDevInfo)
{
return StateChange(DICS_ENABLE,dwDevID,hDevInfo);
}
BOOL DisableDevice(DWORD dwDevID, HDEVINFO hDevInfo)
{
return StateChange(DICS_DISABLE,dwDevID,hDevInfo);
}
BOOL ControlDevice(DWORD dwDevID, HDEVINFO hDevInfo)
{
BOOL bCanDisable;
bCanDisable = (IsDisableable(dwDevID,hDevInfo) && (!IsDisabled(dwDevID,hDevInfo)));
if(bCanDisable)
return DisableDevice(dwDevID,hDevInfo);
else
return EnableDevice(dwDevID,hDevInfo);
}
void EnumNetCards()
{
DWORD Status, Problem;
LPTSTR Buffer = NULL;
DWORD BufSize = 0;
// 返回所有设备信息
HDEVINFO hDevInfo = SetupDiGetClassDevs(NULL,NULL,0,DIGCF_PRESENT|DIGCF_ALLCLASSES) ;
if (INVALID_HANDLE_VALUE == hDevInfo )
return;
SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
//
// 枚举设备
//
for ( DWORD DeviceId=0;
SetupDiEnumDeviceInfo( hDevInfo,DeviceId,&DeviceInfoData);
DeviceId++)
{
// 获得设备的状态
if (CM_Get_DevNode_Status(&Status, &Problem, DeviceInfoData.DevInst ,0) != CR_SUCCESS)
continue;
// 获取设备类名
TCHAR szDevName [MAX_PATH] = _T("") ;
if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_CLASS , &Buffer, (PULONG)&BufSize))
{
lstrcpyn( szDevName, Buffer, MAX_PATH ) ;
}
if ( lstrcmp( szDevName, _T("Net") ) == 0 )
{
TCHAR szName [MAX_PATH] = _T("") ;
if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_ENUMERATOR_NAME , &Buffer, (PULONG)&BufSize))
{
lstrcpyn( szName, Buffer, MAX_PATH ) ;
}
if ( lstrcmp( szName, _T("ROOT") ) != 0 )
{
if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DRIVER , &Buffer, (PULONG)&BufSize))
{
lstrcpyn( szName, Buffer, MAX_PATH ) ;
// 获取设备描述
if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC , &Buffer, (PULONG)&BufSize))
{
lstrcpyn( szName, Buffer, MAX_PATH ) ;
if(ControlDevice(DeviceId,hDevInfo))
{
printf("Successful/n");
}
else
{
printf("FAILED/n");
}
}
}
}
}
}
SetupDiDestroyDeviceInfoList(hDevInfo);
}
BOOL StateChange( DWORD dwNewState, DWORD dwDevID, HDEVINFO hDevInfo)
{
SP_PROPCHANGE_PARAMS PropChangeParams;
SP_DEVINFO_DATA DevInfoData = {sizeof(SP_DEVINFO_DATA)};
SP_DEVINSTALL_PARAMS devParams;
//查询设备信息
if (!SetupDiEnumDeviceInfo( hDevInfo, dwDevID, &DevInfoData))
{
OutputDebugString("SetupDiEnumDeviceInfo FAILED");
return FALSE;
}
//设置设备属性变化参数
PropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
PropChangeParams.Scope = DICS_FLAG_GLOBAL; //使修改的属性保存在所有的硬件属性文件
PropChangeParams.StateChange = dwNewState;
PropChangeParams.HwProfile = 0;
//改变设备属性
if (!SetupDiSetClassInstallParams( hDevInfo,
&DevInfoData,
(SP_CLASSINSTALL_HEADER *)&PropChangeParams,
sizeof(PropChangeParams)))
{
OutputDebugString("SetupDiSetClassInstallParams FAILED");
return FALSE;
}
PropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
PropChangeParams.Scope = DICS_FLAG_CONFIGSPECIFIC;//使修改的属性保存在指定的属性文件
PropChangeParams.StateChange = dwNewState;
PropChangeParams.HwProfile = 0;
//改变设备属性并调用安装服务
if (!SetupDiSetClassInstallParams( hDevInfo,
&DevInfoData,
(SP_CLASSINSTALL_HEADER *)&PropChangeParams,
sizeof(PropChangeParams)) ||
!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo, &DevInfoData))
{
OutputDebugString("SetupDiSetClassInstallParams or SetupDiCallClassInstaller FAILED");
return TRUE;
}
else
{
//判断是否需要重新启动
devParams.cbSize = sizeof(devParams);
if (!SetupDiGetDeviceInstallParams( hDevInfo, &DevInfoData, &devParams))
{
OutputDebugString("SetupDiGetDeviceInstallParams FAILED");
return FALSE;
}
if (devParams.Flags & (DI_NEEDRESTART|DI_NEEDREBOOT))
{
OutputDebugString("Need Restart Computer");
return TRUE;
}
return TRUE;
}
}
BOOL IsDisableable(DWORD dwDevID, HDEVINFO hDevInfo)
{
SP_DEVINFO_DATA DevInfoData = {sizeof(SP_DEVINFO_DATA)};
DWORD dwDevStatus,dwProblem;
if(!SetupDiEnumDeviceInfo(hDevInfo,dwDevID,&DevInfoData))
{
OutputDebugString("SetupDiEnumDeviceInfo FAILED");
return FALSE;
}
//查询设备状态
if(CM_Get_DevNode_Status(&dwDevStatus,&dwProblem,DevInfoData.DevInst,0)!=CR_SUCCESS)
{
OutputDebugString("CM_GET_DevNode_Status FAILED");
return FALSE;
}
return ((dwDevStatus & DN_DISABLEABLE) && (dwProblem != CM_PROB_HARDWARE_DISABLED));
}
BOOL IsDisabled(DWORD dwDevID, HDEVINFO hDevInfo)
{
SP_DEVINFO_DATA DevInfoData = {sizeof(SP_DEVINFO_DATA)};
DWORD dwDevStatus,dwProblem;
if(!SetupDiEnumDeviceInfo(hDevInfo,dwDevID,&DevInfoData))
{
OutputDebugString("SetupDiEnumDeviceInfo FAILED");
return FALSE;
}
//查询设备状态
if(CM_Get_DevNode_Status(&dwDevStatus,&dwProblem,DevInfoData.DevInst,0)!=CR_SUCCESS)
{
OutputDebugString("CM_GET_DevNode_Status FAILED");
return FALSE;
}
return ((dwDevStatus & DN_HAS_PROBLEM) && (dwProblem == CM_PROB_DISABLED));
}
void GuidCopy(GUID guidSrc, GUID *guidDest)
{
guidDest->Data1 = guidSrc.Data1;
guidDest->Data2 = guidSrc.Data2;
guidDest->Data3 = guidSrc.Data3;
memcpy(guidDest->Data4,guidSrc.Data4,8);
}
BOOL ConstructDeviceName(HDEVINFO DevInfoSet, PSP_DEVINFO_DATA DevInfoData, PVOID pBuffer, PULONG Length)
{
//尝试通过各种类型的设备描述获得其设备名称
if (!GetRegistryProperty( DevInfoSet,
DevInfoData,
SPDRP_FRIENDLYNAME , //设备的现实名称
pBuffer,
Length))
{
if (!GetRegistryProperty( DevInfoSet,
DevInfoData,
SPDRP_DEVICEDESC , //设备的描述
pBuffer,
Length))
{
if (!GetRegistryProperty( DevInfoSet,
DevInfoData,
SPDRP_CLASS , //设备类名
pBuffer,
Length))
{
if (!GetRegistryProperty( DevInfoSet,
DevInfoData,
SPDRP_CLASSGUID , //设备的GUID
pBuffer,
Length))
{
//什么都没找到就返回UnknownDevice
*Length = (lstrlen(UNKNOWNDEVICE)+1)*sizeof(TCHAR);
*(LPTSTR *)pBuffer = (PCHAR)LocalAlloc(LPTR,*Length);
_tcscpy(*(LPTSTR *)pBuffer,UNKNOWNDEVICE);
}
}
}
}
return TRUE;
}
BOOL EnumDevices(HDEVINFO hDevInfo)
{
DWORD dwDevID ; //, dwStatus, dwProblem;
SP_DEVINFO_DATA DevInfoData = {sizeof(SP_DEVINFO_DATA)};
LPDEVICE_INFO pDevInfo, pPreDevInfo;
TCHAR *DeviceName = NULL ;
ULONG ulNameLen = 256;
pPreDevInfo = &DevInfo;
//穷举每个设备
for(dwDevID = 0;SetupDiEnumDeviceInfo(hDevInfo,dwDevID,&DevInfoData);dwDevID++)
{
//构造设备信息块
pDevInfo = (LPDEVICE_INFO)malloc(sizeof(DEVICE_INFO));
pDevInfo->pNextDevInfo = NULL;
pDevInfo->DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
pDevInfo->ulDevNameLen;
pDevInfo->DevID = dwDevID;
GuidCopy(DevInfoData.ClassGuid,&pDevInfo->DevInfoData.ClassGuid);
pDevInfo->DevInfoData.DevInst = DevInfoData.DevInst;
pDevInfo->DevInfoData.Reserved = DevInfoData.Reserved;
//这里有个问题,如果用设备信息块结构中的字符串指针
//SetupDiGetDeviceRegistyProperty函数就会返回数据无效,不知道为什么。
//所以下面只能在重新复制一遍了。
ConstructDeviceName(hDevInfo,&DevInfoData,&DeviceName,&ulNameLen);
pDevInfo->ulDevNameLen = ulNameLen;
pDevInfo->lpszDevName = (TCHAR *)malloc(ulNameLen*sizeof(TCHAR));
memcpy(pDevInfo->lpszDevName,DeviceName,ulNameLen);
pDevInfo->bDisableable = IsDisableable(dwDevID, hDevInfo);
pDevInfo->bDisabled = IsDisabled(dwDevID, hDevInfo);
pPreDevInfo->pNextDevInfo = pDevInfo;
pPreDevInfo = pDevInfo;
}
return FALSE;
}
int main(int argc, char* argv[])
{
HDEVINFO hDevInfo = NULL ;
LPDEVICE_INFO pDevInfo = NULL ;
EnumNetCards() ;
return 0 ;
//返回设备信息
hDevInfo = SetupDiGetClassDevs(NULL,NULL,NULL,DIGCF_PRESENT|DIGCF_ALLCLASSES);
DevInfo.DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
DevInfo.ulDevNameLen = 256;
DevInfo.pNextDevInfo = NULL;
//枚举系统设备
EnumDevices(hDevInfo);
pDevInfo = DevInfo.pNextDevInfo;
while(pDevInfo)
{
//从系统设备中查找usb mass storage设备
TCHAR szDebugStr [512] = _T("") ;
_stprintf(szDebugStr,"DevID : %d GUID:%x-%x-%x-%x%x%x%x%x%x%x%x DevInst : %x,DevName:%s IsDisableable:%d, IsDisabled:%d"
,pDevInfo->DevID
,pDevInfo->DevInfoData.ClassGuid.Data1
,pDevInfo->DevInfoData.ClassGuid.Data2
,pDevInfo->DevInfoData.ClassGuid.Data3
,pDevInfo->DevInfoData.ClassGuid.Data4[0]
,pDevInfo->DevInfoData.ClassGuid.Data4[1]
,pDevInfo->DevInfoData.ClassGuid.Data4[2]
,pDevInfo->DevInfoData.ClassGuid.Data4[3]
,pDevInfo->DevInfoData.ClassGuid.Data4[4]
,pDevInfo->DevInfoData.ClassGuid.Data4[5]
,pDevInfo->DevInfoData.ClassGuid.Data4[6]
,pDevInfo->DevInfoData.ClassGuid.Data4[7]
,pDevInfo->DevInfoData.DevInst
,pDevInfo->lpszDevName
,pDevInfo->bDisableable
,pDevInfo->bDisabled);
OutputDebugString(szDebugStr);
printf( "Device name=%s/n", pDevInfo->lpszDevName ) ;
pDevInfo = pDevInfo->pNextDevInfo;
}
SetupDiDestroyDeviceInfoList(hDevInfo);
return 0 ;
}