Index: trunk/src/VBox/Main/src-server/HostDnsService.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/HostDnsService.cpp	(revision 53121)
+++ trunk/src/VBox/Main/src-server/HostDnsService.cpp	(revision 53122)
@@ -36,5 +36,5 @@
 
 static void dumpHostDnsInformation(const HostDnsInformation&);
-static void dumpHostDnsStrVector(const std::string&, const std::vector<std::wstring>&);
+static void dumpHostDnsStrVector(const std::string&, const std::vector<std::string>&);
 
 /* Lockee */
@@ -66,10 +66,10 @@
 }
 
-inline static void detachVectorOfWString(const std::vector<std::wstring>& v,
-                                         std::vector<com::Utf8Str> &aArray)
+inline static void detachVectorOfString(const std::vector<std::string>& v,
+                                        std::vector<com::Utf8Str> &aArray)
 {
     aArray.resize(v.size());
     size_t i = 0;
-    for (std::vector<std::wstring>::const_iterator it = v.begin(); it != v.end(); ++it, ++i)
+    for (std::vector<std::string>::const_iterator it = v.begin(); it != v.end(); ++it, ++i)
         aArray[i] = Utf8Str(it->c_str());
 }
@@ -270,5 +270,5 @@
     dumpHostDnsStrVector("Name Server", m->info->servers);
 
-    detachVectorOfWString(m->info->servers, aNameServers);
+    detachVectorOfString(m->info->servers, aNameServers);
 
     return S_OK;
@@ -301,5 +301,5 @@
     dumpHostDnsStrVector("Search String", m->info->searchList);
 
-    detachVectorOfWString(m->info->searchList, aSearchStrings);
+    detachVectorOfString(m->info->searchList, aSearchStrings);
 
     return S_OK;
@@ -344,14 +344,14 @@
 
     if (!info.domain.empty())
-        LogRel(("DNS domain: %ls\n", info.domain.data()));
-}
-
-
-static void dumpHostDnsStrVector(const std::string& prefix, const std::vector<std::wstring>& v)
+        LogRel(("DNS domain: %s\n", info.domain.c_str()));
+}
+
+
+static void dumpHostDnsStrVector(const std::string& prefix, const std::vector<std::string>& v)
 {
     int i = 1;
-    for (std::vector<std::wstring>::const_iterator it = v.begin();
+    for (std::vector<std::string>::const_iterator it = v.begin();
          it != v.end();
          ++it, ++i)
-        LogRel(("%s %d: %ls\n", prefix.c_str(), i, it->data()));
-}
+        LogRel(("%s %d: %s\n", prefix.c_str(), i, it->c_str()));
+}
Index: trunk/src/VBox/Main/src-server/HostDnsService.h
===================================================================
--- trunk/src/VBox/Main/src-server/HostDnsService.h	(revision 53121)
+++ trunk/src/VBox/Main/src-server/HostDnsService.h	(revision 53122)
@@ -57,7 +57,7 @@
 {
   public:
-    std::vector<std::wstring> servers;
-    std::wstring domain;
-    std::vector<std::wstring> searchList;
+    std::vector<std::string> servers;
+    std::string domain;
+    std::vector<std::string> searchList;
 };
 
@@ -146,78 +146,22 @@
 # endif
 # ifdef RT_OS_WINDOWS
-/* Maximum size of Windows registry key (according to MSDN). */
-#define VBOX_KEY_NAME_LEN_MAX   (255)
-class HostDnsServiceWin: public HostDnsMonitor
+class HostDnsServiceWin : public HostDnsMonitor
 {
     public:
-
-        HostDnsServiceWin();
-        ~HostDnsServiceWin();
-
-        HRESULT init();
+    HostDnsServiceWin();
+    ~HostDnsServiceWin();
+    HRESULT init();
 
     protected:
-
-        virtual void monitorThreadShutdown();
-        virtual int monitorWorker();
-
-    private:
-
-        /* This structure is used in order to link Windows registry key with
-         * an event which is generated once the key has been changed (when interface has updated its DNS setting)
-         * or one of the sub-keys has been deleted or added (when interface added or deleted). */
-        struct Item
-        {
-            HKEY    hKey;                                /** Key handle. */
-            HANDLE  hEvent;                              /** Event handle. */
-            TCHAR   wcsInterface[VBOX_KEY_NAME_LEN_MAX]; /** Path to key within Windows registry. */
-        };
-
-        /* Bit flags to determine what was exactly was changed when Windows triggered event notification. */
-        enum {
-            VBOX_EVENT_NO_CHANGES           = 0,
-            VBOX_EVENT_SERVERS_CHANGED      = RT_BIT(1),
-            VBOX_EVENT_DOMAIN_CHANGED       = RT_BIT(2),
-            VBOX_EVENT_SEARCHLIST_CHANGED   = RT_BIT(3),
-        };
-
-        /* Keys and events storage.
-         * Size of this vector should not be greater than MAXIMUM_WAIT_OBJECTS because
-         * this is exactly maximum amount of events which we allowed to wait for. */
-        std::vector<struct Item> m_aWarehouse;
-        /* Cached host network configuration. */
-        HostDnsInformation m_hostInfoCache;
-
-        /* TCHAR[] constants initialized outside of class definition. */
-        static const TCHAR m_pwcKeyRoot[];
-
-        /* m_aWarehouse array offsets. */
-        enum {
-            VBOX_OFFSET_SHUTDOWN_EVENT = 0,
-            VBOX_OFFSET_TREE_EVENT     = 1,
-            VBOX_OFFSET_SUBTREE_EVENTS = 2,
-        };
-
-        /* Do actual unsubscription for given item. */
-        bool releaseWarehouseItem(int idxItem);
-        /* Release all allocated resources and unsubscribe from everything. */
-        void releaseResources();
-        /* Remove subscription from DNS change notifications and release corresponding resources. */
-        bool dropSubTreeNotifications();
-
-        /* Create & add event into the list of events we monitor to. */
-        bool subscribeTo(TCHAR *wcsPath, TCHAR *wcsInterface, DWORD fFilter);
-        /* Subscribe to DNS changes. */
-        bool enumerateSubTree();
-
-        /* Get plain array of event handles. */
-        void getEventHandles(HANDLE *ahEvents);
-        void extendVectorWithStrings(std::vector<std::wstring>& pVectorToExtend, std::wstring &wcsParameter);
-        HRESULT updateInfo(uint8_t *fWhatsChanged);
-
-        /* This flag indicates whether constructor performed initialization correctly. If not set,
-         * monitorWorker() will not perform any action and will be terminated as soon as there will be
-         * an attempt to run it. */
-        bool m_fInitialized;
+    virtual void monitorThreadShutdown();
+    virtual int monitorWorker();
+
+    private:
+    void strList2List(std::vector<std::string>& lst, char *strLst);
+    HRESULT updateInfo();
+
+    private:
+    struct Data;
+    Data *m;
 };
 # endif
Index: trunk/src/VBox/Main/src-server/HostDnsServiceResolvConf.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/HostDnsServiceResolvConf.cpp	(revision 53121)
+++ trunk/src/VBox/Main/src-server/HostDnsServiceResolvConf.cpp	(revision 53122)
@@ -78,9 +78,9 @@
 }
 
+
 HRESULT HostDnsServiceResolvConf::readResolvConf()
 {
     struct rcp_state st;
-    wchar_t *pwczTmpStr;
-
+    
     st.rcps_flags = RCPSF_NO_STR2IPCONV;
     int rc = rcp_parse(&st, m->resolvConfFilename.c_str());
@@ -92,35 +92,14 @@
     {
         AssertBreak(st.rcps_str_nameserver[i]);
-
-        pwczTmpStr = NULL;
-        rc = RTStrToUtf16(st.rcps_str_nameserver[i], (RTUTF16 **)&pwczTmpStr);
-        if (RT_SUCCESS(rc) && pwczTmpStr)
-        {
-            info.servers.push_back(std::wstring(pwczTmpStr));
-            RTUtf16Free((RTUTF16 *)pwczTmpStr);
-        }
+        info.servers.push_back(st.rcps_str_nameserver[i]);
     }
-
+    
     if (st.rcps_domain)
-    {
-        pwczTmpStr = NULL;
-        rc = RTStrToUtf16(st.rcps_domain, (RTUTF16 **)&pwczTmpStr);
-        if (RT_SUCCESS(rc) && pwczTmpStr)
-        {
-            info.domain = std::wstring(pwczTmpStr);
-            RTUtf16Free((RTUTF16 *)pwczTmpStr);
-        }
-    }
+        info.domain = st.rcps_domain;
 
     for (unsigned i = 0; i != st.rcps_num_searchlist; ++i)
     {
         AssertBreak(st.rcps_searchlist[i]);
-        pwczTmpStr = NULL;
-        rc = RTStrToUtf16(st.rcps_searchlist[i], (RTUTF16 **)&pwczTmpStr);
-        if (RT_SUCCESS(rc) && pwczTmpStr)
-        {
-            info.searchList.push_back(std::wstring(pwczTmpStr));
-            RTUtf16Free((RTUTF16 *)pwczTmpStr);
-        }
+        info.searchList.push_back(st.rcps_searchlist[i]);
     }
     setInfo(info);
Index: trunk/src/VBox/Main/src-server/darwin/HostDnsServiceDarwin.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/darwin/HostDnsServiceDarwin.cpp	(revision 53121)
+++ trunk/src/VBox/Main/src-server/darwin/HostDnsServiceDarwin.cpp	(revision 53122)
@@ -18,5 +18,4 @@
 #include <VBox/com/string.h>
 #include <VBox/com/ptr.h>
-#include <VBox/log.h>
 
 
@@ -163,38 +162,4 @@
 
     return VINF_SUCCESS;
-}
-
-
-static wchar_t *darwinCFStringToUtf16(CFStringRef pStringRef)
-{
-    /* Number of characters (UTF16 encoded, 2 bytes) in the pStringRef. */
-    CFIndex ccStringRef = CFStringGetLength(pStringRef);
-
-    if (ccStringRef > 0)
-    {
-        size_t  cbTmpBuf = (size_t)ccStringRef * sizeof(wchar_t) + 1 /* end of string */;
-        wchar_t *pTmpBuf = (wchar_t *)RTMemAlloc(cbTmpBuf);
-        if (pTmpBuf)
-        {
-            CFIndex ccConverted = CFStringGetBytes(pStringRef,
-                                                   CFRangeMake(0, ccStringRef),
-                                                   kCFStringEncodingUTF16,
-                                                   0,
-                                                   false,
-                                                   (UInt8 *)pTmpBuf,
-                                                   (CFIndex)cbTmpBuf - 1 /* w/o end of string */,
-                                                   NULL);
-            if (ccConverted > 0)
-            {
-                /* Set end of string. */
-                pTmpBuf[ccConverted] = 0;
-                return pTmpBuf;
-            }
-
-            RTMemFree(pTmpBuf);
-        }
-    }
-
-    return NULL;
 }
 
@@ -230,10 +195,8 @@
     if (domainNameRef)
     {
-        wchar_t *pwszDomainName = darwinCFStringToUtf16(domainNameRef);
-        if (pwszDomainName)
-        {
-            info.domain = std::wstring(pwszDomainName);
-            RTMemFree(pwszDomainName);
-        }
+        const char *pszDomainName = CFStringGetCStringPtr(domainNameRef,
+                                                    CFStringGetSystemEncoding());
+        if (pszDomainName)
+            info.domain = pszDomainName;
     }
 
@@ -250,10 +213,10 @@
                 continue;
 
-            wchar_t *pwszServerAddress = darwinCFStringToUtf16(serverAddressRef);
-            if (!pwszServerAddress)
-                continue;
-
-            info.servers.push_back(std::wstring(pwszServerAddress));
-            RTMemFree(pwszServerAddress);
+            const char *pszServerAddress = CFStringGetCStringPtr(serverAddressRef,
+                                                           CFStringGetSystemEncoding());
+            if (!pszServerAddress)
+                continue;
+
+            info.servers.push_back(std::string(pszServerAddress));
         }
     }
@@ -271,10 +234,10 @@
                 continue;
 
-            wchar_t *pwszSearchString = darwinCFStringToUtf16(searchStringRef);
-            if (!pwszSearchString)
-                continue;
-
-            info.searchList.push_back(std::wstring(pwszSearchString));
-            RTMemFree(pwszSearchString);
+            const char *pszSearchString = CFStringGetCStringPtr(searchStringRef,
+                                                          CFStringGetSystemEncoding());
+            if (!pszSearchString)
+                continue;
+
+            info.searchList.push_back(std::string(pszSearchString));
         }
     }
Index: trunk/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp	(revision 53121)
+++ trunk/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp	(revision 53122)
@@ -1,22 +1,6 @@
-/* $Id$ */
-/** @file
- * Host DNS listener for Windows.
- */
-
-/*
- * Copyright (C) 2014 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
+/* -*- indent-tabs-mode: nil; -*- */
 #include <VBox/com/string.h>
 #include <VBox/com/ptr.h>
-#include <VBox/log.h>
+
 
 #include <iprt/assert.h>
@@ -26,243 +10,68 @@
 
 #include <string>
-#include <sstream>
 #include <vector>
 #include "../HostDnsService.h"
 
