2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync/* $Id$ */
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync/** @file
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync * Host DNS listener for Windows.
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync */
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync/*
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync * Copyright (C) 2014 Oracle Corporation
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync *
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync * available from http://www.virtualbox.org. This file is free software;
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync * you can redistribute it and/or modify it under the terms of the GNU
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync * General Public License (GPL) as published by the Free Software
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync */
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync#include "../HostDnsService.h"
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync#include <VBox/com/string.h>
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync#include <VBox/com/ptr.h>
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync#include <iprt/assert.h>
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync#include <iprt/err.h>
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync#include <VBox/log.h>
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync#include <Windows.h>
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync#include <windns.h>
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync#include <algorithm>
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync#include <sstream>
7a0e5c38eeca5147034ace6fe624de57ac2988ddvboxsync#include <string>
7a0e5c38eeca5147034ace6fe624de57ac2988ddvboxsync#include <vector>
7a0e5c38eeca5147034ace6fe624de57ac2988ddvboxsync
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsyncstruct HostDnsServiceWin::Data
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync{
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync HKEY hKeyTcpipParameters;
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync bool fTimerArmed;
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync#define DATA_SHUTDOWN_EVENT 0
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync#define DATA_DNS_UPDATE_EVENT 1
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync#define DATA_TIMER 2
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync#define DATA_MAX_EVENT 3
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync HANDLE haDataEvent[DATA_MAX_EVENT];
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync Data()
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync {
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync hKeyTcpipParameters = NULL;
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync fTimerArmed = false;
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync for (size_t i = 0; i < DATA_MAX_EVENT; ++i)
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync haDataEvent[i] = NULL;
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync }
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync ~Data()
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync {
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync if (hKeyTcpipParameters != NULL)
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync RegCloseKey(hKeyTcpipParameters);
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync for (size_t i = 0; i < DATA_MAX_EVENT; ++i)
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync if (haDataEvent[i] != NULL)
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync CloseHandle(haDataEvent[i]);
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync }
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync};
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsyncHostDnsServiceWin::HostDnsServiceWin()
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync : HostDnsMonitor(true),
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync m(NULL)
735076496e14763dcdef4b43202e7665d4a8da43vboxsync{
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync std::auto_ptr<Data> data(new Data());
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync LONG lrc;
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync lrc = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync 0,
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync KEY_READ|KEY_NOTIFY,
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync &data->hKeyTcpipParameters);
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync if (lrc != ERROR_SUCCESS)
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync {
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync LogRel(("HostDnsServiceWin: failed to open key Tcpip\\Parameters (error %d)\n", lrc));
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync return;
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync }
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync for (size_t i = 0; i < DATA_MAX_EVENT; ++i)
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync {
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync HANDLE h;
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync if (i == DATA_TIMER)
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync h = CreateWaitableTimer(NULL, FALSE, NULL);
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync else
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync h = CreateEvent(NULL, TRUE, FALSE, NULL);
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync if (h == NULL)
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync {
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync LogRel(("HostDnsServiceWin: failed to create event (error %d)\n", GetLastError()));
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync return;
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync }
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync data->haDataEvent[i] = h;
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync }
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync m = data.release();
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync}
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsyncHostDnsServiceWin::~HostDnsServiceWin()
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync{
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync if (m != NULL)
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync delete m;
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync}
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
a6ecd30c53f19c918ea045fa0cc632a68584e7a8vboxsyncHRESULT HostDnsServiceWin::init(VirtualBox *virtualbox)
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync{
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync if (m == NULL)
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync return E_FAIL;
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
a6ecd30c53f19c918ea045fa0cc632a68584e7a8vboxsync HRESULT hrc = HostDnsMonitor::init(virtualbox);
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync if (FAILED(hrc))
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync return hrc;
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync return updateInfo();
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync}
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsyncvoid HostDnsServiceWin::monitorThreadShutdown()
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync{
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync Assert(m != NULL);
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync SetEvent(m->haDataEvent[DATA_SHUTDOWN_EVENT]);
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync}
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsyncstatic inline int registerNotification(const HKEY& hKey, HANDLE& hEvent)
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync{
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync LONG lrc = RegNotifyChangeKeyValue(hKey,
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync TRUE,
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync REG_NOTIFY_CHANGE_LAST_SET,
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync hEvent,
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync TRUE);
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync AssertMsgReturn(lrc == ERROR_SUCCESS,
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync ("Failed to register event on the key. Please debug me!"),
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync VERR_INTERNAL_ERROR);
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync return VINF_SUCCESS;
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync}
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsyncint HostDnsServiceWin::monitorWorker()
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync{
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync Assert(m != NULL);
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync registerNotification(m->hKeyTcpipParameters,
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync monitorThreadInitializationDone();
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync for (;;)
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync {
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync DWORD dwReady;
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync dwReady = WaitForMultipleObjects(DATA_MAX_EVENT, m->haDataEvent,
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync FALSE, INFINITE);
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync if (dwReady == WAIT_OBJECT_0 + DATA_SHUTDOWN_EVENT)
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync break;
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync if (dwReady == WAIT_OBJECT_0 + DATA_DNS_UPDATE_EVENT)
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync {
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync /*
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync * Registry updates for multiple values are not atomic, so
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync * wait a bit to avoid racing and reading partial update.
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync */
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync if (!m->fTimerArmed)
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync {
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync LARGE_INTEGER delay; /* in 100ns units */
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync delay.QuadPart = -2 * 1000 * 1000 * 10LL; /* relative: 2s */
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync BOOL ok = SetWaitableTimer(m->haDataEvent[DATA_TIMER], &delay,
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync 0, NULL, NULL, TRUE);
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync if (ok)
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync {
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync m->fTimerArmed = true;
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync }
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync else
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync {
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync LogRel(("HostDnsServiceWin: failed to arm timer (error %d)\n", GetLastError()));
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync updateInfo();
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync }
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync }
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync ResetEvent(m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync registerNotification(m->hKeyTcpipParameters,
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync }
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync else if (dwReady == WAIT_OBJECT_0 + DATA_TIMER)
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync {
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync m->fTimerArmed = false;
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync updateInfo();
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync }
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync else if (dwReady == WAIT_FAILED)
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync {
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync LogRel(("HostDnsServiceWin: WaitForMultipleObjects failed: error %d\n", GetLastError()));
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync return VERR_INTERNAL_ERROR;
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync }
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync else
735076496e14763dcdef4b43202e7665d4a8da43vboxsync {
0fb953df159d21121359ff648e0ad4c3cb55a1cbvboxsync LogRel(("HostDnsServiceWin: WaitForMultipleObjects unexpected return value %d\n", dwReady));
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync return VERR_INTERNAL_ERROR;
735076496e14763dcdef4b43202e7665d4a8da43vboxsync }
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync }
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync return VINF_SUCCESS;
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync}
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsyncvoid vappend(std::vector<std::string> &v, const std::string &s, char sep = ' ')
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync{
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync if (s.empty())
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync return;
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync std::istringstream stream(s);
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync std::string substr;
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync while (std::getline(stream, substr, sep))
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync {
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync if (substr.empty())
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync continue;
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync if (std::find(v.cbegin(), v.cend(), substr) != v.cend())
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync continue;
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync v.push_back(substr);
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync }
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync}
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsyncHRESULT HostDnsServiceWin::updateInfo()
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync{
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync LONG lrc;
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync std::string strDomain;
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync std::string strDhcpDomain;
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync std::string strSearchList; /* NB: comma separated, no spaces */
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync for (DWORD regIndex = 0; /**/; ++regIndex) {
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync char keyName[256];
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync DWORD cbKeyName = sizeof(keyName);
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync DWORD keyType = 0;
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync char keyData[1024];
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync DWORD cbKeyData = sizeof(keyData);
510229a86fcdcdf2eb0b9540e2981460eab322d5vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync lrc = RegEnumValueA(m->hKeyTcpipParameters, regIndex,
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync keyName, &cbKeyName, 0,
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync &keyType, (LPBYTE)keyData, &cbKeyData);
bca22f037c4fa4df62f7244c27686c0a491821b8vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync if (lrc == ERROR_NO_MORE_ITEMS)
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync break;
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync if (lrc == ERROR_MORE_DATA) /* buffer too small; handle? */
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync continue;
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync if (lrc != ERROR_SUCCESS)
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync {
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync LogRel(("HostDnsServiceWin: RegEnumValue error %d\n", (int)lrc));
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync return E_FAIL;
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync }
3f2299591cfeb8a37a3578bef9c44c1790860948vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync if (keyType != REG_SZ)
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync continue;
3f2299591cfeb8a37a3578bef9c44c1790860948vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync if (cbKeyData > 0 && keyData[cbKeyData - 1] == '\0')
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync --cbKeyData; /* don't count trailing NUL if present */
8dfc5e89cd3421bb0602f33768f00c1f1d40b1d2vboxsync
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync if (RTStrICmp("Domain", keyName) == 0)
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync {
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync strDomain.assign(keyData, cbKeyData);
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync Log2(("... Domain=\"%s\"\n", strDomain.c_str()));
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync }
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync else if (RTStrICmp("DhcpDomain", keyName) == 0)
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync {
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync strDhcpDomain.assign(keyData, cbKeyData);
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync Log2(("... DhcpDomain=\"%s\"\n", strDhcpDomain.c_str()));
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync }
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync else if (RTStrICmp("SearchList", keyName) == 0)
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync {
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync strSearchList.assign(keyData, cbKeyData);
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync Log2(("... SearchList=\"%s\"\n", strSearchList.c_str()));
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync }
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync }
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync HostDnsInformation info;
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync /*
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync * When name servers are configured statically it seems that the
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync * value of Tcpip\Parameters\NameServer is NOT set, inly interface
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync * specific NameServer value is (which triggers notification for
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync * us to pick up the change). Fortunately, DnsApi seems to do the
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync * right thing there.
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync */
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync DNS_STATUS status;
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync PIP4_ARRAY pIp4Array = NULL;
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync // NB: must be set on input it seems, despite docs' claim to the contrary.
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync DWORD cbBuffer = sizeof(&pIp4Array);
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync status = DnsQueryConfig(DnsConfigDnsServerList,
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync DNS_CONFIG_FLAG_ALLOC, NULL, NULL,
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync &pIp4Array, &cbBuffer);
2b114c590cf5a19f8047cd7bde9c7e5ae00aa22bvboxsync
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync if (status == NO_ERROR && pIp4Array != NULL)
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync {
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync for (DWORD i = 0; i < pIp4Array->AddrCount; ++i)
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync {
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync char szAddrStr[16] = "";
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync RTStrPrintf(szAddrStr, sizeof(szAddrStr), "%RTnaipv4", pIp4Array->AddrArray[i]);
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync Log2((" server %d: %s\n", i+1, szAddrStr));
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync info.servers.push_back(szAddrStr);
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync }
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync LocalFree(pIp4Array);
1c4e90385ee797af9a47c1e4c5e727865a813bc5vboxsync }
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync if (!strDomain.empty())
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync {
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync info.domain = strDomain;
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync info.searchList.push_back(strDomain);
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync if (!strDhcpDomain.empty() && strDhcpDomain != strDomain)
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync info.searchList.push_back(strDhcpDomain);
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync }
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync else if (!strDhcpDomain.empty())
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync {
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync info.domain = strDhcpDomain;
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync info.searchList.push_back(strDomain);
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync }
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync vappend(info.searchList, strSearchList, ',');
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync if (info.searchList.size() == 1)
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync info.searchList.clear();
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync HostDnsMonitor::setInfo(info);
735076496e14763dcdef4b43202e7665d4a8da43vboxsync
2d38607d73f5000c2e0913e1a896a8478a5fa1d7vboxsync return S_OK;
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync}