qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] qga:windows os lost ip when network nic change pic order
@ 2017-06-24  5:39 indiffPig
  2017-06-27 21:14 ` Eric Blake
  0 siblings, 1 reply; 3+ messages in thread
From: indiffPig @ 2017-06-24  5:39 UTC (permalink / raw)
  To: mdroth; +Cc: qemu-devel, yin.zuowei

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=yes, Size: 50772 bytes --]

From: "yin.zuowei" <indiffPig@126.com>

Signed-off-by: yin.zuowei <indiffPig@126.com>

bug description: In the windows virtual machine, if there are multiple network cards, the hypothesis is that A/B/C is equipped with a different IP address. Once you delete a B card in the middle and restart the virtual machine, you will find that the A/C of the network card IP has been confused, and the IP of the C network card has become the address of B, and the service has been interrupted. So we did a IP recovery function in qga.This is a serious problem that can lead to business disruption. If you have a better plan, we would like to offer it to you.
---
 qga/restoreIp.cpp | 1848 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 1848 insertions(+)
 create mode 100755 qga/restoreIp.cpp

diff --git a/qga/restoreIp.cpp b/qga/restoreIp.cpp
new file mode 100755
index 0000000..2382136
--- /dev/null
+++ b/qga/restoreIp.cpp
@@ -0,0 +1,1848 @@
+// restoreIp.cpp : ¶¨Òå¿ØÖÆÌ¨Ó¦ÓóÌÐòµÄÈë¿Úµã¡£
+//#include "stdafx.h"
+#include <tchar.h>
+#include <io.h>
+#include <stdio.h>
+#include <winsock2.h>
+#include <windows.h>
+#include <stdlib.h>
+#include <shellapi.h>
+#include <iphlpapi.h>
+#include <winioctl.h>
+#include <vector> 
+#include <map>
+#include <set>
+
+//#pragma comment(lib,"iphlpapi.lib")
+
+CONST DWORD SUCCESS_CODE = 0;
+CONST DWORD ERROR_CODE = 1;
+CONST DWORD CONFLICT_CODE = 2;
+CONST DWORD NO_IP_CODE = 3;
+CONST DWORD NO_FILE_CODE = 4;
+   
+CONST INT RETRY_TIMES = 3;
+CONST INT SLEEP_TIMES = 2000;
+CONST INT LOG_LEN = 512;
+CONST INT MAX_INI_RECORD = 512;
+
+
+/*ҪעÒ⣬¿¼ÂÇunicodeÏ memcpyº¯Êý£¬³¤¶ÈҪʹÓÃXXX_LEN * sizeof(TCHAR)*/
+CONST INT MAC_LEN = 20;
+CONST INT DHCP_LEN = 4;
+CONST INT IP_STR_LEN = 128;
+CONST INT MASK_STR_LEN = 128;
+CONST INT GATE_STR_LEN = 128;
+CONST INT IP_ADDRESS_LEN = 16;
+CONST INT DNS_COUNT = 2; //ĿǰֻÄÜÓÐ2¸öDNSµØÖ·
+CONST INT DNS_STR_LEN = IP_ADDRESS_LEN * DNS_COUNT; 
+CONST INT ADA_NAME_LEN = 40;
+CONST INT MAX_IP_COUNT = IP_STR_LEN/IP_ADDRESS_LEN;
+
+CONST INT DEL_NIC = -1;
+CONST INT ADD_NIC = 1;
+
+
+/*È«¾Ö±äÁ¿Ò»ÂÉÓà g_¿ªÍ·*/
+TCHAR g_configPath[MAX_PATH];
+BOOL g_VistaOrLater;
+
+CONST INT MAX_PREBUFF_LEN = MAC_LEN*MAX_INI_RECORD;
+TCHAR * g_preMem;
+
+
+/*ÐÂÔöÍø¿¨£¬¸Ã¼üÖµ»á·¢Éú±ä»¯£¨É¾³ý²»»á·¢Éú±ä»¯£©£»ÆôÓýûÓÃÍø¿¨¾ø´ó²¿·Ö²»´¥·¢£¬ÓÐʱÑÓ³Ù´¥·¢£»ÐÞ¸ÄIP£¬ÓÐʱºòÒ²»á·¢Éú±ä»¯£¬ÓÐʱÓÖ²»±ä»¯£¬²»Ì«¾«È·*/
+LPCTSTR NIC_CHANGE = _T("SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}");
+
+/*ip±ä»¯¸Ã¼üÖµ¾Í»á±ä»¯£¬·Ç³£¼°Ê±*/
+LPCTSTR IP_CHANGE = _T("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\");
+
+/*×¼±¸Í¬Ê±¼à¿ØÉÏÃæÁ½¸öÖµ£¬µ«Íø¿¨µÄÐÂÔöÓëɾ³ý»òIP±ä»¯£¬ÒÔǰºóö¾Ù²îÒìΪ׼*/
+
+LPCTSTR DHCP_KEY = _T("dhcp");
+LPCTSTR DHCP_ON = _T("yes");
+LPCTSTR DHCP_OFF = _T("no");
+LPCTSTR IP_KEY = _T("ip");    
+LPCTSTR MASK_KEY = _T("mask");
+LPCTSTR GATEWAY_KEY = _T("gateWay");
+LPCTSTR DNS_KEY = _T("dns");
+LPCTSTR DHCP_IP = _T("169.254");
+
+
+VOID LogEvent(LPCTSTR pFormat, ...)
+{
+    TCHAR  chMsg[LOG_LEN] = {0};
+    HANDLE  hEventSource;
+    LPTSTR  lpszStrings[1];
+    va_list pArg;
+
+    va_start(pArg, pFormat);
+    _vsntprintf(chMsg,LOG_LEN -1 ,pFormat,pArg);
+    va_end(pArg);
+
+    lpszStrings[0] = chMsg;
+
+    hEventSource = RegisterEventSource(NULL, TEXT("QGA"));
+    if (hEventSource != NULL)
+    {
+        ReportEvent(hEventSource, EVENTLOG_INFORMATION_TYPE, 
+            0, 0, NULL, 1, 0, (LPCTSTR*) &lpszStrings[0], NULL);
+        DeregisterEventSource(hEventSource);
+    }
+}
+
+
+
+BOOL FileExist(LPCTSTR pszFileName)
+{
+	BOOL bExist = FALSE;
+	HANDLE hFile;
+
+	if (NULL != pszFileName)
+	{
+		// Use the preferred Win32 API call and not the older OpenFile.
+		hFile = CreateFile(
+			pszFileName,
+			GENERIC_READ,
+			FILE_SHARE_READ | FILE_SHARE_WRITE,
+			NULL,
+			OPEN_EXISTING,
+			0,
+			0);
+
+		if (hFile != INVALID_HANDLE_VALUE)
+		{
+			// If the handle is valid then the file exists.
+			CloseHandle(hFile);
+			bExist = TRUE;
+		}
+	}
+
+	return bExist;
+}
+
+//»ñÈ¡µ±Ç°ÏµÍ³ÖеÄÍø¿¨ÐÅÏ¢
+typedef struct _IP_MASK_INFO
+{
+	TCHAR ip[IP_ADDRESS_LEN];
+	TCHAR mask[IP_ADDRESS_LEN];
+}IP_MASK_INFO;
+
+typedef struct _GATEWAY_INFO
+{
+	TCHAR gateWay[IP_ADDRESS_LEN];
+}GATEWAY_INFO;
+
+
+typedef struct _ADAPTER_INFO
+{
+	TCHAR mac[MAC_LEN];
+	UINT index;
+	TCHAR name[ADA_NAME_LEN];
+	TCHAR dhcpStatus[DHCP_LEN];
+	TCHAR dns[DNS_COUNT][IP_ADDRESS_LEN];
+	std::vector<IP_MASK_INFO>ipMaskVec;
+	std::vector<GATEWAY_INFO>gateWayVec;
+}ADAPTER_INFO, *PADAPTER_INFO;
+
+typedef struct _ADA_DIFF_INFO
+{
+	INT addOrDel;
+	PADAPTER_INFO adaInfo;
+}ADA_DIFF_INFO, *PADA_DIFF_INFO;
+
+VOID charToTchar (const char * _char, TCHAR * tchar)  
+{  
+#ifdef UNICODE
+    INT iLength ; 
+    iLength = MultiByteToWideChar (CP_ACP, 0, _char, strlen (_char) + 1, NULL, 0) ;  
+    MultiByteToWideChar (CP_ACP, 0, _char, strlen (_char) + 1, tchar, iLength) ;  
+#else
+	//Õâ¸öº¯ÊýÊÇÓÐΣÏÕµÄ
+	strcpy(tchar, _char);
+#endif
+} 
+
+TCHAR* ByteToStr(BYTE *pData, INT nCount, TCHAR* pMac)
+{
+	int i = 0;
+
+	for (i = 0; i < nCount; i++){
+		wsprintf(pMac + _tcslen(pMac), _T("%02X-"),pData[i]);
+	}
+    
+	pMac[_tcslen(pMac) - 1] = '\0';
+	return pMac;
+}
+
+
+/*ip ÓпÉÄÜÊÇÏàµÈµÄ£¬Ö»ÊǶà¸öIP˳Ðò²»Í¬£¬´ËÖÖÇé¿öÒªµ÷ÓÃcmpAdaIpIsEqualWithFile*/
+BOOL cmpStrIsEqual(LPCTSTR srcStr, LPCTSTR dstStr)
+{
+    BOOL ret = TRUE;
+    if (0 != _tcscmp(srcStr, dstStr))
+    {
+        ret = FALSE;
+    }
+    return ret;
+}
+
+/*»ñÈ¡:str:strÖÐ×Ö·û´®ÖÐÔªËØµÄ¸öÊý*/
+UINT getVauleCountInStr(TCHAR * str)
+{
+	TCHAR *index = NULL;
+	UINT count = 0;
+	index = _tcschr(str, _T(':'));
+
+	//»ñÈ¡strÖеÄÔªËØ¸öÊý
+	while ((index != NULL))
+	{
+		count++;
+		index = _tcschr(&index[1], _T(':'));
+	}
+	return count;
+}
+
+/*Èç¹ûÔÚ:192.168.25.111ÖÐÕÒµ½192.168.25.11£¬ÄÇôҲÈÏΪÊÇÏàͬ£¬ÕâÊDz»¶ÔµÄ£¬Òª¶ÔÕâÖÖÇé¿ö½øÐд¦Àí
+¹Ê¸Ãº¯ÊýÊǺÜÓбØÒª´æÔÚµÄ*/
+BOOL checkIpInStr(TCHAR *ipStr, TCHAR *ip)
+{
+	if(0 == _tcslen(ip))
+		return FALSE;
+
+	TCHAR *index = _tcsstr(ipStr, ip);
+	if(NULL == index)
+		return FALSE;
+
+	if(index[_tcslen(ip)] != _T('\0') && index[_tcslen(ip)] != _T(':'))
+	{
+		return FALSE;
+	}
+
+	return TRUE;
+
+}
+
+
+/*Ö÷ÒªÊÇ¿¼ÂǶà¸öIPÖ»ÊÇ˳Ðò±ä»¯£¬µ«Êµ¼ÊÄÚÈÝû±äµÄÇé¿ö£¬ipStrFileÊÇÒÔ¡°:ip1:ip2¡±µÄ¸ñʽ½øÐÐ
+ʵÏÖµÄЧÂÊ¿ÉÄÜÊǸöÎÊÌ⣬µ«Ä¿Ç°ÓÅÏȱ£Ö¤¹¦ÄÜ*/
+BOOL cmpAdaIpIsEqualIpStr(ADAPTER_INFO *pAda, TCHAR * ipStr)
+{
+
+	//¶þÕßipµÄ¸öÊý²»Ïàͬ£¬ÔòÅжÏΪ²»Í¬
+	if (pAda->ipMaskVec.size() != getVauleCountInStr(ipStr))
+	{
+		return FALSE;
+	}
+
+	//¸öÊýÏàͬǰÌáÏ£¬ÔٱȽÏÄÚÈÝ£¬Èç¹ûÄÚÈÝÓÐÒ»¸ö²»Ò»Ñù£¬¾ÍÅжÏΪ²»Í¬
+	if(!pAda->ipMaskVec.empty())
+	{
+		for(std::vector<IP_MASK_INFO>::iterator iter=pAda->ipMaskVec.begin(); iter!=pAda->ipMaskVec.end(); iter++)
+		{
+			if(!checkIpInStr(ipStr, (*iter).ip))
+				return FALSE;
+		}
+	}
+	return TRUE;
+}
+
+BOOL cmpAdaMaskIsEqualMaskStr(ADAPTER_INFO *pAda, TCHAR * maskStr)
+{
+	//¶þÕßmaskµÄ¸öÊý²»Ïàͬ£¬ÔòÅжÏΪ²»Í¬
+	if (pAda->ipMaskVec.size() != getVauleCountInStr(maskStr))
+	{
+		return FALSE;
+	}
+
+	//¸öÊýÏàͬǰÌáÏ£¬ÔٱȽÏÄÚÈÝ£¬Èç¹ûÄÚÈÝÓÐÒ»¸ö²»Ò»Ñù£¬¾ÍÅжÏΪ²»Í¬
+	if(!pAda->ipMaskVec.empty())
+	{
+		for(std::vector<IP_MASK_INFO>::iterator iter=pAda->ipMaskVec.begin(); iter!=pAda->ipMaskVec.end(); iter++)
+		{
+			if(!checkIpInStr(maskStr, (*iter).mask))
+				return FALSE;
+		}
+	}
+	return TRUE;
+}
+
+BOOL cmpAdaDnsEqualDnsStr(ADAPTER_INFO *pAda, TCHAR * dnsStr)
+{
+	//¶þÕßmaskµÄ¸öÊý²»Ïàͬ£¬ÔòÅжÏΪ²»Í¬
+	UINT count = 0;
+	for(UINT i = 0; i < DNS_COUNT; i++)
+	{
+		if(_tcslen(pAda->dns[i]) != 0)
+		{
+			count++;
+		}
+
+	}
+
+	if (count != getVauleCountInStr(dnsStr))
+	{
+		return FALSE;
+	}
+
+	//¸öÊýÏàͬǰÌáÏ£¬ÔٱȽÏÄÚÈÝ£¬Èç¹ûÄÚÈÝÓÐÒ»¸ö²»Ò»Ñù£¬¾ÍÅжÏΪ²»Í¬
+	if(count != 0)
+	{
+		for(UINT i = 0; i < count; i++)
+		{
+			if(_tcslen(pAda->dns[i]) != 0)
+			{
+				if(!checkIpInStr(dnsStr, pAda->dns[i]))
+					return FALSE;
+			}
+		}
+	}
+	return TRUE;
+}
+
+inline BOOL cmpAdaGateWayIsEqualMaskStr(ADAPTER_INFO *pAda, TCHAR * gateWayStr)
+{
+	//¶þÕßmaskµÄ¸öÊý²»Ïàͬ£¬ÔòÅжÏΪ²»Í¬
+	if (pAda->gateWayVec.size() != getVauleCountInStr(gateWayStr))
+	{
+		return FALSE;
+	}
+
+	//¸öÊýÏàͬǰÌáÏ£¬ÔٱȽÏÄÚÈÝ£¬Èç¹ûÄÚÈÝÓÐÒ»¸ö²»Ò»Ñù£¬¾ÍÅжÏΪ²»Í¬
+	if(!pAda->gateWayVec.empty())
+	{
+		for(std::vector<GATEWAY_INFO>::iterator iter=pAda->gateWayVec.begin(); iter!=pAda->gateWayVec.end(); iter++)
+		{
+			if(!checkIpInStr(gateWayStr, (*iter).gateWay))
+				return FALSE;
+		}
+	}
+	return TRUE;
+}
+
+BOOL isNullIp(TCHAR * ip)
+{
+	if ((_tcslen(ip) == 0) || cmpStrIsEqual(ip, _T("0.0.0.0")) || (0 == _tcsncmp(ip, DHCP_IP, _tcslen(DHCP_IP))))
+		return TRUE;
+
+	return FALSE;
+}
+
+TCHAR *getMacStrFromAda(PIP_ADAPTER_INFO pAda, TCHAR *macBuff)
+{
+    return ByteToStr(pAda->Address, pAda->AddressLength, &macBuff[0]);
+}
+
+//0 ²»¿ªÆô 
+UINT getDhcpStatusFromAda(PIP_ADAPTER_INFO pAda, TCHAR *dhcpBuff)
+{
+    if(dhcpBuff != NULL)
+    {
+        if(0 == pAda->DhcpEnabled)
+        {
+            _tcsncpy(dhcpBuff, DHCP_OFF, DHCP_LEN);
+        }
+        else
+        {
+            _tcsncpy(dhcpBuff, DHCP_ON, DHCP_LEN);
+        }
+            
+    }
+    return pAda->DhcpEnabled;
+}
+
+DWORD readDhcpStatusFromFileByMac(LPCTSTR lpMac, LPCTSTR lpFileName, TCHAR* lpDhcpStatus)
+{
+    return GetPrivateProfileString(lpMac, DHCP_KEY, _T(""), lpDhcpStatus, DHCP_LEN, lpFileName);
+}
+
+VOID writeDhcpStatusToFileByMac(LPCTSTR dpchStatus, LPCTSTR lpMac, LPCTSTR lpFileName, TCHAR *logBuff)
+{
+    WritePrivateProfileString(lpMac, DHCP_KEY, dpchStatus, lpFileName);
+    if(logBuff != NULL)
+    {
+        _tcsncpy(logBuff, dpchStatus, DHCP_LEN);
+    }
+}
+/*
+TCHAR *getIpStrFromAda(PIP_ADAPTER_INFO pAda, TCHAR *ipBuff)
+{
+    IP_ADDR_STRING *pIpAddr = &pAda->IpAddressList;
+	TCHAR tmpStr[IP_ADDRESS_LEN] = {0};
+	INT count = 0;
+    while(NULL != pIpAddr)
+    {
+		charToTchar(pIpAddr->IpAddress.String, tmpStr);
+		if(!isNullIp(tmpStr))
+		{
+			if (++count > MAX_IP_COUNT)
+				break;
+			wsprintf(ipBuff + _tcslen(ipBuff), _T(":%s"),tmpStr);
+		}
+        pIpAddr = pIpAddr->Next;
+    }
+    return ipBuff;
+}
+*/
+DWORD readIpStrFromFileByMac(LPCTSTR lpMac, LPCTSTR lpFileName, TCHAR* lpIpStr)
+{
+    return GetPrivateProfileString(lpMac, IP_KEY, _T(""), lpIpStr, IP_STR_LEN, lpFileName);
+}
+
+
+VOID writeIpStrToFileByMac(std::vector<IP_MASK_INFO> &ipMaskVec, LPCTSTR lpMac, LPCTSTR lpFileName, TCHAR *logBuff)
+{
+	TCHAR ipBuff[IP_STR_LEN] = {0};
+	if(ipMaskVec.size() != 0)
+	{
+		for(std::vector<IP_MASK_INFO>::iterator iter=ipMaskVec.begin(); iter!=ipMaskVec.end(); iter++)
+		{
+			wsprintf(ipBuff + _tcslen(ipBuff), _T(":%s"), (*iter).ip);
+		}
+		WritePrivateProfileString(lpMac, IP_KEY, ipBuff, lpFileName);
+		if(logBuff != NULL)
+		{
+			_tcsncpy(logBuff, ipBuff, IP_STR_LEN);
+		}
+	}
+}
+
+/*
+TCHAR *getMaskStrFromAda(PIP_ADAPTER_INFO pAda, TCHAR *maskBuff)
+{
+    IP_ADDR_STRING *pMaskAddr = &pAda->IpAddressList;
+	TCHAR tmpStr[IP_ADDRESS_LEN] = {0};
+	INT count = 0;
+    while(NULL != pMaskAddr)
+    {
+		charToTchar(pMaskAddr->IpMask.String, tmpStr);
+		if(!isNullIp(tmpStr))
+		{
+			if (++count > MAX_IP_COUNT)
+				break;
+			wsprintf(maskBuff + _tcslen(maskBuff), _T(":%s"), tmpStr);
+		}
+        pMaskAddr = pMaskAddr->Next;
+    }
+    return maskBuff;
+}
+*/
+
+DWORD readMaskStrFromFileByMac(LPCTSTR lpMac, LPCTSTR lpFileName, TCHAR* lpMaskStr)
+{
+    return GetPrivateProfileString(lpMac, MASK_KEY, _T(""), lpMaskStr, MASK_STR_LEN, lpFileName);
+}
+
+VOID writeMaskStrToFileByMac(std::vector<IP_MASK_INFO> &ipMaskVec, LPCTSTR lpMac, LPCTSTR lpFileName, TCHAR *logBuff)
+{
+	TCHAR maskBuff[MASK_STR_LEN]={0};
+	if(ipMaskVec.size() != 0)
+	{
+		for(std::vector<IP_MASK_INFO>::iterator iter=ipMaskVec.begin(); iter!=ipMaskVec.end(); iter++)
+		{
+			wsprintf(maskBuff + _tcslen(maskBuff), _T(":%s"), (*iter).mask);
+		}
+		WritePrivateProfileString(lpMac, MASK_KEY, maskBuff, lpFileName);
+		if(logBuff != NULL)
+		{
+			_tcsncpy(logBuff,maskBuff, MASK_STR_LEN);
+		}
+	}
+}
+/*
+TCHAR *getGateWayStrFromAda(PIP_ADAPTER_INFO pAda, TCHAR *gateWayBuff)
+{
+    IP_ADDR_STRING *pGateWayAddr = &pAda->GatewayList;
+	TCHAR tmpStr[IP_ADDRESS_LEN] = {0};
+	INT count = 0;
+    while(NULL != pGateWayAddr)
+    {
+		charToTchar(pGateWayAddr->IpAddress.String, tmpStr);
+		if(!isNullIp(tmpStr))
+		{
+			if (++count > MAX_IP_COUNT)
+				break;
+			wsprintf(gateWayBuff + _tcslen(gateWayBuff), _T(":%s"), tmpStr);
+		}
+        pGateWayAddr = pGateWayAddr->Next;
+    }
+    return gateWayBuff;
+}
+*/
+DWORD readGateWayStrFromFileByMac(LPCTSTR lpMac, LPCTSTR lpFileName, TCHAR* lpGateWayStr)
+{
+    return GetPrivateProfileString(lpMac, GATEWAY_KEY, _T(""), lpGateWayStr, GATE_STR_LEN, lpFileName);
+}
+
+VOID writeGateWayStrToFileByMac(std::vector<GATEWAY_INFO> &gateWayVec, LPCTSTR lpMac, LPCTSTR lpFileName, TCHAR *logBuff)
+{
+	TCHAR gateWayBuff[GATE_STR_LEN] = {0};
+	if(gateWayVec.size() != 0 )
+	{
+		for(std::vector<GATEWAY_INFO>::iterator iter=gateWayVec.begin(); iter!=gateWayVec.end(); iter++)
+		{
+			wsprintf(gateWayBuff + _tcslen(gateWayBuff), _T(":%s"), (*iter).gateWay);
+		}
+		WritePrivateProfileString(lpMac, GATEWAY_KEY, gateWayBuff, lpFileName);
+		if(logBuff != NULL)
+		{
+			_tcsncpy(logBuff,gateWayBuff, GATE_STR_LEN);
+		}
+	}else{
+		/*Èç¹ûÍø¿¨Ã»ÓÐGATEWAY£¬ÔòÎļþÖÐÒ²ÒªÇå³ýGATEWAYÑ¡Ïî*/
+		WritePrivateProfileString(lpMac, GATEWAY_KEY, NULL, lpFileName);
+	}
+}
+
+DWORD readDnsStrFromFileByMac(LPCTSTR lpMac, LPCTSTR lpFileName, TCHAR* lpDns)
+{
+	return GetPrivateProfileString(lpMac, DNS_KEY, _T(""), lpDns, DNS_STR_LEN, lpFileName);
+}
+
+/*ÕâÀï±È½Ï¾À½á£¬Èç¹ûÊÇ¿ÕDSN£¬ÔòÖ±½ÓÇå³ý;¶øIPÄØ£¬Èç¹ûÊǿգ¬Ôò²»Ð´È룻¿¼ÂÇϸÃÈçºÎ*/
+VOID writeDnsStrToFileByMac(TCHAR dns[][IP_ADDRESS_LEN], LPCTSTR lpMac, LPCTSTR lpFileName, TCHAR *logBuff)
+{
+	TCHAR dnsBuff[DNS_STR_LEN] = {0};
+
+	if (_tcslen(dns[0]) != 0)
+	{
+		for(int i = 0; i < DNS_COUNT; i++)
+		{
+			if (_tcslen(dns[i]) != 0)
+			{
+				wsprintf(dnsBuff + _tcslen(dnsBuff), _T(":%s"), dns[i]);
+			}
+		}
+		WritePrivateProfileString(lpMac, DNS_KEY, dnsBuff, lpFileName);
+		if(logBuff != NULL)
+		{
+			_tcsncpy(logBuff, dnsBuff, DNS_STR_LEN);
+		}
+	}else{
+		/*Èç¹ûÍø¿¨Ã»ÓÐDNS£¬ÔòÎļþÖÐÒ²ÒªÇå³ýDNSÑ¡Ïî*/
+		WritePrivateProfileString(lpMac, DNS_KEY, NULL, lpFileName);
+	}
+
+}
+/*ADAPTER_INFOÀïÃæµÄIP¶¼ÊǺϷ¨µÄ£¬ÒòΪ֮ǰÌîÈëÈÝÆ÷ʱ£¬¾ÍÒѾ­×öÁ˼ì²é*/
+DWORD getIpFromAdaInfo(ADAPTER_INFO * pAdaInfo, TCHAR *ipBuff)
+{
+	INT count = 0;
+	if(pAdaInfo->ipMaskVec.size() != 0)
+	{
+		for(std::vector<IP_MASK_INFO>::iterator iter=pAdaInfo->ipMaskVec.begin(); iter!=pAdaInfo->ipMaskVec.end(); iter++)
+		{
+			if (++count > MAX_IP_COUNT)
+				break;
+				wsprintf(ipBuff + _tcslen(ipBuff), _T(":%s"), (*iter).ip);
+		}
+		return SUCCESS_CODE;
+	}
+	
+	return NO_IP_CODE;
+}
+
+VOID getMaskFromAdaInfo(ADAPTER_INFO * pAdaInfo, TCHAR *maskBuff)
+{
+	INT count = 0;
+	if(pAdaInfo->ipMaskVec.size() != 0)
+	{
+		for(std::vector<IP_MASK_INFO>::iterator iter=pAdaInfo->ipMaskVec.begin(); iter!=pAdaInfo->ipMaskVec.end(); iter++)
+		{
+			if (++count > MAX_IP_COUNT)
+				break;
+			wsprintf(maskBuff + _tcslen(maskBuff), _T(":%s"), (*iter).mask);
+		}
+	}
+}
+VOID getGateWayFromAdaInfo(ADAPTER_INFO * pAdaInfo, TCHAR *gateWayBuff)
+{
+	INT count = 0;
+	if(pAdaInfo->gateWayVec.size() != 0)
+	{
+		for(std::vector<GATEWAY_INFO>::iterator iter=pAdaInfo->gateWayVec.begin(); iter!=pAdaInfo->gateWayVec.end(); iter++)
+		{
+			if (++count > MAX_IP_COUNT)
+				break;
+			wsprintf(gateWayBuff + _tcslen(gateWayBuff), _T(":%s"), (*iter).gateWay);
+		}
+	}
+}
+
+VOID getDnsFromAdaInfo(ADAPTER_INFO * pAdaInfo, TCHAR *dnsBuff)
+{
+	if(_tcslen(pAdaInfo->dns[0]) != 0)
+	{
+		for(int i = 0; i < DNS_COUNT; i++)
+		{
+			if (_tcslen(pAdaInfo->dns[i]) != 0)
+			{
+				wsprintf(dnsBuff + _tcslen(dnsBuff), _T(":%s"), pAdaInfo->dns[i]);
+			}
+		}
+
+	}
+}
+
+/*¸Ãº¯ÊýÊDz»¿ÉÖØÈëµÄ*/
+BOOL isMacExistInFile(LPCTSTR lpMac, LPCTSTR lpFileName)
+{
+	TCHAR *chSectionNames = g_preMem;
+	TCHAR *pSectionName;
+	int i, j = 0; 
+    BOOL ret = FALSE;
+
+	memset(g_preMem, 0, MAX_PREBUFF_LEN*sizeof(TCHAR));
+	GetPrivateProfileSectionNames(chSectionNames, MAX_PREBUFF_LEN, lpFileName);  
+	for(i=0 ;i<MAX_PREBUFF_LEN ;i++,j++)
+	{
+		if(chSectionNames[0]=='\0')
+			break;
+
+		if(chSectionNames[i]=='\0')
+		{
+			pSectionName=&chSectionNames[i-j]; 
+			j = -1;
+
+			if(cmpStrIsEqual(pSectionName, lpMac))
+            {
+                ret = TRUE;
+                break;
+            }
+
+			if(chSectionNames[i+1]==0)
+			{
+				break;
+			}
+		} 
+	}
+    return ret;
+}
+
+VOID freeAdaInfoVec(std::vector<ADAPTER_INFO *> & pAdaInfoVec)
+{
+	if(pAdaInfoVec.size() != 0)
+	{
+		for(std::vector<ADAPTER_INFO *>::iterator iter=pAdaInfoVec.begin(); iter!=pAdaInfoVec.end(); iter++)
+		{
+			delete((*iter));
+		}
+	}
+}
+
+VOID getAdaDnsInfo (ADAPTER_INFO & pAdapter)
+{
+	IP_PER_ADAPTER_INFO* pPerAdapt = NULL;  
+	ULONG ulLen = 0;  
+	int err = GetPerAdapterInfo( pAdapter.index, pPerAdapt, &ulLen);  
+	if( err == ERROR_BUFFER_OVERFLOW )  
+	{  
+		pPerAdapt = (IP_PER_ADAPTER_INFO*) malloc(ulLen);  
+		err = GetPerAdapterInfo( pAdapter.index, pPerAdapt, &ulLen );  
+		if( err == ERROR_SUCCESS )  
+		{  
+			IP_ADDR_STRING* pNext = &( pPerAdapt->DnsServerList );  
+			TCHAR tmpIp[IP_ADDRESS_LEN] = {0};
+
+			if (NULL != pNext)//×Ô¶¯»ñȡΪfalse 
+			{  
+				charToTchar(pNext->IpAddress.String, tmpIp);
+
+				if(!isNullIp(tmpIp))
+				{
+					memcpy(pAdapter.dns[0], tmpIp, sizeof(tmpIp));
+                                        pNext=pNext->Next;
+					if (NULL != pNext)  
+					{  
+						memset(tmpIp, 0, sizeof(tmpIp));
+						charToTchar(pNext->IpAddress.String, tmpIp);
+						if(!isNullIp(tmpIp))
+							memcpy(pAdapter.dns[1], tmpIp, sizeof(tmpIp));
+					}  
+				}
+			}  
+		}  
+	}
+
+	if(pPerAdapt)
+		free(pPerAdapt);
+}
+
+DWORD GetNicInfo(std::vector<ADAPTER_INFO *> & ppAdaInfo)
+{
+	PIP_ADAPTER_INFO pAdapterInfo;
+    PIP_ADAPTER_INFO pAdapter = NULL;
+    DWORD dwRetVal = 0;
+	ADAPTER_INFO *tmpAdaInfo = NULL;
+
+    ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO);
+    pAdapterInfo = (IP_ADAPTER_INFO *) malloc(sizeof (IP_ADAPTER_INFO));
+    if (pAdapterInfo == NULL) {
+		LogEvent(_T("[QGA]Error allocating memory needed to call GetAdaptersinfo"));
+        return ERROR_NOT_ENOUGH_MEMORY;
+    }
+
+    if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
+        free(pAdapterInfo);
+        pAdapterInfo = (IP_ADAPTER_INFO *) malloc(ulOutBufLen);
+        if (pAdapterInfo == NULL) {
+			LogEvent(_T("[QGA]Error allocating pAdapterInfo needed to call GetAdaptersinfo"));
+            return ERROR_NOT_ENOUGH_MEMORY;
+        }
+    }
+
+    if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
+        pAdapter = pAdapterInfo;
+        while (pAdapter) {
+
+            if (pAdapter->Type != MIB_IF_TYPE_ETHERNET) {
+				pAdapter = pAdapter->Next;
+				continue;
+			}
+
+			tmpAdaInfo = new ADAPTER_INFO();
+			 if (tmpAdaInfo == NULL) {
+			LogEvent(_T("[QGA]Error allocating tmpAdaInfo needed to call GetAdaptersinfo"));
+            return ERROR_NOT_ENOUGH_MEMORY;
+
+			}
+
+			memset(tmpAdaInfo->mac, 0, sizeof(tmpAdaInfo->mac));
+			tmpAdaInfo->index = 0;
+			memset(tmpAdaInfo->dhcpStatus, 0, sizeof(tmpAdaInfo->dhcpStatus));
+			getMacStrFromAda(pAdapter, tmpAdaInfo->mac);
+			getDhcpStatusFromAda(pAdapter, tmpAdaInfo->dhcpStatus);
+			tmpAdaInfo->index = pAdapter->Index;
+			charToTchar(pAdapter->AdapterName, tmpAdaInfo->name);
+
+			memset(tmpAdaInfo->dns[0], 0, sizeof(tmpAdaInfo->dns[0]));
+			memset(tmpAdaInfo->dns[1], 0, sizeof(tmpAdaInfo->dns[1]));
+
+			//»ñÈ¡IP MASK GATEWAY
+			IP_ADDR_STRING *pIpAddr = &pAdapter->IpAddressList;
+			IP_MASK_INFO tmpIpMask; 
+			while(NULL != pIpAddr)
+			{
+				memset(tmpIpMask.ip, 0, sizeof(tmpIpMask.ip));
+				memset(tmpIpMask.mask, 0, sizeof(tmpIpMask.mask));
+				charToTchar(pIpAddr->IpAddress.String, tmpIpMask.ip);
+				charToTchar(pIpAddr->IpMask.String, tmpIpMask.mask);
+				if(!isNullIp(tmpIpMask.ip) && !isNullIp(tmpIpMask.mask))
+				{
+					(tmpAdaInfo->ipMaskVec).push_back(tmpIpMask);
+				}
+				pIpAddr = pIpAddr->Next;
+			}
+
+			IP_ADDR_STRING *pGateWayAddr = &pAdapter->GatewayList;
+			GATEWAY_INFO tmpGateWay; 
+			while(NULL != pGateWayAddr)
+			{
+				memset(tmpGateWay.gateWay, 0, sizeof(tmpGateWay.gateWay));
+				charToTchar(pGateWayAddr->IpAddress.String, tmpGateWay.gateWay);
+				if(!isNullIp(tmpGateWay.gateWay))
+				{
+					(*tmpAdaInfo).gateWayVec.push_back(tmpGateWay);
+				}
+				pGateWayAddr = pGateWayAddr->Next;
+			}
+
+			//dns
+			getAdaDnsInfo((*tmpAdaInfo));
+
+			ppAdaInfo.push_back(tmpAdaInfo);
+			pAdapter = pAdapter->Next;
+        }
+    } else {
+		if(ERROR_NO_DATA != dwRetVal)
+			LogEvent(_T("GetAdaptersInfo failed with error: %d\n"), dwRetVal);
+    }
+    if (pAdapterInfo)
+        free(pAdapterInfo);
+
+    return ERROR_SUCCESS;
+}
+
+BOOL cmpDnsInfoIsEqualWithFile(ADAPTER_INFO * pAdaInfo, TCHAR *pIniPath)
+{
+	TCHAR dnsFileBuff[DNS_STR_LEN] = {0};
+
+	readDnsStrFromFileByMac(pAdaInfo->mac, pIniPath, dnsFileBuff);
+	if(!cmpAdaDnsEqualDnsStr(pAdaInfo, dnsFileBuff))
+		return FALSE;
+
+	return TRUE;
+
+}
+BOOL cmpIpInfoIsEqualWithFile(ADAPTER_INFO * pAdaInfo, TCHAR *pIniPath)
+{
+	TCHAR ipFileBuff[IP_STR_LEN] = {0};
+	TCHAR maskFileBuff[MASK_STR_LEN] = {0};
+	TCHAR gateWayFileBuff[GATE_STR_LEN] = {0};
+
+	
+	readIpStrFromFileByMac(pAdaInfo->mac, pIniPath, ipFileBuff);
+	if(!cmpAdaIpIsEqualIpStr(pAdaInfo, ipFileBuff))
+		return FALSE;
+
+	readMaskStrFromFileByMac(pAdaInfo->mac, pIniPath, maskFileBuff);
+	if(!cmpAdaMaskIsEqualMaskStr(pAdaInfo, maskFileBuff))
+		return FALSE;
+
+	readGateWayStrFromFileByMac(pAdaInfo->mac, pIniPath, gateWayFileBuff);
+	if(!cmpAdaGateWayIsEqualMaskStr(pAdaInfo, gateWayFileBuff))
+		return FALSE;
+
+	return TRUE;
+
+}
+//±£´æÒ»¿éÍø¿¨ÐÅÏ¢µÄº¯Êý
+VOID saveAdaIpToFile(ADAPTER_INFO * pAdaInfo, TCHAR *pIniPath)
+{
+    TCHAR logDhcpBuff[DHCP_LEN] = {0};
+    TCHAR logIpBuff[IP_STR_LEN] = {0};
+    TCHAR logMaskBuff[MASK_STR_LEN] = {0};
+    TCHAR logGateWayBuff[GATE_STR_LEN] = {0};
+
+    writeDhcpStatusToFileByMac(pAdaInfo->dhcpStatus, pAdaInfo->mac, pIniPath, logDhcpBuff);
+
+	//Èç¹ûÊÇͨ¹ýDHCPµÄ·½Ê½»ñÈ¡µÄIP£¬ÔòÖ»±£´æDHCPÐÅÏ¢µ½iniÎļþ
+	if(cmpStrIsEqual(pAdaInfo->dhcpStatus, DHCP_ON))
+	{
+		LogEvent(_T("[QGA]save mac:%s dhcp:%s  to file"), pAdaInfo->mac, logDhcpBuff);
+		return;
+	}
+    writeIpStrToFileByMac(pAdaInfo->ipMaskVec, pAdaInfo->mac, pIniPath, logIpBuff);
+    writeMaskStrToFileByMac(pAdaInfo->ipMaskVec, pAdaInfo->mac, pIniPath, logMaskBuff);
+    writeGateWayStrToFileByMac(pAdaInfo->gateWayVec, pAdaInfo->mac, pIniPath, logGateWayBuff);
+
+    LogEvent(_T("[QGA]save mac:%s dhcp:%s ip:%s mask %s gateway %s to file"), pAdaInfo->mac, logDhcpBuff, logIpBuff, logMaskBuff, logGateWayBuff);
+    
+}
+
+//±£´æÒ»¿éÍø¿¨DNSÐÅÏ¢µÄº¯Êý
+VOID saveAdaDnsToFile(ADAPTER_INFO * pAdaInfo, TCHAR *pIniPath)
+{
+
+	TCHAR logDnsBuff[DNS_STR_LEN] = {0};
+
+	if(!cmpDnsInfoIsEqualWithFile(pAdaInfo, pIniPath))
+		writeDnsStrToFileByMac(pAdaInfo->dns, pAdaInfo->mac, pIniPath, logDnsBuff);
+
+	LogEvent(_T("[QGA]save mac:%s dns:%s to file"), pAdaInfo->mac, logDnsBuff);
+
+}
+VOID saveAdaIpDnsToFile(ADAPTER_INFO * pAdaInfo, TCHAR *pIniPath)
+{
+	saveAdaIpToFile(pAdaInfo, pIniPath);
+	saveAdaDnsToFile(pAdaInfo, pIniPath);
+}
+//±£´æÍø¿¨MACºÍIP DNSÐÅÏ¢µ½config.ini
+VOID saveNicInfo(std::vector<ADAPTER_INFO  *> &pNicInfoVec, TCHAR *pIniPath)
+{
+	LogEvent(_T("[QGA]save nic config info start."));
+	if(pNicInfoVec.size() != 0)
+	{
+		for(std::vector<ADAPTER_INFO *>::iterator iter=pNicInfoVec.begin(); iter!=pNicInfoVec.end(); iter++)
+		{
+			 saveAdaIpDnsToFile((*iter), pIniPath);
+		}
+	}
+	LogEvent(_T("[QGA]save nic config info end."));
+}
+
+VOID setAdaIpFromDhcp(ADAPTER_INFO * pAdaInfo)
+{
+	TCHAR cmd[MAX_PATH] = {0};
+
+	if(g_VistaOrLater)
+	{
+		wsprintf(cmd, _T("netsh interface ip set address name=\"%d\" source=dhcp"), pAdaInfo->index);
+	}
+	else
+	{
+		wsprintf(cmd, _T("netsh interface ip set address name=\"%s\" source=dhcp"), pAdaInfo->name);
+	}
+    _tsystem(cmd);
+	LogEvent(_T("[QGA] exec mac %s cmd %s"), pAdaInfo->mac, cmd);
+}
+
+VOID setAdaDnsFromDhcp(ADAPTER_INFO * pAdaInfo)
+{
+	TCHAR cmd[MAX_PATH] = {0};
+
+	if(g_VistaOrLater)
+	{
+		wsprintf(cmd, _T("netsh interface ip set dns name=\"%d\" source=dhcp"), pAdaInfo->index);
+	}
+	else
+	{
+		wsprintf(cmd, _T("netsh interface ip set dns name=\"%s\" source=dhcp"), pAdaInfo->name);
+	}
+	_tsystem(cmd);
+	LogEvent(_T("[QGA] exec mac %s cmd %s"), pAdaInfo->mac, cmd);
+}
+
+VOID setAdaIpDnsFromDhcpSyncFile(ADAPTER_INFO * pAdaInfo)
+{
+	setAdaIpFromDhcp(pAdaInfo);
+	//ɾ³ýºó£¬Ö±½Ó±£´æDHCPµÄ¸ñʽµ½Îļþ
+	writeDhcpStatusToFileByMac(DHCP_ON, pAdaInfo->mac, g_configPath, NULL);
+
+	setAdaDnsFromDhcp(pAdaInfo);
+	writeDnsStrToFileByMac(pAdaInfo->dns, pAdaInfo->mac, g_configPath, NULL);
+
+
+}
+VOID createDnsCmd(ADAPTER_INFO * pAdaInfo, LPCTSTR dns, BOOL first, TCHAR *cmd)
+{
+	if(g_VistaOrLater)
+	{
+		wsprintf(cmd,
+			_T("netsh interface ip %s dns name=\"%d\" %s %s=%s %s"),
+			first ? _T("set") : _T("add"),
+			pAdaInfo->index,
+			first ? _T("source=static") : _T(""),
+			g_VistaOrLater ? _T("address") : _T("addr"),
+			dns,
+			g_VistaOrLater ? _T("validate = no") : _T(""));
+	}
+	else //only for xp
+	{
+		wsprintf(cmd,
+			_T("netsh interface ip %s dns name=\"%s\" %s %s=%s %s"),
+			first ? _T("set") : _T("add"),
+			pAdaInfo->name,
+			first ? _T("source=static") : _T(""),
+			g_VistaOrLater ? _T("address") : _T("addr"),
+			dns,
+			g_VistaOrLater ? _T("validate = no") : _T(""));
+	}
+	LogEvent(_T("[QGA] exec mac %s cmd %s"), pAdaInfo->mac, cmd);
+}
+VOID setAdaDnsFromStr(ADAPTER_INFO * pAdaInfo, TCHAR *dnsBuff)
+{
+	TCHAR *dns = NULL;
+	TCHAR *dnsNext = NULL;
+	BOOL first = TRUE;
+	TCHAR cmd[MAX_PATH];
+
+
+	dns = _tcschr(dnsBuff, _T(':'));
+
+	while ((dns != NULL))
+	{
+		dnsNext = _tcschr(&dns[1], _T(':'));
+		if(dnsNext) 
+			*dnsNext = 0;
+		createDnsCmd(pAdaInfo, &dns[1], first, cmd);
+		_tsystem(cmd);
+		first = FALSE;
+		dns = dnsNext;
+	}
+}
+/*ÉèÖÃÍø¿¨µÄDNS*/
+VOID setAdaDnsFromFile(ADAPTER_INFO * pAdaInfo, TCHAR *pIniPath)
+{
+	TCHAR dnsFileBuff[DNS_STR_LEN] = {0};
+	
+	readDnsStrFromFileByMac(pAdaInfo->mac, pIniPath, dnsFileBuff);
+
+	//Èç¹û´ø»Ö¸´µÄÊÇ¿Õdns£¬Ö±½Ó´Ódhcp»ñÈ¡dnsºóÍ˳ö
+	if(isNullIp(dnsFileBuff))
+	{
+		LogEvent(_T("[QGA]restore dns in file is null, set MAC %s dns form dhcp."), pAdaInfo->mac);
+		setAdaDnsFromDhcp(pAdaInfo);
+		return;
+	}
+	else 
+	{
+		//±È½ÏµÄDNSÊÇ·ñÏàµÈµÄ¹¤×÷²»ÄÜ·ÅÔÚÕâÀïÃæ£¬Òª·ÅÔÚÍâÃæ
+		LogEvent(_T("[QGA]set MAC %s dns %s ."), pAdaInfo->mac, dnsFileBuff);
+		setAdaDnsFromStr(pAdaInfo, dnsFileBuff);
+	}
+}
+
+VOID setOSversion(VOID)
+{
+    OSVERSIONINFO osvi;
+	ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
+	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+	GetVersionEx(&osvi);
+	g_VistaOrLater = (osvi.dwMajorVersion >= 6);
+}
+
+//Çø·ÖÁËXP£¬¹ÊÒª²âÊÔXP
+VOID createIpCmd(ADAPTER_INFO * pAdaInfo, LPCTSTR ip, LPCTSTR mask, BOOL first, TCHAR *cmd)
+{
+	if(g_VistaOrLater)
+	{
+		wsprintf(cmd,
+			_T("netsh interface ip %s address name=\"%d\" %s %s=%s mask=%s"),
+			first ? _T("set") : _T("add"),
+			pAdaInfo->index,
+			first ? _T("source=static") : _T(""),
+			g_VistaOrLater ? _T("address") : _T("addr"),
+			ip,
+			mask);
+	}
+	else //only for xp
+	{
+		wsprintf(cmd,
+			_T("netsh interface ip %s address name=\"%s\" %s %s=%s mask=%s"),
+			first ? _T("set") : _T("add"),
+			pAdaInfo->name,
+			first ? _T("source=static") : _T(""),
+			g_VistaOrLater ? _T("address") : _T("addr"),
+			ip,
+			mask);
+	}
+	LogEvent(_T("[QGA] exec mac %s cmd %s"), pAdaInfo->mac, cmd);
+}
+//gwmetric==0ÊDZíÊ¾Íø¿¨ÔÚÍ¬Ò»Íø¶Î£¬ÕâÀïÆäʵÊDz»ÑϽ÷µÄ
+VOID createGateWayCmd(ADAPTER_INFO * pAdaInfo, LPCTSTR gateWay, TCHAR *cmd)
+{
+	if(g_VistaOrLater)
+	{
+		wsprintf(cmd,
+				_T("netsh interface ip add address name=\"%d\" gateway=%s gwmetric=0"),
+				pAdaInfo->index,
+				gateWay);
+	}
+	else
+	{
+		wsprintf(cmd,
+				_T("netsh interface ip add address name=\"%s\" gateway=%s gwmetric=0"),
+				pAdaInfo->name,
+				gateWay);
+	}
+}
+
+//¸Ãº¯ÊýµÄ²»¹æ·¶ÔÚÓÚ:ÐÞ¸ÄÁËÈë²Î±äÁ¿µÄÖµ
+VOID setAdaIpFromStr(ADAPTER_INFO * pAdaInfo, TCHAR * ipBuff, TCHAR * maskBuff, TCHAR * gateWay)
+{
+    TCHAR *ip = NULL;
+    TCHAR *mask = NULL;
+    TCHAR *gate = NULL;
+
+	TCHAR *ipNext = NULL;
+    TCHAR *maskNext = NULL;
+    TCHAR *gateNext = NULL;
+
+    BOOL first = TRUE;
+    TCHAR cmd[MAX_PATH];
+    
+    ip = _tcschr(ipBuff, _T(':'));
+    mask = _tcschr(maskBuff, _T(':'));
+    gate = _tcschr(gateWay, _T(':'));
+    
+    while ((ip != NULL) && (mask != NULL))
+    {
+		ipNext = _tcschr(&ip[1], _T(':'));
+		if(ipNext) 
+			*ipNext = 0;
+		maskNext = _tcschr(&mask[1], _T(':'));
+		if(maskNext) 
+			*maskNext = 0;
+
+        createIpCmd(pAdaInfo, &ip[1], &mask[1] , first, cmd);
+        _tsystem(cmd);
+        first = FALSE;
+       
+		ip = ipNext;
+		mask = maskNext;
+    }
+
+    
+    while ((gate != NULL))
+    {
+		gateNext = _tcschr(&gate[1], _T(':'));
+		if(gateNext) 
+			*gateNext = 0;
+
+        createGateWayCmd(pAdaInfo, &gate[1], cmd);
+        _tsystem(cmd);
+        
+		gate = gateNext;
+    }
+}
+
+VOID setAdaIpFromFile(ADAPTER_INFO * pAdaInfo, TCHAR *pIniPath)
+{
+    TCHAR dhcpBuff[DHCP_LEN] = {0};
+    TCHAR ipBuff[IP_STR_LEN] = {0};
+    TCHAR maskBuff[MASK_STR_LEN] = {0};
+    TCHAR gateWay[GATE_STR_LEN] = {0};
+
+    readDhcpStatusFromFileByMac(pAdaInfo->mac, pIniPath, dhcpBuff);
+
+    //Èç¹ûÊÇ¿ªÆôDHCP·½Ê½£¬Ôò´ÓDHCP·½Ê½»ñÈ¡IP
+    if(cmpStrIsEqual(dhcpBuff, DHCP_ON))
+    {
+        LogEvent(_T("[QGA]set MAC %s ip form dhcp."), pAdaInfo->mac);
+		setAdaIpFromDhcp(pAdaInfo);
+        return;    
+    }
+
+    //´ÓÅäÖÃÎļþÖжÁÈ¡IP MASK GATEWAYºó£¬½øÐÐÉèÖÃ
+    readIpStrFromFileByMac(pAdaInfo->mac, pIniPath, ipBuff);
+    
+	/*Èç¹û´ý»Ö¸´µÄIPÊÇ¿ÕIP£¬ÔòÖ±½Ó´ÓDHCP»ñȡһ¸ö169µÄIPºóÍ˳ö*/
+	if(isNullIp(ipBuff))
+	{
+		LogEvent(_T("[QGA]restore ip in file is null, set MAC %s ip form dhcp."), pAdaInfo->mac);
+		setAdaIpFromDhcp(pAdaInfo);
+		writeDhcpStatusToFileByMac(DHCP_ON, pAdaInfo->mac, pIniPath, NULL);
+	}
+	else
+	{
+		readMaskStrFromFileByMac(pAdaInfo->mac, pIniPath, maskBuff);
+		readGateWayStrFromFileByMac(pAdaInfo->mac, pIniPath, gateWay);
+		LogEvent(_T("[QGA]set MAC %s ip %s netmask %s gateway %s."), pAdaInfo->mac, ipBuff, maskBuff, gateWay);
+		setAdaIpFromStr(pAdaInfo, ipBuff, maskBuff, gateWay);
+	}
+    
+}
+
+//³åÍ»ÊǼì²âʲô£º¼ì²â´ýÒª»Ö¸´µÄIP´®£¬ÊÇ·ñÒѾ­´æÔÚÓÚÆäËûÍø¿¨Ö®ÉÏ
+BOOL checkIpConflict(ADAPTER_INFO * pAdaInfo, TCHAR *ipStr)
+{
+
+    DWORD dwRet;
+	std::vector<ADAPTER_INFO *> pAdaInfoVect;
+    
+	if(isNullIp(ipStr))
+		return FALSE;
+
+    //ÖØÐ»ñÈ¡µ±Ç°Íø¿¨ËùÓеÄIPµØÖ·
+    if ((dwRet = GetNicInfo(pAdaInfoVect)) != ERROR_SUCCESS)
+    {
+        LogEvent(_T("[QGA]cannot get nic info."));
+        return dwRet;
+    }
+
+	if(pAdaInfoVect.size() != 0)
+	{
+		for(std::vector<ADAPTER_INFO*>::iterator iter=pAdaInfoVect.begin(); iter!=pAdaInfoVect.end(); iter++)
+		{
+			//Ìø¹ý×Ô¼º£¬Ö»±È½ÏÆäËûÍø¿¨
+			if((*iter)->index == pAdaInfo->index)
+				continue;
+
+			if((*iter)->ipMaskVec.size() != 0)
+			{
+				for(std::vector<IP_MASK_INFO>::iterator iter1=(*iter)->ipMaskVec.begin(); iter1!=(*iter)->ipMaskVec.end(); iter1++)
+				{
+					if(checkIpInStr(ipStr, (*iter1).ip))
+					{
+						LogEvent(_T("[QGA] mac %s want restore or inherit ip %s , but conflict with mac %s "), pAdaInfo->mac, ipStr, (*iter)->mac);
+						freeAdaInfoVec(pAdaInfoVect);
+						return TRUE;
+					}
+				}
+			}
+		}
+	}
+	freeAdaInfoVec(pAdaInfoVect);
+    return FALSE;
+}
+DWORD updateAdaFromFile(ADAPTER_INFO * pAdaInfo, TCHAR *pIniPath)
+{
+    TCHAR ipFileBuff[IP_STR_LEN] = {0};
+	TCHAR dhcpFileBuff[DHCP_LEN] = {0};
+    DWORD ret = SUCCESS_CODE;
+
+	do{
+	readDhcpStatusFromFileByMac(pAdaInfo->mac, pIniPath, dhcpFileBuff);
+
+	//Èç¹û¶¼ÊÇ´ÓDHCP»ñÈ¡µÄIP£¬Ôò²»ÐèÒª»Ö¸´IP
+		if(cmpStrIsEqual(pAdaInfo->dhcpStatus, DHCP_ON) && cmpStrIsEqual(dhcpFileBuff, DHCP_ON)){
+			//Èç¹ûDNS²»ÏàµÈ£¬ÔòÉèÖÃDNSºóÍ˳ö
+			if(!cmpDnsInfoIsEqualWithFile(pAdaInfo, pIniPath))
+				setAdaDnsFromFile(pAdaInfo, pIniPath);
+			break;
+       }
+
+	readIpStrFromFileByMac(pAdaInfo->mac, pIniPath, ipFileBuff);
+
+    //ip ²»ÏàµÈÔò×ö»Ö¸´¶¯×÷¡£
+		if(!cmpIpInfoIsEqualWithFile(pAdaInfo,pIniPath)){
+			if(!checkIpConflict(pAdaInfo, ipFileBuff)){
+            setAdaIpFromFile(pAdaInfo, pIniPath);
+			}else{
+            ret = CONFLICT_CODE;
+				break;
+        }
+    }
+
+		//dns²»ÏàµÈÔò×öDNS»Ö¸´¶¯×÷
+		if(!cmpDnsInfoIsEqualWithFile(pAdaInfo, pIniPath))
+			setAdaDnsFromFile(pAdaInfo, pIniPath);
+	}while(0);
+
+    return ret;
+}
+
+DWORD updateNicInfo(std::vector<ADAPTER_INFO  *> &pNicInfoVec, TCHAR *pIniPath)
+{	
+    TCHAR ipFileBuff[IP_STR_LEN] = { 0 };
+    std::vector<ADAPTER_INFO *> infoList; 
+    DWORD ret = SUCCESS_CODE;
+
+	if(pNicInfoVec.size() != 0)
+	{
+		for(std::vector<ADAPTER_INFO *>::iterator iter=pNicInfoVec.begin(); iter!=pNicInfoVec.end(); iter++)
+		{
+			if(isMacExistInFile((*iter)->mac, pIniPath))
+			{
+				//IP³åÍ»
+				if(CONFLICT_CODE == updateAdaFromFile(*iter, pIniPath))
+				{
+					setAdaIpFromDhcp((*iter));
+					infoList.push_back(*iter);
+					LogEvent(_T("[QGA] mac %s restore ip conflict, insert to list"),(*iter)->mac);
+					continue;
+				}
+			}
+			else
+			{
+				saveAdaIpDnsToFile(*iter, pIniPath);
+			}
+		}
+	
+		if(infoList.size() != 0)
+		{
+			//È绹·¢Éú³åÍ»£¬¾ÍÊÇϵͳ±¾À´IP¾Í´æÔÚ³åÍ»£¬±¨´í»òÍ˳ö£¬²»Êǻָ´IP¹¦ÄܵÄÎÊÌâ
+			for(std::vector<ADAPTER_INFO *>::iterator iter=infoList.begin(); iter!=infoList.end(); iter++)
+			{
+				readIpStrFromFileByMac((*iter)->mac, pIniPath, ipFileBuff);
+				if(!checkIpConflict((*iter), ipFileBuff))
+				{
+					setAdaIpFromFile((*iter), pIniPath);
+					//dns²»ÏàµÈÔò×öDNS»Ö¸´¶¯×÷
+					if(!cmpDnsInfoIsEqualWithFile((*iter), pIniPath))
+						setAdaDnsFromFile((*iter), pIniPath);
+				}
+				else
+				{
+					ret = CONFLICT_CODE;
+					LogEvent(_T("[QGA] mac %s can not restore ip, because conflict"),(*iter)->mac);
+				}
+			}
+		}
+	}
+
+    return ret;
+}
+
+
+DWORD restoreNicIp(std::vector<ADAPTER_INFO  *> &pAdaInfoVect)
+{
+    DWORD ret = SUCCESS_CODE;
+
+    if (FileExist(g_configPath))
+    {
+        ret = updateNicInfo(pAdaInfoVect, g_configPath);
+    }
+    else
+    {
+        saveNicInfo(pAdaInfoVect, g_configPath);
+		ret = NO_FILE_CODE;
+    }
+
+    return ret ;
+
+}
+/*¼ì²éIP»Ö¸´ÊÇ·ñ³É¹¦*/
+DWORD checkRestoreNicIpResult(VOID)
+{
+	DWORD ret = SUCCESS_CODE;
+
+	TCHAR ipFileBuff[IP_STR_LEN] = {0};
+	TCHAR ipAdaBuff[IP_STR_LEN] = {0};
+	TCHAR dhcpFileBuff[DHCP_LEN] = {0};
+	DWORD dwRet;
+
+	std::vector<ADAPTER_INFO  *> pAdaInfoVect;
+
+	if ((dwRet = GetNicInfo(pAdaInfoVect)) != ERROR_SUCCESS)
+	{
+		LogEvent(_T("[QGA]cannot get nic info."));
+		return dwRet;
+	}
+
+	for(std::vector<ADAPTER_INFO *>::iterator iter=pAdaInfoVect.begin(); iter!=pAdaInfoVect.end(); iter++)
+	{
+		if(isMacExistInFile((*iter)->mac, g_configPath))
+		{
+			memset(dhcpFileBuff, 0, sizeof(dhcpFileBuff));
+			readDhcpStatusFromFileByMac((*iter)->mac, g_configPath, dhcpFileBuff);
+			//Èç¹û¶¼ÒѾ­ÊÇ´ÓDHCP»ñÈ¡µÄIP£¬Ôò˵Ã÷»Ö¸´³É¹¦¡£
+			if(cmpStrIsEqual((*iter)->dhcpStatus, DHCP_ON) && cmpStrIsEqual(dhcpFileBuff, DHCP_ON))
+			{
+				//dns²»ÏàµÈÔò×öDNS»Ö¸´¶¯×÷
+				if(!cmpDnsInfoIsEqualWithFile((*iter), g_configPath))
+					setAdaDnsFromFile((*iter), g_configPath);
+				continue;
+			}
+
+			//Èç¹ûÎļþÊÇ´ÓDHCP»ñÈ¡£¬µ«ÊÇʵ¼Êȱ²»ÊÇ´ÓDHCP,˵Ã÷ûÓгɹ¦£¬ÖØÐ´ÓDHCP»Ö¸´Ò»´ÎIP
+			if(cmpStrIsEqual((*iter)->dhcpStatus, DHCP_OFF) && cmpStrIsEqual(dhcpFileBuff, DHCP_ON))
+			{
+				LogEvent(_T("[QGA] mac %s ip not from dhcp ,but file is from dhcp, restore ip from dhcp"), (*iter)->mac);
+				setAdaIpFromDhcp(*iter);
+				//dns²»ÏàµÈÔò×öDNS»Ö¸´¶¯×÷
+				if(!cmpDnsInfoIsEqualWithFile((*iter), g_configPath))
+					setAdaDnsFromFile((*iter), g_configPath);
+				ret = ERROR_CODE;
+				continue;
+			}
+
+			//Èç¹ûÎļþÊÇ·ÇDHCP£¬Êµ¼ÊµÄIPÈ´ÊÇDHCP,Ôò³¢ÊÔ»Ö¸´Ò»´Î
+			if(cmpStrIsEqual((*iter)->dhcpStatus, DHCP_ON) && cmpStrIsEqual(dhcpFileBuff, DHCP_OFF))
+			{
+				LogEvent(_T("[QGA] mac %s ip from dhcp ,but file is not from dhcp, restore ip from file"), (*iter)->mac);
+				setAdaIpFromFile(*iter, g_configPath);
+				//dns²»ÏàµÈÔò×öDNS»Ö¸´¶¯×÷
+				if(!cmpDnsInfoIsEqualWithFile((*iter), g_configPath))
+					setAdaDnsFromFile((*iter), g_configPath);
+				ret = ERROR_CODE;
+				continue;
+			}
+
+			//Èç¹ûÎļþÊÇ·ÇDHCP£¬Êµ¼ÊµÄIPÒ²ÊÇ·ÇDHCP,µ«ÊÇIP¶Ô²»ÉÏ£¬Ôò³¢ÊÔ»Ö¸´Ò»´Î
+			if(cmpStrIsEqual((*iter)->dhcpStatus, DHCP_OFF) && cmpStrIsEqual(dhcpFileBuff, DHCP_OFF))
+			{
+				memset(ipFileBuff, 0, sizeof(ipFileBuff));
+				readIpStrFromFileByMac((*iter)->mac, g_configPath, ipFileBuff);
+				
+				if(!cmpAdaIpIsEqualIpStr((*iter), ipFileBuff))
+				{
+					memset(ipAdaBuff, 0, sizeof(ipAdaBuff));
+					getIpFromAdaInfo(*iter, ipAdaBuff);
+					LogEvent(_T("[QGA] mac %s ip %s is not same as file %s, so restore ip from file"), (*iter)->mac, ipAdaBuff, ipFileBuff);
+					setAdaIpFromFile(*iter, g_configPath);
+					ret = ERROR_CODE;
+				}
+
+				//dns²»ÏàµÈÔò×öDNS»Ö¸´¶¯×÷
+				if(!cmpDnsInfoIsEqualWithFile((*iter), g_configPath))
+					setAdaDnsFromFile((*iter), g_configPath);
+
+				continue;
+			}
+
+		}
+	}
+	freeAdaInfoVec(pAdaInfoVect);
+	return ret ;
+}
+
+VOID delRecordByMac(LPCTSTR lpMac, TCHAR *pIniPath)
+{
+	WritePrivateProfileString(lpMac, NULL, NULL, pIniPath);
+}
+
+/*ʹÓÃÁËÈ«¾Ö±äÁ¿£¬¸Ãº¯ÊýÊDz»¿ÉÖØÈëµÄ:Õâ¸öº¯ÊýÊÇÔÚ¸Éʲô £¿µ±Ç°Íø¿¨ÉèÖõÄIP£¬ÊÇ·ñÓëÎļþÖÐÒѾ­´æÔÚµÄ
+IP³åÍ»£¬Èç¹û³åÍ»£¬ÎÒÃÇÈÏΪÎļþÖеÄIPÊǶàÓàµÄ£¬¾ÍÒªÇå³þ¼Ç¼ÎļþÖеĶÔÓ¦¼Ç¼¡£µ«ÒªÖ÷Òª£¬²»ÒªÓë×Ô¼ºµÄ
+MACµØÖ·±È½Ï£¬¼´ÒªÌø¹ý×Ô¼º£¬²»ÈÏΪ×Ô¼ºÓë×Ô¼º³åÍ»*/
+VOID clearConflictIpInConfig(ADAPTER_INFO * pAdaInfo, TCHAR *pIniPath)
+{
+	/*¸Ãº¯ÊýÊDz»¿ÉÖØÈëµÄ£¬ÁíÍâÒ»¸öº¯ÊýҲʹÓÃÁËg_preMem£¬¶þÕßÒ²²»ÄÜͬʱʹÓÃ*/
+	TCHAR *chSectionNames = g_preMem;
+	TCHAR *pSectionName;
+	TCHAR ipStr[IP_STR_LEN] = {0};
+	int i, j = 0; 
+
+	memset(g_preMem, 0, MAX_PREBUFF_LEN*sizeof(TCHAR));
+	GetPrivateProfileSectionNames(chSectionNames, MAX_PREBUFF_LEN, pIniPath);  
+	for(i=0 ;i<MAX_PREBUFF_LEN ;i++,j++)
+	{
+		if(chSectionNames[0]=='\0')
+			break;
+
+		if(chSectionNames[i]=='\0')
+		{
+			pSectionName=&chSectionNames[i-j]; 
+			j = -1;
+
+			//Ìø¹ý×Ô¼º
+			if(cmpStrIsEqual(pSectionName, pAdaInfo->mac))
+			{
+				continue;
+			}
+
+			memset(ipStr, 0, sizeof(ipStr));
+			readIpStrFromFileByMac(pSectionName, pIniPath, ipStr);
+
+			if(!isNullIp(ipStr))
+			{
+				if((pAdaInfo)->ipMaskVec.size() != 0)
+				{
+					for(std::vector<IP_MASK_INFO>::iterator iter=pAdaInfo->ipMaskVec.begin(); iter!=pAdaInfo->ipMaskVec.end(); iter++)
+					{
+						if(!isNullIp((*iter).ip) && checkIpInStr(ipStr, (*iter).ip))
+						{
+							LogEvent(_T("[QGA] clear mac %s ip %s in ini-file, ip %s already at mac %s"), pSectionName, ipStr, (*iter).ip, pAdaInfo->mac);
+							WritePrivateProfileString(pSectionName, NULL, NULL, pIniPath);
+							/*ÕÒµ½Ò»¸ö¾ÍÍ˳öÁË£¬ÕâÀïÊDz»ÊÇÒª¼ÌÐøÕÒ£¬ÏÈÕâÑù´¦Àí*/
+							return;
+						}
+					}
+				}
+			}
+
+
+			if(chSectionNames[i+1]==0)
+			{
+				break;
+			}
+		} 
+	}
+}
+
+/*¸Ãº¯ÊýÓësaveAdaIpToFileÎ¨Ò»Çø±ð£º»á¼ì²éconfig.iniÖеÄIP³åÍ»£¬µ«ÊÇÓ¦¸Ã½÷É÷ʹÓÃ*/
+VOID updateFileIpFromAda(ADAPTER_INFO * pAdaInfo, TCHAR *pIniPath)
+{
+	clearConflictIpInConfig(pAdaInfo, pIniPath);
+	saveAdaIpToFile(pAdaInfo, pIniPath);
+}
+
+VOID updataFileDnsFromAda(ADAPTER_INFO * pAdaInfo, TCHAR *pIniPath)
+{
+	saveAdaDnsToFile(pAdaInfo, pIniPath);
+}
+
+DWORD updateFileInfo(ADAPTER_INFO * pAdaInfo, TCHAR *pIniPath)
+{
+	
+	TCHAR dhcpFileBuff[DHCP_LEN] = {0};
+	DWORD ret = SUCCESS_CODE;
+	BOOL adaDhcp = FALSE;
+	BOOL fileDhcp = FALSE;
+
+	readDhcpStatusFromFileByMac(pAdaInfo->mac, pIniPath, dhcpFileBuff);
+	fileDhcp = cmpStrIsEqual(dhcpFileBuff, DHCP_ON);
+
+	adaDhcp = cmpStrIsEqual(pAdaInfo->dhcpStatus, DHCP_ON);
+
+
+	if(adaDhcp && (!fileDhcp))/*Èç¹ûÊÇ´ÓDHCP»ñÈ¡IP£¬µ«ÅäÖÃÎļþ²»ÊÇ£¬Ôò¸üÐÂÎļþ*/
+		{
+		writeDhcpStatusToFileByMac(DHCP_ON, pAdaInfo->mac, pIniPath, NULL);
+		LogEvent(_T("[QGA]change file mac %s ip from dhcp "), pAdaInfo->mac);
+		}
+	else if((!adaDhcp) && fileDhcp) /*Èç¹ûÍø¿¨²»´ÓDHCP»ñÈ¡£¬µ«ÅäÖÃÎļþÊÇ´ÓDHCP»ñÈ¡,¸üÐÂÎļþ*/
+		{
+		updateFileIpFromAda(pAdaInfo, pIniPath);
+	}
+	else if((!adaDhcp)&&(!fileDhcp))/*Èç¹ûÍø¿¨²»´ÓDHCP»ñÈ¡£¬ÅäÖÃÎļþÒ²²»ÊÇ£¬¶Ô±ÈIPÊÇ·ñÏàͬ¾ö¶¨ÊÇ·ñ¸üÐÂÎļþ*/
+	{
+		
+	//ip mask gateway²»ÏàµÈÔò¸üÐÂFileÎļþ
+	if(!cmpIpInfoIsEqualWithFile(pAdaInfo,pIniPath))
+		updateFileIpFromAda(pAdaInfo, pIniPath);
+	}
+	//else //Èç¹û¶¼ÊÇͨ¹ýDHCP»ñÈ¡IP£¬Ôò²»ÐèÒª¸üÐÂÎļþIP(adaDhcp && fileDhcp)
+	//{
+		//LogEvent(_T("[QGA]mac %s ip and file all from dhcp, do nothing"), pAdaInfo->mac);
+	//}
+
+
+	//Èç¹ûDNS²»ÏàµÈ£¬Ôò¸üÐÂfileÎļþ
+	if(!cmpDnsInfoIsEqualWithFile(pAdaInfo, pIniPath))
+	{
+		updataFileDnsFromAda(pAdaInfo, pIniPath);
+	}
+
+	return ret;
+}
+
+DWORD updateConfigFile(std::vector<ADAPTER_INFO  *> &pNicInfoVec, TCHAR *pIniPath)
+{	
+	TCHAR ipBuff[IP_STR_LEN] = { 0 };
+	std::vector<ADAPTER_INFO *> infoList; 
+	DWORD ret = SUCCESS_CODE;
+
+	if(pNicInfoVec.size() != 0)
+	{
+		for(std::vector<ADAPTER_INFO *>::iterator iter=pNicInfoVec.begin(); iter!=pNicInfoVec.end(); iter++)
+		{
+			if(isMacExistInFile((*iter)->mac, pIniPath))
+			{
+				//¸üÐÂÅäÖÃÎļþÀïÃæµÄIP¼Ç¼
+				updateFileInfo((*iter), pIniPath);
+			}
+			else
+			{
+				/*з¢ÏÖµÄÍø¿¨£¬¼ì²éÆä¼Ì³ÐµÄIPÊÇ·ñÓëÏÖ´æÍø¿¨³åÍ»*/
+				getIpFromAdaInfo(*iter, ipBuff);
+				if(checkIpConflict(*iter, ipBuff))
+				{
+					//Èç¹ûÆä¼Ì³ÐÍø¿¨Óëϵͳ³åÍ»£¬Ôòɾ³ýÆäÏÖÔÚIPÓëDNS
+					LogEvent(_T("[QGA]new mac %s ip %s conflict with other nic , set ip dns from dhcp"), (*iter)->mac, ipBuff);
+					setAdaIpDnsFromDhcpSyncFile(*iter);
+				}
+				else
+				{
+					/*¿¼ÂÇʹÓÃsaveAdaIpDnsToFile»¹ÊÇupdateFileIpFromAda*/
+					saveAdaIpDnsToFile(*iter, pIniPath);
+				}
+			}
+				
+		}
+	}
+	return ret;
+}
+
+VOID setIniFilePath()
+{
+	GetModuleFileName(NULL, g_configPath, sizeof(g_configPath));
+	(_tcsrchr(g_configPath, _T('\\')))[1] = 0;
+	_tcscat(g_configPath, _T("config.ini"));
+       LogEvent(_T("[QAG] ini file %s %d"), g_configPath, MAC_LEN);
+}
+
+DWORD dealConfigFileByAdaInfo(std::vector<ADAPTER_INFO  *> & pAdaInfoVect)
+{
+	//DWORD dwRet = 0;
+	DWORD ret = SUCCESS_CODE;
+
+	if (FileExist(g_configPath))
+	{
+		ret = updateConfigFile(pAdaInfoVect, g_configPath);
+	}
+	else
+	{
+		saveNicInfo(pAdaInfoVect, g_configPath);
+	}
+
+	return ret ;
+}
+
+DWORD dealConfigFile(VOID)
+{
+	DWORD dwRet = 0;
+	DWORD ret = SUCCESS_CODE;
+
+	std::vector<ADAPTER_INFO  *> pAdaInfoVect;
+
+	if ((dwRet = GetNicInfo(pAdaInfoVect)) != ERROR_SUCCESS)
+	{
+		LogEvent(_T("[QGA]cannot get nic info."));
+		return dwRet;
+	}
+
+	if (FileExist(g_configPath))
+	{
+		ret = updateConfigFile(pAdaInfoVect, g_configPath);
+	}
+	else
+	{
+		saveNicInfo(pAdaInfoVect, g_configPath);
+	}
+
+	freeAdaInfoVec(pAdaInfoVect);
+
+	return ret ;
+
+}
+
+/*diff Ó¦ÓÃÁË first second ÀïÃæµÄ¿Õ¼ä£¬ÒªÔÚ¶þÕߺóÃæÏú»Ù*/
+VOID diffAdaVect(std::vector<ADAPTER_INFO  *> &first, std::vector<ADAPTER_INFO  *> &second, std::vector<ADA_DIFF_INFO> &diff)
+{
+	std::map<INT,ADAPTER_INFO *> first_index;
+	std::map<INT,ADAPTER_INFO *> second_index;
+
+	for(std::vector<ADAPTER_INFO *>::iterator iter=first.begin(); iter!=first.end(); iter++)
+	{
+		first_index[(*iter)->index] = (*iter);
+	}
+
+	for(std::vector<ADAPTER_INFO *>::iterator iter=second.begin(); iter!=second.end(); iter++)
+	{
+		second_index[(*iter)->index] = (*iter);
+	}
+
+	for(std::map<INT, ADAPTER_INFO *>::iterator iter=first_index.begin(); iter!=first_index.end(); iter++)
+	{
+		//Èç¹û¶þÖÐûÓУ¬ÔòÈÏΪÊÇɾ³ýÁ˵Ä
+		if (second_index.end() == second_index.find((*iter).first))
+		{
+			ADA_DIFF_INFO tmp ;
+			tmp.addOrDel = DEL_NIC;
+			tmp.adaInfo = (*iter).second;
+			diff.push_back(tmp);
+		}
+	}
+
+	for(std::map<INT, ADAPTER_INFO *>::iterator iter=second_index.begin(); iter!=second_index.end(); iter++)
+	{
+		//Èç¹ûÒ»ÖÐûÓУ¬ÔòÈÏΪÊÇÐÂÔöµÄ
+		if (first_index.end() == first_index.find((*iter).first))
+		{
+			ADA_DIFF_INFO tmp ;
+			tmp.addOrDel = ADD_NIC;
+			tmp.adaInfo = (*iter).second;
+			diff.push_back(tmp);
+		}
+	}
+
+}
+//ûÓÐÍø¿¨IDµÄ±ä¶à±äÉÙ£¬Ö»ÓÐipʼþ·¢Éú£¬È϶¨ÊÇIP±ä»¯£»ÕâÀïÈç¹ûÓÐʱ¼ä£¬ºóÐø¿ÉÒÔͨ¹ýDIFF²éÕÒµ½¸ü¼ÓÏêϸµÄ±ä»¯£¬¾«È·µ½Ò»¿éÖ¸¶¨Íø¿¨
+VOID doIpChangeEvent(std::vector<ADAPTER_INFO  *> &currAdaVect)
+{
+	dealConfigFileByAdaInfo(currAdaVect);
+}
+
+VOID doNicChangeEvnet(std::vector<ADA_DIFF_INFO> & diffAdaVect)
+{
+	//´¦ÀíÍø¿¨Ôö¼ÓÓëɾ³ýµÄʼþ
+	for(std::vector<ADA_DIFF_INFO>::iterator iter=diffAdaVect.begin(); iter!=diffAdaVect.end(); iter++)
+	{
+		//´¦ÀíÍø¿¨É¾³ý
+		if((*iter).addOrDel == DEL_NIC)
+		{
+			delRecordByMac((*iter).adaInfo->mac, g_configPath);
+			LogEvent(_T("[QGA]del mac %s record from config"), (*iter).adaInfo->mac);
+		}
+		else if((*iter).addOrDel == ADD_NIC) //´¦ÀíÍø¿¨Ôö¼Ó
+		{
+			//¿ÉÒÔ¿¼ÂÇ·â×°Ò»¸öº¯Êý£¬µ±Ç°Ê±¼äÀ´²»¼°ÁË
+			if(isMacExistInFile((*iter).adaInfo->mac, g_configPath))
+			{
+				//
+				if(CONFLICT_CODE == updateAdaFromFile((*iter).adaInfo, g_configPath))
+				{
+					/*Èç¹û´ý»Ö¸´µÄIP£¬Ó뵱ǰϵͳÏò³åÍ»£¬ÔòÖ±½Ó´ÓDHCP·ÖÅä*/
+					LogEvent(_T("[QGA]new mac %s restore ip but conflict with other nic , set ip dns from dhcp"), (*iter).adaInfo->mac);
+					setAdaIpDnsFromDhcpSyncFile((*iter).adaInfo);
+				}
+			}
+			else
+			{
+				//ÕâÀïÒª×öµÄ±È½ÏÍêÉÆ£¬»¹Òª¼ì²éÍø¿¨¼Ì³ÐÖÁ×¢²á±íµÄIPÊÇ·ñ³åÍ»£¬µ«ÊÇÕâ¸ö²»ÊÇIP»Ö¸´µÄ¹¦ÄÜ£¬¸ÃÎÊÌâÊÇϵͳ×ÔÉíÎÊÌâ
+				/*з¢ÏÖµÄÍø¿¨£¬¼ì²éÆä¼Ì³ÐµÄIPÊÇ·ñÓëÏÖ´æÍø¿¨³åÍ»*/
+				TCHAR ipBuff[IP_STR_LEN] = {0};
+				getIpFromAdaInfo((*iter).adaInfo, ipBuff);
+				if(checkIpConflict((*iter).adaInfo, ipBuff))
+				{
+					//Èç¹ûÆä¼Ì³ÐÍø¿¨IPÓëϵͳ³åÍ»£¬Ôòɾ³ýÆäÏÖÔÚIPÓëDNS
+					LogEvent(_T("[QGA]new mac %s ip %s conflict with other nic , set ip dns from dhcp"), (*iter).adaInfo->mac, ipBuff);
+					setAdaIpDnsFromDhcpSyncFile((*iter).adaInfo);
+				}
+				else
+				{
+					saveAdaIpDnsToFile((*iter).adaInfo, g_configPath);
+				}
+			}
+		}
+	}
+}
+
+DWORD WINAPI monitorThread (PVOID pParam)
+{
+	HANDLE hEvent[2];
+	INT nicCount = 0;
+	INT ipCount = 0;
+	INT timeOutCount = 0;
+	BOOL waitAlong = FALSE;
+	DWORD dwRet;
+	INT retryTimes = 0;
+
+	std::vector<ADAPTER_INFO  *> * pAdaInfoLastVect = new std::vector<ADAPTER_INFO  *> ();
+
+	if ((dwRet = GetNicInfo(*pAdaInfoLastVect)) != ERROR_SUCCESS)
+	{
+		LogEvent(_T("[QGA]cannot get nic info."));
+		return dwRet;
+	}
+	//½øÀ´¾Í½øÐÐÒ»´Î»Ö¸´£¬ÓдæÔڵıØÒª¡£
+	dwRet = restoreNicIp(*pAdaInfoLastVect);
+
+	/*Èç¹ûrestoreNicIpÀïÃæÖ»×öÁ˱£´æÎļþµÄ²Ù×÷£¬ÄÇôû±ØÒª¼ì²é»Ö¸´³É¹¦Óë·ñ*/
+	if(dwRet != NO_FILE_CODE)
+	{
+		while(retryTimes < RETRY_TIMES)
+		{
+			if(ERROR_SUCCESS == checkRestoreNicIpResult())
+			{
+				break;
+			}
+			Sleep(SLEEP_TIMES);
+			retryTimes++;
+		}
+	}
+	
+
+	hEvent[0]= CreateEvent(NULL, FALSE, FALSE, NULL);
+	hEvent[1]= CreateEvent(NULL, FALSE, FALSE, NULL);
+
+	DWORD dwFilter0 = REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | REG_NOTIFY_CHANGE_LAST_SET;
+	DWORD dwFilter1 = REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | REG_NOTIFY_CHANGE_LAST_SET;
+	HKEY hKey[2] = {NULL, NULL};
+
+	LogEvent(_T("[QGA]monitorThread start.\n"));
+
+	//´ò¿ª¼üÖµ
+	if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, NIC_CHANGE, 0, KEY_READ, &hKey[0]) != ERROR_SUCCESS)
+	{
+		LogEvent(_T("[QGA][monitorThread]:Open Register  failed.\n"));
+		return   ERROR_CODE;
+	}
+
+	if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, IP_CHANGE, 0, KEY_READ, &hKey[1]) != ERROR_SUCCESS)
+	{
+		LogEvent(_T("[QGA][monitorThread]:Open Register  failed.\n"));
+		return   ERROR_CODE;
+	}
+
+	//¼à¿ØÄ³Ò»Ïî±ä»¯
+	while (TRUE)
+	{
+
+		if (::RegNotifyChangeKeyValue(hKey[0],
+			TRUE,
+			dwFilter0,
+			hEvent[0],
+			TRUE) != ERROR_SUCCESS)
+		{
+			LogEvent(_T("[QGA][monitorFileThread]:Watch NIC_CHANGE failed.\n"));
+			return   ERROR_CODE;
+		}
+
+		if (::RegNotifyChangeKeyValue(hKey[1],
+			TRUE,
+			dwFilter1,
+			hEvent[1],
+			TRUE) != ERROR_SUCCESS)
+		{
+			LogEvent(_T("[QGA][monitorFileThread]:Watch IP_CHANGE failed.\n"));
+			return   ERROR_CODE;
+		}
+
+		DWORD index = WaitForMultipleObjects(2, hEvent, FALSE, (waitAlong ? INFINITE: 1500));
+
+		/*µ±Á¬Ðø¶à¸öʼþ·¢Éúʱ£¬µÈ´ýµ½Ã»ÓÐʼþ·¢ÉúµÄʱ¿Ì²ÅÖ´Ðж¯×÷£¬×öÁËÒ»¸öÑÓʱÅжϻúÖÆ*/
+		if(index == WAIT_OBJECT_0)
+		{
+			nicCount++;
+			waitAlong = FALSE;
+		}
+		else if(index == WAIT_OBJECT_0 + 1)
+		{
+			ipCount++;
+			waitAlong = FALSE;
+		}
+		else if (index == WAIT_TIMEOUT)
+		{
+
+			if((nicCount == 0) && (ipCount == 0))
+			{
+				timeOutCount++;
+				if(timeOutCount >= RETRY_TIMES)
+				{
+					timeOutCount = 0;
+					waitAlong = TRUE;
+					//LogEvent(_T("[QGA]:time out.\n"));
+				}
+				//Õâ¸öÊÇÑÓʱµÄ¹Ø¼ü,continue²»Äܵô
+				continue;
+			}
+
+			//Ö»Óе±Íø¿¨±ä»¯Ê¼þÈ«²¿³öÀ´Íê±Ïºó£¬²Å´¦Àíʼþ£¬¿¼ÂÇ·â×°³ÉÒ»¸öº¯Êý£¬Ã»ÓÐʱ¼äÁË
+			
+			std::vector<ADAPTER_INFO  *> * pAdaInfoVect = new std::vector<ADAPTER_INFO  *> ();
+
+			std::vector<ADA_DIFF_INFO> adaDiffInfoVect;
+
+			if ((dwRet = GetNicInfo((*pAdaInfoVect))) != ERROR_SUCCESS)
+			{
+				LogEvent(_T("[QGA]cannot get nic info."));
+				return dwRet;
+			}
+
+			diffAdaVect((*pAdaInfoLastVect), (*pAdaInfoVect), adaDiffInfoVect);
+
+
+			/*ÎÒÃÇÈÏΪһ¸öʱ¿Ì£¬²»»áͬʱ·¢ÉúIP±ä»¯ÓëÍø¿¨Ôöɾ£»
+			*µ¥´¿ÐÞ¸ÄIP£¬²»»á´¥·¢Íø¿¨Ôöɾ£»¶ø·¢ÉúÍø¿¨Ôöɾ£¬Èç¹ûû´¥·¢IPÐ޸ģ¬Ò²Ã»ÎÊÌ⣻Èç¹ûÍø¿¨Ôöɾ´¥·¢ÁËIPÐ޸ģ¬ÔòºóÐøÁ÷³Ì»á×Ô¶¯´¥·¢IPʼþ£»¹Êÿ´ÎÖ»
+			´¦ÀíÒ»ÖÖʼþ£¬¼ò»¯Á÷³Ì*/
+			if((ipCount > 0) && adaDiffInfoVect.empty())
+			{
+				doIpChangeEvent(*pAdaInfoVect);
+			}
+			else if(!adaDiffInfoVect.empty())
+			{
+				doNicChangeEvnet(adaDiffInfoVect);
+			}
+
+
+			//ÊÍ·ÅÏÈǰµÄÄڴ棬×îºóÒ»¸öÔªËØ²»»áÊÍ·Å£¬µÈ´ý½ø³Ì×Ô¶¯½áÊø
+			freeAdaInfoVec((*pAdaInfoLastVect));
+			free(pAdaInfoLastVect);
+
+			pAdaInfoLastVect = pAdaInfoVect;
+
+			timeOutCount = 0;
+			waitAlong = FALSE;
+			nicCount = 0;
+			ipCount = 0;
+
+		}
+		else
+		{
+			LogEvent(_T("[QGA]:default changed, change error %d\n"), index);
+		}
+	}
+
+	LogEvent(_T("[QGA]watching monitorFileThread ...end"));
+
+	return SUCCESS_CODE;
+}
+
+extern "C" VOID ipMonitorInit(VOID); 
+
+VOID allocatePreMem(VOID)
+{
+	g_preMem = new TCHAR[MAX_PREBUFF_LEN];
+	if(g_preMem == NULL)
+	{
+		LogEvent(_T("[QGA]allocatePreMem failed "));
+		_exit(ERROR_CODE);
+	}
+}
+
+VOID ipMonitorInit(VOID)
+{
+    HANDLE hThreadWatch;
+    setOSversion();
+
+    /*no suitable for xp*/
+    if(!g_VistaOrLater)
+         return;
+
+    setIniFilePath();
+	//Ô¤ÏÈ·ÖÅäÒ»¿éÈ«¾ÖÄڴ棬ºóÐøÁ¬ÐøÊ¹Óã¬Ã»ÓлØÊÕ»ú»á
+	allocatePreMem();
+    
+    hThreadWatch = CreateThread(NULL, 0, monitorThread, NULL, 0, NULL);
+    if (hThreadWatch == NULL)
+    {
+        LogEvent(_T("[QGA]Create monitorIpThread failed"));
+        _exit(1);
+    }
+    CloseHandle(hThreadWatch);
+    
+    LogEvent(_T("[QGA]create thread to monitorIP success"));
+}
+
+/*
+int _tmain(int argc, _TCHAR* argv[])
+{
+	ipMonitorInit();
+
+	_tsystem(_T("pause"));
+	return 0;
+}*/
+
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2017-06-28 12:18 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-06-24  5:39 [Qemu-devel] [PATCH] qga:windows os lost ip when network nic change pic order indiffPig
2017-06-27 21:14 ` Eric Blake
2017-06-28 12:16   ` indiffpig

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).