xp设置IP不重启(静态+动态)

本文是通过禁用启用网卡让IP设置生效,因为使用DhcpNotifyConfigChange方法效果不好,且容易发生溢出问题

typedef int (CALLBACK* DHCPNOTIFYPROC)(LPWSTR, LPWSTR, BOOL, DWORD, DWORD, DWORD, int);

typedef struct tagAdapterInfo
{
string strName;// 适配器名称
string strDriverDesc;// 适配器描述
string strIP; // IP地址
string strNetMask;// 子网掩码
string strNetGate;// 网关
}ADAPTER_INFO;

BOOL GetAdapterInfo();
BOOL RegGetIP(ADAPTER_INFO *pAI, LPCTSTR lpszAdapterName, int nIndex = 0);

vector<ADAPTER_INFO*> AdapterInfoVector;


//-----------------------------------------------------------------
// 取得所有网卡信息
//-----------------------------------------------------------------
BOOL GetAdapterInfo()
{
// 这里的代码适合WINDOWS2000,对于NT需要读取HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards
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)
{
ADAPTER_INFO *pAI = new ADAPTER_INFO;
pAI->strDriverDesc = (LPCTSTR)szData;
dwBufSize = 256;
if(RegQueryValueEx(hSubKey, "NetCfgInstanceID", 0, &dwDataType, szData, &dwBufSize) == ERROR_SUCCESS)
{
pAI->strName = (LPCTSTR)szData;
RegGetIP(pAI, (LPCTSTR)szData);
}
AdapterInfoVector.push_back(pAI);// 加入到容器中
}
}
}
RegCloseKey(hNdiIntKey);
}
RegCloseKey(hSubKey);
}

dwBufSize = 256;
} /* end of while */

RegCloseKey(hKey);

return TRUE;
}


//-----------------------------------------------------------------
// 得到注册表中的IP信息
// nIndex暂时未处理
//-----------------------------------------------------------------

BOOL RegGetIP(ADAPTER_INFO *pAI, LPCTSTR lpszAdapterName, int nIndex/* =0 */)
{
ASSERT(pAI);

HKEY hKey;
string strKeyName = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\";
strKeyName += lpszAdapterName;
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
strKeyName.c_str(),
0,
KEY_READ,
&hKey) != ERROR_SUCCESS)
return FALSE;


unsigned char szData[256];
DWORD dwDataType, dwBufSize;


dwBufSize = 256;
if(RegQueryValueEx(hKey, "IPAddress", 0, &dwDataType, szData, &dwBufSize) == ERROR_SUCCESS)
pAI->strIP = (LPCTSTR)szData;


dwBufSize = 256;
if(RegQueryValueEx(hKey, "SubnetMask", 0, &dwDataType, szData, &dwBufSize) == ERROR_SUCCESS)
pAI->strNetMask = (LPCTSTR)szData;


dwBufSize = 256;
if(RegQueryValueEx(hKey, "DefaultGateway", 0, &dwDataType, szData, &dwBufSize) == ERROR_SUCCESS)
pAI->strNetGate = (LPCTSTR)szData;


RegCloseKey(hKey);
return TRUE;
}


//-----------------------------------------------------------------
// 设置注册表中的IP信息
//-----------------------------------------------------------------
BOOL RegSetIP(LPCTSTR lpszAdapterName, int nIndex, LPCTSTR pIPAddress, LPCTSTR pNetMask, LPCTSTR pNetGate,LPCTSTR pDnsAddress)
{
HKEY hKey;
string strKeyName = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\";
strKeyName += lpszAdapterName;
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
strKeyName.c_str(),
0,
KEY_WRITE,
&hKey) != ERROR_SUCCESS)
return FALSE;


char mszIPAddress[100];
char mszNetMask[100];
char mszNetGate[100];
char szDnsAddr[100];

strncpy(mszIPAddress, pIPAddress, 98);
strncpy(mszNetMask, pNetMask, 98);
strncpy(mszNetGate, pNetGate, 98);
strncpy(szDnsAddr, pDnsAddress, 98);


int nIP, nMask, nGate,nDnsAddr;
int enableDHCP=0;


nIP = strlen(mszIPAddress);
nMask = strlen(mszNetMask);
nGate = strlen(mszNetGate);
nDnsAddr = strlen(szDnsAddr);


*(mszIPAddress + nIP + 1) = 0x00;
nIP += 2;


*(mszNetMask + nMask + 1) = 0x00;
nMask += 2;


*(mszNetGate + nGate + 1) = 0x00;
nGate += 2;


*(szDnsAddr + nDnsAddr + 1) = 0x00;
nDnsAddr += 2;


RegSetValueEx(hKey, "IPAddress", 0, REG_MULTI_SZ, (unsigned char*)mszIPAddress, nIP);
RegSetValueEx(hKey, "SubnetMask", 0, REG_MULTI_SZ, (unsigned char*)mszNetMask, nMask);
RegSetValueEx(hKey, "DefaultGateway", 0, REG_MULTI_SZ, (unsigned char*)mszNetGate, nGate);
RegSetValueEx(hKey, "NameServer", 0, REG_SZ, (unsigned char*)szDnsAddr, nDnsAddr);

RegSetValueEx(hKey, "EnableDHCP", 0, REG_DWORD, (unsigned char*)&enableDHCP, sizeof(DWORD) );


RegCloseKey(hKey);


return TRUE;
}


//-----------------------------------------------------------------
// 设置注册表中DHCP
//-----------------------------------------------------------------
BOOL RegSetDHCPIP(LPCTSTR lpszAdapterName, int nIndex)
{
HKEY hKey;
string strKeyName = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\";
strKeyName += lpszAdapterName;
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
strKeyName.c_str(),
0,
KEY_WRITE,
&hKey) != ERROR_SUCCESS)
return FALSE;

int enableDHCP=1;
char mszIPAddress[100];
char mszNetMask[100];
char mszNetGate[100];
char szDnsAddr[100];


strncpy(mszIPAddress, "0.0.0.0", 98);
strncpy(mszNetMask, "0.0.0.0", 98);
strncpy(mszNetGate, "", 98);
strncpy(szDnsAddr, "", 98);


int nIP, nMask, nGate,nDnsAddr;


nIP = strlen(mszIPAddress);
nMask = strlen(mszNetMask);
nGate = strlen(mszNetGate);
nDnsAddr=strlen(szDnsAddr);


*(mszIPAddress + nIP + 1) = 0x00;
nIP += 2;


*(mszNetMask + nMask + 1) = 0x00;
nMask += 2;


*(mszNetGate + nGate + 1) = 0x00;
nGate += 2;


*(szDnsAddr + nDnsAddr + 1) = 0x00;
nDnsAddr += 2;


RegSetValueEx(hKey, "IPAddress", 0, REG_MULTI_SZ, (unsigned char*)mszIPAddress, nIP);
RegSetValueEx(hKey, "SubnetMask", 0, REG_MULTI_SZ, (unsigned char*)mszNetMask, nMask);
RegSetValueEx(hKey, "DefaultGateway", 0, REG_MULTI_SZ, (unsigned char*)mszNetGate, nGate);
RegSetValueEx(hKey, "NameServer", 0, REG_SZ, (unsigned char*)szDnsAddr, nDnsAddr);


int errCode = RegSetValueEx(hKey, "EnableDHCP", 0, REG_DWORD, (unsigned char*)&enableDHCP, sizeof(DWORD) );

RegCloseKey(hKey);
return TRUE;
}


//-----------------------------------------------------------------
// 通知IP地址的改变
//-----------------------------------------------------------------

BOOL NotifyIPChange(LPCTSTR lpszAdapterName, int nIndex, LPCTSTR pIPAddress, LPCTSTR pNetMask)
{
BOOL bResult = FALSE;
HINSTANCE hDhcpDll;
DHCPNOTIFYPROCpDhcpNotifyProc;
WCHAR wcAdapterName[256];


MultiByteToWideChar(CP_ACP, 0, lpszAdapterName, -1, wcAdapterName,256);


if((hDhcpDll = LoadLibrary("dhcpcsvc")) == NULL)
return FALSE;


if((pDhcpNotifyProc = (DHCPNOTIFYPROC)GetProcAddress(hDhcpDll, "DhcpNotifyConfigChange")) != NULL)
if((pDhcpNotifyProc)(NULL, wcAdapterName, TRUE, nIndex, NULL,NULL, 0) == ERROR_SUCCESS)
bResult = TRUE;


FreeLibrary(hDhcpDll);
return bResult;
}
 
