diff --git a/osdep/EthernetTap.cpp b/osdep/EthernetTap.cpp index f30a96e60..4f3d20f40 100644 --- a/osdep/EthernetTap.cpp +++ b/osdep/EthernetTap.cpp @@ -96,6 +96,35 @@ std::shared_ptr 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(new WindowsEthernetTap(homePath,mac,mtu,metric,nwid,friendlyName,handler,arg)); #endif // __WINDOWS__ diff --git a/osdep/WindowsEthernetTap.cpp b/osdep/WindowsEthernetTap.cpp index 596fec340..3048626a5 100644 --- a/osdep/WindowsEthernetTap.cpp +++ b/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];