Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix potential type incompatibility for in-proc WinRT components #1610

Merged
merged 4 commits into from
May 14, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions src/WinRT.Runtime/Marshalers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1304,7 +1304,19 @@ public static T FromAbi(IntPtr ptr)
Marshal.QueryInterface(ptr, ref iid_iunknown, out iunknownPtr);
if (IUnknownVftbl.IsReferenceToManagedObject(iunknownPtr))
{
return (T)ComWrappersSupport.FindObject<object>(iunknownPtr);
// We use a global instance of ComWrappers, but it's possible to use different projections of the same type
// when both server and client are managed and in the same process.
// In this case, we need to check if the object is of the same type as the one we're trying to cast to.
// If it's not, we need to create an RCW for the object.
// We cannot use T directly here as it may lead to invalid cast due to the above reason.
if (ComWrappersSupport.FindObject<object>(iunknownPtr) is T obj)
{
return obj;
}
else
{
return ComWrappersSupport.CreateRcwForComObject<T>(ptr);
}
}
else
{
Expand Down Expand Up @@ -1414,7 +1426,19 @@ public static T FromAbi<T>(IntPtr nativeDelegate)
}
else if (IUnknownVftbl.IsReferenceToManagedObject(nativeDelegate))
{
return ComWrappersSupport.FindObject<T>(nativeDelegate);
// We use a global instance of ComWrappers, but it's possible to use different projections of the same type
// when both server and client are managed and in the same process.
// In this case, we need to check if the object is of the same type as the one we're trying to cast to.
// If it's not, we need to create an RCW for the object.
// We cannot use T directly here as it may lead to invalid cast due to the above reason.
if (ComWrappersSupport.FindObject<object>(nativeDelegate) is T obj)
{
return obj;
}
else
{
return ComWrappersSupport.CreateRcwForComObject<T>(nativeDelegate);
}
}
else
{
Expand Down