您的位置:逆风者 VC++ 正文
 添加时间:2007-09-01 原文发表:2007-08-31 人气:156 来源:vckbase.com

本文章共3036字,分2页,当前第1页,快速翻页:
 

不重起Windows直接更改IP地址
作者:浙江省温岭电信局 王骏

注:本文适用于WINDOWS NT/2000/XP/2003

下载本文示例工程
逆风者

源代码运行效果图如下:


设置IP地址只需要更改注册表中关于适配器的相应设置,但更改后需要重新启动系统才能生效,而AddIPAddress函数只能添加IP而不是更改当前的IP,我们在Windows NT/2000界面上操作不需要重新启动就可以生效,那系统到底做了什么额外的工作才使IP设置直接生效呢?笔者通过跟踪explorer.exe中API的调用发现在netcfgx.dll中调用了dhcpcsvc.dll中一个未公开的API:DhcpNotifyConfigChange,现将不重新启动WINDOWS直接更改IP地址的详细方法介绍如下:

一、获取适配器名称

这里指的适配器名称要区别于适配器描述,比如我的一块网卡,适配器描述是:Realtek RTL8139(A) PCI Fast Ethernet Adapter,适配器名称为:{66156DC3-44A4-434C-B8A9-0E5DB4B3EEAD}。获取适配器名称的方法有多种:

1.1 调用IP helper API取得适配器名称

ULONG ulAdapterInfoSize = sizeof(IP_ADAPTER_INFO);

IP_ADAPTER_INFO *pAdapterInfoBkp, *pAdapterInfo = (IP_ADAPTER_INFO*)new char[ulAdapterInfoSize];

if( GetAdaptersInfo(pAdapterInfo, &ulAdapterInfoSize) == ERROR_BUFFER_OVERFLOW ) // 缓冲区不够大

{

	delete pAdapterInfo;

	pAdapterInfo = (IP_ADAPTER_INFO*)new char[ulAdapterInfoSize];

	pAdapterInfoBkp = pAdapterInfo;

}

if( GetAdaptersInfo(pAdapterInfo, &ulAdapterInfoSize) == ERROR_SUCCESS )

{

	do{ // 遍历所有适配器

		if(pAdapterInfo->Type == MIB_IF_TYPE_ETHERNET)	// 判断是否为以太网接口

		{

			// pAdapterInfo->Description 是适配器描述

			// pAdapterInfo->AdapterName 是适配器名称

		}

		pAdapterInfo = pAdapterInfo->Next;

	}while(pAdapterInfo);

}

delete pAdapterInfoBkp;
1.2 读取注册表取得适配器名称

在Windows2000中可以通过遍历 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Class\{4d36e972-e325-11ce-bfc1-08002be10318}\000n\ (n是从0开始编号的数字)所有接口, 在Windows NT中可以读取HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards中的信息,下面以Windows2000为例:
HKEY hKey, hSubKey, hNdiIntKey;



if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,

			"System\\CurrentControlSet\\Control\\Class\\{4d36e972-e325-11ce-bfc1-08002be10318}",

			0,

			KEY_READ,

			&hKey) != ERROR_SUCCESS)

	return FALSE;



DWORD dwIndex = 0;

DWORD dwBufSize = 256;

DWORD dwDataType;

char szSubKey[256];

unsigned char szData[256];



while(RegEnumKeyEx(hKey, dwIndex  , szSubKey, &dwBufSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)

{

	if(RegOpenKeyEx(hKey, szSubKey, 0, KEY_READ, &hSubKey) == ERROR_SUCCESS)

	{		

		if(RegOpenKeyEx(hSubKey, "Ndi\\Interfaces", 0, KEY_READ, &hNdiIntKey) == ERROR_SUCCESS)

		{

			dwBufSize = 256;

			if(RegQueryValueEx(hNdiIntKey, "LowerRange", 0, &dwDataType, szData, &dwBufSize) == ERROR_SUCCESS)

			{

				if(strcmp((char*)szData, "ethernet") == 0)		//	判断是不是以太网卡

				{

					dwBufSize = 256;

					if(RegQueryValueEx(hSubKey, "DriverDesc", 0, &dwDataType, szData, &dwBufSize) == ERROR_SUCCESS)

					{

						// szData 中便是适配器详细描述

						dwBufSize = 256;

						if(RegQueryValueEx(hSubKey, "NetCfgInstanceID", 0, &dwDataType, szData, &dwBufSize) == ERROR_SUCCESS)

						{

							// szData 中便是适配器名称

						}

					}

				}

			}

			RegCloseKey(hNdiIntKey);

		}

		RegCloseKey(hSubKey);

	}



	dwBufSize = 256;

}	/* end of while */

		

RegCloseKey(hKey); 
 
本文章更多内容1 - 2 - 下一页>>
相关文章

类似于FlashGet的悬浮框的制作
毫秒定时器
C :使用 Visual C 2005 的现代语言特色
IP Messenger 详细分析
可设置单元格颜色的ClistCtrl类
利用VC++开发ASP图像处理组件(二)
从 ADO 迁移到 ADO.NET(一)
获得 Win32 窗口句柄的更好的方法
关于 IDispatch 接口的 LPDispatch 属性的实
用ATL开发复合控件
MFC程序员的WTL指南: 中文版序言
COM 组件设计与应用(五)——用 ATL 写第一
编写多文档应用程序
PhotoShop插件开发之选区(Selection)
VC初学者入门系列之二:消息循环
定制调试诊断工具和实用程序——摆脱DLL“地
WMI 的一个实现
自绘按钮的实现
《系统飞狐》系列软件中的“系统监视器”开
定时显示远程计算机的桌面

相关评论


本文章所属分类:首页 VC++

  热门关键字: