C++实现DNS动态修改

Home / C++ MrLee 2016-4-21 4443

本站原先发了一篇修改DNS的文章,不过那个实现有点问题,会断开网络连接。这里实现不会断开连接,动态更新DNS。看源码
#include 
#include 
#include "Iphlpapi.h"
#include 
#include 
#include 
using namespace std;
typedef int (CALLBACK* DNSFLUSHPROC)();
typedef int (CALLBACK* DHCPNOTIFYPROC)(LPWSTR, LPWSTR, BOOL, DWORD, DWORD, DWORD, int);
typedef struct _Adapt_Info
{
	char			AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];
	string			NameSever;
}AdaptInfo, *PADAPTINFO;

bool RegSetDNS(LPCTSTR lpszAdapterName, LPCTSTR pDNS)
{
	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 mszDNS[100];
	strncpy(mszDNS, pDNS, 98);
	int nDNS;
	nDNS = strlen(mszDNS);
	*(mszDNS + nDNS + 1) = 0x00;	// REG_MULTI_SZ need add one more 0
	nDNS += 2;
	RegSetValueEx(hKey, "NameServer", 0, REG_SZ, (unsigned char*)mszDNS, nDNS);
	RegCloseKey(hKey);
	return true;
}
BOOL NotifyIPChange(LPCTSTR lpszAdapterName)
{
	BOOL			bResult = FALSE;
	HINSTANCE		hDhcpDll;
	DHCPNOTIFYPROC	pDhcpNotifyProc;
	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, FALSE, 0, NULL,NULL, 0) == ERROR_SUCCESS)
			bResult = TRUE;
	FreeLibrary(hDhcpDll);
	return bResult;
}
bool FlushDNS()
{
	bool			bResult = FALSE;
	HINSTANCE		hDnsDll;
	DNSFLUSHPROC	pDnsFlushProc;
	if((hDnsDll = LoadLibrary("dnsapi")) == NULL)
		return false;
	if((pDnsFlushProc = (DNSFLUSHPROC)GetProcAddress(hDnsDll, "DnsFlushResolverCache")) != NULL)
	{
		if ( (pDnsFlushProc)() == ERROR_SUCCESS)
		{
			bResult = false;
		}
	}
	
	FreeLibrary(hDnsDll);
	return bResult;
}

int main()
{
	vector vecAdpif;
	PIP_ADDR_STRING   pAddrStr; 
	ULONG ulAdapterInfoSize = sizeof(IP_ADAPTER_INFO);
	IP_ADAPTER_INFO *pAdapterInfoBkp, *pAdapterInfo = (IP_ADAPTER_INFO*)new char[ulAdapterInfoSize];
	
	ULONG ulPerAdapterInfoSize = sizeof(IP_PER_ADAPTER_INFO );
	IP_PER_ADAPTER_INFO  *pPerAdapterInfoBkp, *pPerAdapterInfo = (IP_PER_ADAPTER_INFO *)new char[ulPerAdapterInfoSize];
	
	if( GetAdaptersInfo(pAdapterInfo, &ulAdapterInfoSize) == ERROR_BUFFER_OVERFLOW ) // out of buff
	{
		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)	// If type is etherent
			{
				if( GetPerAdapterInfo(
							pAdapterInfo->Index,
							pPerAdapterInfo,
							&ulPerAdapterInfoSize) == ERROR_BUFFER_OVERFLOW ) // out of buff
				{
					delete pPerAdapterInfo;
					pPerAdapterInfo = (IP_PER_ADAPTER_INFO*)new char[ulPerAdapterInfoSize];
					pPerAdapterInfoBkp = pPerAdapterInfo;
				}
				
				DWORD dwRet;
				if((dwRet = GetPerAdapterInfo(
							pAdapterInfo->Index,
							pPerAdapterInfo,
							&ulPerAdapterInfoSize)) == ERROR_SUCCESS)
				{
					AdaptInfo tmpadpif;
					
					pAddrStr   =   pPerAdapterInfo->DnsServerList.Next;
					strncpy(tmpadpif.AdapterName, pAdapterInfo->AdapterName, sizeof(pAdapterInfo->AdapterName));
					tmpadpif.NameSever = pPerAdapterInfo->DnsServerList.IpAddress.String;
					cout<DnsServerList.IpAddress.String<DnsServerList.IpAddress.String, tmp) == 0 )
					{	
						return 0;
					}
					while(pAddrStr)   
					{   
						tmpadpif.NameSever += ",";
						tmpadpif.NameSever += pAddrStr->IpAddress.String;
						cout<IpAddress.String<Next;   
					}
					vecAdpif.push_back( tmpadpif );
					RegSetDNS( tmpadpif.AdapterName, tmp);
					NotifyIPChange(pAdapterInfo->AdapterName);
				}
			}
			pAdapterInfo = pAdapterInfo->Next;
		}while(pAdapterInfo);
		
		FlushDNS();	
	}
	
	delete pAdapterInfoBkp;
	return 0;
}

项目源码:Test

本文链接:https://www.it72.com/9290.htm

推荐阅读
最新回复 (0)
返回