-/* In order to monitor DNS setting updates we need to receive notification about
- * Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\* keys changes.
- * Since it is not possible to use patterns when subscribing key changes, we need to find valid paths for all such
- * keys manually and subscribe to changes one by one (see enumerateSubTree()). */
-const TCHAR HostDnsServiceWin::m_pwcKeyRoot[] = _T("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces");
-
-
-HostDnsServiceWin::HostDnsServiceWin()
-    : HostDnsMonitor(true),
-      m_aWarehouse(),
-      m_hostInfoCache(),
-      m_fInitialized(false)
-{
-    /* Add monitor destroy event.
-     * This event should have index '0' at the events array in order to separate it from
-     * DNS and tree change events. When this event occurs all resources should be released. */
-    if (subscribeTo(NULL, NULL, 0))
+struct HostDnsServiceWin::Data
+{
+    HostDnsServiceWin::Data(){}
+    HKEY hKeyTcpipParameters;
+#define DATA_DNS_UPDATE_EVENT 0
+#define DATA_SHUTDOWN_EVENT   1
+#define DATA_MAX_EVENT        2
+    HANDLE haDataEvent[DATA_MAX_EVENT];
+};
+
+static inline int registerNotification(const HKEY& hKey, HANDLE& hEvent)
+{
+    LONG lrc = RegNotifyChangeKeyValue(hKey,
+                                       TRUE,
+                                       REG_NOTIFY_CHANGE_LAST_SET,
+                                       hEvent,
+                                       TRUE);
+    AssertMsgReturn(lrc == ERROR_SUCCESS,
+                    ("Failed to register event on the key. Please debug me!"),
+                    VERR_INTERNAL_ERROR);
+
+    return VINF_SUCCESS;
+}
+
+HostDnsServiceWin::HostDnsServiceWin():HostDnsMonitor(true), m(NULL)
+{
+    m = new Data();
+
+    m->haDataEvent[DATA_DNS_UPDATE_EVENT] = CreateEvent(NULL,
+      TRUE, FALSE, NULL);
+    AssertReleaseMsg(m->haDataEvent[DATA_DNS_UPDATE_EVENT],
+      ("Failed to create event for DNS event (%d)\n", GetLastError()));
+
+    m->haDataEvent[DATA_SHUTDOWN_EVENT] = CreateEvent(NULL,
+      TRUE, FALSE, NULL);
+    AssertReleaseMsg(m->haDataEvent[DATA_SHUTDOWN_EVENT],
+      ("Failed to create event for Shutdown signal (%d)\n", GetLastError()));
+
+    LONG lrc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+      TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"),
+      0, KEY_READ|KEY_NOTIFY, &m->hKeyTcpipParameters);
+    AssertReleaseMsg(lrc == ERROR_SUCCESS,
+      ("Failed to open Registry Key for read and update notifications (%d)\n",
+      GetLastError()));
+}
+
+
+HostDnsServiceWin::~HostDnsServiceWin()
+{
+    if (m && !m->hKeyTcpipParameters)
     {
-        /* Add registry tree change event and corresponding key.
-         * This event should have index '1' at the events array in order to separate it from DNS events.
-         * When this event occurs it means there are changes in the list of available network interfaces.
-         * Network interfaces should be re-enumerated, all DNS events and keys data should re-initialized. */
-        if (subscribeTo(const_cast<TCHAR *>(m_pwcKeyRoot), NULL, REG_NOTIFY_CHANGE_NAME))
-        {
-            /* Enumerate all available network interfaces, create events and corresponding keys and perform subscription.  */
-            if (enumerateSubTree())
-            {
-                updateInfo(NULL);
-                m_fInitialized = true;
-                return;
-            }
-            else
-                LogRel(("WARNING: cannot set up monitor properly (3); monitor now disabled.\n"));
-        }
-        else
-            /* Too bad we can't even subscribe to notifications about network interfaces changes. */
-            LogRel(("WARNING: cannot set up monitor properly (2); monitor now disabled.\n"));
+        RegCloseKey(m->hKeyTcpipParameters);
+        m->hKeyTcpipParameters = 0;
+
+        CloseHandle(m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
+        CloseHandle(m->haDataEvent[DATA_SHUTDOWN_EVENT]);
+
+        delete m;
+
+        m = NULL;
     }
-    else
-        /* Too bad we can't even subscribe to destroy event. */
-        LogRel(("WARNING: cannot set up monitor properly (1); monitor now disabled.\n"));
-
-    releaseResources();
-}
-
-
-HostDnsServiceWin::~HostDnsServiceWin()
-{
-    monitorThreadShutdown();
-    releaseResources();
-    m_fInitialized = false;
-}
-
-
-bool HostDnsServiceWin::releaseWarehouseItem(int idxItem)
-{
-    bool rc = true;
-    /* We do not check if idxItem is in valid range of m_aWarehouse here
-     * (a bit of performance optimization), so make sure you provided a valid value! */
-    struct Item oTmpItem = m_aWarehouse[idxItem];
-
-    /* Non-zero return code means ResetEvent() succeeded. */
-    rc = ResetEvent(oTmpItem.hEvent) != 0;
-    if (!rc) LogRel(("Failed to reset event (idxItem=%d); monitor unstable (rc=%d).\n", idxItem, GetLastError()));
-    CloseHandle(oTmpItem.hEvent);
-    oTmpItem.hEvent = NULL;
-
-    RegCloseKey(oTmpItem.hKey);
-    oTmpItem.hKey   = NULL;
-
-    Log2(("Unsubscribed from %ls notifications\n", oTmpItem.wcsInterface));
-
-    m_aWarehouse.erase(m_aWarehouse.begin() + idxItem);
-
-    return rc;
-}
-
-
-bool HostDnsServiceWin::dropSubTreeNotifications()
-{
-    bool rc = true;
-    /* Any sub-tree events we subscribed? */
-    if (m_aWarehouse.size() > VBOX_OFFSET_SUBTREE_EVENTS)
-        /* Going from the end to the beginning. */
-        for (int idxItem = (int)m_aWarehouse.size() - 1; idxItem >= VBOX_OFFSET_SUBTREE_EVENTS; idxItem--)
-            rc &= releaseWarehouseItem(idxItem);
-
-    size_t cElementsLeft = m_aWarehouse.size();
-    if (cElementsLeft != VBOX_OFFSET_SUBTREE_EVENTS)
-    {
-        LogRel(("DNS monitor unstable; %d events left after dropping.\n", (int)cElementsLeft - VBOX_OFFSET_SUBTREE_EVENTS));
-        return false;
-    }
-
-    return rc;
-}
-
-
-void HostDnsServiceWin::releaseResources()
-{
-    /* First, drop notifications subscription for sub-tree keys. */
-    dropSubTreeNotifications();
-
-    /* Then release notification about tree structure changes. */
-    if (m_aWarehouse.size() > VBOX_OFFSET_TREE_EVENT)
-        releaseWarehouseItem(VBOX_OFFSET_TREE_EVENT);
-
-    /* Release shutdown event. */
-    if (m_aWarehouse.size() > VBOX_OFFSET_SHUTDOWN_EVENT)
-        releaseWarehouseItem(VBOX_OFFSET_SHUTDOWN_EVENT);
-
-    AssertReturnVoid(m_aWarehouse.size() == 0);
-}
-
-
-bool HostDnsServiceWin::subscribeTo(TCHAR *wcsPath, TCHAR *wcsInterface, DWORD fFilter)
-{
-    HKEY   hTmpKey    = NULL;
-    HANDLE hTmpEvent  = NULL;
-
-    /* Do not add more than MAXIMUM_WAIT_OBJECTS items to the array due to WaitForMultipleObjects() limitation. */
-    if ((m_aWarehouse.size() + 1 /* the array size if we would add an extra item */ ) > MAXIMUM_WAIT_OBJECTS)
-    {
-        LogRel(("Too many items to monitor.\n"));
-        return false;
-    }
-
-    hTmpEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
-    if (!hTmpEvent)
-        return false;
-
-    /* wcsPath might not be specified if we want to subscribe to the termination event. In this case
-     * it is assumed that this is the first issued subscription request (i.e., m_aWarehouse.size() == 0). */
-    if (wcsPath)
-    {
-        LONG rc;
-        /* Open registry key itself. */
-        rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, wcsPath, 0, KEY_READ | KEY_NOTIFY, &hTmpKey);
-        if (rc == ERROR_SUCCESS)
-        {
-            /* Link registry key and notification event. */
-            rc = RegNotifyChangeKeyValue(hTmpKey, TRUE, fFilter, hTmpEvent, TRUE);
-            if (rc != ERROR_SUCCESS)
-            {
-                /* Don't leak! */
-                RegCloseKey(hTmpKey);
-                LogRel(("Unable to register key notification (rc=0x%X).\n", rc));
-            }
-        }
-        else
-            LogRel(("Unable to open key (rc=0x%X)\n", rc));
-
-        /* All good so far? */
-        if (rc != ERROR_SUCCESS)
-        {
-            LogRel(("WARNING: unable to set up %ls registry key notifications.\n", wcsPath));
-            CloseHandle(hTmpEvent);
-            return false;
-        }
-    }
-    else if (m_aWarehouse.size() > 0)
-    {
-        LogRel(("Subscription to termination event already established.\n"));
-        CloseHandle(hTmpEvent);
-        return false;
-    }
-
-    /* Finally, construct array item and queue it. */
-    struct Item oTmpItem = { hTmpKey, hTmpEvent, NULL };
-
-    /* Sub-tree keys should provide interface name (UUID). This is needed in order to
-     * collect all useful network settings to HostDnsInformation storage object to provide it to parent class. */
-    if (wcsInterface)
-        _tcscpy(oTmpItem.wcsInterface, wcsInterface);
-
-    if (wcsPath)
-        Log2(("Subscription to %ls established.\n", wcsPath));
-
-    m_aWarehouse.push_back(oTmpItem);
-
-    return true;
-}
-
-
-bool HostDnsServiceWin::enumerateSubTree()
-{
-    LONG  rc = 0;
-    HKEY  hTmpKey;
-    DWORD cSubKeys = 0;
-    DWORD cbSubKeyNameMax = 0;
-
-    /* Enumerate all the available interfaces. */
-    rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, m_pwcKeyRoot, 0, KEY_READ, &hTmpKey);
-    if (rc == ERROR_SUCCESS)
-    {
-        /* Get info about amount of available network interfaces. */
-        rc = RegQueryInfoKey(hTmpKey, NULL, NULL, NULL, &cSubKeys, &cbSubKeyNameMax, NULL, NULL, NULL, NULL, NULL, NULL);
-        if (rc == ERROR_SUCCESS)
-        {
-            /* Now iterate over interfaces if:
-             * 1) there are interfaces available and
-             * 2) maximum length of an interface name conforms to our buffer allocation size. */
-            if (cSubKeys > 0 && cbSubKeyNameMax <= VBOX_KEY_NAME_LEN_MAX)
-            {
-                TCHAR sSubKeyName[VBOX_KEY_NAME_LEN_MAX];
-                for (DWORD idxSubKey = 0; idxSubKey < cSubKeys; idxSubKey++)
-                {
-                    rc = RegEnumKey(hTmpKey, idxSubKey, sSubKeyName, VBOX_KEY_NAME_LEN_MAX);
-                    if (rc == ERROR_SUCCESS)
-                    {
-                        /* Since we already know interface name (actually UUID), construct full registry path here. */
-                        TCHAR sSubKeyFullPath[VBOX_KEY_NAME_LEN_MAX];
-                        RT_ZERO(sSubKeyFullPath);
-                        _tcscpy(sSubKeyFullPath, m_pwcKeyRoot);
-                        rc  = _tcscat_s(sSubKeyFullPath, VBOX_KEY_NAME_LEN_MAX, _T("\\"));
-                        rc |= _tcscat_s(sSubKeyFullPath, VBOX_KEY_NAME_LEN_MAX, sSubKeyName);
-                        if (rc == 0)
-                            subscribeTo(sSubKeyFullPath, sSubKeyName, REG_NOTIFY_CHANGE_LAST_SET);
-                    }
-                    else
-                        LogRel(("Unable to open interfaces list (1).\n"));
-                }
-                RegCloseKey(hTmpKey);
-                return true;
-            }
-            else
-                LogRel(("Unable to open interfaces list (2).\n"));
-        }
-        else
-            LogRel(("Unable to open interfaces list (3).\n"));
-        RegCloseKey(hTmpKey);
-    }
-    else
-        LogRel(("Unable to open interfaces list (4).\n"));
-    return false;
 }
 
