HostDnsServiceWin.cpp revision a6ecd30c53f19c918ea045fa0cc632a68584e7a8
/* $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;
* 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.
*/
#include "../HostDnsService.h"
#include <Windows.h>
#include <windns.h>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
struct HostDnsServiceWin::Data
{
bool fTimerArmed;
#define DATA_SHUTDOWN_EVENT 0
#define DATA_DNS_UPDATE_EVENT 1
#define DATA_TIMER 2
#define DATA_MAX_EVENT 3
Data()
{
fTimerArmed = false;
for (size_t i = 0; i < DATA_MAX_EVENT; ++i)
haDataEvent[i] = NULL;
}
~Data()
{
if (hKeyTcpipParameters != NULL)
for (size_t i = 0; i < DATA_MAX_EVENT; ++i)
if (haDataEvent[i] != NULL)
CloseHandle(haDataEvent[i]);
}
};
: HostDnsMonitor(true),
m(NULL)
{
L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
0,
if (lrc != ERROR_SUCCESS)
{
return;
}
for (size_t i = 0; i < DATA_MAX_EVENT; ++i)
{
HANDLE h;
if (i == DATA_TIMER)
else
if (h == NULL)
{
return;
}
data->haDataEvent[i] = h;
}
}
{
if (m != NULL)
delete m;
}
{
if (m == NULL)
return E_FAIL;
return hrc;
return updateInfo();
}
{
}
{
TRUE,
TRUE);
("Failed to register event on the key. Please debug me!"),
return VINF_SUCCESS;
}
int HostDnsServiceWin::monitorWorker()
{
for (;;)
{
break;
{
/*
* Registry updates for multiple values are not atomic, so
* wait a bit to avoid racing and reading partial update.
*/
if (!m->fTimerArmed)
{
if (ok)
{
m->fTimerArmed = true;
}
else
{
updateInfo();
}
}
}
{
m->fTimerArmed = false;
updateInfo();
}
else if (dwReady == WAIT_FAILED)
{
return VERR_INTERNAL_ERROR;
}
else
{
return VERR_INTERNAL_ERROR;
}
}
return VINF_SUCCESS;
}
{
if (s.empty())
return;
{
continue;
continue;
}
}
{
char keyName[256];
char keyData[1024];
if (lrc == ERROR_NO_MORE_ITEMS)
break;
continue;
if (lrc != ERROR_SUCCESS)
{
return E_FAIL;
}
continue;
--cbKeyData; /* don't count trailing NUL if present */
{
}
{
}
{
}
}
/*
* When name servers are configured statically it seems that the
* value of Tcpip\Parameters\NameServer is NOT set, inly interface
* specific NameServer value is (which triggers notification for
* us to pick up the change). Fortunately, DnsApi seems to do the
* right thing there.
*/
// NB: must be set on input it seems, despite docs' claim to the contrary.
{
{
}
}
{
}
else if (!strDhcpDomain.empty())
{
}
return S_OK;
}