summaryrefslogtreecommitdiffhomepage
path: root/windows
diff options
context:
space:
mode:
Diffstat (limited to 'windows')
-rw-r--r--windows/winnet/src/winnet/netmonitor.cpp92
1 files changed, 52 insertions, 40 deletions
diff --git a/windows/winnet/src/winnet/netmonitor.cpp b/windows/winnet/src/winnet/netmonitor.cpp
index 86186dc2c6..a1e4c29bb6 100644
--- a/windows/winnet/src/winnet/netmonitor.cpp
+++ b/windows/winnet/src/winnet/netmonitor.cpp
@@ -153,7 +153,20 @@ void NetMonitor::updateConnectivity()
//static
void __stdcall NetMonitor::Callback(void *context, MIB_IPINTERFACE_ROW *hint, MIB_NOTIFICATION_TYPE updateType)
{
- reinterpret_cast<NetMonitor *>(context)->callback(hint, updateType);
+ auto nm = reinterpret_cast<NetMonitor *>(context);
+
+ try
+ {
+ nm->callback(hint, updateType);
+ }
+ catch (const std::exception &err)
+ {
+ nm->m_logSink->error(err.what());
+ }
+ catch (...)
+ {
+ nm->m_logSink->error("Unspecified error in NetMonitor::Callback()");
+ }
}
void NetMonitor::callback(MIB_IPINTERFACE_ROW *hint, MIB_NOTIFICATION_TYPE updateType)
@@ -167,72 +180,71 @@ void NetMonitor::callback(MIB_IPINTERFACE_ROW *hint, MIB_NOTIFICATION_TYPE updat
MIB_IF_ROW2 iface = { 0 };
iface.InterfaceLuid = hint->InterfaceLuid;
- if (NO_ERROR != GetIfEntry2(&iface))
+ const auto status = GetIfEntry2(&iface);
+
+ if (NO_ERROR != status)
{
- // Failed to query interface.
- return;
+ std::stringstream ss;
+
+ ss << "GetIfEntry2() failed for LUID 0x" << std::hex << iface.InterfaceLuid.Value
+ << " during processing of MibAddInstance, error: 0x" << status;
+
+ throw std::runtime_error(ss.str());
}
+ //
+ // The reason for removing an existing entry is that enabling
+ // an interface on the adapter might change the overall properties in the
+ // "row" which is merely an abstraction over all interfaces.
+ //
+
+ m_cache.erase(iface.InterfaceLuid.Value);
AddCacheEntry(m_cache, iface);
break;
}
case MibDeleteInstance:
{
- const auto cacheEntry = m_cache.find(hint->InterfaceLuid.Value);
+ m_cache.erase(hint->InterfaceLuid.Value);
+
+ MIB_IF_ROW2 iface = { 0 };
+ iface.InterfaceLuid = hint->InterfaceLuid;
+
+ const auto status = GetIfEntry2(&iface);
- if (m_cache.end() != cacheEntry)
+ if (NO_ERROR == status)
{
- cacheEntry->second.connected = false;
+ AddCacheEntry(m_cache, iface);
}
break;
}
case MibParameterNotification:
{
- auto cacheEntry = m_cache.find(hint->InterfaceLuid.Value);
-
- if (m_cache.end() == cacheEntry)
- {
- //
- // A change occurred on an interface that we're not tracking.
- // Perhaps the MibAddInstance logic failed for some reason.
- //
-
- MIB_IF_ROW2 iface = { 0 };
- iface.InterfaceLuid = hint->InterfaceLuid;
+ MIB_IF_ROW2 iface = { 0 };
+ iface.InterfaceLuid = hint->InterfaceLuid;
- if (NO_ERROR != GetIfEntry2(&iface))
- {
- // Failed to query interface.
- return;
- }
+ const auto status = GetIfEntry2(&iface);
- AddCacheEntry(m_cache, iface);
- }
- else
+ if (NO_ERROR != status)
{
//
- // Abort processing if this is a known interface that we don't care about.
+ // Only update the cache if we can look up the interface details.
+ // This way, if the interface was connected and continues to be so, we don't
+ // mistakenly switch the status to "offline".
//
- if (false == cacheEntry->second.valid)
- {
- return;
- }
- //
- // Update cache.
- //
+ std::stringstream ss;
- MIB_IF_ROW2 iface = { 0 };
- iface.InterfaceLuid = hint->InterfaceLuid;
+ ss << "GetIfEntry2() failed for LUID 0x" << std::hex << iface.InterfaceLuid.Value
+ << " during processing of MibParameterNotification, error: 0x" << status;
- const auto status = GetIfEntry2(&iface);
-
- cacheEntry->second.connected =
- (NO_ERROR == status ? MediaConnectStateConnected == iface.MediaConnectState : false);
+ throw std::runtime_error(ss.str());
}
+ m_cache.erase(iface.InterfaceLuid.Value);
+ AddCacheEntry(m_cache, iface);
+
break;
}
}