Adapter.h
#ifndef AdapterH
#define AdapterH #include #include #include #include #include #include "AdapterInfo.h" #include "lib.h" #include "ProcessView.h" #include "IpUtil.h" #include "MyUnicodeString.h" #pragma comment(lib, "IPHLPAPI.lib") using namespace std; class Adapter { public: Adapter(); ~Adapter(); list* getAdapterInfoList(); TStringList* getAdapterNameList(); UnicodeString getAdapterName(UnicodeString& regName); UnicodeString isAdapterInfoValid(AdapterInfo* adapterInfo); UnicodeString isMaskValid(UnicodeString& mask); bool applyAdapterInfo(AdapterInfo* adapterInfo); void setProcessView(ProcessView* _processView); AdapterInfo* getAdapterInfo(UnicodeString& adapterName); UnicodeString isIPTaken(AdapterInfo* _adapterInfo); void freeAdapterInfoList(list* adapterInfoList); UnicodeString getPrefferedAdapterName(); AdapterInfo* getPrefferedAdapter(); private: bool updateDns(AdapterInfo* adapterInfo); bool updateIP(AdapterInfo* adapterInfo); bool updateBothDns(AdapterInfo* adapterInfo); bool updateMac(AdapterInfo* adapterInfo); bool updateDns(UnicodeString& adapterName,UnicodeString& dns); bool updateDnsDhcp(UnicodeString& adapterName); bool updateIPDhcp(UnicodeString& adapterName); bool updateIPStatic(AdapterInfo* adapterInfo); bool execCmd(UnicodeString& cmd); UnicodeString getDnsServerStr(UnicodeString& regName); void setDns(AdapterInfo* adapterinfo,UnicodeString& regName); ProcessView* processView; void setFinishPercent(int percent); bool deleteAllDns(UnicodeString& adapterName); bool isNowIPGetByDhcp(UnicodeString& adapterName); bool isNowDnsGetByDhcp(UnicodeString& adapterName); bool isIpEquals(AdapterInfo* adapterInfo1,AdapterInfo* adapterInfo2); bool isDnsEquals(AdapterInfo* adapterInfo1,AdapterInfo* adapterInfo2); UnicodeString getIPMultiSZFromReg(UnicodeString& regName,UnicodeString& key); UnicodeString getIPSZFromReg(UnicodeString& regName,UnicodeString& key); UnicodeString getIPFromReg(UnicodeString& regName); UnicodeString getMaskFromReg(UnicodeString& regName); UnicodeString getGatewayFromReg(UnicodeString& regName); void setIPInfoInReg(UnicodeString& regName,UnicodeString& key,UnicodeString& value); bool isGetDnsByDhcp(UnicodeString& regName); bool enableNetwork(UnicodeString& adapterName,bool enabled); UnicodeString getFormattedMac(UnicodeString& mac); bool isAdapterExist(UnicodeString& _adapterName); };#endif
Adapter.cpp
#include "Adapter.h" const UnicodeString DNS_NAME_SPLIT = L" "; Adapter::Adapter() { processView = NULL; } Adapter::~Adapter() { } list* Adapter::getAdapterInfoList() { list* adapterInfoList = new list(); ULONG ulAdapterInfoSize = sizeof(IP_ADAPTER_INFO); IP_ADAPTER_INFO* pAdapterInfo = (IP_ADAPTER_INFO*)new char[ulAdapterInfoSize]; //缓冲区不够大 if(GetAdaptersInfo(pAdapterInfo,&ulAdapterInfoSize)==ERROR_BUFFER_OVERFLOW) { delete[] pAdapterInfo; pAdapterInfo = (IP_ADAPTER_INFO*)new char[ulAdapterInfoSize]; } IP_ADAPTER_INFO* firstPAdapterInfo = pAdapterInfo; IP_ADDR_STRING ip_list; if(GetAdaptersInfo(pAdapterInfo,&ulAdapterInfoSize)==ERROR_SUCCESS) { do { // 遍历所有适配器 if(pAdapterInfo->Type == MIB_IF_TYPE_ETHERNET) // 判断是否为以太网接口 { AdapterInfo* adapterinfo = new AdapterInfo(); ip_list=pAdapterInfo-> IpAddressList; UnicodeString regName = pAdapterInfo->AdapterName; adapterinfo->regName = regName; //适配器名称 adapterinfo->adapterName = getAdapterName(regName); adapterinfo->ip = ip_list.IpAddress.String; //IP地址 if(adapterinfo->ip==L"0.0.0.0") { adapterinfo->ip = getIPFromReg(regName); } adapterinfo->mask = ip_list.IpMask.String; //字掩网码 if(adapterinfo->mask==L"0.0.0.0") { adapterinfo->mask = getMaskFromReg(regName); } adapterinfo->gateway = pAdapterInfo-> GatewayList.IpAddress.String; if(adapterinfo->gateway==L"0.0.0.0") { adapterinfo->gateway = getGatewayFromReg(regName); } if(pAdapterInfo->DhcpEnabled) { adapterinfo->isGetIpByDhcp = true; } setDns(adapterinfo,regName); adapterInfoList->push_back(adapterinfo); } pAdapterInfo = pAdapterInfo->Next; }while(pAdapterInfo); } delete[] firstPAdapterInfo; return adapterInfoList; } UnicodeString Adapter::getIPFromReg(UnicodeString& regName) { UnicodeString key = "IPAddress"; UnicodeString value = getIPMultiSZFromReg(regName,key); if(value.IsEmpty()) { key = "DhcpIPAddress"; value = getIPSZFromReg(regName,key); } return value; } UnicodeString Adapter::getMaskFromReg(UnicodeString& regName) { UnicodeString key = "SubnetMask"; UnicodeString value = getIPMultiSZFromReg(regName,key); if(value.IsEmpty()) { key = "DhcpSubnetMask"; value = getIPSZFromReg(regName,key); } return value; } UnicodeString Adapter::getGatewayFromReg(UnicodeString& regName) { UnicodeString key = "DefaultGateway"; UnicodeString value = getIPMultiSZFromReg(regName,key); if(value.IsEmpty()) { key = "DhcpDefaultGateway"; value = getIPMultiSZFromReg(regName,key); } return value; } UnicodeString Adapter::getIPMultiSZFromReg(UnicodeString& regName,UnicodeString& key) { TRegistry *Reg=new TRegistry; Reg->RootKey=HKEY_LOCAL_MACHINE; UnicodeString section = "\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\"; section += regName; Reg->OpenKey(section, false); UnicodeString str = L""; if(Reg->ValueExists(key)) { DWORD dwBuf=Reg->GetDataSize(key); wchar_t *bBuf=new wchar_t[dwBuf+1]; Reg->ReadBinaryData(key, bBuf, dwBuf); wchar_t *szChar=(wchar_t*)bBuf; str = UnicodeString(szChar); delete[] bBuf; } Reg->CloseKey(); delete Reg; return str; } UnicodeString Adapter::getIPSZFromReg(UnicodeString& regName,UnicodeString& key) { TRegIniFile* regIniFile = new TRegIniFile(""); regIniFile->RootKey = HKEY_LOCAL_MACHINE; UnicodeString section = "\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\"; section += regName; UnicodeString name = regIniFile->ReadString(section,key,L""); delete regIniFile; return name; } UnicodeString Adapter::getAdapterName(UnicodeString& regName) { TRegIniFile* regIniFile = new TRegIniFile(""); regIniFile->RootKey = HKEY_LOCAL_MACHINE; UnicodeString section = "\\SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\"; section += regName; section += "\\Connection"; UnicodeString key("Name"); UnicodeString name = regIniFile->ReadString(section,key,"Failed to get name"); delete regIniFile; return name; } UnicodeString Adapter::getDnsServerStr(UnicodeString& regName) { TRegIniFile* regIniFile = new TRegIniFile(""); regIniFile->RootKey = HKEY_LOCAL_MACHINE; UnicodeString section = "\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\"; section += regName; UnicodeString dnsNameStr; UnicodeString key; //Try to find in key "NameServer"(used for static ip) key = L"NameServer"; dnsNameStr = regIniFile->ReadString(section,key,""); if(dnsNameStr.IsEmpty()) { //Try to find in key "DhcpNameServer"(used for dhcp) key = L"DhcpNameServer"; dnsNameStr = regIniFile->ReadString(section,key,""); } else { MyUnicodeString str(dnsNameStr); str.replace(L",",DNS_NAME_SPLIT); dnsNameStr = str.getString(); } delete regIniFile; return dnsNameStr; } bool Adapter::isGetDnsByDhcp(UnicodeString& regName) { bool result = false; TRegIniFile* regIniFile = new TRegIniFile(""); regIniFile->RootKey = HKEY_LOCAL_MACHINE; UnicodeString section = "\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\"; section += regName; UnicodeString dnsNameStr; UnicodeString key; key = L"NameServer"; dnsNameStr = regIniFile->ReadString(section,key,""); if(dnsNameStr.IsEmpty()) { result = true; } delete regIniFile; return result; } void Adapter::setDns(AdapterInfo* adapterinfo,UnicodeString& regName) { adapterinfo->isGetDnsByDhcp = isGetDnsByDhcp(regName); UnicodeString dnsServerStr = getDnsServerStr(regName); MyUnicodeString myUnicodeString(dnsServerStr); UnicodeString split = DNS_NAME_SPLIT; list* dnsList = myUnicodeString.split(split); if(dnsList!=NULL) { list::iterator iter; int index = 0; for(iter=dnsList->begin();iter!=dnsList->end();iter++) { if(index==0) { adapterinfo->preferredDns = **iter; } else if (index==1) { adapterinfo->alternateDns = **iter; } else break; index++; } myUnicodeString.freeSplitList(dnsList); } } TStringList* Adapter::getAdapterNameList() { TStringList* nameList = new TStringList(); list* adapterInfoList = getAdapterInfoList(); list::iterator iter; for(iter=adapterInfoList->begin();iter!=adapterInfoList->end();iter++) { AdapterInfo* adapterInfo = *iter; UnicodeString adapterName = adapterInfo->adapterName; nameList->Add(adapterName); } freeAdapterInfoList(adapterInfoList); return nameList; } bool Adapter::applyAdapterInfo(AdapterInfo* adapterInfo) { bool result = true; const int FINISHED = 100; setFinishPercent(0); AdapterInfo* currentAdapterInfo = getAdapterInfo(adapterInfo->adapterName); adapterInfo->regName= currentAdapterInfo->regName; //Update Mac if(adapterInfo->isToChangeMac) { updateMac(adapterInfo); enableNetwork(adapterInfo->adapterName,false); enableNetwork(adapterInfo->adapterName,true); setFinishPercent(30); } //Update IP if( !isIpEquals(currentAdapterInfo,adapterInfo)) { result = updateIP(adapterInfo); } delete currentAdapterInfo; setFinishPercent(50); //Update DNS if(result) //If succeess { result = updateDns(adapterInfo); } setFinishPercent(FINISHED); return result; } bool Adapter::updateDns(AdapterInfo* adapterInfo) { UnicodeString adapterName = adapterInfo->adapterName; bool result = false; if(adapterInfo->isGetDnsByDhcp) //by dhcp { result = updateDnsDhcp(adapterName); } else { if(adapterInfo->isAllDnsEmpty()) { result = deleteAllDns(adapterInfo->adapterName); } else if(adapterInfo->isAllDnsFilled()) { result = updateBothDns(adapterInfo); } else if( !adapterInfo->isPrefferedDnsEmpty()) { result = updateDns(adapterName,adapterInfo->preferredDns); } else if( !adapterInfo->isAlternateDnsEmpty()) { result = updateDns(adapterName,adapterInfo->alternateDns); } } return result; } bool Adapter::updateBothDns(AdapterInfo* adapterInfo) { bool result; UnicodeString cmd = ""; UnicodeString adapterName = adapterInfo->adapterName; UnicodeString regName = adapterInfo->regName; UnicodeString prefferedDns = adapterInfo->preferredDns; UnicodeString alternateDns = adapterInfo->alternateDns; //Add first cmd += "netsh interface ip set dns \""; cmd += adapterName; cmd += "\" static "; cmd += prefferedDns; result = execCmd(cmd); if(result) { //Add second cmd = ""; cmd += "netsh interface ip add dns \""; cmd += adapterName; cmd += "\" "; cmd += alternateDns; result = execCmd(cmd); } return result; } bool Adapter::updateMac(AdapterInfo* adapterInfo) { TRegIniFile* regIniFile = new TRegIniFile(""); regIniFile->RootKey = HKEY_LOCAL_MACHINE; UnicodeString section = "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}"; TStrings * strings = new TStringList(); regIniFile->OpenKey(section,true); regIniFile->GetKeyNames(strings); for(int i=0;iCount;i++) { UnicodeString key = strings->Strings[i]; UnicodeString netCfgInstanceId = regIniFile->ReadString(key,"NetCfgInstanceId",""); if(netCfgInstanceId==adapterInfo->regName) { String mac = getFormattedMac(adapterInfo->mac); regIniFile->WriteString(key,"NetworkAddress",mac); break; } } delete strings; delete regIniFile; return true; } UnicodeString Adapter::getFormattedMac(UnicodeString& mac) { MyUnicodeString myUnicodeString(mac); myUnicodeString.replace("-",""); myUnicodeString.replace(":",""); UnicodeString formattedMac = myUnicodeString.getString(); myUnicodeString.release(); return formattedMac; } bool Adapter::deleteAllDns(UnicodeString& adapterName) { bool result; UnicodeString cmd; cmd = "netsh interface ip delete dns \""+adapterName+"\" ALL"; result = execCmd(cmd); return result; } bool Adapter::updateDns(UnicodeString& adapterName,UnicodeString& dns) { UnicodeString cmd = ""; cmd += "netsh interface ip set dns \""; cmd += adapterName; cmd += "\" static "; cmd += dns; return execCmd(cmd); } bool Adapter::updateDnsDhcp(UnicodeString& adapterName) { if(isNowDnsGetByDhcp(adapterName)) { return true; } else { UnicodeString cmd = ""; cmd += "netsh interface ip "; cmd += " set dns \""; cmd += adapterName; cmd += "\" dhcp"; return execCmd(cmd); } } bool Adapter::updateIP(AdapterInfo* adapterInfo) { UnicodeString adapterName = adapterInfo->adapterName; bool result = false; if(adapterInfo->isGetIpByDhcp) //by dhcp { result = updateIPDhcp(adapterName); } else { result = updateIPStatic(adapterInfo); } return result; } bool Adapter::updateIPStatic(AdapterInfo* adapterInfo) { bool result; UnicodeString adapterName = adapterInfo->adapterName; UnicodeString cmd = ""; cmd += "netsh interface ip set address name=\""; cmd += adapterName; cmd += "\" source=static "; cmd += "addr="; cmd += adapterInfo->ip; cmd += " mask="; cmd += adapterInfo->mask; cmd += " gateway="; if(adapterInfo->gateway.IsEmpty()) { cmd += "none"; } else { cmd += adapterInfo->gateway; cmd += " gwmetric=1"; } result = execCmd(cmd); return result; } bool Adapter::updateIPDhcp(UnicodeString& adapterName) { if(isNowIPGetByDhcp(adapterName)) return true; else { UnicodeString cmd = ""; cmd += "netsh interface ip "; cmd += " set address \""; cmd += adapterName; cmd += "\" dhcp"; return execCmd(cmd); } } bool Adapter::isNowIPGetByDhcp(UnicodeString& adapterName) { bool isGetByDhcp; AdapterInfo* adapterInfo = getAdapterInfo(adapterName); if(adapterInfo->isGetIpByDhcp) isGetByDhcp = true; else isGetByDhcp = false; delete adapterInfo; return isGetByDhcp; } bool Adapter::isNowDnsGetByDhcp(UnicodeString& adapterName) { bool isGetByDhcp; AdapterInfo* adapterInfo = getAdapterInfo(adapterName); if(adapterInfo->isGetDnsByDhcp) isGetByDhcp = true; else isGetByDhcp = false; delete adapterInfo; return isGetByDhcp; } bool Adapter::execCmd(UnicodeString& cmd) { return execProgram(cmd); } AdapterInfo* Adapter::getAdapterInfo(UnicodeString& adapterName) { AdapterInfo *result = NULL; list* adapterInfoList = getAdapterInfoList(); list::iterator iter; for(iter=adapterInfoList->begin();iter!=adapterInfoList->end();iter++) { AdapterInfo* adapterInfo = *iter; if(adapterName==adapterInfo->adapterName) { result = adapterInfo->copy(); break; } } freeAdapterInfoList(adapterInfoList); return result; } void Adapter::setProcessView(ProcessView* _processView) { processView = _processView; } void Adapter::setFinishPercent(int percent) { if(processView!=NULL) processView->setFinishPercent(percent); } UnicodeString Adapter::isAdapterInfoValid(AdapterInfo* adapterInfo) { UnicodeString result = L""; UnicodeString ip = adapterInfo->ip; UnicodeString mask = adapterInfo->mask; UnicodeString gateway = adapterInfo->gateway; UnicodeString preferredDns = adapterInfo->preferredDns; UnicodeString alternateDns = adapterInfo->alternateDns; if( !adapterInfo->isGetIpByDhcp) { if(ip.IsEmpty()) { result = L"IP address is empty"; } else if( !isIPValid(ip)) { result = L"Invalid IP address: ["; result += ip; result += L"]"; } else if( !isMaskValid(mask).IsEmpty()) { result = isMaskValid(mask); } else if( !gateway.IsEmpty() && !isIPValid(gateway)) { result = L"Invalid default gateway: ["; result += gateway; result += L"]"; } } if( !adapterInfo->isGetDnsByDhcp) { if( !preferredDns.IsEmpty() && !isIPValid(preferredDns)) { result = L"Invalid Preferred DNS Server: ["; result += preferredDns; result += L"]"; } else if( !alternateDns.IsEmpty() && !isIPValid(alternateDns)) { result = L"Invalid alternate DNS Server: ["; result += alternateDns; result += L"]"; } } return result; } UnicodeString Adapter::isMaskValid(UnicodeString& mask) { UnicodeString result = L""; if(mask.IsEmpty()) { result = "Subnet mask is empty"; } else if( !isIPValid(mask)) { result = "Invalid subnet mask: ["; result += mask; result += "]"; } else { DWORD maskValue = getIpAddrIntValue(mask); const DWORD MIN_MASK_VALUE = getIpAddrIntValue("255.0.0.0"); if(maskValueadapterName; for(iter=adapterInfoList->begin();iter!=adapterInfoList->end();iter++) { AdapterInfo* adapterInfo = *iter; UnicodeString name = adapterInfo->adapterName; if(name==inputAdapterName) continue; else { if(_adapterInfo->ip==adapterInfo->ip) { result = adapterInfo->ip; result += " is taken by "; result += name; } } } freeAdapterInfoList(adapterInfoList); return result; } void Adapter::freeAdapterInfoList(list* adapterInfoList) { if(adapterInfoList!=NULL) { list::iterator iter; for(iter=adapterInfoList->begin();iter!=adapterInfoList->end();iter++) { AdapterInfo* adapterInfo = *iter; delete adapterInfo; } delete adapterInfoList; } } bool Adapter::isIpEquals(AdapterInfo* adapterInfo1,AdapterInfo* adapterInfo2) { bool isEquals = true; if(adapterInfo1->isGetIpByDhcp != adapterInfo2->isGetIpByDhcp) { isEquals = false; } else if(adapterInfo1->isGetIpByDhcp==false) { if(adapterInfo1->ip != adapterInfo2->ip) { isEquals = false; } else if(adapterInfo1->mask != adapterInfo2->mask) { isEquals = false; } else if(adapterInfo1->gateway != adapterInfo2->gateway) { isEquals = false; } } return isEquals; } bool Adapter::isDnsEquals(AdapterInfo* adapterInfo1,AdapterInfo* adapterInfo2) { bool isEquals = true; if(adapterInfo1->isGetDnsByDhcp != adapterInfo2->isGetDnsByDhcp) { isEquals = false; } else if(adapterInfo1->isGetDnsByDhcp==false) { if(adapterInfo1->preferredDns != adapterInfo2->preferredDns) { isEquals = false; } else if(adapterInfo1->alternateDns != adapterInfo2->alternateDns) { isEquals = false; } } return isEquals; } void Adapter::setIPInfoInReg(UnicodeString& regName,UnicodeString& key,UnicodeString& value) { TRegistry *Reg=new TRegistry; Reg->RootKey=HKEY_LOCAL_MACHINE; UnicodeString section = "\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\"; section += regName; Reg->OpenKey(section, false); Reg->WriteString(key,value); Reg->CloseKey(); delete Reg; } bool Adapter::enableNetwork(UnicodeString& adapterName,bool enabled) { bool result; UnicodeString cmd = "netsh interface set interface "; cmd += "\""+adapterName+"\""; if(enabled) { cmd += " enabled"; } else { cmd += " disabled"; } result = execCmd(cmd); return result; } UnicodeString Adapter::getPrefferedAdapterName() { UnicodeString adapterName =L""; list* adapterInfoList = getAdapterInfoList(); if(adapterInfoList->size()>=1) { String preferredAdapter = PREFFERED_ADAPTER; if(isAdapterExist(preferredAdapter)) { adapterName = preferredAdapter; } else { list::iterator iter; iter = adapterInfoList->begin(); AdapterInfo* adapterInfo = *iter; adapterName = adapterInfo->adapterName; } } freeAdapterInfoList(adapterInfoList); return adapterName; } AdapterInfo* Adapter::getPrefferedAdapter() { String adapterName = getPrefferedAdapterName(); return getAdapterInfo(adapterName); } bool Adapter::isAdapterExist(UnicodeString& _adapterName) { bool isExist = false; list* adapterInfoList = getAdapterInfoList(); list::iterator iter; for(iter=adapterInfoList->begin();iter!=adapterInfoList->end();iter++) { AdapterInfo* adapterInfo = *iter; if(adapterInfo->adapterName==_adapterName) { isExist = true; break; } } freeAdapterInfoList(adapterInfoList); return isExist; }