From: "yin.zuowei" <indiff...@126.com> Signed-off-by: yin.zuowei <indiff...@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???????????????????????????????????????????????????? +????????????????????????*/ +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]); + } + } + + } +} + +/*??????????????????*/ +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???????????????????????????????????????? +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); +} + +/*??????????????????????????????????:?????????????????? ????????????????IP???????????????????????? +IP????????????????????????????????IP?????????????????????????????????????????????????????????????? +MAC????????????????????????????????????????????*/ +VOID clearConflictIpInConfig(ADAPTER_INFO * pAdaInfo, TCHAR *pIniPath) +{ + /*????????????????????????????????????????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); + /*????????????????????????????????????????????????*/ + 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