不得不再提关于禁用网卡的问题

ha123 2005-04-20 02:08:37
在google以及csdn上搜索了一下关于网卡禁用的程序,发现所示用的方法都一样,都是使用SetupAPI相关函数,本人也用同样方法写了一个程序,但是发现一个问题(在2k以及XP下都有),使用程序启用和禁用网卡都很正常,但如果是手工禁用网卡(在设备管理器中选择网卡,并停用),则无法用程序启用,而程序却报告启用成功,事实上此时网卡无法使用。本人登陆OS是Administrator身份。现将程序贴上,希望大家指点迷津。
#include <windows.h>
#include <SetupAPI.h>
#include <stdio.h>
#include <tchar.h>

#pragma comment(lib,"setupapi.lib")

DWORD CtrlNetcard(BOOL bStatus);

void _tmain(int arg, TCHAR** argv)
{
BOOL b = FALSE;
DWORD err = 0;
if(2 == arg)
{
argv++;
if(!_tcsicmp(TEXT("enable"), *argv))
{
b = TRUE;
err = CtrlNetcard(TRUE);
}
else if(!_tcsicmp(TEXT("disable"), *argv))
{
b = FALSE;
err = CtrlNetcard(FALSE);
}
else
{
goto main_end;
}

_tprintf("\n%s NetAdapter %s !\n",
b ? TEXT("Enable") : TEXT("Disable"),
err ? TEXT("fail") : TEXT("success"));
return;

}
main_end:
_tprintf(TEXT("\nenable NetCard: enable"));
_tprintf(TEXT("\ndisable NetCard: disable\n"));

}

DWORD CtrlNetcard(BOOL bStatus)
{
LPCTSTR HardwareId = TEXT("{4D36E972-E325-11CE-BFC1-08002BE10318}");
GUID g = {0X4D36E972, 0XE325, 0X11CE, {0XBF, 0XC1, 0X08, 0X00, 0X2B, 0XE1, 0X03, 0X18}};
DWORD NewState = 0;
//调用ddk函数,来禁用网卡
DWORD i = 0, err = 0;

HDEVINFO hDevInfo = NULL;
SP_DEVINFO_DATA spDevInfoData = {0};

NewState = bStatus ? DICS_ENABLE : DICS_DISABLE;

//访问系统的硬件库
hDevInfo = SetupDiGetClassDevs(NULL, TEXT("PCI"), NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);
if(INVALID_HANDLE_VALUE == hDevInfo)
{
_tprintf(TEXT("访问系统硬件出错!"));
return GetLastError();
}

//枚举硬件,获得需要的接口
spDevInfoData.cbSize=sizeof(SP_DEVINFO_DATA);
memcmp(&(spDevInfoData.ClassGuid), &g, sizeof(GUID));

for(i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &spDevInfoData); i++)
{

PBYTE PropertyBuffer = NULL;
DWORD PropertyBufferSize = 0;

//获得硬件的属性值

while(!SetupDiGetDeviceRegistryProperty(
hDevInfo,
&spDevInfoData,
SPDRP_CLASSGUID,
NULL,
PropertyBuffer,
PropertyBufferSize,
&PropertyBufferSize))
{
if(ERROR_INSUFFICIENT_BUFFER == GetLastError())
{
if(PropertyBuffer)
{
free(PropertyBuffer);
}
PropertyBuffer = (PBYTE)malloc(PropertyBufferSize);
}
else
{
break;
}
}

if(!PropertyBuffer)
{
continue;
}

if(!_tcsicmp(HardwareId, (LPTSTR)PropertyBuffer))
{
SP_PROPCHANGE_PARAMS spPropChangeParams ;

free(PropertyBuffer);

spPropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
spPropChangeParams.ClassInstallHeader.InstallFunction=DIF_PROPERTYCHANGE;
spPropChangeParams.Scope = DICS_FLAG_GLOBAL;
spPropChangeParams.StateChange = NewState;

if(!SetupDiSetClassInstallParams(hDevInfo,&spDevInfoData,(SP_CLASSINSTALL_HEADER*)&spPropChangeParams,sizeof(spPropChangeParams)))
{
err = GetLastError();
goto cleanup_DeviceInfo;
}

if(!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,hDevInfo,&spDevInfoData))
{
err = GetLastError();
goto cleanup_DeviceInfo;
}

}
else
{
free(PropertyBuffer);
}

}

cleanup_DeviceInfo :

SetupDiDestroyDeviceInfoList(hDevInfo);

return err;
}
...全文
1032 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
dzq138 2005-06-15
  • 打赏
  • 举报
回复
..
柯本 2005-04-21
  • 打赏
  • 举报
回复
我查了一下,0x800704D5错误为
//
// MessageId: ERROR_RETRY
//
// MessageText:
//
// The operation could not be completed. A retry should be performed.
//
估计目的是充许重试,不用exit退出,在此应该没用(程序没有retry)
柯本 2005-04-21
  • 打赏
  • 举报
回复
1.

CLSID_ConnectionManager
{ 0xBA126AD1, 0x2166, 0x11D1, { 0xB1, 0xD0, 0x0, 0x80, 0x5F, 0xC1, 0x27, 0xE } }

IID_INetConnectionConnectUi
{ 0xC08956A3, 0x1CD3, 0x11D1, { 0xB1, 0xC5, 0x0, 0x80, 0x5F, 0xC1, 0x27, 0xE } }

