HostDnsServiceWin.cpp revision 735076496e14763dcdef4b43202e7665d4a8da43
735076496e14763dcdef4b43202e7665d4a8da43vboxsync/* $Id$ */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync/** @file
735076496e14763dcdef4b43202e7665d4a8da43vboxsync * Host DNS listener for Windows.
735076496e14763dcdef4b43202e7665d4a8da43vboxsync */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync/*
735076496e14763dcdef4b43202e7665d4a8da43vboxsync * Copyright (C) 2014 Oracle Corporation
735076496e14763dcdef4b43202e7665d4a8da43vboxsync *
735076496e14763dcdef4b43202e7665d4a8da43vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
735076496e14763dcdef4b43202e7665d4a8da43vboxsync * available from http://www.virtualbox.org. This file is free software;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync * you can redistribute it and/or modify it under the terms of the GNU
735076496e14763dcdef4b43202e7665d4a8da43vboxsync * General Public License (GPL) as published by the Free Software
735076496e14763dcdef4b43202e7665d4a8da43vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
735076496e14763dcdef4b43202e7665d4a8da43vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
735076496e14763dcdef4b43202e7665d4a8da43vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
735076496e14763dcdef4b43202e7665d4a8da43vboxsync */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync#include <VBox/com/string.h>
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync#include <VBox/com/ptr.h>
735076496e14763dcdef4b43202e7665d4a8da43vboxsync#include <VBox/log.h>
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync#include <iprt/assert.h>
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync#include <iprt/err.h>
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync#include <Windows.h>
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
7a0e5c38eeca5147034ace6fe624de57ac2988ddvboxsync#include <string>
735076496e14763dcdef4b43202e7665d4a8da43vboxsync#include <sstream>
7a0e5c38eeca5147034ace6fe624de57ac2988ddvboxsync#include <vector>
7a0e5c38eeca5147034ace6fe624de57ac2988ddvboxsync#include "../HostDnsService.h"
7a0e5c38eeca5147034ace6fe624de57ac2988ddvboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync/* In order to monitor DNS setting updates we need to receive notification about
735076496e14763dcdef4b43202e7665d4a8da43vboxsync * Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\* keys changes.
735076496e14763dcdef4b43202e7665d4a8da43vboxsync * Since it is not possible to use patterns when subscribing key changes, we need to find valid paths for all such
735076496e14763dcdef4b43202e7665d4a8da43vboxsync * keys manually and subscribe to changes one by one (see enumerateSubTree()). */
735076496e14763dcdef4b43202e7665d4a8da43vboxsyncconst wchar_t HostDnsServiceWin::pwcKeyRoot[] = L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces";
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsyncHostDnsServiceWin::HostDnsServiceWin()
735076496e14763dcdef4b43202e7665d4a8da43vboxsync : HostDnsMonitor(true),
735076496e14763dcdef4b43202e7665d4a8da43vboxsync m_aWarehouse(),
735076496e14763dcdef4b43202e7665d4a8da43vboxsync m_hostInfoCache(),
735076496e14763dcdef4b43202e7665d4a8da43vboxsync m_fInitialized(false)
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync{
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Add monitor destroy event.
735076496e14763dcdef4b43202e7665d4a8da43vboxsync * This event should have index '0' at the events array in order to separate it from
735076496e14763dcdef4b43202e7665d4a8da43vboxsync * DNS and tree change events. When this event occurs all resources should be released. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (subscribeTo(NULL, NULL, 0))
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Add registry tree change event and corresponding key.
735076496e14763dcdef4b43202e7665d4a8da43vboxsync * This event should have index '1' at the events array in order to separate it from DNS events.
735076496e14763dcdef4b43202e7665d4a8da43vboxsync * When this event occurs it means there are changes in the list of available network interfaces.
735076496e14763dcdef4b43202e7665d4a8da43vboxsync * Network interfaces should be re-enumerated, all DNS events and keys data should re-initialized. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (subscribeTo(pwcKeyRoot, NULL, REG_NOTIFY_CHANGE_NAME))
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Enumerate all available network interfaces, create events and corresponding keys and perform subscription. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (enumerateSubTree())
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync updateInfo(NULL);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync m_fInitialized = true;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync return;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync else
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("WARNING: cannot set up monitor properly (3); monitor now disabled.\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync else
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Too bad we can't even subscribe to notifications about network interfaces changes. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("WARNING: cannot set up monitor properly (2); monitor now disabled.\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync else
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Too bad we can't even subscribe to destroy event. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("WARNING: cannot set up monitor properly (1); monitor now disabled.\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync releaseResources();
735076496e14763dcdef4b43202e7665d4a8da43vboxsync}
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsyncHostDnsServiceWin::~HostDnsServiceWin()
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync{
735076496e14763dcdef4b43202e7665d4a8da43vboxsync monitorThreadShutdown();
735076496e14763dcdef4b43202e7665d4a8da43vboxsync releaseResources();
735076496e14763dcdef4b43202e7665d4a8da43vboxsync m_fInitialized = false;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync}
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsyncbool HostDnsServiceWin::releaseWarehouseItem(int idxItem)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync{
735076496e14763dcdef4b43202e7665d4a8da43vboxsync bool rc = true;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* We do not check if idxItem is in valid range of m_aWarehouse here
735076496e14763dcdef4b43202e7665d4a8da43vboxsync * (a bit of performance optimization), so make sure you provided a valid value! */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync struct Item oTmpItem = m_aWarehouse[idxItem];
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Non-zero return code means ResetEvent() succeeded. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync rc = ResetEvent(oTmpItem.hEvent) != 0;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (!rc) LogRel(("Failed to reset event (idxItem=%d); monitor unstable (rc=%d).\n", idxItem, GetLastError()));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync CloseHandle(oTmpItem.hEvent);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync oTmpItem.hEvent = NULL;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync RegCloseKey(oTmpItem.hKey);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync oTmpItem.hKey = NULL;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync Log2(("Unsubscribed from %ls notifications\n", oTmpItem.wcsInterface));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync m_aWarehouse.erase(m_aWarehouse.begin() + idxItem);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync return rc;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync}
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsyncbool HostDnsServiceWin::dropSubTreeNotifications()
735076496e14763dcdef4b43202e7665d4a8da43vboxsync{
735076496e14763dcdef4b43202e7665d4a8da43vboxsync bool rc = true;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Any sub-tree events we subscribed? */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (m_aWarehouse.size() > VBOX_OFFSET_SUBTREE_EVENTS)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Going from the end to the beginning. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync for (int idxItem = (int)m_aWarehouse.size() - 1; idxItem >= VBOX_OFFSET_SUBTREE_EVENTS; idxItem--)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync rc &= releaseWarehouseItem(idxItem);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync size_t cElementsLeft = m_aWarehouse.size();
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (cElementsLeft != VBOX_OFFSET_SUBTREE_EVENTS)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("DNS monitor unstable; %d events left after dropping.\n", (int)cElementsLeft - VBOX_OFFSET_SUBTREE_EVENTS));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync return false;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync return rc;
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync}
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsyncvoid HostDnsServiceWin::releaseResources()
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync{
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* First, drop notifications subscription for sub-tree keys. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync dropSubTreeNotifications();
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Then release notification about tree structure changes. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (m_aWarehouse.size() > VBOX_OFFSET_TREE_EVENT)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync releaseWarehouseItem(VBOX_OFFSET_TREE_EVENT);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Release shutdown event. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (m_aWarehouse.size() > VBOX_OFFSET_SHUTDOWN_EVENT)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync releaseWarehouseItem(VBOX_OFFSET_SHUTDOWN_EVENT);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync AssertReturnVoid(m_aWarehouse.size() == 0);
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync}
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsyncbool HostDnsServiceWin::subscribeTo(const wchar_t *wcsPath, const wchar_t *wcsInterface, DWORD fFilter)
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync{
735076496e14763dcdef4b43202e7665d4a8da43vboxsync HKEY hTmpKey = NULL;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync HANDLE hTmpEvent = NULL;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Do not add more than MAXIMUM_WAIT_OBJECTS items to the array due to WaitForMultipleObjects() limitation. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if ((m_aWarehouse.size() + 1 /* the array size if we would add an extra item */ ) > MAXIMUM_WAIT_OBJECTS)
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("Too many items to monitor.\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync return false;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync hTmpEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (!hTmpEvent)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync return false;
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* wcsPath might not be specified if we want to subscribe to the termination event. In this case
735076496e14763dcdef4b43202e7665d4a8da43vboxsync * it is assumed that this is the first issued subscription request (i.e., m_aWarehouse.size() == 0). */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (wcsPath)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LONG rc;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Open registry key itself. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, wcsPath, 0, KEY_READ | KEY_NOTIFY, &hTmpKey);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (rc == ERROR_SUCCESS)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Link registry key and notification event. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync rc = RegNotifyChangeKeyValue(hTmpKey, TRUE, fFilter, hTmpEvent, TRUE);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (rc != ERROR_SUCCESS)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Don't leak! */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync RegCloseKey(hTmpKey);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("Unable to register key notification (rc=0x%X).\n", rc));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync else
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("Unable to open key (rc=0x%X)\n", rc));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* All good so far? */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (rc != ERROR_SUCCESS)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("WARNING: unable to set up %ls registry key notifications.\n", wcsPath));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync CloseHandle(hTmpEvent);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync return false;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync else if (m_aWarehouse.size() > 0)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("Subscription to termination event already established.\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync CloseHandle(hTmpEvent);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync return false;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Finally, construct array item and queue it. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync struct Item oTmpItem = { hTmpKey, hTmpEvent, NULL };
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Sub-tree keys should provide interface name (UUID). This is needed in order to
735076496e14763dcdef4b43202e7665d4a8da43vboxsync * collect all useful network settings to HostDnsInformation storage object to provide it to parent class. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (wcsInterface)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync wcscpy(oTmpItem.wcsInterface, wcsInterface);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (wcsPath)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync Log2(("Subscription to %ls established.\n", wcsPath));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync m_aWarehouse.push_back(oTmpItem);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync return true;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync}
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsyncbool HostDnsServiceWin::enumerateSubTree()
735076496e14763dcdef4b43202e7665d4a8da43vboxsync{
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LONG rc = 0;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync HKEY hTmpKey;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync DWORD cSubKeys = 0;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync DWORD cbSubKeyNameMax = 0;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Enumerate all the available interfaces. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, pwcKeyRoot, 0, KEY_READ, &hTmpKey);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (rc == ERROR_SUCCESS)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Get info about amount of available network interfaces. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync rc = RegQueryInfoKeyW(hTmpKey, NULL, NULL, NULL, &cSubKeys, &cbSubKeyNameMax, NULL, NULL, NULL, NULL, NULL, NULL);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (rc == ERROR_SUCCESS)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Now iterate over interfaces if:
735076496e14763dcdef4b43202e7665d4a8da43vboxsync * 1) there are interfaces available and
735076496e14763dcdef4b43202e7665d4a8da43vboxsync * 2) maximum length of an interface name conforms to our buffer allocation size. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (cSubKeys > 0 && cbSubKeyNameMax <= VBOX_KEY_NAME_LEN_MAX)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync wchar_t sSubKeyName[VBOX_KEY_NAME_LEN_MAX];
735076496e14763dcdef4b43202e7665d4a8da43vboxsync for (DWORD idxSubKey = 0; idxSubKey < cSubKeys; idxSubKey++)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync rc = RegEnumKeyW(hTmpKey, idxSubKey, sSubKeyName, VBOX_KEY_NAME_LEN_MAX);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (rc == ERROR_SUCCESS)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Since we already know interface name (actually UUID), construct full registry path here. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync wchar_t sSubKeyFullPath[VBOX_KEY_NAME_LEN_MAX];
735076496e14763dcdef4b43202e7665d4a8da43vboxsync RT_ZERO(sSubKeyFullPath);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync wcscpy(sSubKeyFullPath, pwcKeyRoot);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync rc = wcscat_s(sSubKeyFullPath, VBOX_KEY_NAME_LEN_MAX, L"\\");
735076496e14763dcdef4b43202e7665d4a8da43vboxsync rc |= wcscat_s(sSubKeyFullPath, VBOX_KEY_NAME_LEN_MAX, sSubKeyName);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (rc == 0)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync subscribeTo(sSubKeyFullPath, sSubKeyName, REG_NOTIFY_CHANGE_LAST_SET);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync else
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("Unable to open interfaces list (1).\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync RegCloseKey(hTmpKey);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync return true;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync else
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("Unable to open interfaces list (2).\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync else
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("Unable to open interfaces list (3).\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync RegCloseKey(hTmpKey);
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync else
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("Unable to open interfaces list (4).\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync return false;
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync}
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
3f2299591cfeb8a37a3578bef9c44c1790860948vboxsyncHRESULT HostDnsServiceWin::init()
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync{
0faefdb9edd752514d5dfed8353118e47e57f0ebvboxsync HRESULT hrc = HostDnsMonitor::init();
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync AssertComRCReturn(hrc, hrc);
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync return updateInfo(NULL);
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync}
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsyncvoid HostDnsServiceWin::monitorThreadShutdown()
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync{
735076496e14763dcdef4b43202e7665d4a8da43vboxsync AssertReturnVoid(m_aWarehouse.size() > VBOX_OFFSET_SHUTDOWN_EVENT);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync SetEvent(m_aWarehouse[VBOX_OFFSET_SHUTDOWN_EVENT].hEvent);
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync}
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsyncvoid HostDnsServiceWin::extendVectorWithStrings(std::vector<std::string> &pVectorToExtend, const std::wstring &wcsParameter)
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync{
735076496e14763dcdef4b43202e7665d4a8da43vboxsync std::wstringstream wcsStream(wcsParameter);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync std::wstring wcsSubString;
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync while (std::getline(wcsStream, wcsSubString, L' '))
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync std::string str = std::_Narrow_str(wcsSubString);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync pVectorToExtend.push_back(str);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync}
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync#ifdef DEBUG
735076496e14763dcdef4b43202e7665d4a8da43vboxsyncstatic void hostDnsWinDumpList(const std::vector<std::string> &awcszValues)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync{
735076496e14763dcdef4b43202e7665d4a8da43vboxsync for (int idxItem = 0; idxItem < awcszValues.size(); idxItem++)
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("%s\n", awcszValues[idxItem].c_str()));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync}
735076496e14763dcdef4b43202e7665d4a8da43vboxsync#endif /* DEBUG */
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
bca22f037c4fa4df62f7244c27686c0a491821b8vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsyncHRESULT HostDnsServiceWin::updateInfo(uint8_t *fWhatsChanged)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync{
735076496e14763dcdef4b43202e7665d4a8da43vboxsync HostDnsInformation pHostDnsInfo;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync RT_ZERO(pHostDnsInfo);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Any interfaces available? */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (m_aWarehouse.size() > VBOX_OFFSET_SUBTREE_EVENTS)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Walk across all the available interfaces and collect network configuration data:
735076496e14763dcdef4b43202e7665d4a8da43vboxsync * domain name, name servers and search list. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync for (int idxKey = VBOX_OFFSET_SUBTREE_EVENTS; idxKey < m_aWarehouse.size(); idxKey++)
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LONG rc;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Get number of key values. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync DWORD cValues = 0;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync rc = RegQueryInfoKeyW(m_aWarehouse[idxKey].hKey, NULL, NULL, NULL, NULL, NULL, NULL, &cValues, NULL, NULL, NULL, NULL);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (rc == ERROR_SUCCESS)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync for (DWORD idxValue = 0; idxValue < cValues; idxValue++)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync wchar_t wcsValueName[VBOX_KEY_NAME_LEN_MAX];
735076496e14763dcdef4b43202e7665d4a8da43vboxsync DWORD cbValueName = VBOX_KEY_NAME_LEN_MAX;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync wchar_t wcsData[VBOX_KEY_NAME_LEN_MAX];
735076496e14763dcdef4b43202e7665d4a8da43vboxsync DWORD cbData = VBOX_KEY_NAME_LEN_MAX;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Walk across all the properties of given interface. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync rc = RegEnumValueW(m_aWarehouse[idxKey].hKey, idxValue, wcsValueName, &cbValueName, 0, NULL, (LPBYTE)wcsData, &cbData);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (rc == ERROR_SUCCESS)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (( wcscmp(wcsValueName, L"Domain") == 0
735076496e14763dcdef4b43202e7665d4a8da43vboxsync || wcscmp(wcsValueName, L"DhcpDomain") == 0)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync && wcslen(wcsData) > 0)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* We rely on that fact that Windows host cannot be a member of more than one domain in the same time! */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (pHostDnsInfo.domain.empty())
735076496e14763dcdef4b43202e7665d4a8da43vboxsync pHostDnsInfo.domain = std::_Narrow_str(std::wstring(wcsData));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync else if (( wcscmp(wcsValueName, L"NameServer") == 0
735076496e14763dcdef4b43202e7665d4a8da43vboxsync || wcscmp(wcsValueName, L"DhcpNameServer") == 0)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync && wcslen(wcsData) > 0)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync extendVectorWithStrings(pHostDnsInfo.servers, std::wstring(wcsData));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync else if (wcscmp(wcsValueName, L"SearchList") == 0
735076496e14763dcdef4b43202e7665d4a8da43vboxsync && wcslen(wcsData) > 0)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync extendVectorWithStrings(pHostDnsInfo.searchList, std::wstring(wcsData));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync uint8_t fChanged = VBOX_EVENT_NO_CHANGES;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Compare cached network settings and newly obtained ones. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (pHostDnsInfo.servers != m_hostInfoCache.servers)
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync#ifdef DEBUG
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("Servers changed from:\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync hostDnsWinDumpList(m_hostInfoCache.servers);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("to:\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync hostDnsWinDumpList(pHostDnsInfo.servers);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync#endif /* DEBUG */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync fChanged |= VBOX_EVENT_SERVERS_CHANGED;
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync }
bca22f037c4fa4df62f7244c27686c0a491821b8vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (pHostDnsInfo.domain != m_hostInfoCache.domain)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync#ifdef DEBUG
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("Domain changed: [%s]->[%s].\n",
735076496e14763dcdef4b43202e7665d4a8da43vboxsync m_hostInfoCache.domain.empty() ? "NONE" : m_hostInfoCache.domain.c_str(),
735076496e14763dcdef4b43202e7665d4a8da43vboxsync pHostDnsInfo.domain.c_str()));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync#endif /* DEBUG */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync fChanged |= VBOX_EVENT_DOMAIN_CHANGED;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
510b14148124a664875cdb3a996433bd92c9324evboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (pHostDnsInfo.searchList != m_hostInfoCache.searchList)
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync#ifdef DEBUG
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("SearchList changed from:\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync hostDnsWinDumpList(m_hostInfoCache.searchList);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("to:\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync hostDnsWinDumpList(pHostDnsInfo.searchList);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync#endif /* DEBUG */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync fChanged |= VBOX_EVENT_SEARCHLIST_CHANGED;
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync }
bca22f037c4fa4df62f7244c27686c0a491821b8vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Provide info about changes if requested. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (fWhatsChanged)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync *fWhatsChanged = fChanged;
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Update host network configuration cache. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync m_hostInfoCache.servers.clear();
735076496e14763dcdef4b43202e7665d4a8da43vboxsync m_hostInfoCache.servers = pHostDnsInfo.servers;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync m_hostInfoCache.domain.clear();
735076496e14763dcdef4b43202e7665d4a8da43vboxsync m_hostInfoCache.domain.assign(pHostDnsInfo.domain);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync m_hostInfoCache.searchList.clear();
735076496e14763dcdef4b43202e7665d4a8da43vboxsync m_hostInfoCache.searchList = pHostDnsInfo.searchList;
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync HostDnsMonitor::setInfo(pHostDnsInfo);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
3f2299591cfeb8a37a3578bef9c44c1790860948vboxsync
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync return S_OK;
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync}
3f2299591cfeb8a37a3578bef9c44c1790860948vboxsync
8dfc5e89cd3421bb0602f33768f00c1f1d40b1d2vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsyncvoid HostDnsServiceWin::getEventHandles(HANDLE *ahEvents)
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync{
735076496e14763dcdef4b43202e7665d4a8da43vboxsync AssertReturnVoid(m_aWarehouse.size() > 0);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync for (int idxHandle = 0; idxHandle < m_aWarehouse.size(); idxHandle++)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync ahEvents[idxHandle] = m_aWarehouse[idxHandle].hEvent;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync}
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsyncint HostDnsServiceWin::monitorWorker()
735076496e14763dcdef4b43202e7665d4a8da43vboxsync{
735076496e14763dcdef4b43202e7665d4a8da43vboxsync monitorThreadInitializationDone();
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync uint8_t fWhatsChabged = VBOX_EVENT_NO_CHANGES;
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (!m_fInitialized)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("Host DNS monitor was not initialized properly.\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync return VERR_INTERNAL_ERROR;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync HANDLE ahEvents[MAXIMUM_WAIT_OBJECTS];
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync while (true)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Each new iteration we need to update event handles list we monitor. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync RT_ZERO(ahEvents);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync getEventHandles(ahEvents);
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync DWORD rc = WaitForMultipleObjects((DWORD)m_aWarehouse.size(), ahEvents, FALSE, INFINITE);
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync AssertMsgReturn(rc != WAIT_FAILED,
735076496e14763dcdef4b43202e7665d4a8da43vboxsync ("WaitForMultipleObjects failed (%d) to wait! Please debug",
735076496e14763dcdef4b43202e7665d4a8da43vboxsync GetLastError()), VERR_INTERNAL_ERROR);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Shutdown requested. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (rc == (WAIT_OBJECT_0 + VBOX_OFFSET_SHUTDOWN_EVENT)) break;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Interfaces amount changed. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync else if (rc == (WAIT_OBJECT_0 + VBOX_OFFSET_TREE_EVENT))
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync Log2(("Network interfaces amount changed.\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Drop interface events. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (dropSubTreeNotifications())
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Drop event which is corresponds to interfaces tree changes. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (releaseWarehouseItem(VBOX_OFFSET_TREE_EVENT))
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Restart interface tree monitoring. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (subscribeTo(pwcKeyRoot, NULL, REG_NOTIFY_CHANGE_NAME))
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Restart interface events. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (enumerateSubTree())
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync Log2(("Monitor restarted successfully.\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync fWhatsChabged = VBOX_EVENT_NO_CHANGES;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync updateInfo(&fWhatsChabged);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (fWhatsChabged & VBOX_EVENT_SERVERS_CHANGED)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("Notification sent (1).\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync notifyAll();
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync continue;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync else
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("Monitor unstable: failed to subscribe network configuration changes.\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync else
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("Monitor unstable: failed to subscribe interface changes.\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync else
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("Monitor unstable: failed to unsubscribe from interfaces amount changes.\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync else
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("Monitor unstable: failed to unsubscribe from previous notifications.\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* If something went wrong, we break monitoring. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync break;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* DNS update events range. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync else if (rc >= (WAIT_OBJECT_0 + VBOX_OFFSET_SUBTREE_EVENTS) &&
735076496e14763dcdef4b43202e7665d4a8da43vboxsync rc < (WAIT_OBJECT_0 + m_aWarehouse.size()))
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync Log2(("Network setting has changed at interface %ls.\n", m_aWarehouse[rc - WAIT_OBJECT_0].wcsInterface));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Drop previous notifications first. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (dropSubTreeNotifications())
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* Re-subscribe. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (enumerateSubTree())
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync Log2(("Restart monitoring.\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync fWhatsChabged = VBOX_EVENT_NO_CHANGES;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync updateInfo(&fWhatsChabged);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync if (fWhatsChabged & VBOX_EVENT_SERVERS_CHANGED)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("Notification sent (2).\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync notifyAll();
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync continue;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync else
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("WARNING: Monitor unstable: unable to re-subscribe to notifications.\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync else
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("WARNING: Monitor unstable: failed to unsubscribe from previous notifications.\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
735076496e14763dcdef4b43202e7665d4a8da43vboxsync /* If something went wrong, we stop monitoring. */
735076496e14763dcdef4b43202e7665d4a8da43vboxsync break;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync else
735076496e14763dcdef4b43202e7665d4a8da43vboxsync AssertMsgFailedReturn(("WaitForMultipleObjects returns out of bound (%d) index %d. Please debug!\n", m_aWarehouse.size(), rc), VERR_INTERNAL_ERROR);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync LogRel(("Monitor thread exited.\n"));
735076496e14763dcdef4b43202e7665d4a8da43vboxsync return VINF_SUCCESS;
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync}