Просмотр исходного кода

Fix multiple networks on Windows

Grant Limberg 4 лет назад
Родитель
Сommit
a9e4fb0ed9
2 измененных файлов с 35 добавлено и 23 удалено
  1. 29 0
      osdep/EthernetTap.cpp
  2. 6 23
      osdep/WindowsEthernetTap.cpp

+ 29 - 0
osdep/EthernetTap.cpp

@@ -96,6 +96,35 @@ std::shared_ptr<EthernetTap> EthernetTap::newInstance(
 #endif // __LINUX__
 
 #ifdef __WINDOWS__
+	HRESULT hres = CoInitializeEx(0, COINIT_MULTITHREADED);
+	if (FAILED(hres)) {
+		throw std::runtime_error("WinEthernetTap: COM initialization failed");
+	}
+
+	static bool _comInit = false;
+	static Mutex _comInit_m;
+
+	{
+		Mutex::Lock l(_comInit_m);
+		if (!_comInit) {
+			hres = CoInitializeSecurity(
+				NULL,
+				-1,
+				NULL,
+				NULL,
+				RPC_C_AUTHN_LEVEL_DEFAULT,
+				RPC_C_IMP_LEVEL_IMPERSONATE,
+				NULL,
+				EOAC_NONE,
+				NULL
+			);
+			if (FAILED(hres)) {
+				CoUninitialize();
+				throw std::runtime_error("WinEthernetTap: Failed to initialize security");
+			}
+			_comInit = true;
+		}
+	}
 	return std::shared_ptr<EthernetTap>(new WindowsEthernetTap(homePath,mac,mtu,metric,nwid,friendlyName,handler,arg));
 #endif // __WINDOWS__
 

+ 6 - 23
osdep/WindowsEthernetTap.cpp

@@ -474,29 +474,6 @@ WindowsEthernetTap::WindowsEthernetTap(
 	char data[1024];
 	char tag[24];
 
-	// Initialize COM
-	HRESULT hres = CoInitializeEx(0, COINIT_MULTITHREADED);
-	if (FAILED(hres)) {
-		throw std::runtime_error("WinEthernetTap: COM initialization failed");
-	}
-
-	hres = CoInitializeSecurity(
-		NULL,
-		-1,
-		NULL,
-		NULL,
-		RPC_C_AUTHN_LEVEL_DEFAULT,
-		RPC_C_IMP_LEVEL_IMPERSONATE,
-		NULL,
-		EOAC_NONE,
-		NULL
-	);
-	if (FAILED(hres)) {
-		CoUninitialize();
-		throw std::runtime_error("WinEthernetTap: Failed to initialize security");
-	}
-
-
 	// We "tag" registry entries with the network ID to identify persistent devices
 	OSUtils::ztsnprintf(tag,sizeof(tag),"%.16llx",(unsigned long long)nwid);
 
@@ -970,6 +947,12 @@ NET_IFINDEX WindowsEthernetTap::interfaceIndex() const
 void WindowsEthernetTap::threadMain()
 	throw()
 {
+	HRESULT hres = CoInitializeEx(0, COINIT_MULTITHREADED);
+	if (FAILED(hres)) {
+		fprintf(stderr, "WinEthernetTap: COM initialization failed");
+		return;
+	}
+
 	char tapReadBuf[ZT_MAX_MTU + 32];
 	char tapPath[128];
 	HANDLE wait4[3];