Index: trunk/src/VBox/Main/src-server/HostDnsService.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/HostDnsService.cpp	(revision 108010)
+++ trunk/src/VBox/Main/src-server/HostDnsService.cpp	(revision 108012)
@@ -42,18 +42,15 @@
 #include <algorithm>
 #include <set>
-#include <iprt/sanitized/string>
 #include "HostDnsService.h"
 
 
 
-static void dumpHostDnsStrVector(const std::string &prefix, const std::vector<std::string> &v)
+static void dumpHostDnsStrVector(const char *prefix, const std::vector<com::Utf8Str> &v)
 {
     int i = 1;
-    for (std::vector<std::string>::const_iterator it = v.begin();
-         it != v.end();
-         ++it, ++i)
-        LogRel(("  %s %d: %s\n", prefix.c_str(), i, it->c_str()));
+    for (std::vector<com::Utf8Str>::const_iterator it = v.begin(); it != v.end(); ++it, ++i)
+        LogRel(("  %s %d: %s\n", prefix, i, it->c_str()));
     if (v.empty())
-        LogRel(("  no %s entries\n", prefix.c_str()));
+        LogRel(("  no %s entries\n", prefix));
 }
 
@@ -62,5 +59,5 @@
     dumpHostDnsStrVector("server", info.servers);
 
-    if (!info.domain.empty())
+    if (info.domain.isNotEmpty())
         LogRel(("  domain: %s\n", info.domain.c_str()));
     else
@@ -77,6 +74,6 @@
     else
     {
-        std::set<std::string> l(servers.begin(), servers.end());
-        std::set<std::string> r(info.servers.begin(), info.servers.end());
+        std::set<com::Utf8Str> l(servers.begin(), servers.end());
+        std::set<com::Utf8Str> r(info.servers.begin(), info.servers.end());
 
         fSameServers = (l == r);
@@ -93,17 +90,4 @@
 
     return fSameServers && fSameDomain && fSameSearchList;
-}
-
-DECLINLINE(void) detachVectorOfStrings(const std::vector<std::string>& v, std::vector<com::Utf8Str> &aArray)
-{
-    aArray.resize(v.size());
-    size_t i = 0;
-    for (std::vector<std::string>::const_iterator it = v.begin(); it != v.end(); ++it, ++i)
-        aArray[i] = Utf8Str(it->c_str()); /** @todo r=bird: *it isn't necessarily UTF-8 clean!!
-                                           * On darwin we do silly shit like using CFStringGetSystemEncoding()
-                                           * that may be UTF-8 but doesn't need to be.
-                                           *
-                                           * Why on earth are we using std::string here anyway?
-                                           */
 }
 
@@ -384,5 +368,5 @@
     dumpHostDnsStrVector("name server", m->info.servers);
 
-    detachVectorOfStrings(m->info.servers, aNameServers);
+    aNameServers = m->info.servers;
 
     return S_OK;
@@ -394,5 +378,5 @@
     AssertReturn(m != NULL, E_FAIL);
 
-    LogRel(("HostDnsMonitorProxy::GetDomainName: %s\n", m->info.domain.empty() ? "no domain set" : m->info.domain.c_str()));
+    LogRel(("HostDnsMonitorProxy::GetDomainName: %s\n", m->info.domain.isEmpty() ? "no domain set" : m->info.domain.c_str()));
     *pDomainName = m->info.domain.c_str();
 
@@ -408,5 +392,5 @@
     dumpHostDnsStrVector("search string", m->info.searchList);
 
-    detachVectorOfStrings(m->info.searchList, aSearchStrings);
+    aSearchStrings = m->info.searchList;
 
     return S_OK;
Index: trunk/src/VBox/Main/src-server/HostDnsService.h
===================================================================
--- trunk/src/VBox/Main/src-server/HostDnsService.h	(revision 108010)
+++ trunk/src/VBox/Main/src-server/HostDnsService.h	(revision 108012)
@@ -37,5 +37,4 @@
 
 #include <list>
-#include <iprt/sanitized/string>
 #include <vector>
 
@@ -53,8 +52,7 @@
 
 public:
-    /** @todo r=bird: Why on earth are we using std::string and not Utf8Str?   */
-    std::vector<std::string> servers;
-    std::string domain;
-    std::vector<std::string> searchList;
+    std::vector<com::Utf8Str> servers;
+    com::Utf8Str domain;
+    std::vector<com::Utf8Str> searchList;
     bool equals(const HostDnsInformation &, uint32_t fLaxComparison = 0) const;
 };
@@ -109,5 +107,5 @@
     mutable RTCLockMtx m_LockMtx;
 
-public: /** @todo r=andy Why is this public? */
+//public: /** @todo r=andy Why is this public? */
 
     struct Data;
@@ -160,6 +158,6 @@
 public:
 
-    HRESULT init(HostDnsMonitorProxy *pProxy);
-    void uninit(void);
+    HRESULT init(HostDnsMonitorProxy *pProxy) RT_OVERRIDE;
+    void uninit(void) RT_OVERRIDE;
 
 protected:
@@ -185,6 +183,6 @@
 public:
 
-    HRESULT init(HostDnsMonitorProxy *pProxy);
-    void uninit(void);
+    HRESULT init(HostDnsMonitorProxy *pProxy) RT_OVERRIDE;
+    void uninit(void) RT_OVERRIDE;
 
 protected:
@@ -215,7 +213,7 @@
 
     HRESULT init(HostDnsMonitorProxy *pProxy, const char *aResolvConfFileName);
-    void uninit(void);
-
-    const std::string& getResolvConf(void) const;
+    void uninit(void) RT_OVERRIDE;
+
+    const Utf8Str &getResolvConf(void) const;
 
 protected:
@@ -238,4 +236,44 @@
     HostDnsServiceSolaris() {}
     virtual ~HostDnsServiceSolaris() {}
+
+public:
+
+    virtual HRESULT init(HostDnsMonitorProxy *pProxy) RT_OVERRIDE
+    {
+        return HostDnsServiceResolvConf::init(pProxy, "/etc/resolv.conf");
+    }
+};
+
+#  endif
+#  if defined(RT_OS_LINUX) || defined(DOXYGEN_RUNNING)
+class HostDnsServiceLinux : public HostDnsServiceResolvConf
+{
+public:
+
+    HostDnsServiceLinux() : HostDnsServiceResolvConf(true), m_fdShutdown(-1) {}
+    virtual ~HostDnsServiceLinux();
+
+public:
+
+    HRESULT init(HostDnsMonitorProxy *pProxy) RT_OVERRIDE;
+
+protected:
+
+    int monitorThreadShutdown(RTMSINTERVAL uTimeoutMs) RT_OVERRIDE;
+    int monitorThreadProc(void) RT_OVERRIDE;
+
+    /** Socket end to write shutdown notification to, so the monitor thread will
+     *  wake up and terminate. */
+    int m_fdShutdown;
+};
+
+#  endif
+#  if defined(RT_OS_FREEBSD) || defined(DOXYGEN_RUNNING)
+class HostDnsServiceFreebsd: public HostDnsServiceResolvConf
+{
+public:
+
+    HostDnsServiceFreebsd(){}
+    virtual ~HostDnsServiceFreebsd() {}
 
 public:
@@ -248,44 +286,4 @@
 
 #  endif
-#  if defined(RT_OS_LINUX) || defined(DOXYGEN_RUNNING)
-class HostDnsServiceLinux : public HostDnsServiceResolvConf
-{
-public:
-
-    HostDnsServiceLinux() : HostDnsServiceResolvConf(true), m_fdShutdown(-1) {}
-    virtual ~HostDnsServiceLinux();
-
-public:
-
-    HRESULT init(HostDnsMonitorProxy *pProxy);
-
-protected:
-
-    int monitorThreadShutdown(RTMSINTERVAL uTimeoutMs) RT_OVERRIDE;
-    int monitorThreadProc(void) RT_OVERRIDE;
-
-    /** Socket end to write shutdown notification to, so the monitor thread will
-     *  wake up and terminate. */
-    int m_fdShutdown;
-};
-
-#  endif
-#  if defined(RT_OS_FREEBSD) || defined(DOXYGEN_RUNNING)
-class HostDnsServiceFreebsd: public HostDnsServiceResolvConf
-{
-public:
-
-    HostDnsServiceFreebsd(){}
-    virtual ~HostDnsServiceFreebsd() {}
-
-public:
-
-    virtual HRESULT init(HostDnsMonitorProxy *pProxy)
-    {
-        return HostDnsServiceResolvConf::init(pProxy, "/etc/resolv.conf");
-    }
-};
-
-#  endif
 #  if defined(RT_OS_OS2) || defined(DOXYGEN_RUNNING)
 class HostDnsServiceOs2 : public HostDnsServiceResolvConf
@@ -299,5 +297,5 @@
 
     /* XXX: \\MPTN\\ETC should be taken from environment variable ETC  */
-    virtual HRESULT init(HostDnsMonitorProxy *pProxy)
+    virtual HRESULT init(HostDnsMonitorProxy *pProxy) RT_OVERRIDE
     {
         return HostDnsServiceResolvConf::init(pProxy, "\\MPTN\\ETC\\RESOLV2");
Index: trunk/src/VBox/Main/src-server/HostDnsServiceResolvConf.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/HostDnsServiceResolvConf.cpp	(revision 108010)
+++ trunk/src/VBox/Main/src-server/HostDnsServiceResolvConf.cpp	(revision 108012)
@@ -49,6 +49,4 @@
 #include <VBox/log.h>
 
-#include <iprt/sanitized/string>
-
 #include "HostDnsService.h"
 #include "../../Devices/Network/slirp/resolv_conf_parser.h"
@@ -62,5 +60,5 @@
     };
 
-    std::string resolvConfFilename;
+    com::Utf8Str resolvConfFilename;
 };
 
