转:如何编程实现启用禁用网卡
/*****************************************************************************
演示如何编程实现启用禁用网卡
Mady By ZwelL
2004.7.29
zwell@sohu.com
*****************************************************************************/
#include
#include
#include
#include
#pragma comment(lib,”ws2_32.lib”)
#pragma comment(lib,”setupapi.lib”)
BOOL DisableNetInterface(bool bStatus)
{
IN LPTSTR HardwareId ;
//硬件ComponentId,注册表地址:system\currentcontrolset\class\{4D36E972-E325-11CE-BFC1-08002BE10318}\0000
HardwareId=”PCI\\VEN_10EC&DEV_8139&SUBSYS_813910EC” ;
DWORD NewState ;
if(bStatus)
{
NewState=DICS_DISABLE ;
//禁用
}
else
{
NewState=DICS_ENABLE ;
//启用
}
//调用ddk函数,来禁用网卡
DWORD i,err ;
BOOL Found=false ;
HDEVINFO hDevInfo ;
SP_DEVINFO_DATA spDevInfoData ;
//访问系统的硬件库
hDevInfo=SetupDiGetClassDevs(NULL,”PCI”,NULL,DIGCF_ALLCLASSES|DIGCF_PRESENT);
if(hDevInfo==INVALID_HANDLE_VALUE)
{
printf(”访问系统硬件出错!”);
return false ;
}
//枚举硬件,获得需要的接口
spDevInfoData.cbSize=sizeof(SP_DEVINFO_DATA);
for(i=0;SetupDiEnumDeviceInfo(hDevInfo,i,&spDevInfoData);i++)
{
DWORD DataT ;
LPTSTR p,buffer=NULL ;
DWORD buffersize=0 ;
//获得硬件的属性值
while(!SetupDiGetDeviceRegistryProperty(
hDevInfo,
&spDevInfoData,
SPDRP_HARDWAREID,
&DataT,
(PBYTE)buffer,
buffersize,
&buffersize))
{
if(GetLastError()==ERROR_INVALID_DATA)
{
//不存在HardwareID. Continue.
break ;
}
else if(GetLastError()==ERROR_INSUFFICIENT_BUFFER)
{
//buffer size不对.
if(buffer)
LocalFree(buffer);
buffer=(char*)LocalAlloc(LPTR,buffersize);
}
else
{
//未知错误
goto cleanup_DeviceInfo ;
}
}
if(GetLastError()==ERROR_INVALID_DATA)
continue ;
//比较,找到和网卡ID相同的项
for(p=buffer;*p&&(p<&buffer[buffersize]);p+=lstrlen(p)+sizeof(TCHAR))
{
if(!_tcscmp(HardwareId,p))
{
//找到网卡
Found=TRUE ;
break ;
}
}
if(buffer)
LocalFree(buffer);
//如果相等
if(Found)
{
//禁用该设备
SP_PROPCHANGE_PARAMS spPropChangeParams ;
spPropChangeParams.ClassInstallHeader.cbSize=sizeof(SP_CLASSINSTALL_HEADER);
spPropChangeParams.ClassInstallHeader.InstallFunction=DIF_PROPERTYCHANGE ;
spPropChangeParams.Scope=DICS_FLAG_GLOBAL ;
spPropChangeParams.StateChange=NewState ;
//禁用:DICS_DISABLE,DICS_ENABLE启用
//
if(!SetupDiSetClassInstallParams(hDevInfo,&spDevInfoData,(SP_CLASSINSTALL_HEADER*)&spPropChangeParams,sizeof(spPropChangeParams)))
{
DWORD errorcode=GetLastError();
}
if(!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,hDevInfo,&spDevInfoData))
{
DWORD errorcode=GetLastError();
}
switch(NewState)
{
case DICS_DISABLE :
printf(”成功禁用网络!”);
break ;
case DICS_ENABLE :
printf(”成功启用网络!”);
break ;
}
break ;
}
}
//退出时,清理工作环境
cleanup_DeviceInfo :
err=GetLastError();
SetupDiDestroyDeviceInfoList(hDevInfo);
SetLastError(err);
return true ;
}
void usage(char *exefile)
{
printf(”Usage:%s [-e|-d]\r\n”, exefile);
printf(”\t-e: Enable the network card.\r\n”);
printf(”\t-d: Disable the network card.\r\n”);
exit(0);
}
int main(int argc,char**argv)
{
if(argc<2)
usage(argv[0]);
if(!DisableNetInterface((strstr(argv[1],”-d”)>0?TRUE:FALSE)))
printf(”对网卡操作失败!”);
return 0;
}
//————————————————————————————————————
例子二:
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <setupapi.h>
#pragma comment (lib,”setupapi”)
#define UnknownDevice TEXT(”<Unknown Device>”)
HDEVINFO hDevInfo = 0;
BOOL StateChange(DWORD NewState, DWORD SelectedItem,HDEVINFO hDevInfo)
{
SP_PROPCHANGE_PARAMS PropChangeParams = {sizeof(SP_CLASSINSTALL_HEADER)};
SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
HCURSOR hCursor;
//
// This may take a while :^(
//
hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
//
// Get a handle to the Selected Item.
//
if (!SetupDiEnumDeviceInfo(hDevInfo,SelectedItem,&DeviceInfoData))
{
printf(”EnumDeviceInfo”);
return FALSE;
}
//
// Set the PropChangeParams structure.
//
PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
PropChangeParams.Scope = DICS_FLAG_GLOBAL;
PropChangeParams.StateChange = NewState;
if (!SetupDiSetClassInstallParams(hDevInfo,
&DeviceInfoData,
(SP_CLASSINSTALL_HEADER *)&PropChangeParams,
sizeof(PropChangeParams)))
{
printf(”SetClassInstallParams”);
SetCursor(hCursor);
return FALSE;
}
//
// Call the ClassInstaller and perform the change.
//
if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,
hDevInfo,
&DeviceInfoData))
{
printf(”SetClassInstallParams”);
SetCursor(hCursor);
return TRUE;
}
SetCursor(hCursor);
return TRUE;
}
BOOL IsClassNet( GUID * ClassGuid )
{
#define MAX_NUM 50
HKEY hKeyClass;
LONG lRet;
char ClassType[MAX_NUM];
char NetClass[MAX_NUM] = “Net”;
DWORD dwLength = MAX_NUM,dwType = REG_SZ;
if (hKeyClass = SetupDiOpenClassRegKey(ClassGuid,KEY_READ))
{
lRet = RegQueryValueEx(hKeyClass,
TEXT(”Class”),
NULL, &dwType, LPBYTE(ClassType), &dwLength);
RegCloseKey(hKeyClass);
if (lRet != ERROR_SUCCESS)
return FALSE;
if (!strcmp(ClassType,NetClass))
return TRUE;
}
return FALSE;
}
int main(int argc, char* argv[])
{
if (INVALID_HANDLE_VALUE == (hDevInfo =
SetupDiGetClassDevs(NULL,NULL,0,
DIGCF_PRESENT|DIGCF_ALLCLASSES)))
{
printf(”GetClassDevs”);
return 0;
}
DWORD i, Status, Problem;
SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
HKEY hKeyClass;
char DeviceName[200];
for (i=0;SetupDiEnumDeviceInfo(hDevInfo,i,&DeviceInfoData);i++)
{
if (IsClassNet(&DeviceInfoData.ClassGuid))
{
//printf(” the class’s index is %d\n”,i);
//DICS_DISABLE–>禁用网络
//DICS_ENABLE—>恢复网络
if (StateChange(DICS_ENABLE,i,hDevInfo))
printf(”.”);
//printf(”NetWork %s”, (DICS_ENABLE)?”enabled”:”disabled”);
}
}
return 0;
}
禁用网卡会造成死机,如何办?
cxy131 —— 2004年08月02日 @10:37 am
我按此方法禁用网卡,有几次会造成死机,不知为何,如何办
问题出在这一句:
if(!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,hDevInfo,&spDevInfoData))
{
DWORD errorcode=GetLastError();
}
程序死在此处,此时网卡已不能手工恢复(禁用或恢复),请解答,有避免的办法吗?
另:天网防火墙中的断开/接通网络功能是如何实现的,有VC的相应代码吗?
cxy131 —— 2004年08月02日 @10:48 am
楼上的两位,上面的程序我在WIN2000/XP/2003都测试过了,没有问题啊,
而且代码已经是最简的了,可能跟系统有点关系,我再找找资料看一下,晚点给你们答复啊。。。
zwell —— 2004年08月02日 @5:17 pm
我的操作系统windows 2000,网卡是PCI接口的,TYPE=PCI,NAME=Intel(R) PRO/1000 MT Network Connection
我猜想:问题可能是网卡正忙,此时不允许禁用,就象断开U盘时有时会提示"….正忙,稍后再断开…"一样,
但问题是:如何得知网卡正忙?,是否允许禁用?
手工禁用网卡(网上邻居->属性->网络和拨号连接->本地连接->属性->禁用或恢复),有时同样会出现网卡"死掉"现象,
cxy —— 2004年08月03日 @3:38 pm
我找了一些资料,你用这个试试看可以不:
// Hardware.cpp : Implementation of CHardware
#include "stdafx.h"
#include "NetCA_HARDWARE.h"
#include "Hardware.h"
#define UnknownDevice TEXT("<Unknown Device>")
/////////////////////////////////////////////////////////////////////////////
// CHardware
/*****************禁用设备********************************
参数说明: DriverID[in]–设备在注册表中的唯一标识
pVal[out,retval]–返回值,成功为0,失败为1
创建时间: 2002-6-21
**********************************************************/
STDMETHODIMP CHardware::Disable(BSTR DriverID, long *pVal)
{
BOOL ShowHidden = 0;
HDEVINFO hDevInfo = 0;
long len;
//init the value
TIndex = -1;
len = wcstombs(NULL,DriverID,wcslen(DriverID));
len = len + 1;
DrvID = (char *)malloc(len);
memset(DrvID,0,len+1);
wcstombs(DrvID,DriverID,wcslen(DriverID));
if (INVALID_HANDLE_VALUE == (hDevInfo =
SetupDiGetClassDevs(NULL,NULL,NULL,
DIGCF_PRESENT|DIGCF_ALLCLASSES)))
{
*pVal = -1;
return S_OK;
}
//get the index of drv in the set
EnumAddDevices(ShowHidden,hDevInfo);
//disable the drv
// if ((IsDisableable(TIndex,hDevInfo))&&(!(TIndex==-1)))
if (!IsDisabled(TIndex,hDevInfo))
if (IsDisableable(TIndex,hDevInfo))
if (StateChange(DICS_DISABLE,TIndex,hDevInfo))
*pVal = 0;
else
*pVal = -1;
else
*pVal = 1;
else
*pVal = 0;
if(hDevInfo)
SetupDiDestroyDeviceInfoList(hDevInfo);
return S_OK;
}
BOOL CHardware::EnumAddDevices(BOOL ShowHidden, HDEVINFO hDevInfo)
{
DWORD i, Status, Problem;
LPTSTR IOName=NULL;
DWORD len=0;
SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
//
// Enumerate though all the devices.
//
for (i=0;SetupDiEnumDeviceInfo(hDevInfo,i,&DeviceInfoData);i++)
{
//
// Should we display this device, or move onto the next one.
//
if (CR_SUCCESS != CM_Get_DevNode_Status(&Status, &Problem,
DeviceInfoData.DevInst,0))
{
continue;
}
if (!(ShowHidden || !((Status & DN_NO_SHOW_IN_DM) ||
IsClassHidden(&DeviceInfoData.ClassGuid))))
continue;
//
// Get a friendly name for the device.
//
ConstructDeviceName(hDevInfo,&DeviceInfoData,
&IOName,
(PULONG)&len);
if (strcmp(IOName,DrvID) == 0)
{
TIndex = i;
return TRUE;
}
}
return TRUE;
}
×××××××××××××××××××××××××××××
BOOL CHardware::IsClassHidden(GUID *ClassGuid)
{
BOOL bHidden = FALSE;
HKEY hKeyClass;
//
// If the devices class has the NoDisplayClass value then
// don’t display this device.
//
if (hKeyClass = SetupDiOpenClassRegKey(ClassGuid,KEY_READ))
{
bHidden = (RegQueryValueEx(hKeyClass,
REGSTR_VAL_NODISPLAYCLASS,
NULL, NULL, NULL, NULL) == ERROR_SUCCESS);
RegCloseKey(hKeyClass);
}
return bHidden;
}
BOOL CHardware::ConstructDeviceName(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PVOID Buffer, PULONG Length)
{
if (!GetRegistryProperty(DeviceInfoSet,
DeviceInfoData,
SPDRP_DRIVER ,
Buffer,
Length))
{
if (!GetRegistryProperty(DeviceInfoSet,
DeviceInfoData,
SPDRP_DEVICEDESC ,
Buffer,
Length))
{
if (!GetRegistryProperty(DeviceInfoSet,
DeviceInfoData,
SPDRP_CLASS ,
Buffer,
Length))
{
if (!GetRegistryProperty(DeviceInfoSet,
DeviceInfoData,
SPDRP_CLASSGUID ,
Buffer,
Length))
{
*Length = (_tcslen(UnknownDevice)+1)*sizeof(TCHAR);
Buffer =(char *)malloc(*Length);
_tcscpy(*(LPTSTR *)Buffer,UnknownDevice);
}
}
}
}
return TRUE;
}
BOOL CHardware::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)
{
//
// We need to change the buffer size.
//
if (*(LPTSTR *)Buffer)
LocalFree(*(LPTSTR *)Buffer);
*(LPTSTR *)Buffer = (PCHAR)LocalAlloc(LPTR,*Length);
}
else
{
//
// Unknown Failure.
//
return FALSE;
}
}
return (*(LPTSTR *)Buffer)[0];
}
BOOL CHardware::StateChange(DWORD NewState, DWORD SelectedItem, HDEVINFO hDevInfo)
{
SP_PROPCHANGE_PARAMS PropChangeParams = {sizeof(SP_CLASSINSTALL_HEADER)};
SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
//
// Get a handle to the Selected Item.
//
if (!SetupDiEnumDeviceInfo(hDevInfo,SelectedItem,&DeviceInfoData))
{
return FALSE;
}
//
// Set the PropChangeParams structure.
//
PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
PropChangeParams.Scope = DICS_FLAG_GLOBAL;
PropChangeParams.StateChange = NewState;
if (!SetupDiSetClassInstallParams(hDevInfo,
&DeviceInfoData,
(SP_CLASSINSTALL_HEADER *)&PropChangeParams,
sizeof(PropChangeParams)))
{
return FALSE;
}
//
// Call the ClassInstaller and perform the change.
//
if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,
hDevInfo,
&DeviceInfoData))
{
return TRUE;
}
return TRUE;
}
BOOL CHardware::IsDisabled(DWORD SelectedItem, HDEVINFO hDevInfo)
{
SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
DWORD Status, Problem;
//
// Get a handle to the Selected Item.
//
if (!SetupDiEnumDeviceInfo(hDevInfo,SelectedItem,&DeviceInfoData))
{
return FALSE;
}
if (CR_SUCCESS != CM_Get_DevNode_Status(&Status, &Problem,
DeviceInfoData.DevInst,0))
{
return FALSE;
}
return ((Status & DN_HAS_PROBLEM) && (CM_PROB_DISABLED == Problem)) ;
}
BOOL CHardware::IsDisableable(DWORD SelectedItem, HDEVINFO hDevInfo)
{
SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)};
DWORD Status, Problem;
//
// Get a handle to the Selected Item.
//
if (!SetupDiEnumDeviceInfo(hDevInfo,SelectedItem,&DeviceInfoData))
{
return FALSE;
}
if (CR_SUCCESS != CM_Get_DevNode_Status(&Status, &Problem,
DeviceInfoData.DevInst,0))
{
return FALSE;
}
return ((Status & DN_DISABLEABLE) &&
(CM_PROB_HARDWARE_DISABLED != Problem));
}
STDMETHODIMP CHardware::Enable(BSTR DriverID, long *pVal)
{
BOOL ShowHidden = 0;
HDEVINFO hDevInfo = 0;
long len;
//init the value
TIndex = -1;
len = wcstombs(NULL,DriverID,wcslen(DriverID));
len = len + 1;
DrvID = (char *)malloc(len);
memset(DrvID,0,len+1);
wcstombs(DrvID,DriverID,wcslen(DriverID));
if (INVALID_HANDLE_VALUE == (hDevInfo =
SetupDiGetClassDevs(NULL,NULL,NULL,
DIGCF_PRESENT|DIGCF_ALLCLASSES)))
{
*pVal = -1;
return S_OK;
}
//get the index of drv in the set
EnumAddDevices(ShowHidden,hDevInfo);
//disable the drv
if (IsDisabled(TIndex,hDevInfo))
if (StateChange(DICS_ENABLE,TIndex,hDevInfo))
*pVal = 0;
else
*pVal = -1;
else
*pVal = 0;
if(hDevInfo)
SetupDiDestroyDeviceInfoList(hDevInfo);
return S_OK;
}
××××××××××××××××××××××××××××××××××××
zwell —— 2004年08月05日 @11:11 am
哦,忘记说了,我在上面增加了一个,不知道你看了没有,
上面的两个我都测试过了,没问题的.
到上面找"例子二:"就是的了.
zwell —— 2004年08月06日 @10:06 am
这些我也试过,还是不行,
BOOL CHardware::IsDisableable(DWORD SelectedItem, HDEVINFO hDevInfo)
{
}
函数本是检测是否允许禁用网卡的,但实际并不起作用
cxy —— 2004年08月06日 @8:19 am
这些我也试过,还是不行,
BOOL CHardware::IsDisableable(DWORD SelectedItem, HDEVINFO hDevInfo)
{
}
函数本是检测是否允许禁用网卡的,但实际并不起作用
cxy —— 2004年08月06日 @8:19 am
windows 2000 server 下禁用网卡造成网卡不能恢复确实时有发生,如安装了"上网助手",则每次不能恢复,
我一直想不明白为何?请指教!
cxy —— 2004年08月31日 @8:49 am
还有,如果我先是手动禁止网卡的,用上面的程序则无法再启用,谢谢能回复!非常谢谢!
QQ:411272242
liyuan —— 2004年09月21日 @9:52 am
我想知道手动禁止时,系统是怎么处理的?为什么手动禁止后,用上面的程序无法再启用呢?
wangsheng —— 2004年10月21日 @1:28 pm
还有用程序禁止后,手动启动不了?
为什么?
cons —— 2004年10月31日 @10:54 am
Thanks for your source code![:-)](http://blog.donews.com/zwell/wp-includes/images/smilies/icon_smile.gif)
Matt —— 2006年03月09日 @5:20 am
不行样。。。。
匿名 —— 2007年06月16日 @7:18 pm
为什么例子二在VC2005中编译后release后只有一个7k的exe,能运行,但是无法实现功能。
而在VC6中没有问题。
同一环境中测试的。
请指点,谢谢。
skight —— 2008年04月04日 @4:34 pm