summaryrefslogtreecommitdiff
path: root/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2014-03-26 19:21:20 +0000
committer <>2014-05-08 15:03:54 +0000
commitfb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch)
treec2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/Main/src-server/win/HostDnsServiceWin.cpp
parent58ed4748338f9466599adfc8a9171280ed99e23f (diff)
downloadVirtualBox-master.tar.gz
Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2.HEADVirtualBox-4.3.10master
Diffstat (limited to 'src/VBox/Main/src-server/win/HostDnsServiceWin.cpp')
-rw-r--r--src/VBox/Main/src-server/win/HostDnsServiceWin.cpp233
1 files changed, 233 insertions, 0 deletions
diff --git a/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp b/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp
new file mode 100644
index 00000000..1bd72233
--- /dev/null
+++ b/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp
@@ -0,0 +1,233 @@
+/* -*- indent-tabs-mode: nil; -*- */
+#include <VBox/com/string.h>
+#include <VBox/com/ptr.h>
+
+
+#include <iprt/assert.h>
+#include <iprt/err.h>
+
+#include <Windows.h>
+
+#include <string>
+#include <vector>
+#include "../HostDnsService.h"
+
+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)
+ {
+ RegCloseKey(m->hKeyTcpipParameters);
+ m->hKeyTcpipParameters = 0;
+
+ CloseHandle(m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
+ CloseHandle(m->haDataEvent[DATA_SHUTDOWN_EVENT]);
+
+ delete m;
+
+ m = NULL;
+ }
+}
+
+
+HRESULT HostDnsServiceWin::init()
+{
+ HRESULT hrc = HostDnsMonitor::init();
+ AssertComRCReturn(hrc, hrc);
+
+ return updateInfo();
+}
+
+
+void HostDnsServiceWin::monitorThreadShutdown()
+{
+ SetEvent(m->haDataEvent[DATA_SHUTDOWN_EVENT]);
+}
+
+
+int HostDnsServiceWin::monitorWorker()
+{
+ registerNotification(m->hKeyTcpipParameters,
+ m->haDataEvent[DATA_DNS_UPDATE_EVENT]);
+
+ monitorThreadInitializationDone();
+
+ DWORD dwRc;
+ while (true)
+ {
+ dwRc = WaitForMultipleObjects(DATA_MAX_EVENT,
+ m->haDataEvent,
+ FALSE,
+ INFINITE);
+ AssertMsgReturn(dwRc != WAIT_FAILED,
+ ("WaitForMultipleObjects failed (%d) to wait! Please debug",
+ GetLastError()), VERR_INTERNAL_ERROR);
+
+ 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;
+ }
+ else
+ {
+ AssertMsgFailedReturn(
+ ("WaitForMultipleObjects returns out of bound index %d. Please debug!",
+ dwRc),
+ VERR_INTERNAL_ERROR);
+ }
+ }
+ 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);
+
+}