IID_INetConnectionManager
{ 0xC08956A2, 0x1CD3, 0x11D1, { 0xB1, 0xC5, 0x0, 0x80, 0x5F, 0xC1, 0x27, 0xE } }

2.
我是在网上找来的,没细细研究过

3.
VC 编译需 windows 2000 SDK
我的在ntsdk下,编译命令
cl -I\ntsdk\include tn1.cpp \ntsdk\lib\ole32.lib \ntsdk\lib\uuid.lib
ha123 2005-04-21
  • 打赏
  • 举报
回复
to keiy
我有两个问题
1.
CLSID_ConnectionManager
IID_INetConnectionConnectUi
IID_INetConnectionManager
这三个GUID号是多少?

2.在CheckHR中
为什么要做 hr != 0x800704D5 这个判断?
柯本 2005-04-20
  • 打赏
  • 举报
回复


swprintf(ifname,L"%S",argv[1]); //Copy the interface name "Local Area Connection"
为 MultiByteToWideChar(CP_ACP,0,argv[1],-1,ifname,100);
通过


tn1 本地连接 4 0 禁用
tn1 本地连接 4 1 启用
手工停的也能启
柯本 2005-04-20
  • 打赏
  • 举报
回复
我的到另一方法,正在试:
#define _WIN32_WINNT 0x0502

#include <windows.h>
#include <stdio.h>
#include <objbase.h>
#include <netcon.h>

//Check the HRESULT of COM calls and exit on ERROR
#define CheckHR(info) \
{ \
HRESULT hr = (info); \
if(FAILED(hr)) \
{ \
if ( hr != 0x800704D5 ) \
{ \
printf("ERROR HR"); \
exit(1); \
} \
}\
}


typedef enum
{
DISABLE = 0, //Disable the Network Connection
ENABLE = 1, //Enable the Network Connection
PORT_STATUS = 2, //Get the Network Port Status Command
LINK_STATUS = 3, //Get the Network Link Status Command
ENDIS_PORT = 4 //Disable/Enable Network Connection Command
}PORTSTATUS;



void main(int argc, char** argv)
{
INetConnectionManager* pManager;
INetConnection* pConnection;
IEnumNetConnection* pEnum;
INetConnectionConnectUi* pConnectionUI;

ULONG celtFetched;

BOOL bFoundInterface = FALSE;
int nPortStatus = -1;
int nCmd = -1;
wchar_t ifname[100];


if (argc <= 2 )
{
printf("ERROR1");
return;
}

swprintf(ifname,L"%S",argv[1]); //Copy the interface name "Local Area Connection"
nCmd = atoi(argv[2]); //Copy the Command
if ( argc == 4 )
{
nPortStatus = ( argv[3][0] == '1' ) ? 1:0 ; //Copy the Status to be Set
}


//Initialize COM
CheckHR( CoInitialize(NULL) );
//Get an Instance of INetConnectionManager
CheckHR( CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER, IID_INetConnectionManager, (void**)&pManager) );
//Enumerate the Network Connections
CheckHR( pManager->EnumConnections(NCME_DEFAULT, &pEnum) );
//Release the InetConnectionManager
pManager->Release();

while( pEnum->Next(1, &pConnection, &celtFetched) == S_OK )
{
NETCON_PROPERTIES* properties;
//Get the properties of a Network Connection
CheckHR( pConnection->GetProperties(&properties) );
//Check the Interface Name
if ( (wcscmp(properties->pszwName,ifname)) == 0 )
{
bFoundInterface = TRUE;
switch(nCmd)
{
case PORT_STATUS:
case LINK_STATUS:
{
switch(properties->Status)
{
case NCS_DISCONNECTED:
case NCS_DISCONNECTING:
case NCS_HARDWARE_NOT_PRESENT:
case NCS_HARDWARE_DISABLED:
case NCS_HARDWARE_MALFUNCTION:
case NCS_AUTHENTICATION_FAILED:
case NCS_INVALID_ADDRESS:
case NCS_CREDENTIALS_REQUIRED:
printf("Port is not Functioning");
break;
case NCS_CONNECTED:
{
if ( nCmd == PORT_STATUS )
printf("Port is UP");
else
printf("Link is UP");
}
break;
case NCS_MEDIA_DISCONNECTED:
printf("MEDIADISCONNECTED");
break;
default:
printf("ERROR2");
break;
}
}
break;
case ENDIS_PORT:
{
switch(nPortStatus)
{
case DISABLE:
{
if(SUCCEEDED(pConnection->QueryInterface(IID_INetConnectionConnectUi, (void**)pConnectionUI)))
{
pConnectionUI->SetConnection(pConnection);
pConnectionUI->Disconnect(NULL, NCUC_NO_UI);
pConnectionUI->Release();
}
else
{
CheckHR( pConnection->Disconnect() );
}
}
break;
case ENABLE:
{
if(SUCCEEDED(pConnection->QueryInterface(IID_INetConnectionConnectUi, (void**)pConnectionUI)))
{
pConnectionUI->SetConnection(pConnection);
pConnectionUI->Connect(NULL, NCUC_NO_UI);
pConnectionUI->Release();
}
else
{
CheckHR( pConnection->Connect() );
}
}
break;
default:
printf("ERROR 3");
break;
}
}
break;
default:
printf("ERROR 4");
break;
}
CoTaskMemFree(properties);
pConnection->Release();
break;
}
else
{
CoTaskMemFree(properties);
pConnection->Release();
continue;
}
}
if ( !bFoundInterface )
printf("ERROR 5");

pEnum->Release();
CoUninitialize();
}

2,643

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