HostDnsServiceWin.cpp revision 510b14148124a664875cdb3a996433bd92c9324e
510b14148124a664875cdb3a996433bd92c9324evboxsync/* -*- indent-tabs-mode: nil; -*- */
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync#include <VBox/com/string.h>
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync#include <VBox/com/ptr.h>
510b14148124a664875cdb3a996433bd92c9324evboxsync
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync#include <iprt/assert.h>
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync#include <iprt/err.h>
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync#include <Windows.h>
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
7a0e5c38eeca5147034ace6fe624de57ac2988ddvboxsync#include <string>
7a0e5c38eeca5147034ace6fe624de57ac2988ddvboxsync#include <vector>
7a0e5c38eeca5147034ace6fe624de57ac2988ddvboxsync#include "../HostDnsService.h"
7a0e5c38eeca5147034ace6fe624de57ac2988ddvboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsyncstruct HostDnsServiceWin::Data
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync{
510b14148124a664875cdb3a996433bd92c9324evboxsync HostDnsServiceWin::Data(){}
510b14148124a664875cdb3a996433bd92c9324evboxsync HKEY hKeyTcpipParameters;
510b14148124a664875cdb3a996433bd92c9324evboxsync#define DATA_DNS_UPDATE_EVENT 0
510b14148124a664875cdb3a996433bd92c9324evboxsync#define DATA_SHUTDOWN_EVENT 1
510b14148124a664875cdb3a996433bd92c9324evboxsync#define DATA_MAX_EVENT 2
510b14148124a664875cdb3a996433bd92c9324evboxsync HANDLE haDataEvent[DATA_MAX_EVENT];
510b14148124a664875cdb3a996433bd92c9324evboxsync};
510b14148124a664875cdb3a996433bd92c9324evboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsyncstatic inline int registerNotification(const HKEY& hKey, HANDLE& hEvent)
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync{
510b14148124a664875cdb3a996433bd92c9324evboxsync LONG lrc = RegNotifyChangeKeyValue(hKey,
510b14148124a664875cdb3a996433bd92c9324evboxsync TRUE,
510b14148124a664875cdb3a996433bd92c9324evboxsync REG_NOTIFY_CHANGE_LAST_SET,
510b14148124a664875cdb3a996433bd92c9324evboxsync hEvent,
510b14148124a664875cdb3a996433bd92c9324evboxsync TRUE);
510b14148124a664875cdb3a996433bd92c9324evboxsync AssertMsgReturn(lrc == ERROR_SUCCESS,
510b14148124a664875cdb3a996433bd92c9324evboxsync ("Failed to register event on the key. Please debug me!"),
510b14148124a664875cdb3a996433bd92c9324evboxsync VERR_INTERNAL_ERROR);
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync return VINF_SUCCESS;
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync}
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsyncHostDnsServiceWin::HostDnsServiceWin():HostDnsMonitor(true), m(NULL)
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync{
510b14148124a664875cdb3a996433bd92c9324evboxsync m = new Data();
510b14148124a664875cdb3a996433bd92c9324evboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync m->haDataEvent[DATA_DNS_UPDATE_EVENT] = CreateEvent(NULL,
510b14148124a664875cdb3a996433bd92c9324evboxsync TRUE, FALSE, NULL);
510b14148124a664875cdb3a996433bd92c9324evboxsync AssertReleaseMsg(m->haDataEvent[DATA_DNS_UPDATE_EVENT],
510b14148124a664875cdb3a996433bd92c9324evboxsync ("Failed to create event for DNS event (%d)\n", GetLastError()));
510b14148124a664875cdb3a996433bd92c9324evboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync m->haDataEvent[DATA_SHUTDOWN_EVENT] = CreateEvent(NULL,
510b14148124a664875cdb3a996433bd92c9324evboxsync TRUE, FALSE, NULL);
510b14148124a664875cdb3a996433bd92c9324evboxsync AssertReleaseMsg(m->haDataEvent[DATA_SHUTDOWN_EVENT],
510b14148124a664875cdb3a996433bd92c9324evboxsync ("Failed to create event for Shutdown signal (%d)\n", GetLastError()));
510b14148124a664875cdb3a996433bd92c9324evboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync LONG lrc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
510b14148124a664875cdb3a996433bd92c9324evboxsync TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"),
510b14148124a664875cdb3a996433bd92c9324evboxsync 0, KEY_READ|KEY_NOTIFY, &m->hKeyTcpipParameters);
510b14148124a664875cdb3a996433bd92c9324evboxsync AssertReleaseMsg(lrc == ERROR_SUCCESS,
510b14148124a664875cdb3a996433bd92c9324evboxsync ("Failed to open Registry Key for read and update notifications (%d)\n",
510b14148124a664875cdb3a996433bd92c9324evboxsync GetLastError()));
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync}
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsyncHostDnsServiceWin::~HostDnsServiceWin()
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync{
510b14148124a664875cdb3a996433bd92c9324evboxsync if (m && !m->hKeyTcpipParameters)
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync {
510b14148124a664875cdb3a996433bd92c9324evboxsync RegCloseKey(m->hKeyTcpipParameters);
510b14148124a664875cdb3a996433bd92c9324evboxsync m->hKeyTcpipParameters = 0;
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync CloseHandle(m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
510b14148124a664875cdb3a996433bd92c9324evboxsync CloseHandle(m->haDataEvent[DATA_SHUTDOWN_EVENT]);
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync delete m;
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync m = NULL;
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync }
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync}
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
3f2299591cfeb8a37a3578bef9c44c1790860948vboxsyncHRESULT HostDnsServiceWin::init()
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync{
0faefdb9edd752514d5dfed8353118e47e57f0ebvboxsync HRESULT hrc = HostDnsMonitor::init();
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync AssertComRCReturn(hrc, hrc);
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync return updateInfo();
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync}
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsyncvoid HostDnsServiceWin::monitorThreadShutdown()
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync{
510b14148124a664875cdb3a996433bd92c9324evboxsync SetEvent(m->haDataEvent[DATA_SHUTDOWN_EVENT]);
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync}
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsyncint HostDnsServiceWin::monitorWorker()
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync{
510b14148124a664875cdb3a996433bd92c9324evboxsync registerNotification(m->hKeyTcpipParameters,
510b14148124a664875cdb3a996433bd92c9324evboxsync m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync monitorThreadInitializationDone();
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync DWORD dwRc;
510b14148124a664875cdb3a996433bd92c9324evboxsync while (true)
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync {
510b14148124a664875cdb3a996433bd92c9324evboxsync dwRc = WaitForMultipleObjects(DATA_MAX_EVENT,
510b14148124a664875cdb3a996433bd92c9324evboxsync m->haDataEvent,
510b14148124a664875cdb3a996433bd92c9324evboxsync FALSE,
510b14148124a664875cdb3a996433bd92c9324evboxsync INFINITE);
510b14148124a664875cdb3a996433bd92c9324evboxsync AssertMsgReturn(dwRc != WAIT_FAILED,
510b14148124a664875cdb3a996433bd92c9324evboxsync ("WaitForMultipleObjects failed (%d) to wait! Please debug",
510b14148124a664875cdb3a996433bd92c9324evboxsync GetLastError()), VERR_INTERNAL_ERROR);
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync if ((dwRc - WAIT_OBJECT_0) == DATA_DNS_UPDATE_EVENT)
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync {
510b14148124a664875cdb3a996433bd92c9324evboxsync updateInfo();
510b14148124a664875cdb3a996433bd92c9324evboxsync notifyAll();
510b14148124a664875cdb3a996433bd92c9324evboxsync ResetEvent(m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
510b14148124a664875cdb3a996433bd92c9324evboxsync registerNotification(m->hKeyTcpipParameters,
510b14148124a664875cdb3a996433bd92c9324evboxsync m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
bca22f037c4fa4df62f7244c27686c0a491821b8vboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync }
510b14148124a664875cdb3a996433bd92c9324evboxsync else if ((dwRc - WAIT_OBJECT_0) == DATA_SHUTDOWN_EVENT)
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync {
510b14148124a664875cdb3a996433bd92c9324evboxsync break;
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync }
510b14148124a664875cdb3a996433bd92c9324evboxsync else
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync {
510b14148124a664875cdb3a996433bd92c9324evboxsync AssertMsgFailedReturn(
510b14148124a664875cdb3a996433bd92c9324evboxsync ("WaitForMultipleObjects returns out of bound index %d. Please debug!",
510b14148124a664875cdb3a996433bd92c9324evboxsync dwRc),
510b14148124a664875cdb3a996433bd92c9324evboxsync VERR_INTERNAL_ERROR);
dbbd0cae65188dffbd927bdde2d88cbeec2e26davboxsync }
510b14148124a664875cdb3a996433bd92c9324evboxsync }
510b14148124a664875cdb3a996433bd92c9324evboxsync return VINF_SUCCESS;
510b14148124a664875cdb3a996433bd92c9324evboxsync}
bca22f037c4fa4df62f7244c27686c0a491821b8vboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsyncHRESULT HostDnsServiceWin::updateInfo()
510b14148124a664875cdb3a996433bd92c9324evboxsync{
510b14148124a664875cdb3a996433bd92c9324evboxsync HRESULT hrc;
510b14148124a664875cdb3a996433bd92c9324evboxsync DWORD regIndex;
510b14148124a664875cdb3a996433bd92c9324evboxsync BYTE abDomain[256];
510b14148124a664875cdb3a996433bd92c9324evboxsync BYTE abNameServers[256];
510b14148124a664875cdb3a996433bd92c9324evboxsync BYTE abSearchList[256];
510b14148124a664875cdb3a996433bd92c9324evboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync RT_ZERO(abDomain);
510b14148124a664875cdb3a996433bd92c9324evboxsync RT_ZERO(abNameServers);
510b14148124a664875cdb3a996433bd92c9324evboxsync RT_ZERO(abSearchList);
510b14148124a664875cdb3a996433bd92c9324evboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync regIndex = 0;
510b14148124a664875cdb3a996433bd92c9324evboxsync do {
510b14148124a664875cdb3a996433bd92c9324evboxsync CHAR keyName[256];
510b14148124a664875cdb3a996433bd92c9324evboxsync DWORD cbKeyName = sizeof(keyName);
510b14148124a664875cdb3a996433bd92c9324evboxsync DWORD keyType = 0;
510b14148124a664875cdb3a996433bd92c9324evboxsync BYTE keyData[1024];
510b14148124a664875cdb3a996433bd92c9324evboxsync DWORD cbKeyData = sizeof(keyData);
510b14148124a664875cdb3a996433bd92c9324evboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync hrc = RegEnumValueA(m->hKeyTcpipParameters, regIndex, keyName, &cbKeyName, 0,
510b14148124a664875cdb3a996433bd92c9324evboxsync &keyType, keyData, &cbKeyData);
510b14148124a664875cdb3a996433bd92c9324evboxsync if ( hrc == ERROR_SUCCESS
510b14148124a664875cdb3a996433bd92c9324evboxsync || hrc == ERROR_MORE_DATA)
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync {
510b14148124a664875cdb3a996433bd92c9324evboxsync if ( RTStrICmp("Domain", keyName) == 0
510b14148124a664875cdb3a996433bd92c9324evboxsync && cbKeyData > 1
510b14148124a664875cdb3a996433bd92c9324evboxsync && cbKeyData < sizeof(abDomain))
510b14148124a664875cdb3a996433bd92c9324evboxsync memcpy(abDomain, keyData, cbKeyData);
510b14148124a664875cdb3a996433bd92c9324evboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync else if ( RTStrICmp("DhcpDomain", keyName) == 0
510b14148124a664875cdb3a996433bd92c9324evboxsync && cbKeyData > 1
510b14148124a664875cdb3a996433bd92c9324evboxsync && abDomain[0] == 0
510b14148124a664875cdb3a996433bd92c9324evboxsync && cbKeyData < sizeof(abDomain))
510b14148124a664875cdb3a996433bd92c9324evboxsync memcpy(abDomain, keyData, cbKeyData);
510b14148124a664875cdb3a996433bd92c9324evboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync else if ( RTStrICmp("NameServer", keyName) == 0
510b14148124a664875cdb3a996433bd92c9324evboxsync && cbKeyData > 1
510b14148124a664875cdb3a996433bd92c9324evboxsync && cbKeyData < sizeof(abNameServers))
510b14148124a664875cdb3a996433bd92c9324evboxsync memcpy(abNameServers, keyData, cbKeyData);
510b14148124a664875cdb3a996433bd92c9324evboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync else if ( RTStrICmp("DhcpNameServer", keyName) == 0
510b14148124a664875cdb3a996433bd92c9324evboxsync && cbKeyData > 1
510b14148124a664875cdb3a996433bd92c9324evboxsync && abNameServers[0] == 0
510b14148124a664875cdb3a996433bd92c9324evboxsync && cbKeyData < sizeof(abNameServers))
510b14148124a664875cdb3a996433bd92c9324evboxsync memcpy(abNameServers, keyData, cbKeyData);
510b14148124a664875cdb3a996433bd92c9324evboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync else if ( RTStrICmp("SearchList", keyName) == 0
510b14148124a664875cdb3a996433bd92c9324evboxsync && cbKeyData > 1
510b14148124a664875cdb3a996433bd92c9324evboxsync && cbKeyData < sizeof(abSearchList))
510b14148124a664875cdb3a996433bd92c9324evboxsync memcpy(abSearchList, keyData, cbKeyData);
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync }
510b14148124a664875cdb3a996433bd92c9324evboxsync regIndex++;
510b14148124a664875cdb3a996433bd92c9324evboxsync } while (hrc != ERROR_NO_MORE_ITEMS);
bca22f037c4fa4df62f7244c27686c0a491821b8vboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync /* OK, now parse and update DNS structures. */
510b14148124a664875cdb3a996433bd92c9324evboxsync /* domain name */
510b14148124a664875cdb3a996433bd92c9324evboxsync HostDnsInformation info;
510b14148124a664875cdb3a996433bd92c9324evboxsync info.domain = (char*)abDomain;
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync /* server list */
510b14148124a664875cdb3a996433bd92c9324evboxsync strList2List(info.servers, (char *)abNameServers);
510b14148124a664875cdb3a996433bd92c9324evboxsync /* search list */
510b14148124a664875cdb3a996433bd92c9324evboxsync strList2List(info.searchList, (char *)abSearchList);
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync HostDnsMonitor::setInfo(info);
3f2299591cfeb8a37a3578bef9c44c1790860948vboxsync
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync return S_OK;
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync}
3f2299591cfeb8a37a3578bef9c44c1790860948vboxsync
8dfc5e89cd3421bb0602f33768f00c1f1d40b1d2vboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsyncvoid HostDnsServiceWin::strList2List(std::vector<std::string>& lst, char *strLst)
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync{
510b14148124a664875cdb3a996433bd92c9324evboxsync char *next, *current;
510b14148124a664875cdb3a996433bd92c9324evboxsync char address[512];
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync AssertPtrReturnVoid(strLst);
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync if (strlen(strLst) == 0)
510b14148124a664875cdb3a996433bd92c9324evboxsync return;
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync current = strLst;
510b14148124a664875cdb3a996433bd92c9324evboxsync do {
510b14148124a664875cdb3a996433bd92c9324evboxsync RT_ZERO(address);
510b14148124a664875cdb3a996433bd92c9324evboxsync next = RTStrStr(current, " ");
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync if (next)
510b14148124a664875cdb3a996433bd92c9324evboxsync strncpy(address, current, RT_MIN(sizeof(address)-1, next - current));
510b14148124a664875cdb3a996433bd92c9324evboxsync else
510b14148124a664875cdb3a996433bd92c9324evboxsync strcpy(address, current);
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync lst.push_back(std::string(address));
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync
510b14148124a664875cdb3a996433bd92c9324evboxsync current = next + 1;
510b14148124a664875cdb3a996433bd92c9324evboxsync } while(next);
63fdb92b88f31446f6ea53241c0d127677c71c7evboxsync
18b1f1bb3429f8bfc1a52cfaeb2445e9fb1f55cdvboxsync}