@@ -96,5 +94,5 @@
 }
 
-const std::string& HostDnsServiceResolvConf::getResolvConf(void) const
+const com::Utf8Str &HostDnsServiceResolvConf::getResolvConf(void) const
 {
     return m->resolvConfFilename;
@@ -104,5 +102,4 @@
 {
     struct rcp_state st;
-
     st.rcps_flags = RCPSF_NO_STR2IPCONV;
     int vrc = rcp_parse(&st, m->resolvConfFilename.c_str());
@@ -114,17 +111,22 @@
     {
         AssertBreak(st.rcps_str_nameserver[i]);
+        RTStrPurgeEncoding(st.rcps_str_nameserver[i]);
         info.servers.push_back(st.rcps_str_nameserver[i]);
     }
 
     if (st.rcps_domain)
+    {
+        RTStrPurgeEncoding(st.rcps_domain);
         info.domain = st.rcps_domain;
+    }
 
     for (unsigned i = 0; i != st.rcps_num_searchlist; ++i)
     {
         AssertBreak(st.rcps_searchlist[i]);
+        RTStrPurgeEncoding(st.rcps_searchlist[i]);
         info.searchList.push_back(st.rcps_searchlist[i]);
     }
+
     setInfo(info);
-
     return S_OK;
 }
Index: trunk/src/VBox/Main/src-server/darwin/HostDnsServiceDarwin.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/darwin/HostDnsServiceDarwin.cpp	(revision 108010)
+++ trunk/src/VBox/Main/src-server/darwin/HostDnsServiceDarwin.cpp	(revision 108012)
@@ -38,5 +38,4 @@
 #include <SystemConfiguration/SCDynamicStore.h>
 
-#include <iprt/sanitized/string>
 #include <vector>
 #include "../HostDnsService.h"
@@ -185,8 +184,23 @@
 }
 
+DECLINLINE(bool) queryCFStringAsUtf8Str(CFStringRef hRefSrc, com::Utf8Str &a_rDst, size_t cbMax)
+{
+    a_rDst.reserve(_1K);
+    if (!CFStringGetCString(hRefSrc, a_rDst.mutableRaw(), (CFIndex)a_rDst.capacity(), kCFStringEncodingUTF8))
+    {
+        a_rDst.reserve(cbMax);
+        if (!CFStringGetCString(hRefSrc, a_rDst.mutableRaw(), (CFIndex)a_rDst.capacity(), kCFStringEncodingUTF8))
+            return false;
+    }
+    RTStrPurgeEncoding(a_rDst.mutableRaw()); /* paranoia */
+    a_rDst.jolt();
+    return true;
+}
+
+
 int HostDnsServiceDarwin::updateInfo(void)
 {
     CFPropertyListRef propertyRef = SCDynamicStoreCopyValue(m->m_store, kStateNetworkGlobalDNSKey);
-    /**
+    /*
      * # scutil
      * \> get State:/Network/Global/DNS
@@ -205,19 +219,17 @@
      * }
      */
-
     if (!propertyRef)
         return VINF_SUCCESS;
+    CFDictionaryRef const propertyAsDictRef = static_cast<CFDictionaryRef>(propertyRef);
 
     HostDnsInformation info;
-    CFStringRef domainNameRef = (CFStringRef)CFDictionaryGetValue(static_cast<CFDictionaryRef>(propertyRef), CFSTR("DomainName"));
+    com::Utf8Str       strTmp;
+
+    CFStringRef const domainNameRef = (CFStringRef)CFDictionaryGetValue(propertyAsDictRef, CFSTR("DomainName"));
     if (domainNameRef)
-    {
-        const char *pszDomainName = CFStringGetCStringPtr(domainNameRef, CFStringGetSystemEncoding());
-        if (pszDomainName)
-            info.domain = pszDomainName;
-    }
-
-    CFArrayRef serverArrayRef = (CFArrayRef)CFDictionaryGetValue(static_cast<CFDictionaryRef>(propertyRef),
-                                                                 CFSTR("ServerAddresses"));
+        if (queryCFStringAsUtf8Str(domainNameRef, strTmp, _16K))
+            info.domain = strTmp;
+
+    CFArrayRef const serverArrayRef = (CFArrayRef)CFDictionaryGetValue(propertyAsDictRef, CFSTR("ServerAddresses"));
     if (serverArrayRef)
     {
@@ -225,23 +237,12 @@
         for (CFIndex i = 0; i < cItems; ++i)
         {
-            CFStringRef serverAddressRef = (CFStringRef)CFArrayGetValueAtIndex(serverArrayRef, i);
-            if (!serverAddressRef)
-                continue;
-
-            /** @todo r=bird: This code is messed up as CFStringGetCStringPtr is documented
-             *  to return NULL even if the string is valid.   Furthermore, we must have
-             *  UTF-8 - some joker might decide latin-1 is better here for all we know
-             *  and we'll end up with evil invalid UTF-8 sequences. */
-            const char *pszServerAddress = CFStringGetCStringPtr(serverAddressRef, CFStringGetSystemEncoding());
-            if (!pszServerAddress)
-                continue;
-
-            /** @todo r=bird: Why on earth are we using std::string and not Utf8Str?   */
-            info.servers.push_back(std::string(pszServerAddress));
+            CFStringRef const serverAddressRef = (CFStringRef)CFArrayGetValueAtIndex(serverArrayRef, i);
+            if (serverAddressRef)
+                if (queryCFStringAsUtf8Str(serverAddressRef, strTmp, _16K))
+                    info.servers.push_back(strTmp);
         }
     }
 
-    CFArrayRef searchArrayRef = (CFArrayRef)CFDictionaryGetValue(static_cast<CFDictionaryRef>(propertyRef),
-                                                                 CFSTR("SearchDomains"));
+    CFArrayRef const searchArrayRef = (CFArrayRef)CFDictionaryGetValue(propertyAsDictRef, CFSTR("SearchDomains"));
     if (searchArrayRef)
     {
@@ -250,17 +251,7 @@
         {
             CFStringRef searchStringRef = (CFStringRef)CFArrayGetValueAtIndex(searchArrayRef, i);
-            if (!searchStringRef)
-                continue;
-
-            /** @todo r=bird: This code is messed up as CFStringGetCStringPtr is documented
-             *  to return NULL even if the string is valid.   Furthermore, we must have
-             *  UTF-8 - some joker might decide latin-1 is better here for all we know
-             *  and we'll end up with evil invalid UTF-8 sequences. */
-            const char *pszSearchString = CFStringGetCStringPtr(searchStringRef, CFStringGetSystemEncoding());
-            if (!pszSearchString)
-                continue;
-
-            /** @todo r=bird: Why on earth are we using std::string and not Utf8Str?   */
-            info.searchList.push_back(std::string(pszSearchString));
+            if (searchStringRef)
+                if (queryCFStringAsUtf8Str(searchStringRef, strTmp, _64K))
+                    info.searchList.push_back(strTmp);
         }
     }
Index: trunk/src/VBox/Main/src-server/linux/HostDnsServiceLinux.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/linux/HostDnsServiceLinux.cpp	(revision 108010)
+++ trunk/src/VBox/Main/src-server/linux/HostDnsServiceLinux.cpp	(revision 108012)
@@ -45,4 +45,5 @@
 #include <string.h>
 #include <unistd.h>
+#include <stdlib.h>
 
 #include <fcntl.h>
Index: trunk/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp	(revision 108010)
+++ trunk/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp	(revision 108012)
@@ -48,6 +48,4 @@
 
 #include <algorithm>
-#include <iprt/sanitized/sstream>
-#include <iprt/sanitized/string>
 #include <vector>
 
@@ -60,28 +58,25 @@
                                        hEvent,
                                        TRUE);
-    AssertMsgReturn(lrc == ERROR_SUCCESS,
-                    ("Failed to register event on the key. Please debug me!"),
-                    VERR_INTERNAL_ERROR);
+    AssertLogRelMsgReturn(lrc == ERROR_SUCCESS,
+                          ("Failed to register event on the key. Please debug me!"),
+                          VERR_INTERNAL_ERROR);
 
     return VINF_SUCCESS;
 }
 
-static void appendTokenizedStrings(std::vector<std::string> &vecStrings, const std::string &strToAppend, char chDelim = ' ')
-{
-    if (strToAppend.empty())
+static void appendTokenizedStrings(std::vector<com::Utf8Str> &vecStrings, const com::Utf8Str &strToAppend, char chDelim = ' ')
+{
+    if (strToAppend.isEmpty())
         return;
 
-    std::istringstream stream(strToAppend);
-    std::string substr;
-
-    while (std::getline(stream, substr, chDelim))
-    {
-        if (substr.empty())
-            continue;
-
-        if (std::find(vecStrings.cbegin(), vecStrings.cend(), substr) != vecStrings.cend())
-            continue;
-
-        vecStrings.push_back(substr);
+    RTCString const strDelim(1, chDelim);
+    auto const      lstSubStrings  = strToAppend.split(strDelim);
+    size_t const    cSubStrings    = lstSubStrings.size();
+    for (size_t i = 0; i < cSubStrings; i++)
+    {
+        RTCString const &strCur = lstSubStrings[i];
+        if (strCur.isNotEmpty())
+            if (std::find(vecStrings.cbegin(), vecStrings.cend(), strCur) == vecStrings.cend())
+                vecStrings.push_back(strCur);
     }
 }
@@ -97,5 +92,5 @@
 #define DATA_TIMER            2
 #define DATA_MAX_EVENT        3
-    HANDLE haDataEvent[DATA_MAX_EVENT];
+    HANDLE ahDataEvents[DATA_MAX_EVENT];
 
     Data()
@@ -105,5 +100,5 @@
 
         for (size_t i = 0; i < DATA_MAX_EVENT; ++i)
-            haDataEvent[i] = NULL;
+            ahDataEvents[i] = NULL;
     }
 
@@ -111,9 +106,15 @@
     {
         if (hKeyTcpipParameters != NULL)
+        {
             RegCloseKey(hKeyTcpipParameters);
+            hKeyTcpipParameters = NULL;
+        }
 
         for (size_t i = 0; i < DATA_MAX_EVENT; ++i)
-            if (haDataEvent[i] != NULL)
-                CloseHandle(haDataEvent[i]);
+            if (ahDataEvents[i] != NULL)
+            {
+                CloseHandle(ahDataEvents[i]);
+                ahDataEvents[i] = NULL;
+            }
     }
 };
@@ -137,39 +138,31 @@
         return E_FAIL;
 
-    bool fRc = true;
     LONG lRc = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
                              L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
                              0,
-                             KEY_READ|KEY_NOTIFY,
+                             KEY_READ | KEY_NOTIFY,
                              &m->hKeyTcpipParameters);
     if (lRc != ERROR_SUCCESS)
     {
         LogRel(("HostDnsServiceWin: failed to open key Tcpip\\Parameters (error %d)\n", lRc));
-        fRc = false;
-    }
-    else
-    {
-        for (size_t i = 0; i < DATA_MAX_EVENT; ++i)
-        {
-            HANDLE h;
-
-            if (i ==  DATA_TIMER)
-                h = CreateWaitableTimer(NULL, FALSE, NULL);
-            else
-                h = CreateEvent(NULL, TRUE, FALSE, NULL);
-
-            if (h == NULL)
-            {
-                LogRel(("HostDnsServiceWin: failed to create event (error %d)\n", GetLastError()));
-                fRc = false;
-                break;
-            }
-
-            m->haDataEvent[i] = h;
-        }
-    }
-
-    if (!fRc)
         return E_FAIL;
+    }
+
+    for (size_t i = 0; i < DATA_MAX_EVENT; ++i)
+    {
+        HANDLE h;
+        if (i == DATA_TIMER)
+            h = CreateWaitableTimer(NULL, FALSE, NULL);
+        else
+            h = CreateEvent(NULL, TRUE, FALSE, NULL);
+        if (h == NULL)
+        {
+            LogRel(("HostDnsServiceWin: failed to create %s (error %d)\n",
+                    i == DATA_TIMER ? "waitable timer" : "event", GetLastError()));
+            return E_FAIL;
+        }
+
+        m->ahDataEvents[i] = h;
+    }
 
     HRESULT hrc = HostDnsServiceBase::init(pProxy);
