diff --git a/natvis/cppwinrt.natvis b/natvis/cppwinrt.natvis
index 168b5542e..7fad2e26c 100644
--- a/natvis/cppwinrt.natvis
+++ b/natvis/cppwinrt.natvis
@@ -14,6 +14,11 @@
null
+
+
+
+ null
+
diff --git a/natvis/cppwinrt_visualizer.cpp b/natvis/cppwinrt_visualizer.cpp
index 1e2539910..b44be1268 100644
--- a/natvis/cppwinrt_visualizer.cpp
+++ b/natvis/cppwinrt_visualizer.cpp
@@ -207,21 +207,26 @@ HRESULT cppwinrt_visualizer::EvaluateVisualizedExpression(
IF_FAIL_RET(pTypeSymbol->get_name(&bstrTypeName));
// Visualize top-level C++/WinRT objects containing ABI pointers
- bool isAbiObject;
+ ObjectType objectType;
if (wcscmp(bstrTypeName, L"winrt::Windows::Foundation::IInspectable") == 0)
{
- isAbiObject = false;
+ objectType = ObjectType::Projection;
}
// Visualize nested object properties via raw ABI pointers
else if ((wcscmp(bstrTypeName, L"winrt::impl::IInspectable") == 0) ||
(wcscmp(bstrTypeName, L"winrt::impl::inspectable_abi") == 0))
{
- isAbiObject = true;
+ objectType = ObjectType::Abi;
+ }
+ // Visualize C++/WinRT object implementations
+ else if (wcsncmp(bstrTypeName, L"winrt::impl::producer<", wcslen(L"winrt::impl::producer<")) == 0)
+ {
+ objectType = ObjectType::Abi;
}
// Visualize all raw IInspectable pointers
else if (wcscmp(bstrTypeName, L"IInspectable") == 0)
{
- isAbiObject = true;
+ objectType = ObjectType::Abi;
}
else
{
@@ -231,7 +236,7 @@ HRESULT cppwinrt_visualizer::EvaluateVisualizedExpression(
return S_OK;
}
- IF_FAIL_RET(object_visualizer::CreateEvaluationResult(pVisualizedExpression, isAbiObject, ppResultObject));
+ IF_FAIL_RET(object_visualizer::CreateEvaluationResult(pVisualizedExpression, objectType, ppResultObject));
return S_OK;
}
diff --git a/natvis/object_visualizer.cpp b/natvis/object_visualizer.cpp
index 4b1f7efd5..8bcb86877 100644
--- a/natvis/object_visualizer.cpp
+++ b/natvis/object_visualizer.cpp
@@ -99,14 +99,14 @@ static HRESULT EvaluatePropertyExpression(
_In_ PropertyData const& prop,
_In_ DkmVisualizedExpression* pExpression,
_In_ DkmPointerValueHome* pObject,
- bool isAbiObject,
+ ObjectType objectType,
_Out_ com_ptr& pEvaluationResult
)
{
wchar_t abiAddress[40];
auto process = pExpression->RuntimeInstance()->Process();
bool is64Bit = ((process->SystemInformation()->Flags() & DefaultPort::DkmSystemInformationFlags::Is64Bit) != 0);
- swprintf_s(abiAddress, is64Bit ? L"%s0x%I64x" : L"%s0x%08x", isAbiObject ? L"(::IUnknown*)" : L"*(::IUnknown**)", pObject->Address());
+ swprintf_s(abiAddress, is64Bit ? L"%s0x%I64x" : L"%s0x%08x", objectType == ObjectType::Abi ? L"(::IUnknown*)" : L"*(::IUnknown**)", pObject->Address());
wchar_t wszEvalText[500];
std::wstring propCast;
PCWSTR propField;
@@ -174,12 +174,12 @@ static HRESULT EvaluatePropertyString(
_In_ PropertyData const& prop,
_In_ DkmVisualizedExpression* pExpression,
_In_ DkmPointerValueHome* pObject,
- bool isAbiObject,
+ ObjectType objectType,
_Out_ com_ptr& pValue
)
{
com_ptr pEvaluationResult;
- IF_FAIL_RET(EvaluatePropertyExpression(prop, pExpression, pObject, isAbiObject, pEvaluationResult));
+ IF_FAIL_RET(EvaluatePropertyExpression(prop, pExpression, pObject, objectType, pEvaluationResult));
if (pEvaluationResult->TagValue() != DkmEvaluationResult::Tag::SuccessResult)
{
return E_FAIL;
@@ -195,11 +195,11 @@ static HRESULT EvaluatePropertyString(
static std::string GetRuntimeClass(
_In_ DkmVisualizedExpression* pExpression,
_In_ DkmPointerValueHome* pObject,
- bool isAbiObject
+ ObjectType objectType
)
{
com_ptr pValue;
- EvaluatePropertyString({ IID_IInspectable, -2, PropertyCategory::String }, pExpression, pObject, isAbiObject, pValue);
+ EvaluatePropertyString({ IID_IInspectable, -2, PropertyCategory::String }, pExpression, pObject, objectType, pValue);
if (!pValue || pValue->Length() == 0)
{
return "";
@@ -210,16 +210,11 @@ static std::string GetRuntimeClass(
static HRESULT ObjectToString(
_In_ DkmVisualizedExpression* pExpression,
_In_ DkmPointerValueHome* pObject,
- bool isAbiObject,
- _Out_ com_ptr& pValue,
- bool* unavailable = nullptr
+ ObjectType objectType,
+ _Out_ com_ptr& pValue
)
{
- if (unavailable)
- {
- *unavailable = false;
- }
- if (SUCCEEDED(EvaluatePropertyString({ IID_IStringable, 0, PropertyCategory::String }, pExpression, pObject, isAbiObject, pValue)))
+ if (SUCCEEDED(EvaluatePropertyString({ IID_IStringable, 0, PropertyCategory::String }, pExpression, pObject, objectType, pValue)))
{
if (pValue && pValue->Length() > 0)
{
@@ -229,7 +224,7 @@ static HRESULT ObjectToString(
// WINRT_abi_val returned 0, which may be success or failure (due to VirtualQuery validation)
// Call back for the runtime class name to determine which it was
- if (!GetRuntimeClass(pExpression, pObject, isAbiObject).empty())
+ if (!GetRuntimeClass(pExpression, pObject, objectType).empty())
{
return DkmString::Create(L"", pValue.put());
}
@@ -237,17 +232,13 @@ static HRESULT ObjectToString(
// VirtualQuery validation failed (as determined by no runtime class name) or an
// exception escaped WINRT_abi_val (e.g, bad pointer, which we try to avoid via VirtualQuery)
- if (unavailable)
- {
- *unavailable = true;
- }
return DkmString::Create(L"