diff options
author | Adam Ierymenko <adam.ierymenko@zerotier.com> | 2013-08-26 17:48:47 -0400 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@zerotier.com> | 2013-08-26 17:48:47 -0400 |
commit | 4a370c5f3f31dad945d37bfc83fc7a7b01735acb (patch) | |
tree | 5c044bd87789e4c2ff3911a147631ed09bd7d267 /node | |
parent | 487eb17ec075dd2bdc91f78b41577b070d90f8f5 (diff) | |
download | infinitytier-4a370c5f3f31dad945d37bfc83fc7a7b01735acb.tar.gz infinitytier-4a370c5f3f31dad945d37bfc83fc7a7b01735acb.zip |
Windows: disable and enable tap to allow changes to take effect.
Diffstat (limited to 'node')
-rw-r--r-- | node/EthernetTap.cpp | 57 | ||||
-rw-r--r-- | node/EthernetTap.hpp | 3 |
2 files changed, 52 insertions, 8 deletions
diff --git a/node/EthernetTap.cpp b/node/EthernetTap.cpp index 745b8c8e..8b171b4c 100644 --- a/node/EthernetTap.cpp +++ b/node/EthernetTap.cpp @@ -750,6 +750,13 @@ EthernetTap::EthernetTap( if (mtu > ZT_IF_MTU) throw std::runtime_error("MTU too large for Windows tap"); +#ifdef _WIN64 + const char *devcon = "\\devcon64.exe"; +#else + BOOL f64 = FALSE; + const char *devcon = ((IsWow64Process(GetCurrentProcess(),&f64) == TRUE) ? "\\devcon64.exe" : "\\devcon32.exe"); +#endif + Mutex::Lock _l(_systemTapInitLock); // only init one tap at a time, process-wide HKEY nwAdapters; @@ -782,13 +789,20 @@ EthernetTap::EthernetTap( existingDeviceInstances.insert(instanceId); } - if ((_myDeviceInstanceId.length() == 0)&&(instanceId.length() != 0)) { + std::string instanceIdPath; + type = 0; + dataLen = sizeof(data); + if (RegGetValueA(nwAdapters,subkeyName,"DeviceInstanceID",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) + instanceIdPath.assign(data,dataLen); + + if ((_myDeviceInstanceId.length() == 0)&&(instanceId.length() != 0)&&(instanceIdPath.length() != 0)) { type = 0; dataLen = sizeof(data); if (RegGetValueA(nwAdapters,subkeyName,"_ZeroTierTapIdentifier",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) { data[dataLen] = '\0'; if (!strcmp(data,tag)) { _myDeviceInstanceId = instanceId; + _myDeviceInstanceIdPath = instanceIdPath; mySubkeyName = subkeyName; subkeyIndex = -1; // break outer loop } @@ -803,12 +817,6 @@ EthernetTap::EthernetTap( // If there is no device, try to create one if (_myDeviceInstanceId.length() == 0) { // Execute devcon to install an instance of the Microsoft Loopback Adapter -#ifdef _WIN64 - const char *devcon = "\\devcon64.exe"; -#else - BOOL f64 = FALSE; - const char *devcon = ((IsWow64Process(GetCurrentProcess(),&f64) == TRUE) ? "\\devcon64.exe" : "\\devcon32.exe"); -#endif STARTUPINFOA startupInfo; startupInfo.cb = sizeof(startupInfo); PROCESS_INFORMATION processInfo; @@ -844,6 +852,10 @@ EthernetTap::EthernetTap( if (existingDeviceInstances.count(std::string(data,dataLen)) == 0) { RegSetKeyValueA(nwAdapters,subkeyName,"_ZeroTierTapIdentifier",REG_SZ,tag,(DWORD)(strlen(tag)+1)); _myDeviceInstanceId.assign(data,dataLen); + type = 0; + dataLen = sizeof(data); + if (RegGetValueA(nwAdapters,subkeyName,"DeviceInstanceID",RRF_RT_ANY,&type,(PVOID)data,&dataLen) == ERROR_SUCCESS) + _myDeviceInstanceIdPath.assign(data,dataLen); mySubkeyName = subkeyName; subkeyIndex = -1; // break outer loop } @@ -885,6 +897,37 @@ EthernetTap::EthernetTap( throw std::runtime_error("unable to convert instance ID GUID to native GUID (invalid NetCfgInstanceId in registry?)"); } + // Disable and enable interface to ensure settings take effect + { + STARTUPINFOA startupInfo; + startupInfo.cb = sizeof(startupInfo); + PROCESS_INFORMATION processInfo; + memset(&startupInfo,0,sizeof(STARTUPINFOA)); + memset(&processInfo,0,sizeof(PROCESS_INFORMATION)); + if (!CreateProcessA(NULL,(LPSTR)(std::string("\"") + _r->homePath + devcon + "\" disable @" + _myDeviceInstanceIdPath).c_str(),NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo)) { + RegCloseKey(nwAdapters); + throw std::runtime_error(std::string("unable to find or execute devcon at ")+devcon); + } + WaitForSingleObject(processInfo.hProcess,INFINITE); + CloseHandle(processInfo.hProcess); + CloseHandle(processInfo.hThread); + } + { + STARTUPINFOA startupInfo; + startupInfo.cb = sizeof(startupInfo); + PROCESS_INFORMATION processInfo; + memset(&startupInfo,0,sizeof(STARTUPINFOA)); + memset(&processInfo,0,sizeof(PROCESS_INFORMATION)); + if (!CreateProcessA(NULL,(LPSTR)(std::string("\"") + _r->homePath + devcon + "\" enable @" + _myDeviceInstanceIdPath).c_str(),NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo)) { + RegCloseKey(nwAdapters); + throw std::runtime_error(std::string("unable to find or execute devcon at ")+devcon); + } + WaitForSingleObject(processInfo.hProcess,INFINITE); + CloseHandle(processInfo.hProcess); + CloseHandle(processInfo.hThread); + } + + // Open the tap, which is in this weird Windows analog of /dev #ifdef UNICODE wchar_t tapPath[4096]; swprintf_s(tapPath,L"\\\\.\\Global\\%S.tap",_myDeviceInstanceId.c_str()); diff --git a/node/EthernetTap.hpp b/node/EthernetTap.hpp index b4128abd..87a7de55 100644 --- a/node/EthernetTap.hpp +++ b/node/EthernetTap.hpp @@ -219,7 +219,8 @@ private: char _tapReadBuf[ZT_IF_MTU + 32]; HANDLE _injectSemaphore; GUID _deviceGuid; - std::string _myDeviceInstanceId; + std::string _myDeviceInstanceId; // NetCfgInstanceId, a GUID + std::string _myDeviceInstanceIdPath; // DeviceInstanceID, another kind of "instance ID" std::queue< std::pair< Array<char,ZT_IF_MTU + 32>,unsigned int > > _injectPending; Mutex _injectPending_m; volatile bool _run; |