@@ -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,
+ RPC_C_AUTHN_LEVEL_DEFAULT,
+ RPC_C_IMP_LEVEL_IMPERSONATE,
+ EOAC_NONE,
+ NULL
+ );
+ 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__
@@ -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,
- RPC_C_AUTHN_LEVEL_DEFAULT,
- RPC_C_IMP_LEVEL_IMPERSONATE,
- EOAC_NONE,
- NULL
- );
- 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()
{
+ fprintf(stderr, "WinEthernetTap: COM initialization failed");
+ return;
char tapReadBuf[ZT_MAX_MTU + 32];
char tapPath[128];
HANDLE wait4[3];