diff options
| author | Odd Stranne <odd@mullvad.net> | 2018-06-07 22:06:14 +0200 |
|---|---|---|
| committer | Odd Stranne <odd@mullvad.net> | 2018-06-18 08:45:17 +0200 |
| commit | 139453ea5edd1565fcf676e3872c8ff1f8bb9047 (patch) | |
| tree | ce29e1c73b5174a3d704b3eee0667a4628a1f589 /windows | |
| parent | 0410af44dc8df4c61211d9602eda4d6524648deb (diff) | |
| download | mullvadvpn-139453ea5edd1565fcf676e3872c8ff1f8bb9047.tar.xz mullvadvpn-139453ea5edd1565fcf676e3872c8ff1f8bb9047.zip | |
Remove code that has been migrated to libcommon
Update references to migrated code
Diffstat (limited to 'windows')
31 files changed, 32 insertions, 1255 deletions
diff --git a/windows/windns/src/windns/comhelpers.cpp b/windows/windns/src/windns/comhelpers.cpp deleted file mode 100644 index dea61b40d9..0000000000 --- a/windows/windns/src/windns/comhelpers.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "stdafx.h" -#include "comhelpers.h" -#include <algorithm> - -_variant_t ComGetProperty(CComPtr<IWbemClassObject> obj, const std::wstring &name) -{ - _variant_t val; - - const auto status = obj->Get(name.c_str(), 0, &val, nullptr, nullptr); - - VALIDATE_COM(status, "Retrieve COM property value"); - - return val; -} - -_variant_t ComGetPropertyAlways(CComPtr<IWbemClassObject> obj, const std::wstring &name) -{ - auto val = ComGetProperty(obj, name); - - if (VT_EMPTY == V_VT(&val) || VT_NULL == V_VT(&val)) - { - throw std::runtime_error("A required COM property value is empty."); - } - - return val; -} - -std::wstring ComConvertString(BSTR src) -{ - return std::wstring(src, SysStringLen(src)); -} - -std::vector<std::wstring> ComConvertStringArray(SAFEARRAY *src) -{ - CComSafeArray<BSTR> safeArray(src); - - std::vector<std::wstring> result; - result.reserve(safeArray.GetCount()); - - for (ULONG i = 0; i < safeArray.GetCount(); ++i) - { - result.emplace_back(ComConvertString(safeArray.GetAt(i))); - } - - return result; -} - -CComSafeArray<BSTR> ComConvertIntoStringArray(const std::vector<std::wstring> &src) -{ - CComSafeArray<BSTR> result; - - std::for_each(src.begin(), src.end(), [&](const std::wstring &str) - { - result.Add(_bstr_t(str.c_str())); - }); - - return result; -} - -_variant_t ComPackageStringArray(CComSafeArray<BSTR> &src) -{ - VARIANT v; - - V_VT(&v) = VT_ARRAY | VT_BSTR; - V_ARRAY(&v) = src.Detach(); - - _variant_t vv; - - vv.Attach(v); - - return vv; -}
\ No newline at end of file diff --git a/windows/windns/src/windns/comhelpers.h b/windows/windns/src/windns/comhelpers.h deleted file mode 100644 index 67e1a46aea..0000000000 --- a/windows/windns/src/windns/comhelpers.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "libcommon/error.h" -#include <string> -#include <vector> -#include <stdexcept> -#include <winerror.h> -#include <atlbase.h> -#include <comutil.h> -#include <atlsafe.h> -#include <wbemidl.h> - -#define VALIDATE_COM(status, operation)\ -if(FAILED(status))\ -{\ - ::common::error::Throw(operation, status);\ -} - -_variant_t ComGetProperty(CComPtr<IWbemClassObject> obj, const std::wstring &name); -_variant_t ComGetPropertyAlways(CComPtr<IWbemClassObject> obj, const std::wstring &name); -std::wstring ComConvertString(BSTR src); -std::vector<std::wstring> ComConvertStringArray(SAFEARRAY *src); -CComSafeArray<BSTR> ComConvertIntoStringArray(const std::vector<std::wstring> &src); - -// NOTE: This consumes the source variable -_variant_t ComPackageStringArray(CComSafeArray<BSTR> &src); diff --git a/windows/windns/src/windns/configmanager.cpp b/windows/windns/src/windns/configmanager.cpp index 09b3049fa4..0751eba251 100644 --- a/windows/windns/src/windns/configmanager.cpp +++ b/windows/windns/src/windns/configmanager.cpp @@ -1,6 +1,6 @@ #include "stdafx.h" #include "configmanager.h" -#include "windns/serialization/serializer.h" +#include "libcommon/serialization/serializer.h" #include <utility> #include <algorithm> diff --git a/windows/windns/src/windns/interfaceconfig.cpp b/windows/windns/src/windns/interfaceconfig.cpp index 249c629e81..7ca2339442 100644 --- a/windows/windns/src/windns/interfaceconfig.cpp +++ b/windows/windns/src/windns/interfaceconfig.cpp @@ -1,6 +1,9 @@ #include "stdafx.h" #include "interfaceconfig.h" -#include "windns/comhelpers.h" +#include "libcommon/com.h" +#include "libcommon/wmi/wmi.h" + +using namespace common; InterfaceConfig::InterfaceConfig(CComPtr<IWbemClassObject> instance) { @@ -8,12 +11,12 @@ InterfaceConfig::InterfaceConfig(CComPtr<IWbemClassObject> instance) // V_xxx macros seem to require an l-value so access the correct field directly instead. // - m_configIndex = ComGetPropertyAlways(instance, L"Index").ulVal; + m_configIndex = wmi::WmiGetPropertyAlways(instance, L"Index").ulVal; - m_dhcp = ComGetPropertyAlways(instance, L"DHCPEnabled").boolVal; + m_dhcp = wmi::WmiGetPropertyAlways(instance, L"DHCPEnabled").boolVal; - m_interfaceIndex = ComGetPropertyAlways(instance, L"InterfaceIndex").ulVal; - m_interfaceGuid = ComConvertString(ComGetPropertyAlways(instance, L"SettingID").bstrVal); + m_interfaceIndex = wmi::WmiGetPropertyAlways(instance, L"InterfaceIndex").ulVal; + m_interfaceGuid = ComConvertString(wmi::WmiGetPropertyAlways(instance, L"SettingID").bstrVal); m_servers = nchelpers::GetDnsServers(instance); } diff --git a/windows/windns/src/windns/interfaceconfig.h b/windows/windns/src/windns/interfaceconfig.h index a72142e6a4..30782ebe13 100644 --- a/windows/windns/src/windns/interfaceconfig.h +++ b/windows/windns/src/windns/interfaceconfig.h @@ -1,8 +1,8 @@ #pragma once #include "windns/netconfighelpers.h" -#include "windns/serialization/deserializer.h" -#include "windns/serialization/serializer.h" +#include "libcommon/serialization/deserializer.h" +#include "libcommon/serialization/serializer.h" #include <cstdint> #include <string> #include <vector> diff --git a/windows/windns/src/windns/netconfigeventsink.cpp b/windows/windns/src/windns/netconfigeventsink.cpp index cd544af924..2923fecfe7 100644 --- a/windows/windns/src/windns/netconfigeventsink.cpp +++ b/windows/windns/src/windns/netconfigeventsink.cpp @@ -2,6 +2,8 @@ #include "netconfigeventsink.h" #include "windns/netconfighelpers.h" +using namespace common; + NetConfigEventSink::NetConfigEventSink(std::shared_ptr<wmi::IConnection> connection, std::shared_ptr<ConfigManager> configManager) : m_connection(connection) , m_configManager(configManager) diff --git a/windows/windns/src/windns/netconfigeventsink.h b/windows/windns/src/windns/netconfigeventsink.h index 994fac860c..342278c08c 100644 --- a/windows/windns/src/windns/netconfigeventsink.h +++ b/windows/windns/src/windns/netconfigeventsink.h @@ -1,20 +1,20 @@ #pragma once -#include "windns/wmi/ieventsink.h" -#include "windns/wmi/iconnection.h" +#include "libcommon/wmi/ieventsink.h" +#include "libcommon/wmi/iconnection.h" #include "windns/configmanager.h" #include <memory> -class NetConfigEventSink : public wmi::IModificationEventSink +class NetConfigEventSink : public common::wmi::IModificationEventSink { public: - NetConfigEventSink(std::shared_ptr<wmi::IConnection> connection, std::shared_ptr<ConfigManager> configManager); + NetConfigEventSink(std::shared_ptr<common::wmi::IConnection> connection, std::shared_ptr<ConfigManager> configManager); void update(CComPtr<IWbemClassObject> previous, CComPtr<IWbemClassObject> target) override; private: - std::shared_ptr<wmi::IConnection> m_connection; + std::shared_ptr<common::wmi::IConnection> m_connection; std::shared_ptr<ConfigManager> m_configManager; }; diff --git a/windows/windns/src/windns/netconfighelpers.cpp b/windows/windns/src/windns/netconfighelpers.cpp index f43f578a55..70eb81b3ae 100644 --- a/windows/windns/src/windns/netconfighelpers.cpp +++ b/windows/windns/src/windns/netconfighelpers.cpp @@ -1,8 +1,11 @@ #include "stdafx.h" #include "netconfighelpers.h" -#include "comhelpers.h" +#include "libcommon/com.h" +#include "libcommon/wmi/wmi.h" #include "netsh.h" +using namespace common; + namespace nchelpers { @@ -10,7 +13,7 @@ OptionalStringList GetDnsServers(CComPtr<IWbemClassObject> instance) { OptionalStringList result; - auto servers = ComGetProperty(instance, L"DNSServerSearchOrder"); + auto servers = wmi::WmiGetProperty(instance, L"DNSServerSearchOrder"); if (VT_EMPTY == V_VT(&servers) || VT_NULL == V_VT(&servers)) { @@ -25,7 +28,7 @@ OptionalStringList GetDnsServers(CComPtr<IWbemClassObject> instance) uint32_t GetInterfaceIndex(CComPtr<IWbemClassObject> instance) { - return ComGetPropertyAlways(instance, L"InterfaceIndex").ulVal; + return wmi::WmiGetPropertyAlways(instance, L"InterfaceIndex").ulVal; } void SetDnsServers(uint32_t interfaceIndex, const std::vector<std::wstring> &servers) diff --git a/windows/windns/src/windns/netconfighelpers.h b/windows/windns/src/windns/netconfighelpers.h index f1c796b445..c3b963c954 100644 --- a/windows/windns/src/windns/netconfighelpers.h +++ b/windows/windns/src/windns/netconfighelpers.h @@ -1,6 +1,5 @@ #pragma once -#include "wmi/iconnection.h" #include <string> #include <memory> #include <vector> diff --git a/windows/windns/src/windns/serialization/deserializer.cpp b/windows/windns/src/windns/serialization/deserializer.cpp deleted file mode 100644 index dce6ada950..0000000000 --- a/windows/windns/src/windns/serialization/deserializer.cpp +++ /dev/null @@ -1,108 +0,0 @@ -#include "stdafx.h" -#include "deserializer.h" -#include <stdexcept> - -namespace common::serialization -{ - -Deserializer::Deserializer(const uint8_t *blob, size_t size) - : m_blob(blob, blob + size) - , m_offset(0) -{ -} - -void Deserializer::operator>>(uint8_t &data) -{ - validateType(TypeTag::Uint8); - - read(&data, sizeof(data)); -} - -void Deserializer::operator>>(uint16_t &data) -{ - validateType(TypeTag::Uint16); - - read(&data, sizeof(data)); -} - -void Deserializer::operator>>(uint32_t &data) -{ - validateType(TypeTag::Uint32); - - read(&data, sizeof(data)); -} - -void Deserializer::operator>>(GUID &data) -{ - validateType(TypeTag::Guid); - - read(&data, sizeof(data)); -} - -void Deserializer::operator>>(std::wstring &data) -{ - validateType(TypeTag::String); - - uint32_t strByteLength; - - read(&strByteLength, sizeof(strByteLength)); - - if (0 == strByteLength) - { - data.clear(); - return; - } - - std::vector<uint8_t> raw(strByteLength); - - read(&raw[0], strByteLength); - - data = std::wstring - ( - reinterpret_cast<wchar_t *>(&raw[0]), - reinterpret_cast<wchar_t *>(&raw[0]) + (strByteLength / sizeof(wchar_t)) - ); -} - -void Deserializer::operator>>(std::vector<std::wstring> &data) -{ - validateType(TypeTag::StringArray); - - uint32_t elements; - - read(&elements, sizeof(elements)); - - data.clear(); - - for (uint32_t i = 0; i < elements; ++i) - { - data.emplace_back(std::wstring()); - *this >> *data.rbegin(); - } -} - -void Deserializer::validateType(TypeTag type) -{ - uint8_t readType; - - read(&readType, sizeof(uint8_t)); - - if (readType != static_cast<uint8_t>(type)) - { - throw std::runtime_error("Unexpected data type in stream"); - } -} - -void Deserializer::read(void *data, size_t length) -{ - if (m_offset + length > m_blob.size()) - { - throw std::runtime_error("Read probe passed end of stream"); - } - - memcpy(data, &m_blob[m_offset], length); - - m_offset += length; -} - -} diff --git a/windows/windns/src/windns/serialization/deserializer.h b/windows/windns/src/windns/serialization/deserializer.h deleted file mode 100644 index a2c59400fd..0000000000 --- a/windows/windns/src/windns/serialization/deserializer.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include "typetag.h" -#include <vector> -#include <string> -#include <cstdint> -#include <guiddef.h> - -namespace common::serialization -{ - -class Deserializer -{ -public: - - Deserializer(const uint8_t *blob, size_t size); - - void operator>>(uint8_t &data); - void operator>>(uint16_t &data); - void operator>>(uint32_t &data); - void operator>>(GUID &data); - void operator>>(std::wstring &data); - void operator>>(std::vector<std::wstring> &data); - -private: - - std::vector<uint8_t> m_blob; - size_t m_offset; - - void validateType(TypeTag type); - void read(void *data, size_t length); -}; - -} diff --git a/windows/windns/src/windns/serialization/serializer.cpp b/windows/windns/src/windns/serialization/serializer.cpp deleted file mode 100644 index e4af65db98..0000000000 --- a/windows/windns/src/windns/serialization/serializer.cpp +++ /dev/null @@ -1,111 +0,0 @@ -#include "stdafx.h" -#include "serializer.h" -#include <algorithm> - -namespace -{ - -void Append(std::vector<uint8_t> &v, const void *data, size_t length) -{ - if (0 == length) - { - return; - } - - const auto oldSize = v.size(); - - v.resize(oldSize + length); - memcpy(&v[oldSize], data, length); -} - -std::vector<uint8_t> PackageString(const wchar_t *str) -{ - const auto strByteLength = static_cast<uint32_t>(wcslen(str) * sizeof(wchar_t)); - - std::vector<uint8_t> data; - - Append(data, &strByteLength, sizeof(strByteLength)); - Append(data, str, strByteLength); - - return data; -} - -} // anonymous namespace - -namespace common::serialization -{ - -void Serializer::operator<<(uint8_t data) -{ - append(TypeTag::Uint8, &data, sizeof(uint8_t)); -} - -void Serializer::operator<<(uint16_t data) -{ - append(TypeTag::Uint16, &data, sizeof(uint16_t)); -} - -void Serializer::operator<<(uint32_t data) -{ - append(TypeTag::Uint32, &data, sizeof(uint32_t)); -} - -void Serializer::operator<<(const GUID &data) -{ - append(TypeTag::Guid, &data, sizeof(GUID)); -} - -void Serializer::operator<<(const std::wstring &data) -{ - auto packaged = PackageString(data.c_str()); - - append(TypeTag::String, &packaged[0], packaged.size()); -} - -void Serializer::operator<<(const wchar_t *data) -{ - auto packaged = PackageString(data); - - append(TypeTag::String, &packaged[0], packaged.size()); -} - -void Serializer::operator<<(const std::vector<std::wstring> &data) -{ - std::vector<uint8_t> arrayBlob; - - uint32_t count = static_cast<uint32_t>(data.size()); - - Append(arrayBlob, &count, sizeof(count)); - - std::for_each(data.begin(), data.end(), [&](const std::wstring &str) - { - auto packagedStr = PackageString(str.c_str()); - - // Hack? Makes parsing a lot simpler - arrayBlob.push_back(static_cast<uint8_t>(TypeTag::String)); - - Append(arrayBlob, &packagedStr[0], packagedStr.size()); - }); - - append(TypeTag::StringArray, &arrayBlob[0], arrayBlob.size()); -} - -const std::vector<uint8_t> &Serializer::blob() const -{ - return m_blob; -} - -void Serializer::append(TypeTag type, const void *data, size_t length) -{ - const auto elementSize = sizeof(uint8_t) + length; - const auto oldSize = m_blob.size(); - - m_blob.resize(oldSize + elementSize); - - auto dest = &m_blob[oldSize]; - - *dest++ = static_cast<uint8_t>(type); - memcpy(dest, data, length); -} - -} diff --git a/windows/windns/src/windns/serialization/serializer.h b/windows/windns/src/windns/serialization/serializer.h deleted file mode 100644 index 63e9fdd5bb..0000000000 --- a/windows/windns/src/windns/serialization/serializer.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include "typetag.h" -#include <vector> -#include <string> -#include <cstdint> -#include <guiddef.h> - -namespace common::serialization -{ - -class Serializer -{ -public: - - void operator<<(uint8_t data); - void operator<<(uint16_t data); - void operator<<(uint32_t data); - void operator<<(const GUID &data); - void operator<<(const std::wstring &data); - void operator<<(const wchar_t *data); - void operator<<(const std::vector<std::wstring> &data); - - const std::vector<uint8_t> &blob() const; - -private: - - std::vector<uint8_t> m_blob; - - void append(TypeTag type, const void *data, size_t length); -}; - -} diff --git a/windows/windns/src/windns/serialization/typetag.h b/windows/windns/src/windns/serialization/typetag.h deleted file mode 100644 index a2ab3cccc3..0000000000 --- a/windows/windns/src/windns/serialization/typetag.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -namespace common::serialization -{ - -enum class TypeTag -{ - Uint8, - Uint16, - Uint32, - Guid, // data = binary 16 bytes - String, // data = [uint32: byte length], [UCS-2 string], [NOT zero terminated] - StringArray // data = [uint32: count], count * String -}; - -// -// Each entry is serialized as: -// [uint8: type], [data] -// - -} diff --git a/windows/windns/src/windns/windns.cpp b/windows/windns/src/windns/windns.cpp index ea8ee15c33..566e32ad91 100644 --- a/windows/windns/src/windns/windns.cpp +++ b/windows/windns/src/windns/windns.cpp @@ -2,7 +2,7 @@ #include "windns.h" #include "windnscontext.h" #include "clientsinkinfo.h" -#include "windns/serialization/deserializer.h" +#include "libcommon/serialization/deserializer.h" #include "interfaceconfig.h" #include "dnsreverter.h" #include <vector> diff --git a/windows/windns/src/windns/windns.vcxproj b/windows/windns/src/windns/windns.vcxproj index 89d5c89d33..c4a0ec758c 100644 --- a/windows/windns/src/windns/windns.vcxproj +++ b/windows/windns/src/windns/windns.vcxproj @@ -176,7 +176,6 @@ </ItemDefinitionGroup> <ItemGroup> <ClInclude Include="clientsinkinfo.h" /> - <ClInclude Include="comhelpers.h" /> <ClInclude Include="configmanager.h" /> <ClInclude Include="consoletracesink.h" /> <ClInclude Include="dnsreverter.h" /> @@ -186,23 +185,12 @@ <ClInclude Include="netconfigeventsink.h" /> <ClInclude Include="netconfighelpers.h" /> <ClInclude Include="netsh.h" /> - <ClInclude Include="serialization\deserializer.h" /> - <ClInclude Include="serialization\serializer.h" /> - <ClInclude Include="serialization\typetag.h" /> <ClInclude Include="stdafx.h" /> <ClInclude Include="targetver.h" /> <ClInclude Include="windns.h" /> <ClInclude Include="windnscontext.h" /> - <ClInclude Include="wmi\connection.h" /> - <ClInclude Include="wmi\eventdispatcher.h" /> - <ClInclude Include="wmi\iconnection.h" /> - <ClInclude Include="wmi\ieventsink.h" /> - <ClInclude Include="wmi\methodcall.h" /> - <ClInclude Include="wmi\notification.h" /> - <ClInclude Include="wmi\resultset.h" /> </ItemGroup> <ItemGroup> - <ClCompile Include="comhelpers.cpp" /> <ClCompile Include="configmanager.cpp" /> <ClCompile Include="consoletracesink.cpp" /> <ClCompile Include="dllmain.cpp" /> @@ -211,8 +199,6 @@ <ClCompile Include="netconfigeventsink.cpp" /> <ClCompile Include="netconfighelpers.cpp" /> <ClCompile Include="netsh.cpp" /> - <ClCompile Include="serialization\deserializer.cpp" /> - <ClCompile Include="serialization\serializer.cpp" /> <ClCompile Include="stdafx.cpp"> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> @@ -221,11 +207,6 @@ </ClCompile> <ClCompile Include="windns.cpp" /> <ClCompile Include="windnscontext.cpp" /> - <ClCompile Include="wmi\connection.cpp" /> - <ClCompile Include="wmi\eventdispatcher.cpp" /> - <ClCompile Include="wmi\methodcall.cpp" /> - <ClCompile Include="wmi\notification.cpp" /> - <ClCompile Include="wmi\resultset.cpp" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> diff --git a/windows/windns/src/windns/windns.vcxproj.filters b/windows/windns/src/windns/windns.vcxproj.filters index ff323bfefa..feab7d847f 100644 --- a/windows/windns/src/windns/windns.vcxproj.filters +++ b/windows/windns/src/windns/windns.vcxproj.filters @@ -3,91 +3,30 @@ <ItemGroup> <ClInclude Include="stdafx.h" /> <ClInclude Include="targetver.h" /> - <ClInclude Include="wmi\connection.h"> - <Filter>wmi</Filter> - </ClInclude> - <ClInclude Include="wmi\resultset.h"> - <Filter>wmi</Filter> - </ClInclude> - <ClInclude Include="wmi\iconnection.h"> - <Filter>wmi</Filter> - </ClInclude> <ClInclude Include="windns.h" /> <ClInclude Include="windnscontext.h" /> - <ClInclude Include="wmi\methodcall.h"> - <Filter>wmi</Filter> - </ClInclude> - <ClInclude Include="comhelpers.h" /> <ClInclude Include="configmanager.h" /> <ClInclude Include="itracesink.h" /> <ClInclude Include="consoletracesink.h" /> <ClInclude Include="netconfigeventsink.h" /> <ClInclude Include="netconfighelpers.h" /> <ClInclude Include="macroargument.h" /> - <ClInclude Include="wmi\notification.h"> - <Filter>wmi</Filter> - </ClInclude> <ClInclude Include="dnsreverter.h" /> <ClInclude Include="clientsinkinfo.h" /> - <ClInclude Include="wmi\eventdispatcher.h"> - <Filter>wmi</Filter> - </ClInclude> - <ClInclude Include="wmi\ieventsink.h"> - <Filter>wmi</Filter> - </ClInclude> <ClInclude Include="netsh.h" /> <ClInclude Include="interfaceconfig.h" /> - <ClInclude Include="serialization\deserializer.h"> - <Filter>serialization</Filter> - </ClInclude> - <ClInclude Include="serialization\serializer.h"> - <Filter>serialization</Filter> - </ClInclude> - <ClInclude Include="serialization\typetag.h"> - <Filter>serialization</Filter> - </ClInclude> </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> <ClCompile Include="windns.cpp" /> <ClCompile Include="windnscontext.cpp" /> - <ClCompile Include="wmi\methodcall.cpp"> - <Filter>wmi</Filter> - </ClCompile> - <ClCompile Include="comhelpers.cpp" /> <ClCompile Include="configmanager.cpp" /> <ClCompile Include="consoletracesink.cpp" /> <ClCompile Include="netconfigeventsink.cpp" /> <ClCompile Include="netconfighelpers.cpp" /> - <ClCompile Include="wmi\notification.cpp"> - <Filter>wmi</Filter> - </ClCompile> <ClCompile Include="dnsreverter.cpp" /> - <ClCompile Include="wmi\eventdispatcher.cpp"> - <Filter>wmi</Filter> - </ClCompile> <ClCompile Include="netsh.cpp" /> <ClCompile Include="interfaceconfig.cpp" /> - <ClCompile Include="serialization\deserializer.cpp"> - <Filter>serialization</Filter> - </ClCompile> - <ClCompile Include="serialization\serializer.cpp"> - <Filter>serialization</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <Filter Include="wmi"> - <UniqueIdentifier>{5deb73ee-53cc-49ac-bcdd-0a4b38914f0e}</UniqueIdentifier> - </Filter> - <Filter Include="serialization"> - <UniqueIdentifier>{94b59808-58b6-431c-9b5a-e0bd5315a7af}</UniqueIdentifier> - </Filter> </ItemGroup> </Project>
\ No newline at end of file diff --git a/windows/windns/src/windns/windnscontext.cpp b/windows/windns/src/windns/windnscontext.cpp index efe975e54c..548104ec41 100644 --- a/windows/windns/src/windns/windnscontext.cpp +++ b/windows/windns/src/windns/windnscontext.cpp @@ -1,10 +1,12 @@ #include "stdafx.h" #include "windnscontext.h" -#include "wmi/connection.h" +#include "libcommon/wmi/connection.h" #include "netconfigeventsink.h" #include "netconfighelpers.h" #include "dnsreverter.h" +using namespace common; + WinDnsContext::WinDnsContext() { m_connection = std::make_shared<wmi::Connection>(wmi::Connection::Namespace::Cimv2); diff --git a/windows/windns/src/windns/windnscontext.h b/windows/windns/src/windns/windnscontext.h index 89ff035fa9..c514153edd 100644 --- a/windows/windns/src/windns/windnscontext.h +++ b/windows/windns/src/windns/windnscontext.h @@ -1,8 +1,8 @@ #pragma once #include "windns.h" -#include "wmi/connection.h" -#include "wmi/notification.h" +#include "libcommon/wmi/connection.h" +#include "libcommon/wmi/notification.h" #include "configmanager.h" #include "clientsinkinfo.h" #include <vector> @@ -21,8 +21,8 @@ public: private: - std::shared_ptr<wmi::Connection> m_connection; + std::shared_ptr<common::wmi::Connection> m_connection; std::shared_ptr<ConfigManager> m_configManager; - std::unique_ptr<wmi::Notification> m_notification; + std::unique_ptr<common::wmi::Notification> m_notification; ClientSinkInfo m_sinkInfo; }; diff --git a/windows/windns/src/windns/wmi/connection.cpp b/windows/windns/src/windns/wmi/connection.cpp deleted file mode 100644 index 225586a11d..0000000000 --- a/windows/windns/src/windns/wmi/connection.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "stdafx.h" -#include "connection.h" -#include "windns/comhelpers.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"; - case wmi::Connection::Namespace::StandardCimv2: return L"root\\StandardCIMV2"; - 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); - - if (CO_E_NOTINITIALIZED == status) - { - VALIDATE_COM(CoInitializeEx(nullptr, COINIT_MULTITHREADED), "Initialize COM"); - - 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/windows/windns/src/windns/wmi/connection.h b/windows/windns/src/windns/wmi/connection.h deleted file mode 100644 index 07e5066d1c..0000000000 --- a/windows/windns/src/windns/wmi/connection.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include "iconnection.h" -#include <string> -#define _WIN32_DCOM -#include <windows.h> -#include <atlbase.h> -#include <comutil.h> -#include <comdef.h> - -#pragma comment(lib, "wbemuuid.lib") - -namespace wmi -{ - -class Connection : public IConnection -{ -public: - - enum class Namespace - { - Default, - Cimv2, - StandardCimv2 - }; - - explicit Connection(Namespace ns); - - ResultSet query(const wchar_t *query) override; - - CComPtr<IWbemServices> services() override - { - return m_services; - } - -private: - - CComPtr<IWbemLocator> m_locator; - CComPtr<IWbemServices> m_services; - - _bstr_t m_queryLanguage; -}; - -} diff --git a/windows/windns/src/windns/wmi/eventdispatcher.cpp b/windows/windns/src/windns/wmi/eventdispatcher.cpp deleted file mode 100644 index b92e9766cb..0000000000 --- a/windows/windns/src/windns/wmi/eventdispatcher.cpp +++ /dev/null @@ -1,123 +0,0 @@ -#include "stdafx.h" -#include "eventdispatcher.h" -#include "windns/comhelpers.h" - -namespace wmi -{ - -EventDispatcherBase::EventDispatcherBase() - : m_references(0) - , m_callbacks(0) -{ -} - -bool EventDispatcherBase::processing() const -{ - // - // Cancelling the notification registration WILL NOT wait for the completion of - // callbacks currently in progress :-( - // - // (Observed on Win10) - // - - return 0 != InterlockedAdd(&m_callbacks, 0); -} - -ULONG STDMETHODCALLTYPE EventDispatcherBase::AddRef() -{ - return InterlockedIncrement(&m_references); -} - -ULONG STDMETHODCALLTYPE EventDispatcherBase::Release() -{ - auto refs = InterlockedDecrement(&m_references); - - if (refs == 0) - { - delete this; - } - - return refs; -} - -HRESULT STDMETHODCALLTYPE EventDispatcherBase::QueryInterface(REFIID riid, void **ppv) -{ - if (IID_IUnknown == riid || IID_IWbemObjectSink == riid) - { - *ppv = (IWbemObjectSink *)this; - AddRef(); - - return WBEM_S_NO_ERROR; - } - - return E_NOINTERFACE; -} - -HRESULT STDMETHODCALLTYPE EventDispatcherBase::Indicate -( - LONG numObjects, - IWbemClassObject __RPC_FAR *__RPC_FAR *objects -) -{ - InterlockedIncrement(&m_callbacks); - - try - { - for (LONG i = 0; i < numObjects; ++i) - { - CComPtr<IWbemClassObject> eventRecord(objects[i]); - - dispatch(eventRecord); - } - } - catch (...) - { - // - // There is nowhere to forward this error :-( - // - } - - InterlockedDecrement(&m_callbacks); - - return WBEM_S_NO_ERROR; -} - -HRESULT STDMETHODCALLTYPE EventDispatcherBase::SetStatus -( - LONG, HRESULT, BSTR, IWbemClassObject __RPC_FAR * -) -{ - return WBEM_S_NO_ERROR; -} - -EventDispatcher::EventDispatcher(std::shared_ptr<IEventSink> eventSink) - : m_eventSink(eventSink) -{ -} - -void EventDispatcher::dispatch(CComPtr<IWbemClassObject> eventRecord) -{ - auto rawTarget = ComGetPropertyAlways(eventRecord, L"TargetInstance"); - - CComQIPtr<IWbemClassObject> target(V_UNKNOWN(&rawTarget)); - - m_eventSink->update(target); -} - -ModificationEventDispatcher::ModificationEventDispatcher(std::shared_ptr<IModificationEventSink> eventSink) - : m_eventSink(eventSink) -{ -} - -void ModificationEventDispatcher::dispatch(CComPtr<IWbemClassObject> eventRecord) -{ - auto rawPrevious = ComGetPropertyAlways(eventRecord, L"PreviousInstance"); - auto rawTarget = ComGetPropertyAlways(eventRecord, L"TargetInstance"); - - CComQIPtr<IWbemClassObject> previous(V_UNKNOWN(&rawPrevious)); - CComQIPtr<IWbemClassObject> target(V_UNKNOWN(&rawTarget)); - - m_eventSink->update(previous, target); -} - -} diff --git a/windows/windns/src/windns/wmi/eventdispatcher.h b/windows/windns/src/windns/wmi/eventdispatcher.h deleted file mode 100644 index ec3b01e32a..0000000000 --- a/windows/windns/src/windns/wmi/eventdispatcher.h +++ /dev/null @@ -1,103 +0,0 @@ -#pragma once - -#include "ieventsink.h" -#include <memory> -#include <atlbase.h> -#include <wbemidl.h> - -namespace wmi -{ - -struct IEventDispatcher : public IWbemObjectSink -{ - virtual ~IEventDispatcher() = 0 - { - } - - virtual bool processing() const = 0; -}; - -// -// EventDispatcherBase -// -// Base class for event dispatcher implementations. -// -// The base class has all the logic and COM management but defers actual dispatching -// to the derived class. -// -// From the perspective of COM, this is an event sink, but from the perspective of -// WINDNS code it's a dispatcher that dispatches to the actual sink. -// -class EventDispatcherBase : public IEventDispatcher -{ -public: - - EventDispatcherBase(); - - virtual ~EventDispatcherBase() = 0 - { - } - - bool processing() const override; - - ULONG STDMETHODCALLTYPE AddRef() override; - ULONG STDMETHODCALLTYPE Release() override; - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppv) override; - - HRESULT STDMETHODCALLTYPE Indicate - ( - LONG numObjects, - IWbemClassObject __RPC_FAR *__RPC_FAR *objects - ) - override; - - HRESULT STDMETHODCALLTYPE SetStatus - ( - LONG flags, - HRESULT result, - BSTR param, - IWbemClassObject __RPC_FAR *object - ) - override; - -protected: - - virtual void dispatch(CComPtr<IWbemClassObject> eventRecord) = 0; - -private: - - LONG m_references; - mutable LONG m_callbacks; -}; - -class EventDispatcher : public EventDispatcherBase -{ -public: - - EventDispatcher(std::shared_ptr<IEventSink> eventSink); - -protected: - - void dispatch(CComPtr<IWbemClassObject> eventRecord) override; - -private: - - std::shared_ptr<IEventSink> m_eventSink; -}; - -class ModificationEventDispatcher : public EventDispatcherBase -{ -public: - - ModificationEventDispatcher(std::shared_ptr<IModificationEventSink> eventSink); - -protected: - - void dispatch(CComPtr<IWbemClassObject> eventRecord) override; - -private: - - std::shared_ptr<IModificationEventSink> m_eventSink; -}; - -} diff --git a/windows/windns/src/windns/wmi/iconnection.h b/windows/windns/src/windns/wmi/iconnection.h deleted file mode 100644 index 8683dd6ac5..0000000000 --- a/windows/windns/src/windns/wmi/iconnection.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "resultset.h" -#include <atlbase.h> -#include <wbemidl.h> - -namespace wmi -{ - -struct IConnection -{ - virtual ~IConnection() = 0 - { - } - - virtual ResultSet query(const wchar_t *query) = 0; - virtual CComPtr<IWbemServices> services() = 0; -}; - -} diff --git a/windows/windns/src/windns/wmi/ieventsink.h b/windows/windns/src/windns/wmi/ieventsink.h deleted file mode 100644 index c8c6c01cea..0000000000 --- a/windows/windns/src/windns/wmi/ieventsink.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include <atlbase.h> -#include <wbemidl.h> - -namespace wmi -{ - -// -// IEventSink, use with: -// -// __InstanceCreationEvent -// __InstanceDeletionEvent -// -struct IEventSink -{ - virtual ~IEventSink() = 0 - { - } - - virtual void update(CComPtr<IWbemClassObject> instance) = 0; -}; - -// -// IModificationEventSink, use with: -// -// __InstanceModificationEvent -// -struct IModificationEventSink -{ - virtual ~IModificationEventSink() = 0 - { - } - - virtual void update(CComPtr<IWbemClassObject> previous, CComPtr<IWbemClassObject> target) = 0; -}; - -} diff --git a/windows/windns/src/windns/wmi/methodcall.cpp b/windows/windns/src/windns/wmi/methodcall.cpp deleted file mode 100644 index fcd4f738c8..0000000000 --- a/windows/windns/src/windns/wmi/methodcall.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include "stdafx.h" -#include "methodcall.h" -#include "windns/comhelpers.h" -#include <algorithm> - -namespace wmi -{ - -void MethodCall::addArgument(const std::wstring &name, _variant_t value) -{ - m_arguments.emplace_back(Argument(name, value)); -} - -void MethodCall::addNullArgument(const std::wstring &name, CIMTYPE type) -{ - m_arguments.emplace_back(Argument(name, type)); -} - -_variant_t MethodCall::invoke(IConnection &connection, CComPtr<IWbemClassObject> instance, const std::wstring &methodName) -{ - std::for_each(m_arguments.begin(), m_arguments.end(), [&](const Argument &arg) - { - HRESULT status; - - if (arg.nullValue()) - { - status = instance->Put(arg.name().c_str(), 0, nullptr, arg.type()); - } - else - { - _variant_t &value = const_cast<variant_t &>(arg.value()); - - status = instance->Put(arg.name().c_str(), 0, &value, 0); - } - - VALIDATE_COM(status, "Register COM method argument"); - }); - - _variant_t path; - - auto status = instance->Get(_bstr_t(L"__PATH"), 0, &path, nullptr, nullptr); - - VALIDATE_COM(status, "Get COM instance path"); - - CComPtr<IWbemClassObject> result; - - status = connection.services()->ExecMethod(V_BSTR(&path), _bstr_t(methodName.c_str()), 0, nullptr, instance, &result, nullptr); - - VALIDATE_COM(status, "Execute COM method call"); - - return ComGetProperty(result, L"ReturnValue"); -} - - -// -// the following code is almost what is needed for static method calls -// just remove the path and the in-arg instance -// also, update first arg to ExecMethod -// -//_variant_t MethodCall::call(Connection &connection, CComPtr<IWbemClassObject> instance, const std::wstring &methodName) -//{ -// CComPtr<IWbemClassObject> cls; -// -// auto status = connection.m_services->GetObject(_bstr_t(L"Win32_NetworkAdapterConfiguration"), 0, nullptr, &cls, nullptr); -// VALIDATE_COM(status, "Resolve COM class"); -// -// CComPtr<IWbemClassObject> methodDefinition; -// -// status = cls->GetMethod(methodName.c_str(), 0, &methodDefinition, nullptr); -// VALIDATE_COM(status, "Resolve COM instance method"); -// -// CComPtr<IWbemClassObject> methodInstance; -// -// status = methodDefinition->SpawnInstance(0, &methodInstance); -// VALIDATE_COM(status, "Instantiate COM class for method call"); -// -// std::for_each(m_arguments.begin(), m_arguments.end(), [&](const Argument &arg) -// { -// _variant_t value(arg.value); -// -// // This works for all values except NULL -// auto hr = methodInstance->Put(arg.name.c_str(), 0, &value, 0); -// -// VALIDATE_COM(hr, "Register COM method argument"); -// }); -// -// _variant_t path; -// -// status = instance->Get(_bstr_t(L"__PATH"), 0, &path, nullptr, nullptr); -// VALIDATE_COM(status, "Get COM instance path"); -// -// CComPtr<IWbemClassObject> result; -// -// status = connection.m_services->ExecMethod(path.bstrVal, _bstr_t(methodName.c_str()), 0, nullptr, methodInstance, &result, nullptr/*?*/); -// VALIDATE_COM(status, "Execute COM method call"); -// -// return ComGetProperty(result, L"ReturnValue"); -//} -// - - - - -} diff --git a/windows/windns/src/windns/wmi/methodcall.h b/windows/windns/src/windns/wmi/methodcall.h deleted file mode 100644 index 4d964b60db..0000000000 --- a/windows/windns/src/windns/wmi/methodcall.h +++ /dev/null @@ -1,75 +0,0 @@ -#pragma once - -#include "iconnection.h" -#include <string> -#include <vector> -#include <stdexcept> -#include <comutil.h> - -namespace wmi -{ - -class MethodCall -{ -public: - - void addArgument(const std::wstring &name, _variant_t value); - void addNullArgument(const std::wstring &name, CIMTYPE type); - - _variant_t invoke(IConnection &connection, CComPtr<IWbemClassObject> instance, const std::wstring &methodName); - -private: - - class Argument - { - public: - - Argument(const std::wstring &name, _variant_t value) - : m_name(name) - , m_value(value) - { - if (VT_NULL == V_VT(&value) || VT_EMPTY == V_VT(&value)) - { - throw std::runtime_error("Cannot add null-argument without specifying type."); - } - } - - Argument(const std::wstring &name, CIMTYPE type) - : m_name(name) - , m_type(type) - { - } - - bool nullValue() const - { - return VT_EMPTY == V_VT(&m_value); - } - - const std::wstring &name() const - { - return m_name; - } - - const _variant_t &value() const - { - return m_value; - } - - CIMTYPE type() const - { - return m_type; - } - - private: - - std::wstring m_name; - _variant_t m_value; - - // Explicitly specify type when the value is NULL. - CIMTYPE m_type; - }; - - std::vector<Argument> m_arguments; -}; - -} diff --git a/windows/windns/src/windns/wmi/notification.cpp b/windows/windns/src/windns/wmi/notification.cpp deleted file mode 100644 index b78a0aa298..0000000000 --- a/windows/windns/src/windns/wmi/notification.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "stdafx.h" -#include "notification.h" -#include "windns/comhelpers.h" - -namespace wmi -{ - -Notification::Notification(std::shared_ptr<IConnection> connection, CComPtr<IEventDispatcher> dispatcher) - : m_connection(connection) - , m_dispatcher(dispatcher) -{ -} - -Notification::~Notification() -{ - // - // TODO: Revise to avoid exceptions in dtor. - // - deactivate(); -} - -void Notification::activate(const std::wstring &query) -{ - CComPtr<IUnsecuredApartment> apartment; - - auto status = CoCreateInstance(CLSID_UnsecuredApartment, nullptr, CLSCTX_LOCAL_SERVER, IID_IUnsecuredApartment, (void**)&apartment); - VALIDATE_COM(status, "Create unsecured COM apartment"); - - CComPtr<IUnknown> unknownEventSink; - - status = m_dispatcher->QueryInterface(IID_IUnknown, (void**)&unknownEventSink); - VALIDATE_COM(status, "Retrieve IUnkown interface for event sink"); - - CComPtr<IUnknown> unknownForwarder; - - status = apartment->CreateObjectStub(unknownEventSink, &unknownForwarder); - VALIDATE_COM(status, "Create forwarder for event sink"); - - status = unknownForwarder->QueryInterface(IID_IWbemObjectSink, (void**)&m_forwarder); - VALIDATE_COM(status, "Retrieve sink interface on event sink forwarder"); - - status = m_connection->services()->ExecNotificationQueryAsync(_bstr_t("WQL"), _bstr_t(query.c_str()), 0, nullptr, m_forwarder); - VALIDATE_COM(status, "Register notification query with WMI"); -} - -void Notification::deactivate() -{ - if (nullptr == m_forwarder) - { - return; - } - - auto status = m_connection->services()->CancelAsyncCall(m_forwarder); - VALIDATE_COM(status, "Cancel notification query"); - - m_forwarder.Release(); - - // - // This is a hack-solution for a corner case issue. - // - // Since cancelling the notification registration does not wait for in-progress callbacks - // to complete, we have to implement the corresponding logic ourselves. - // - // Using a Sleep() here is preferable to introducing a critical section in the callback. - // - while (m_dispatcher->processing()) - { - Sleep(100); - } -} - -} diff --git a/windows/windns/src/windns/wmi/notification.h b/windows/windns/src/windns/wmi/notification.h deleted file mode 100644 index 8c9a4f2643..0000000000 --- a/windows/windns/src/windns/wmi/notification.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include "iconnection.h" -#include "eventdispatcher.h" -#include <atlbase.h> -#include <memory> - -namespace wmi -{ - -class Notification -{ -public: - - Notification(std::shared_ptr<IConnection> connection, CComPtr<IEventDispatcher> dispatcher); - ~Notification(); - - Notification(const Notification &) = delete; - Notification &operator=(const Notification &) = delete; - Notification(Notification &&) = delete; - Notification &operator=(Notification &&) = delete; - - void activate(const std::wstring &query); - void deactivate(); - -private: - - std::shared_ptr<IConnection> m_connection; - CComPtr<IEventDispatcher> m_dispatcher; - - CComPtr<IWbemObjectSink> m_forwarder; -}; - -} diff --git a/windows/windns/src/windns/wmi/resultset.cpp b/windows/windns/src/windns/wmi/resultset.cpp deleted file mode 100644 index cea147fa76..0000000000 --- a/windows/windns/src/windns/wmi/resultset.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "stdafx.h" -#include "resultset.h" -#include "windns/comhelpers.h" -#include "libcommon/error.h" - -namespace wmi -{ - -ResultSet::ResultSet(CComPtr<IEnumWbemClassObject> rs) : m_resultset(rs) -{ -} - -bool ResultSet::advance() -{ - if (nullptr != m_result) - { - m_result.Release(); - } - - 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; -} - -CComPtr<IWbemClassObject> ResultSet::result() -{ - return m_result; -} - -} diff --git a/windows/windns/src/windns/wmi/resultset.h b/windows/windns/src/windns/wmi/resultset.h deleted file mode 100644 index 6139a6051a..0000000000 --- a/windows/windns/src/windns/wmi/resultset.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include <string> -#include <atlbase.h> -#include <wbemidl.h> - -namespace wmi -{ - -class ResultSet -{ -public: - - ResultSet(CComPtr<IEnumWbemClassObject> rs); - - ResultSet(const ResultSet &) = delete; - ResultSet &operator=(const ResultSet &) = delete; - ResultSet(ResultSet &&) = default; - ResultSet &operator=(ResultSet &&) = default; - - bool advance(); - - CComPtr<IWbemClassObject> result(); - -private: - - CComPtr<IEnumWbemClassObject> m_resultset; - CComPtr<IWbemClassObject> m_result; -}; - -} |
