summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOdd Stranne <odd@mullvad.net>2018-04-13 17:59:35 +0200
committerOdd Stranne <odd@mullvad.net>2018-06-18 08:45:10 +0200
commit496bc5a7635a1e27b315a9ce7058a639e24cb494 (patch)
tree40d840b45256f9a5dd69eb54c5926258ddca31f4
parent232ef95ae4918d7fd699c0a9e87b3ca4371d5224 (diff)
downloadmullvadvpn-496bc5a7635a1e27b315a9ce7058a639e24cb494.tar.xz
mullvadvpn-496bc5a7635a1e27b315a9ce7058a639e24cb494.zip
Add fundamental WMI code
-rw-r--r--.gitignore1
-rw-r--r--windns/src/windns/comlol.h10
-rw-r--r--windns/src/windns/dllmain.cppbin0 -> 378 bytes
-rw-r--r--windns/src/windns/dnsregistry.h22
-rw-r--r--windns/src/windns/stdafx.cppbin0 -> 588 bytes
-rw-r--r--windns/src/windns/stdafx.hbin0 -> 840 bytes
-rw-r--r--windns/src/windns/targetver.hbin0 -> 766 bytes
-rw-r--r--windns/src/windns/windns.h8
-rw-r--r--windns/src/windns/windns.vcxproj201
-rw-r--r--windns/src/windns/windns.vcxproj.filters34
-rw-r--r--windns/src/windns/wmi/connection.cpp60
-rw-r--r--windns/src/windns/wmi/connection.h44
-rw-r--r--windns/src/windns/wmi/iconnection.h17
-rw-r--r--windns/src/windns/wmi/resultset.cpp40
-rw-r--r--windns/src/windns/wmi/resultset.h35
-rw-r--r--windns/windns.sln48
16 files changed, 520 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 400d25a55d..a50a75ce8c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,4 @@ flow-typed
dist-assets/relays.json
windows/winfw/bin/
**/.vs/
+windns/bin/
diff --git a/windns/src/windns/comlol.h b/windns/src/windns/comlol.h
new file mode 100644
index 0000000000..b009dc1253
--- /dev/null
+++ b/windns/src/windns/comlol.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include "libcommon/error.h"
+#include <winerror.h>
+
+#define VALIDATE_COM(status, operation)\
+if(FAILED(status))\
+{\
+ ::common::error::Throw(operation, status);\
+}
diff --git a/windns/src/windns/dllmain.cpp b/windns/src/windns/dllmain.cpp
new file mode 100644
index 0000000000..dfde574841
--- /dev/null
+++ b/windns/src/windns/dllmain.cpp
Binary files differ
diff --git a/windns/src/windns/dnsregistry.h b/windns/src/windns/dnsregistry.h
new file mode 100644
index 0000000000..cfd43a99b5
--- /dev/null
+++ b/windns/src/windns/dnsregistry.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include <string>
+#include <vector>
+#include <map>
+#include <cstdint>
+
+class DnsRegistry
+{
+public:
+
+ using DnsServers = std::vector<std::wstring>;
+
+ void registerInterface(uint32_t interfaceIndex, const DnsServers &dnsServers);
+
+ const DnsServers getInterfaceSettings(uint32_t interfaceIndex);
+
+private:
+
+ // Organize by interface index.
+ std::map<uint32_t, DnsServers> m_registry;
+};
diff --git a/windns/src/windns/stdafx.cpp b/windns/src/windns/stdafx.cpp
new file mode 100644
index 0000000000..4fdd5990e4
--- /dev/null
+++ b/windns/src/windns/stdafx.cpp
Binary files differ
diff --git a/windns/src/windns/stdafx.h b/windns/src/windns/stdafx.h
new file mode 100644
index 0000000000..b937b12ccd
--- /dev/null
+++ b/windns/src/windns/stdafx.h
Binary files differ
diff --git a/windns/src/windns/targetver.h b/windns/src/windns/targetver.h
new file mode 100644
index 0000000000..932a2e87b6
--- /dev/null
+++ b/windns/src/windns/targetver.h
Binary files differ
diff --git a/windns/src/windns/windns.h b/windns/src/windns/windns.h
new file mode 100644
index 0000000000..450685d8a8
--- /dev/null
+++ b/windns/src/windns/windns.h
@@ -0,0 +1,8 @@
+#pragma once
+
+// simple model:
+
+bool StartEnforcingDns(const wchar_t *primaryServer);
+
+void StopEnforcingDns();
+
diff --git a/windns/src/windns/windns.vcxproj b/windns/src/windns/windns.vcxproj
new file mode 100644
index 0000000000..fa4851d600
--- /dev/null
+++ b/windns/src/windns/windns.vcxproj
@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>15.0</VCProjectVersion>
+ <ProjectGuid>{A5344205-FC37-4572-9C63-8564ECC410AC}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>windns</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>$(SolutionDir)bin\$(Platform)-$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)bin\temp\$(Platform)-$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>$(SolutionDir)bin\$(Platform)-$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)bin\temp\$(Platform)-$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(SolutionDir)bin\$(Platform)-$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)bin\temp\$(Platform)-$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(SolutionDir)bin\$(Platform)-$(Configuration)\</OutDir>
+ <IntDir>$(SolutionDir)bin\temp\$(Platform)-$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>_DEBUG;WINDNS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../../../wfpctl/libwfp/src</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories>
+ <AdditionalDependencies>libcommon.lib;wbemuuid.lib;comsuppw.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>WIN32;_DEBUG;WINDNS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../../../wfpctl/libwfp/src</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories>
+ <AdditionalDependencies>libcommon.lib;wbemuuid.lib;comsuppw.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>WIN32;NDEBUG;WINDNS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../../../wfpctl/libwfp/src</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories>
+ <AdditionalDependencies>libcommon.lib;wbemuuid.lib;comsuppw.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>NDEBUG;WINDNS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../../../wfpctl/libwfp/src</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <LanguageStandard>stdcpplatest</LanguageStandard>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories>
+ <AdditionalDependencies>libcommon.lib;wbemuuid.lib;comsuppw.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="comlol.h" />
+ <ClInclude Include="dnsregistry.h" />
+ <ClInclude Include="stdafx.h" />
+ <ClInclude Include="targetver.h" />
+ <ClInclude Include="windns.h" />
+ <ClInclude Include="wmi\connection.h" />
+ <ClInclude Include="wmi\iconnection.h" />
+ <ClInclude Include="wmi\resultset.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="dllmain.cpp" />
+ <ClCompile Include="stdafx.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="wmi\connection.cpp" />
+ <ClCompile Include="wmi\resultset.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/windns/src/windns/windns.vcxproj.filters b/windns/src/windns/windns.vcxproj.filters
new file mode 100644
index 0000000000..f8becc56c5
--- /dev/null
+++ b/windns/src/windns/windns.vcxproj.filters
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClInclude Include="stdafx.h" />
+ <ClInclude Include="targetver.h" />
+ <ClInclude Include="wmi\connection.h">
+ <Filter>wmi</Filter>
+ </ClInclude>
+ <ClInclude Include="comlol.h" />
+ <ClInclude Include="wmi\resultset.h">
+ <Filter>wmi</Filter>
+ </ClInclude>
+ <ClInclude Include="wmi\iconnection.h">
+ <Filter>wmi</Filter>
+ </ClInclude>
+ <ClInclude Include="dnsregistry.h" />
+ <ClInclude Include="windns.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="dllmain.cpp" />
+ <ClCompile Include="stdafx.cpp" />
+ <ClCompile Include="wmi\connection.cpp">
+ <Filter>wmi</Filter>
+ </ClCompile>
+ <ClCompile Include="wmi\resultset.cpp">
+ <Filter>wmi</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="wmi">
+ <UniqueIdentifier>{5deb73ee-53cc-49ac-bcdd-0a4b38914f0e}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/windns/src/windns/wmi/connection.cpp b/windns/src/windns/wmi/connection.cpp
new file mode 100644
index 0000000000..a2588b139e
--- /dev/null
+++ b/windns/src/windns/wmi/connection.cpp
@@ -0,0 +1,60 @@
+#include "stdafx.h"
+#include "connection.h"
+#include "windns/comlol.h"
+#include <stdexcept>
+#define _WIN32_DCOM
+#include <windows.h>
+#include <wbemidl.h>
+
+namespace
+{
+
+const wchar_t *LiteralNamespace(wmi::Connection::Namespace ns)
+{
+ switch (ns)
+ {
+ case wmi::Connection::Namespace::Default: return L"root\\Default";
+ case wmi::Connection::Namespace::Cimv2: return L"root\\CIMV2";
+ default:
+ {
+ throw std::logic_error("Missing case handler in switch clause");
+ }
+ }
+}
+
+} // anonymous namespace
+
+namespace wmi
+{
+
+Connection::Connection(Namespace ns) : m_queryLanguage(L"WQL")
+{
+ auto status = CoCreateInstance(CLSID_WbemLocator, nullptr, CLSCTX_INPROC_SERVER,
+ IID_IWbemLocator, (LPVOID *)&m_locator);
+
+ VALIDATE_COM(status, "Create COM locator instance");
+
+ status = m_locator->ConnectServer(_bstr_t(LiteralNamespace(ns)), nullptr, nullptr,
+ nullptr, 0, nullptr, nullptr, &m_services);
+
+ VALIDATE_COM(status, "Create COM services instance");
+
+ status = CoSetProxyBlanket(m_services, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr,
+ RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE);
+
+ VALIDATE_COM(status, "Configure COM services auth");
+}
+
+ResultSet Connection::Query(const wchar_t *query)
+{
+ CComPtr<IEnumWbemClassObject> result;
+
+ auto status = m_services->ExecQuery(m_queryLanguage, _bstr_t(query),
+ WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, nullptr, &result);
+
+ VALIDATE_COM(status, "Execute WMI query");
+
+ return ResultSet(result);
+}
+
+}
diff --git a/windns/src/windns/wmi/connection.h b/windns/src/windns/wmi/connection.h
new file mode 100644
index 0000000000..37d658bdaf
--- /dev/null
+++ b/windns/src/windns/wmi/connection.h
@@ -0,0 +1,44 @@
+#pragma once
+
+#include "iconnection.h"
+#include <string>
+#define _WIN32_DCOM
+#include <windows.h>
+#include <atlbase.h>
+#include <comutil.h>
+
+namespace wmi
+{
+
+class Connection : public IConnection
+{
+public:
+
+ enum class Namespace
+ {
+ Default,
+ Cimv2
+ };
+
+ explicit Connection(Namespace ns);
+
+ ResultSet Query(const wchar_t *query) override;
+
+ // TODO: Move to shared base class.
+ ResultSet Query(const std::wstring &str)
+ {
+ return Query(str.c_str());
+ }
+
+private:
+
+ Connection(const Connection &) = delete;
+ Connection &operator=(const Connection &) = delete;
+
+ CComPtr<IWbemLocator> m_locator;
+ CComPtr<IWbemServices> m_services;
+
+ _bstr_t m_queryLanguage;
+};
+
+}
diff --git a/windns/src/windns/wmi/iconnection.h b/windns/src/windns/wmi/iconnection.h
new file mode 100644
index 0000000000..58b5841b91
--- /dev/null
+++ b/windns/src/windns/wmi/iconnection.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "resultset.h"
+
+namespace wmi
+{
+
+struct IConnection
+{
+ virtual ~IConnection() = 0
+ {
+ }
+
+ virtual ResultSet Query(const wchar_t *query) = 0;
+};
+
+}
diff --git a/windns/src/windns/wmi/resultset.cpp b/windns/src/windns/wmi/resultset.cpp
new file mode 100644
index 0000000000..b5914ff6d2
--- /dev/null
+++ b/windns/src/windns/wmi/resultset.cpp
@@ -0,0 +1,40 @@
+#include "stdafx.h"
+#include "resultset.h"
+#include "windns/comlol.h"
+#include "libcommon/error.h"
+
+namespace wmi
+{
+
+ResultSet::ResultSet(CComPtr<IEnumWbemClassObject> rs) : m_resultset(rs)
+{
+}
+
+bool ResultSet::advance()
+{
+ ULONG dummy;
+
+ const auto status = m_resultset->Next(WBEM_INFINITE, 1, &m_result, &dummy);
+
+ VALIDATE_COM(status, "Retrieve next object in COM resultset");
+
+ return WBEM_S_FALSE != status;
+}
+
+_variant_t ResultSet::getResultProperty(const std::wstring &name)
+{
+ _variant_t val;
+
+ auto status = m_result->Get(name.c_str(), 0, &val, nullptr, nullptr);
+
+ VALIDATE_COM(status, "Retrieve COM property value");
+
+ return val;
+}
+
+CComPtr<IWbemClassObject> ResultSet::getResult()
+{
+ return m_result;
+}
+
+}
diff --git a/windns/src/windns/wmi/resultset.h b/windns/src/windns/wmi/resultset.h
new file mode 100644
index 0000000000..bcdefa6c3c
--- /dev/null
+++ b/windns/src/windns/wmi/resultset.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#include <string>
+#include <atlbase.h>
+#include <wbemidl.h>
+#include <comutil.h>
+
+namespace wmi
+{
+
+class ResultSet
+{
+public:
+
+ ResultSet(CComPtr<IEnumWbemClassObject> rs);
+
+ ResultSet(ResultSet &&) = default;
+ ResultSet &operator=(ResultSet &&) = default;
+
+ bool advance();
+
+ _variant_t getResultProperty(const std::wstring &name);
+
+ CComPtr<IWbemClassObject> getResult();
+
+private:
+
+ ResultSet(const ResultSet &) = delete;
+ ResultSet &operator=(const ResultSet &) = delete;
+
+ CComPtr<IEnumWbemClassObject> m_resultset;
+ CComPtr<IWbemClassObject> m_result;
+};
+
+}
diff --git a/windns/windns.sln b/windns/windns.sln
new file mode 100644
index 0000000000..69bc05d9fb
--- /dev/null
+++ b/windns/windns.sln
@@ -0,0 +1,48 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.27130.2027
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcommon", "..\wfpctl\libwfp\src\libcommon\libcommon.vcxproj", "{B52E2D10-A94A-4605-914A-2DCEF6A757EF}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "windns", "src\windns\windns.vcxproj", "{A5344205-FC37-4572-9C63-8564ECC410AC}"
+ ProjectSection(ProjectDependencies) = postProject
+ {B52E2D10-A94A-4605-914A-2DCEF6A757EF} = {B52E2D10-A94A-4605-914A-2DCEF6A757EF}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B52E2D10-A94A-4605-914A-2DCEF6A757EF}.Debug|x64.ActiveCfg = Debug|x64
+ {B52E2D10-A94A-4605-914A-2DCEF6A757EF}.Debug|x64.Build.0 = Debug|x64
+ {B52E2D10-A94A-4605-914A-2DCEF6A757EF}.Debug|x86.ActiveCfg = Debug|Win32
+ {B52E2D10-A94A-4605-914A-2DCEF6A757EF}.Debug|x86.Build.0 = Debug|Win32
+ {B52E2D10-A94A-4605-914A-2DCEF6A757EF}.Release|x64.ActiveCfg = Release|x64
+ {B52E2D10-A94A-4605-914A-2DCEF6A757EF}.Release|x64.Build.0 = Release|x64
+ {B52E2D10-A94A-4605-914A-2DCEF6A757EF}.Release|x86.ActiveCfg = Release|Win32
+ {B52E2D10-A94A-4605-914A-2DCEF6A757EF}.Release|x86.Build.0 = Release|Win32
+ {A5344205-FC37-4572-9C63-8564ECC410AC}.Debug|x64.ActiveCfg = Debug|x64
+ {A5344205-FC37-4572-9C63-8564ECC410AC}.Debug|x64.Build.0 = Debug|x64
+ {A5344205-FC37-4572-9C63-8564ECC410AC}.Debug|x64.Deploy.0 = Debug|x64
+ {A5344205-FC37-4572-9C63-8564ECC410AC}.Debug|x86.ActiveCfg = Debug|Win32
+ {A5344205-FC37-4572-9C63-8564ECC410AC}.Debug|x86.Build.0 = Debug|Win32
+ {A5344205-FC37-4572-9C63-8564ECC410AC}.Debug|x86.Deploy.0 = Debug|Win32
+ {A5344205-FC37-4572-9C63-8564ECC410AC}.Release|x64.ActiveCfg = Release|x64
+ {A5344205-FC37-4572-9C63-8564ECC410AC}.Release|x64.Build.0 = Release|x64
+ {A5344205-FC37-4572-9C63-8564ECC410AC}.Release|x64.Deploy.0 = Release|x64
+ {A5344205-FC37-4572-9C63-8564ECC410AC}.Release|x86.ActiveCfg = Release|Win32
+ {A5344205-FC37-4572-9C63-8564ECC410AC}.Release|x86.Build.0 = Release|Win32
+ {A5344205-FC37-4572-9C63-8564ECC410AC}.Release|x86.Deploy.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {A28F3793-15A7-4EE5-A899-373DF084D91F}
+ EndGlobalSection
+EndGlobal