您的位置:首页 > 理论基础 > 计算机网络

用代码实现"停用/启用"网络连接

2007-04-04 17:46 651 查看
代码如下:

BOOL NetConnect(BOOL bConnect)
{
CoInitialize(NULL) ;

BOOL bReturn = FALSE ;
HRESULT hr ;
CComPtr<IShellDispatch> spShell ;

// search "Shell Object" in MSDN
hr = spShell.CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER) ;

if (hr==S_OK)
{
CComPtr<Folder> spFolder ;
CComVariant varDir(49) ;

spShell->NameSpace( varDir , &spFolder ) ;

if (spFolder)
{
CComPtr<FolderItems> spFolderItems ;

spFolder->Items(&spFolderItems) ;

if (spFolderItems)
{
long length = 0;

hr = spFolderItems->get_Count(&length) ;

for (int i=0; i<length; i++)
{
CComVariant var (i);
CComPtr<FolderItem> spFolderItem ;

spFolderItems->Item(var, &spFolderItem ) ;

if (spFolderItem)
{
CComBSTR bstr ;

spFolderItem->get_Name(&bstr) ;

// 遍历网络连接
// 要考虑系统版本的问题
if (wcsncmp( bstr, L"本地连接", 4)==0)
{
CComPtr<FolderItemVerbs> spFolderItemVerbs ;

spFolderItem->Verbs(&spFolderItemVerbs) ;

if (spFolderItemVerbs)
{
// 遍历菜单项
long iMenu = 0 ;
hr = spFolderItemVerbs->get_Count(&iMenu) ;

for (int m=0; m<iMenu; m++)
{
CComVariant var (m) ;
CComPtr<FolderItemVerb> spFolderItemVerb;

spFolderItemVerbs->Item(var, &spFolderItemVerb ) ;

if (spFolderItemVerb)
{
CComBSTR bstrMenuName ;
LPWSTR pwzMenuName = bConnect ? L"启用":L"停用" ;
spFolderItemVerb->get_Name(&bstrMenuName) ;

if (wcsncmp(bstrMenuName, pwzMenuName , 2)==0)
{
// 执行菜单命令
bReturn = spFolderItemVerb->DoIt()==S_OK ;
}
}
}
}

}
}
}

}
}
}

CoUninitialize();

return bReturn ;
}

以上代码在 xp sp2+vc6+200408-psdk 测试通过 。

此方法并不是我想出来的,而是在CSDN论坛上的VB版块找到的一段VB代码翻译过来的。由这个举一反三,可以实现更多的功能。代码还是有缺陷的, 程序通过名称来寻找要执行的命令,因此不能在所有语言的平台上兼容。还有,有效连接可能不一定叫“本地连接”,另外不能在98下使用。

另外附上用SetupAPI实现的代码,这种方式更具有通用性,推荐使用。

#include <SetupAPI.h>
#include <cfgmgr32.h> // cfgmgr32.h 在Microsoft Windows 2000 DDK 中.
#pragma comment(lib,"setupapi.lib")

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));
}

int main(int argc, char* argv[])
{
EnumNetCards() ;
return 0 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