* [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
* Re: [Qemu-devel] [PATCH] qga:windows os lost ip when network nic change pic order
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
0 siblings, 1 reply; 3+ messages in thread
From: Eric Blake @ 2017-06-27 21:14 UTC (permalink / raw)
To: indiffPig, mdroth; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 1981 bytes --]
On 06/24/2017 12:39 AM, indiffPig@126.com wrote:
> 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 : �������̨Ӧ�ó������ڵ㡣
Your mail header said:
> Content-Type: text/plain; charset=yes
which looks like a bug with your git settings (typically, it should be
charset=UTF-8). Much of the message didn't render for me (not sure if
it lack of fonts on my end, or if it really was garbled en route rather
than being valid UTF-8 round-trip). But we much prefer /* */ comments
over // (even in C++ code), and prefer those comments to be in English.
> +//#pragma comment(lib,"iphlpapi.lib")
Dead code?
> +
> +/*Ҫע�⣬����unicode�� memcpy����������Ҫʹ��XXX_LEN * sizeof(TCHAR)*/
More encoding awkwardness.
It's hard to review the patch when the content is difficult to read.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization: qemu.org | libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Qemu-devel] [PATCH] qga:windows os lost ip when network nic change pic order
2017-06-27 21:14 ` Eric Blake
@ 2017-06-28 12:16 ` indiffpig
0 siblings, 0 replies; 3+ messages in thread
From: indiffpig @ 2017-06-28 12:16 UTC (permalink / raw)
To: Eric Blake; +Cc: mdroth, qemu-devel
That's true. Let me confirm to you whether this problem exists or whether there are any solutions already available. If so, I would like you to tell me the existing solution. My patch comes from the company code, and the code is long.The notes are written in Chinese. We work too much and don't have much spare time. If you are sure there is a problem and need to be resolved, I would like to take the time to refine the code.
At 2017-06-28 05:14:57, "Eric Blake" <eblake@redhat.com> wrote:
>On 06/24/2017 12:39 AM, indiffPig@126.com wrote:
>> 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 : �������̨Ӧ�ó������ڵ㡣
>
>Your mail header said:
>
>> Content-Type: text/plain; charset=yes
>
>which looks like a bug with your git settings (typically, it should be
>charset=UTF-8). Much of the message didn't render for me (not sure if
>it lack of fonts on my end, or if it really was garbled en route rather
>than being valid UTF-8 round-trip). But we much prefer /* */ comments
>over // (even in C++ code), and prefer those comments to be in English.
>
>> +//#pragma comment(lib,"iphlpapi.lib")
>
>Dead code?
>
>> +
>> +/*Ҫע�⣬����unicode�� memcpy����������Ҫʹ��XXX_LEN * sizeof(TCHAR)*/
>
>More encoding awkwardness.
>
>It's hard to review the patch when the content is difficult to read.
>
>--
>Eric Blake, Principal Software Engineer
>Red Hat, Inc. +1-919-301-3266
>Virtualization: qemu.org | libvirt.org
>
^ permalink raw reply [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).