//-----------------------------------------------------------------
//	设置IP地址
//	如果只绑定一个IP,nIndex = 0,暂时未处理一个网卡绑定多个地址
//-----------------------------------------------------------------
BOOL SetIP(LPCTSTR lpszAdapterName, int nIndex, LPCTSTR pIPAddress, LPCTSTR pNetMask, LPCTSTR pNetGate,LPCTSTR pDnsAddress)
{
	if(!RegSetIP(lpszAdapterName, nIndex, pIPAddress, pNetMask, pNetGate,pDnsAddress))
		return FALSE;


	//通知IP地址的改变(此方法会造成栈溢出问题,而且对于设置dhcp的立即生效没有作用,故舍弃)
	//if(!NotifyIPChange(lpszAdapterName, nIndex, pIPAddress, pNetMask))
	//	return FALSE;


	//通过禁用启用网卡实现IP立即生效
	list<TNetCardStruct> cardList;
	EnumNetCards(&cardList);
	if(!cardList.empty())
	{
		NetCardStateChange(&cardList.front(),FALSE);
		Sleep(10);
		NetCardStateChange(&cardList.front(),TRUE);
	}


	return TRUE;
}


//-----------------------------------------------------------------
//	设置DHCP IP地址
//-----------------------------------------------------------------
BOOL SetDHCPIP(LPCTSTR lpszAdapterName, int nIndex)
{
	if(!RegSetDHCPIP(lpszAdapterName, nIndex))
		return FALSE;


	//通知IP地址的改变(此方法会造成栈溢出问题,而且对于设置dhcp的立即生效没有作用,故舍弃)
	//if(!NotifyDHCPIPChange(lpszAdapterName, nIndex))
	//	return FALSE;


	//通过禁用启用网卡实现IP立即生效
	list<TNetCardStruct> cardList;
	EnumNetCards(&cardList);
	if(!cardList.empty())
	{
		NetCardStateChange(&cardList.front(),FALSE);
		Sleep(10);
		NetCardStateChange(&cardList.front(),TRUE);
	}
	return TRUE;
}
 

/*******************************************************网卡禁用启用操作*************************************************/

NetCard.h

#ifndef NETCARD_H_H
#define NETCARD_H_H

#include <Windows.h>
#include <SetupAPI.h>   
#include <cfgmgr32.h>   
#include <list>

using namespace std;


//     cfgmgr32.h 在Microsoft Windows 2000 DDK 中.   
//     要用 CM_Get_DevNode_Status() 来查询状态.   
//---------------------------------------------------------------------------   
typedef struct  NetCardStruct   
{   
    DWORD    Id;         // 网卡设备号   
    string   Name;     // 网卡名   
    bool     Disabled;     // 当前是否禁用   
    bool     Changed;         // 是否更改过   
}TNetCardStruct;   
typedef TNetCardStruct*  PNetCardStruct;   

/*******************函数声明***********************************/
static bool GetRegistryProperty(HDEVINFO DeviceInfoSet,   
                                    PSP_DEVINFO_DATA DeviceInfoData, 
                                    ULONG Property, 
                                    PVOID Buffer,
                                    PULONG Length)   ;
void    EnumNetCards(list<TNetCardStruct>  *NetDeviceList);
bool   NetCardStateChange(PNetCardStruct NetCardPoint, bool Enabled)  ;
/**************************************************************/

#endif

NetCard.cpp

#include "stdafx.h"
#include <SetupAPI.h>   
#include <cfgmgr32.h>     
#include <list>
#include <Windows.h>
#include <SetupAPI.h>

#include "NetCard.h"
 
//---------------------------------------------------------------------------   
//     EnumNetCards 枚举出网卡   
//---------------------------------------------------------------------------   
void  EnumNetCards(list<TNetCardStruct>  *NetDeviceList)   
{   
	string DevValue;   
	PNetCardStruct NetCard;   
	DWORD  Status, Problem;   
	LPTSTR Buffer   = NULL;   
	DWORD  BufSize  = 0;   
	HDEVINFO hDevInfo   = 0;  

	hDevInfo=SetupDiGetClassDevs(NULL,NULL,0,DIGCF_PRESENT|DIGCF_ALLCLASSES); 
	if(INVALID_HANDLE_VALUE==hDevInfo)   
		return; 

	SP_DEVINFO_DATA  DeviceInfoData ={sizeof(SP_DEVINFO_DATA)};

	HKEY hKeyClass;   
	char DeviceName[200];   
	for(DWORD DeviceId=0;SetupDiEnumDeviceInfo(hDevInfo,DeviceId,&DeviceInfoData);DeviceId++)   
	{   
		if (CM_Get_DevNode_Status(&Status, &Problem, DeviceInfoData.DevInst,0) != CR_SUCCESS)   
			continue;   
		if(GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_CLASS , &Buffer, (PULONG)&BufSize))   
			DevValue = string(Buffer);   

		if (strcmp(DevValue.c_str(),"Net") == 0)   
		{   
			DevValue = ""; 

			if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_ENUMERATOR_NAME , &Buffer, (PULONG)&BufSize))   
				DevValue = Buffer;   

			if (strcmp(DevValue.c_str(),"ROOT") != 0)   
			{   
				NetCard = new TNetCardStruct;   
				NetCard->Id = DeviceId;   
				NetCard->Name = "<Unknown Device>";   
				if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DRIVER , &Buffer, (PULONG)&BufSize))   
					if (GetRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC , &Buffer, (PULONG)&BufSize))   
						NetCard->Name = Buffer;   
				NetCard->Disabled = (Status & DN_HAS_PROBLEM) && (CM_PROB_DISABLED == Problem);   
				NetCard->Changed = false;   
				NetDeviceList->push_back(*NetCard);   
			}   
		}   
	}   
}   