@@ -187,9 +180,8 @@
 int HostDnsServiceWin::monitorThreadShutdown(RTMSINTERVAL uTimeoutMs)
 {
-    RT_NOREF(uTimeoutMs);
-
-    AssertPtr(m);
-    SetEvent(m->haDataEvent[DATA_SHUTDOWN_EVENT]);
-    /** @todo r=andy Wait for thread? Check vrc here. Timeouts? */
+    AssertPtrReturn(m, VINF_SUCCESS);
+
+    SetEvent(m->ahDataEvents[DATA_SHUTDOWN_EVENT]);
+    RT_NOREF(uTimeoutMs); /* (Caller waits for the thread) */
 
     return VINF_SUCCESS;
@@ -201,5 +193,5 @@
 
     registerNotification(m->hKeyTcpipParameters,
-                         m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
+                         m->ahDataEvents[DATA_DNS_UPDATE_EVENT]);
 
     onMonitorThreadInitDone();
@@ -207,9 +199,5 @@
     for (;;)
     {
-        DWORD dwReady;
-
-        dwReady = WaitForMultipleObjects(DATA_MAX_EVENT, m->haDataEvent,
-                                         FALSE, INFINITE);
-
+        DWORD dwReady = WaitForMultipleObjects(DATA_MAX_EVENT, m->ahDataEvents, FALSE, INFINITE);
         if (dwReady == WAIT_OBJECT_0 + DATA_SHUTDOWN_EVENT)
             break;
@@ -225,11 +213,6 @@
                 LARGE_INTEGER delay; /* in 100ns units */
                 delay.QuadPart = -2 * 1000 * 1000 * 10LL; /* relative: 2s */
-
-                BOOL ok = SetWaitableTimer(m->haDataEvent[DATA_TIMER], &delay,
-                                           0, NULL, NULL, FALSE);
-                if (ok)
-                {
+                if (SetWaitableTimer(m->ahDataEvents[DATA_TIMER], &delay, 0, NULL, NULL, FALSE))
                     m->fTimerArmed = true;
-                }
                 else
                 {
@@ -239,7 +222,7 @@
             }
 
-            ResetEvent(m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
+            ResetEvent(m->ahDataEvents[DATA_DNS_UPDATE_EVENT]);
             registerNotification(m->hKeyTcpipParameters,
-                                 m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
+                                 m->ahDataEvents[DATA_DNS_UPDATE_EVENT]);
         }
         else if (dwReady == WAIT_OBJECT_0 + DATA_TIMER)
@@ -267,6 +250,6 @@
     HostDnsInformation info;
 
-    std::string strDomain;
-    std::string strSearchList;  /* NB: comma separated, no spaces */
+    com::Utf8Str strDomain;
+    com::Utf8Str strSearchList;  /* NB: comma separated, no spaces */
 
     /*
@@ -279,14 +262,12 @@
     for (DWORD regIndex = 0; /**/; ++regIndex)
     {
-        char keyName[256];
-        DWORD cbKeyName = sizeof(keyName);
-        DWORD keyType = 0;
-        char keyData[1024];
-        DWORD cbKeyData = sizeof(keyData);
-
-/** @todo use unicode API. This isn't UTF-8 clean!   */
-        LSTATUS lrc = RegEnumValueA(m->hKeyTcpipParameters, regIndex,
-                                    keyName, &cbKeyName, 0,
-                                    &keyType, (LPBYTE)keyData, &cbKeyData);
+        WCHAR wszKeyName[256] = {0};
+        DWORD cbKeyName = RT_ELEMENTS(wszKeyName);
+        DWORD keyType   = 0;
+        WCHAR wszKeyData[1024];
+        DWORD cbKeyData = sizeof(wszKeyData);
+        LSTATUS lrc = RegEnumValueW(m->hKeyTcpipParameters, regIndex,
+                                    wszKeyName, &cbKeyName, NULL /*pReserved*/,
+                                    &keyType, (LPBYTE)wszKeyData, &cbKeyData);
 
         if (lrc == ERROR_NO_MORE_ITEMS)
@@ -305,26 +286,27 @@
             continue;
 
-        if (cbKeyData > 0 && keyData[cbKeyData - 1] == '\0')
-            --cbKeyData;     /* don't count trailing NUL if present */
-
-        if (RTStrICmp("Domain", keyName) == 0)
-        {
-            strDomain.assign(keyData, cbKeyData);
+        size_t cwcKeyData = cbKeyData / sizeof(wszKeyData[0]);
+        if (cwcKeyData > 0 && wszKeyData[cwcKeyData - 1] == '\0')
+            --cwcKeyData;     /* don't count trailing NUL if present */
+
+        if (RTUtf16ICmpAscii(wszKeyName, "Domain") == 0)
+        {
+            strDomain.assign(wszKeyData, cwcKeyData);
             LogRel2(("HostDnsServiceWin: Domain=\"%s\"\n", strDomain.c_str()));
         }
-        else if (RTStrICmp("DhcpDomain", keyName) == 0)
-        {
-            std::string strDhcpDomain(keyData, cbKeyData);
+        else if (RTUtf16ICmpAscii(wszKeyName, "SearchList") == 0)
+        {
+            strSearchList.assign(wszKeyData, cwcKeyData);
+            LogRel2(("HostDnsServiceWin: SearchList=\"%s\"\n", strSearchList.c_str()));
+        }
+        else if (LogRelIs2Enabled() && RTUtf16ICmpAscii(wszKeyName, "DhcpDomain") == 0)
+        {
+            com::Utf8Str strDhcpDomain(wszKeyData, cwcKeyData);
             LogRel2(("HostDnsServiceWin: DhcpDomain=\"%s\"\n", strDhcpDomain.c_str()));
         }
-        else if (RTStrICmp("SearchList", keyName) == 0)
-        {
-            strSearchList.assign(keyData, cbKeyData);
-            LogRel2(("HostDnsServiceWin: SearchList=\"%s\"\n", strSearchList.c_str()));
-        }
     }
 
     /* statically configured domain name */
-    if (!strDomain.empty())
+    if (strDomain.isNotEmpty())
     {
         info.domain = strDomain;
@@ -333,5 +315,5 @@
 
     /* statically configured search list */
-    if (!strSearchList.empty())
+    if (strSearchList.isNotEmpty())
         appendTokenizedStrings(info.searchList, strSearchList, ',');
 
@@ -343,23 +325,16 @@
      * right thing there.
      */
-    DNS_STATUS status;
     PIP4_ARRAY pIp4Array = NULL;
-
-    // NB: must be set on input it seems, despite docs' claim to the contrary.
-    DWORD cbBuffer = sizeof(&pIp4Array);
-
-    status = DnsQueryConfig(DnsConfigDnsServerList,
-                            DNS_CONFIG_FLAG_ALLOC, NULL, NULL,
-                            &pIp4Array, &cbBuffer);
-
+    DWORD      cbBuffer  = sizeof(&pIp4Array); // NB: must be set on input it seems, despite docs' claim to the contrary.
+    DNS_STATUS status = DnsQueryConfig(DnsConfigDnsServerList, DNS_CONFIG_FLAG_ALLOC, NULL, NULL, &pIp4Array, &cbBuffer);
     if (status == NO_ERROR && pIp4Array != NULL)
     {
         for (DWORD i = 0; i < pIp4Array->AddrCount; ++i)
         {
-            char szAddrStr[16] = "";
-            RTStrPrintf(szAddrStr, sizeof(szAddrStr), "%RTnaipv4", pIp4Array->AddrArray[i]);
-
-            LogRel2(("HostDnsServiceWin: server %d: %s\n", i+1,  szAddrStr));
-            info.servers.push_back(szAddrStr);
+            char szAddr[16] = "";
+            RTStrPrintf(szAddr, sizeof(szAddr), "%RTnaipv4", pIp4Array->AddrArray[i]);
+
+            LogRel2(("HostDnsServiceWin: server %d: %s\n", i+1,  szAddr));
+            info.servers.push_back(szAddr);
         }
 
@@ -368,111 +343,92 @@
 
 
-    /**
+    /*
      * DnsQueryConfig(DnsConfigSearchList, ...) is not implemented.
      * Call GetAdaptersAddresses() that orders the returned list
      * appropriately and collect IP_ADAPTER_ADDRESSES::DnsSuffix.
      */
-    do {
-        PIP_ADAPTER_ADDRESSES pAddrBuf = NULL;
-        ULONG cbAddrBuf = 8 * 1024;
-        bool fReallocated = false;
-        ULONG err;
-
-        pAddrBuf = (PIP_ADAPTER_ADDRESSES) malloc(cbAddrBuf);
+    do /* not a loop */
+    {
+        ULONG                 cbAddrBuf    = _8K;
+        PIP_ADAPTER_ADDRESSES pAddrBuf     = (PIP_ADAPTER_ADDRESSES)RTMemAllocZ(cbAddrBuf);
         if (pAddrBuf == NULL)
         {
-            LogRel2(("HostDnsServiceWin: failed to allocate %zu bytes"
-                     " of GetAdaptersAddresses buffer\n",
-                     (size_t)cbAddrBuf));
+            LogRel2(("HostDnsServiceWin: failed to allocate %zu bytes of GetAdaptersAddresses buffer\n", (size_t)cbAddrBuf));
             break;
         }
 
-        while (pAddrBuf != NULL)
-        {
-            ULONG cbAddrBufProvided = cbAddrBuf;
-
-            err = GetAdaptersAddresses(AF_UNSPEC,
-                                         GAA_FLAG_SKIP_ANYCAST
-                                       | GAA_FLAG_SKIP_MULTICAST,
-                                       NULL,
-                                       pAddrBuf, &cbAddrBuf);
+        for (unsigned iReallocLoops = 0; ; iReallocLoops++)
+        {
+            ULONG const cbAddrBufProvided = cbAddrBuf; /* for logging */
+
+            ULONG err = GetAdaptersAddresses(AF_UNSPEC,
+                                             GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST,
+                                             NULL,
+                                             pAddrBuf, &cbAddrBuf);
             if (err == NO_ERROR)
+                break;
+            if (err == ERROR_BUFFER_OVERFLOW)
             {
-                break;
-            }
-            else if (err == ERROR_BUFFER_OVERFLOW)
-            {
-                LogRel2(("HostDnsServiceWin: provided GetAdaptersAddresses with %zu"
-                         " but asked again for %zu bytes\n",
+                LogRel2(("HostDnsServiceWin: provided GetAdaptersAddresses with %zu but asked again for %zu bytes\n",
                          (size_t)cbAddrBufProvided, (size_t)cbAddrBuf));
-
-                if (RT_UNLIKELY(fReallocated)) /* what? again?! */
+                if (iReallocLoops < 16)
                 {
-                    LogRel2(("HostDnsServiceWin: ... not going to realloc again\n"));
-                    free(pAddrBuf);
-                    pAddrBuf = NULL;
-                    break;
+                    /* Reallocate the buffer and try again. */
+                    void * const pvNew = RTMemRealloc(pAddrBuf, cbAddrBuf);
+                    if (pvNew)
+                    {
+                        pAddrBuf = (PIP_ADAPTER_ADDRESSES)pvNew;
+                        continue;
+                    }
+
+                    LogRel2(("HostDnsServiceWin: failed to reallocate %zu bytes\n", (size_t)cbAddrBuf));
                 }
-
-                PIP_ADAPTER_ADDRESSES pNewBuf = (PIP_ADAPTER_ADDRESSES) realloc(pAddrBuf, cbAddrBuf);
-                if (pNewBuf == NULL)
-                {
-                    LogRel2(("HostDnsServiceWin: failed to reallocate %zu bytes\n", (size_t)cbAddrBuf));
-                    free(pAddrBuf);
-                    pAddrBuf = NULL;
-                    break;
-                }
-
-                /* try again */
-                pAddrBuf = pNewBuf; /* cbAddrBuf already updated */
-                fReallocated = true;
+                else
+                    LogRel2(("HostDnsServiceWin: iReallocLoops=%d - giving up!\n", iReallocLoops));
             }
             else
+                LogRel2(("HostDnsServiceWin: GetAdaptersAddresses error %d\n", err));
+            RTMemFree(pAddrBuf);
+            pAddrBuf = NULL;
+            break;
+        }
+        if (pAddrBuf)
+        {
+            for (PIP_ADAPTER_ADDRESSES pAdp = pAddrBuf; pAdp != NULL; pAdp = pAdp->Next)
             {
-                LogRel2(("HostDnsServiceWin: GetAdaptersAddresses error %d\n", err));
-                free(pAddrBuf);
-                pAddrBuf = NULL;
-                break;
+                LogRel2(("HostDnsServiceWin: %ls (status %u) ...\n",
+                         pAdp->FriendlyName ? pAdp->FriendlyName : L"(null)", pAdp->OperStatus));
+
+                if (pAdp->OperStatus != IfOperStatusUp)
+                    continue;
+
+                if (pAdp->DnsSuffix == NULL || *pAdp->DnsSuffix == L'\0')
+                    continue;
+
+                char *pszDnsSuffix = NULL;
+                int vrc = RTUtf16ToUtf8Ex(pAdp->DnsSuffix, RTSTR_MAX, &pszDnsSuffix, 0, /* allocate */ NULL);
+                if (RT_FAILURE(vrc))
+                {
+                    LogRel2(("HostDnsServiceWin: failed to convert DNS suffix \"%ls\": %Rrc\n", pAdp->DnsSuffix, vrc));
+                    continue;
+                }
+
+                AssertContinue(pszDnsSuffix != NULL);
+                AssertContinue(*pszDnsSuffix != '\0');
+                LogRel2(("HostDnsServiceWin: ... suffix = \"%s\"\n", pszDnsSuffix));
+
+                appendTokenizedStrings(info.searchList, pszDnsSuffix);
+                RTStrFree(pszDnsSuffix);
             }
-        }
-
-        if (pAddrBuf == NULL)
-            break;
-
-        for (PIP_ADAPTER_ADDRESSES pAdp = pAddrBuf; pAdp != NULL; pAdp = pAdp->Next)
-        {
-            LogRel2(("HostDnsServiceWin: %ls (status %u) ...\n",
-                     pAdp->FriendlyName ? pAdp->FriendlyName : L"(null)", pAdp->OperStatus));
-
-            if (pAdp->OperStatus != IfOperStatusUp)
-                continue;
-
-            if (pAdp->DnsSuffix == NULL || *pAdp->DnsSuffix == L'\0')
-                continue;
-
-            char *pszDnsSuffix = NULL;
-            int vrc = RTUtf16ToUtf8Ex(pAdp->DnsSuffix, RTSTR_MAX, &pszDnsSuffix, 0, /* allocate */ NULL);
-            if (RT_FAILURE(vrc))
-            {
-                LogRel2(("HostDnsServiceWin: failed to convert DNS suffix \"%ls\": %Rrc\n", pAdp->DnsSuffix, vrc));
-                continue;
-            }
-
-            AssertContinue(pszDnsSuffix != NULL);
-            AssertContinue(*pszDnsSuffix != '\0');
-            LogRel2(("HostDnsServiceWin: ... suffix = \"%s\"\n", pszDnsSuffix));
-
-            appendTokenizedStrings(info.searchList, pszDnsSuffix);
-            RTStrFree(pszDnsSuffix);
-        }
-
-        free(pAddrBuf);
+
+            RTMemFree(pAddrBuf);
+        }
     } while (0);
 
 
-    if (info.domain.empty() && !info.searchList.empty())
+    if (info.domain.isEmpty() && !info.searchList.empty())
         info.domain = info.searchList[0];
 
-    if (info.searchList.size() == 1)
+    if (info.searchList.size() == 1) /* ?? */
         info.searchList.clear();
 