@@ -273,5 +82,5 @@
     AssertComRCReturn(hrc, hrc);
 
-    return updateInfo(NULL);
+    return updateInfo();
 }
 
@@ -279,143 +88,5 @@
 void HostDnsServiceWin::monitorThreadShutdown()
 {
-    AssertReturnVoid(m_aWarehouse.size() > VBOX_OFFSET_SHUTDOWN_EVENT);
-    SetEvent(m_aWarehouse[VBOX_OFFSET_SHUTDOWN_EVENT].hEvent);
-}
-
-
-void HostDnsServiceWin::extendVectorWithStrings(std::vector<std::wstring>& pVectorToExtend, std::wstring &wcsParameter)
-{
-    std::wstringstream   wcsStream(wcsParameter);
-    std::wstring         wcsSubString;
-
-    while (std::getline(wcsStream, wcsSubString, _T(' ')))
-        pVectorToExtend.push_back(wcsSubString);
-}
-
-
-#ifdef DEBUG
-static void hostDnsWinDumpList(std::vector<std::wstring>& awcszValues)
-{
-    for (int idxItem = 0; idxItem < awcszValues.size(); idxItem++)
-    {
-        LogRel(("%ls\n", awcszValues[idxItem].data()));
-    }
-}
-#endif /* DEBUG */
-
-
-HRESULT HostDnsServiceWin::updateInfo(uint8_t *fWhatsChanged)
-{
-    HostDnsInformation pHostDnsInfo;
-    RT_ZERO(pHostDnsInfo);
-
-    /* Any interfaces available? */
-    if (m_aWarehouse.size() > VBOX_OFFSET_SUBTREE_EVENTS)
-    {
-        /* Walk across all the available interfaces and collect network configuration data:
-         * domain name, name servers and search list. */
-        for (int idxKey = VBOX_OFFSET_SUBTREE_EVENTS; idxKey < m_aWarehouse.size(); idxKey++)
-        {
-            LONG rc;
-
-            /* Get number of key values. */
-            DWORD cValues = 0;
-            rc = RegQueryInfoKey(m_aWarehouse[idxKey].hKey, NULL, NULL, NULL, NULL, NULL, NULL, &cValues, NULL, NULL, NULL, NULL);
-            if (rc == ERROR_SUCCESS)
-            {
-                for (DWORD idxValue = 0; idxValue < cValues; idxValue++)
-                {
-                    TCHAR wcsValueName[VBOX_KEY_NAME_LEN_MAX];
-                    DWORD cbValueName = VBOX_KEY_NAME_LEN_MAX;
-                    TCHAR wcsData[VBOX_KEY_NAME_LEN_MAX];
-                    DWORD cbData = VBOX_KEY_NAME_LEN_MAX;
-
-                    /* Walk across all the properties of given interface. */
-                    rc = RegEnumValue(m_aWarehouse[idxKey].hKey, idxValue, wcsValueName, &cbValueName, 0, NULL, (LPBYTE)wcsData, &cbData);
-                    if (rc == ERROR_SUCCESS)
-                    {
-
-                        if ((   _tcscmp(wcsValueName, _T("Domain")) == 0
-                             || _tcscmp(wcsValueName, _T("DhcpDomain")) == 0)
-                            && _tcslen(wcsData) > 0)
-                        {
-                            /* We rely on that fact that Windows host cannot be a member of more than one domain in the same time! */
-                            if (pHostDnsInfo.domain.empty())
-                                pHostDnsInfo.domain = std::wstring(wcsData);
-                        }
-                        else if ((   _tcscmp(wcsValueName, _T("NameServer")) == 0
-                                  || _tcscmp(wcsValueName, _T("DhcpNameServer")) == 0)
-                                 && _tcslen(wcsData) > 0)
-                        {
-                            extendVectorWithStrings(pHostDnsInfo.servers, std::wstring(wcsData));
-                        }
-                        else if (_tcscmp(wcsValueName, _T("SearchList")) == 0
-                                 && _tcslen(wcsData) > 0)
-                        {
-                            extendVectorWithStrings(pHostDnsInfo.searchList, std::wstring(wcsData));
-                        }
-                    }
-                }
-            }
-        }
-
-        uint8_t fChanged = VBOX_EVENT_NO_CHANGES;
-        /* Compare cached network settings and newly obtained ones. */
-        if (pHostDnsInfo.servers != m_hostInfoCache.servers)
-        {
-#ifdef DEBUG
-            LogRel(("Servers changed from:\n"));
-            hostDnsWinDumpList(m_hostInfoCache.servers);
-            LogRel(("to:\n"));
-            hostDnsWinDumpList(pHostDnsInfo.servers);
-#endif /* DEBUG */
-            fChanged |= VBOX_EVENT_SERVERS_CHANGED;
-        }
-
-        if (pHostDnsInfo.domain != m_hostInfoCache.domain)
-        {
-#ifdef DEBUG
-            LogRel(("Domain changed: [%ls]->[%ls].\n",
-                m_hostInfoCache.domain.empty() ? _T("NONE") : (const unsigned short *)m_hostInfoCache.domain.data(),
-                pHostDnsInfo.domain.data()));
-#endif /* DEBUG */
-            fChanged |= VBOX_EVENT_DOMAIN_CHANGED;
-        }
-
-        if (pHostDnsInfo.searchList != m_hostInfoCache.searchList)
-        {
-#ifdef DEBUG
-            LogRel(("SearchList changed from:\n"));
-            hostDnsWinDumpList(m_hostInfoCache.searchList);
-            LogRel(("to:\n"));
-            hostDnsWinDumpList(pHostDnsInfo.searchList);
-#endif /* DEBUG */
-            fChanged |= VBOX_EVENT_SEARCHLIST_CHANGED;
-        }
-
-        /* Provide info about changes if requested. */
-        if (fWhatsChanged)
-            *fWhatsChanged = fChanged;
-
-        /* Update host network configuration cache. */
-        m_hostInfoCache.servers.clear();
-        m_hostInfoCache.servers = pHostDnsInfo.servers;
-        m_hostInfoCache.domain.clear();
-        m_hostInfoCache.domain.assign(pHostDnsInfo.domain);
-        m_hostInfoCache.searchList.clear();
-        m_hostInfoCache.searchList = pHostDnsInfo.searchList;
-
-        HostDnsMonitor::setInfo(pHostDnsInfo);
-    }
-
-    return S_OK;
-}
-
-
-void HostDnsServiceWin::getEventHandles(HANDLE *ahEvents)
-{
-    AssertReturnVoid(m_aWarehouse.size() > 0);
-    for (int idxHandle = 0; idxHandle < m_aWarehouse.size(); idxHandle++)
-        ahEvents[idxHandle] = m_aWarehouse[idxHandle].hEvent;
+    SetEvent(m->haDataEvent[DATA_SHUTDOWN_EVENT]);
 }
 