//---------------------------------------------------------------------------   
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 (*(LPTSTR *)Buffer)[0];   
}   


//---------------------------------------------------------------------------   
//     NetCardStateChange 网卡的启用与禁用   
//             NetCardPoint 是 PNetCardStruct 的指针.   
//             Enabled     true = 启用     false = 禁用   
//---------------------------------------------------------------------------   
bool   NetCardStateChange(PNetCardStruct NetCardPoint, bool Enabled) 
{   
	PNetCardStruct NetCard = (PNetCardStruct)NetCardPoint; 
	DWORD DeviceId = NetCard->Id; 
	HDEVINFO hDevInfo = 0; 
	if (INVALID_HANDLE_VALUE == (hDevInfo = 
		SetupDiGetClassDevs(NULL,NULL,0,DIGCF_PRESENT |DIGCF_ALLCLASSES))) 
		return false; 
	SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)}; 
	DWORD Status, Problem; 
	if (!SetupDiEnumDeviceInfo(hDevInfo,DeviceId,&DeviceInfoData)) 
		return false;

	if (CM_Get_DevNode_Status(&Status, &Problem, 
		DeviceInfoData.DevInst,0) != CR_SUCCESS) 
		return false;

	SP_PROPCHANGE_PARAMS PropChangeParams = {sizeof(SP_CLASSINSTALL_HEADER)}; 
	PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; 
	PropChangeParams.Scope = DICS_FLAG_GLOBAL; 
	if (Enabled) 
	{ 
		if (!((Status & DN_HAS_PROBLEM) && (CM_PROB_DISABLED == Problem))) 
		{ 
			NetCard->Disabled = false; 
			return false; 
		} 
		PropChangeParams.StateChange = DICS_ENABLE; 
	} 
	else 
	{ 
		if ((Status & DN_HAS_PROBLEM) && (CM_PROB_DISABLED == Problem)) 
		{ 
			NetCard->Disabled = true; 
			return false; 
		} 
		if (!((Status & DN_DISABLEABLE) && (CM_PROB_HARDWARE_DISABLED != Problem))) 
			return false; 
		PropChangeParams.StateChange = DICS_DISABLE; 
	}

	if (!SetupDiSetClassInstallParams(hDevInfo, &DeviceInfoData, 
		(SP_CLASSINSTALL_HEADER *)&PropChangeParams, sizeof(PropChangeParams))) 
		return false; 
	if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo, &DeviceInfoData)) 
		return false; 
	if (CM_Get_DevNode_Status(&Status, &Problem, 
		DeviceInfoData.DevInst,0) == CR_SUCCESS) 
		NetCard->Disabled = (Status & DN_HAS_PROBLEM) && (CM_PROB_DISABLED == Problem); 
	return true; 
}  

设置静态IP

GetAdapterInfo();


char szIP[16]="111.111.111.11";
char szMask[16]="255.255.255.10";
char szGate[16]="111.111.111.1";
char dnsAddress[16]="222.222.222.1";
 
unsigned char *pIP, *pMask, *pGate;
DWORD dwIP, dwMask, dwGate;
 

if(SetIP(AdapterInfoVector[0]->strName.c_str(), 0, szIP, szMask, szGate,dnsAddress) == TRUE)
::MessageBox(this->m_hWnd, "设置IP地址成功!", "操作结果", MB_OK | MB_ICONINFORMATION);
else
::MessageBox(this->m_hWnd, "设置IP地址失败!", "操作结果", MB_OK | MB_ICONERROR);

设置动态IP

GetAdapterInfo();

if(SetDHCPIP(AdapterInfoVector[0]->strName.c_str(), 0 ) == TRUE)
::MessageBox(this->m_hWnd, "设置IP地址成功!", "操作结果", MB_OK | MB_ICONINFORMATION);
else
::MessageBox(this->m_hWnd, "设置IP地址失败!", "操作结果", MB_OK | MB_ICONERROR);






   

你可能感兴趣的:(String,XP,Microsoft,null,buffer,Parameters)