@@ -423,109 +94,140 @@
 int HostDnsServiceWin::monitorWorker()
 {
+    registerNotification(m->hKeyTcpipParameters,
+                         m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
+
     monitorThreadInitializationDone();
 
-    uint8_t fWhatsChabged = VBOX_EVENT_NO_CHANGES;
-
-    if (!m_fInitialized)
-    {
-        LogRel(("Host DNS monitor was not initialized properly.\n"));
-        return VERR_INTERNAL_ERROR;
-    }
-
-    HANDLE  ahEvents[MAXIMUM_WAIT_OBJECTS];
-
+    DWORD dwRc;
     while (true)
     {
-        /* Each new iteration we need to update event handles list we monitor. */
-        RT_ZERO(ahEvents);
-        getEventHandles(ahEvents);
-
-        DWORD rc = WaitForMultipleObjects((DWORD)m_aWarehouse.size(), ahEvents, FALSE, INFINITE);
-
-        AssertMsgReturn(rc != WAIT_FAILED,
+        dwRc = WaitForMultipleObjects(DATA_MAX_EVENT,
+                                      m->haDataEvent,
+                                      FALSE,
+                                      INFINITE);
+        AssertMsgReturn(dwRc != WAIT_FAILED,
                         ("WaitForMultipleObjects failed (%d) to wait! Please debug",
                          GetLastError()), VERR_INTERNAL_ERROR);
 
-        /* Shutdown requested. */
-        if      (rc == (WAIT_OBJECT_0 + VBOX_OFFSET_SHUTDOWN_EVENT)) break;
-        /* Interfaces amount changed. */
-        else if (rc == (WAIT_OBJECT_0 + VBOX_OFFSET_TREE_EVENT))
-        {
-            Log2(("Network interfaces amount changed.\n"));
-
-            /* Drop interface events. */
-            if (dropSubTreeNotifications())
-            {
-                /* Drop event which is corresponds to interfaces tree changes. */
-                if (releaseWarehouseItem(VBOX_OFFSET_TREE_EVENT))
-                {
-                    /* Restart interface tree monitoring. */
-                    if (subscribeTo(const_cast<TCHAR *>(m_pwcKeyRoot), NULL, REG_NOTIFY_CHANGE_NAME))
-                    {
-                        /* Restart interface events. */
-                        if (enumerateSubTree())
-                        {
-                            Log2(("Monitor restarted successfully.\n"));
-                            fWhatsChabged = VBOX_EVENT_NO_CHANGES;
-                            updateInfo(&fWhatsChabged);
-                            if (fWhatsChabged & VBOX_EVENT_SERVERS_CHANGED)
-                            {
-                                LogRel(("Notification sent (1).\n"));
-                                notifyAll();
-                            }
-                            continue;
-                        }
-                        else
-                            LogRel(("Monitor unstable: failed to subscribe network configuration changes.\n"));
-                    }
-                    else
-                        LogRel(("Monitor unstable: failed to subscribe interface changes.\n"));
-                }
-                else
-                    LogRel(("Monitor unstable: failed to unsubscribe from interfaces amount changes.\n"));
-            }
-            else
-                LogRel(("Monitor unstable: failed to unsubscribe from previous notifications.\n"));
-
-            /* If something went wrong, we break monitoring. */
+        if ((dwRc - WAIT_OBJECT_0) == DATA_DNS_UPDATE_EVENT)
+        {
+            updateInfo();
+            notifyAll();
+            ResetEvent(m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
+            registerNotification(m->hKeyTcpipParameters,
+                                 m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
+
+        }
+        else if ((dwRc - WAIT_OBJECT_0) == DATA_SHUTDOWN_EVENT)
+        {
             break;
-
-        }
-        /* DNS update events range. */
-        else if (rc >= (WAIT_OBJECT_0 + VBOX_OFFSET_SUBTREE_EVENTS) &&
-                 rc <  (WAIT_OBJECT_0 + m_aWarehouse.size()))
-        {
-            Log2(("Network setting has changed at interface %ls.\n", m_aWarehouse[rc - WAIT_OBJECT_0].wcsInterface));
-
-            /* Drop previous notifications first. */
-            if (dropSubTreeNotifications())
-            {
-                /* Re-subscribe. */
-                if (enumerateSubTree())
-                {
-                    Log2(("Restart monitoring.\n"));
-                    fWhatsChabged = VBOX_EVENT_NO_CHANGES;
-                    updateInfo(&fWhatsChabged);
-                    if (fWhatsChabged & VBOX_EVENT_SERVERS_CHANGED)
-                    {
-                        LogRel(("Notification sent (2).\n"));
-                        notifyAll();
-                    }
-                    continue;
-                }
-                else
-                    LogRel(("WARNING: Monitor unstable: unable to re-subscribe to notifications.\n"));
-            }
-            else
-                LogRel(("WARNING: Monitor unstable: failed to unsubscribe from previous notifications.\n"));
-
-            /* If something went wrong, we stop monitoring. */
-            break;
         }
         else
-            AssertMsgFailedReturn(("WaitForMultipleObjects returns out of bound (%d) index %d. Please debug!\n", m_aWarehouse.size(), rc), VERR_INTERNAL_ERROR);
+        {
+            AssertMsgFailedReturn(
+              ("WaitForMultipleObjects returns out of bound index %d. Please debug!",
+                                   dwRc),
+              VERR_INTERNAL_ERROR);
+        }
     }
-    LogRel(("Monitor thread exited.\n"));
     return VINF_SUCCESS;
 }
 
+
+HRESULT HostDnsServiceWin::updateInfo()
+{
+    HRESULT hrc;
+    DWORD regIndex;
+    BYTE abDomain[256];
+    BYTE abNameServers[256];
+    BYTE abSearchList[256];
+
+    RT_ZERO(abDomain);
+    RT_ZERO(abNameServers);
+    RT_ZERO(abSearchList);
+
+    regIndex = 0;
+    do {
+        CHAR keyName[256];
+        DWORD cbKeyName = sizeof(keyName);
+        DWORD keyType = 0;
+        BYTE keyData[1024];
+        DWORD cbKeyData = sizeof(keyData);
+
+        hrc = RegEnumValueA(m->hKeyTcpipParameters, regIndex, keyName, &cbKeyName, 0,
+                            &keyType, keyData, &cbKeyData);
+        if (   hrc == ERROR_SUCCESS
+            || hrc == ERROR_MORE_DATA)
+        {
+            if (   RTStrICmp("Domain", keyName) == 0
+                && cbKeyData > 1
+                && cbKeyData < sizeof(abDomain))
+                memcpy(abDomain, keyData, cbKeyData);
+
+            else if (   RTStrICmp("DhcpDomain", keyName) == 0
+                     && cbKeyData > 1
+                     && abDomain[0] == 0
+                     && cbKeyData < sizeof(abDomain))
+                memcpy(abDomain, keyData, cbKeyData);
+
+            else if (   RTStrICmp("NameServer", keyName) == 0
+                     && cbKeyData > 1
+                     && cbKeyData < sizeof(abNameServers))
+                memcpy(abNameServers, keyData, cbKeyData);
+
+            else if (   RTStrICmp("DhcpNameServer", keyName) == 0
+                     && cbKeyData > 1
+                     && abNameServers[0] == 0
+                     && cbKeyData < sizeof(abNameServers))
+                memcpy(abNameServers, keyData, cbKeyData);
+
+            else if (   RTStrICmp("SearchList", keyName) == 0
+                     && cbKeyData > 1
+                     && cbKeyData < sizeof(abSearchList))
+              memcpy(abSearchList, keyData, cbKeyData);
+        }
+        regIndex++;
+    } while (hrc != ERROR_NO_MORE_ITEMS);
+
+    /* OK, now parse and update DNS structures. */
+    /* domain name */
+    HostDnsInformation info;
+    info.domain = (char*)abDomain;
+
+    /* server list */
+    strList2List(info.servers, (char *)abNameServers);
+    /* search list */
+    strList2List(info.searchList, (char *)abSearchList);
+
+    HostDnsMonitor::setInfo(info);
+
+    return S_OK;
+}
+
+
+void HostDnsServiceWin::strList2List(std::vector<std::string>& lst, char *strLst)
+{
+    char *next, *current;
+    char address[512];
+
+    AssertPtrReturnVoid(strLst);
+
+    if (strlen(strLst) == 0)
+      return;
+
+    current = strLst;
+    do {
+        RT_ZERO(address);
+        next = RTStrStr(current, " ");
+
+        if (next)
+          strncpy(address, current, RT_MIN(sizeof(address)-1, next - current));
+        else
+          strcpy(address, current);
+
+        lst.push_back(std::string(address));
+
+        current = next + 1;
+    } while(next);
+
+}
