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

First stab at ComWrappers usage in the WPF #6606

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

kant2002
Copy link
Contributor

@kant2002 kant2002 commented May 20, 2022

Description

This is minimal change which replace usage built-in COM for IThThreadMgr instance.
Having ComWrappers is important to make #3811 works.

Additionally I remove sharing headers from UnsafeNativeMethodsTextServices.cs since this file used just in WindowsBase.csproj.

Customer Impact

Less chance to have trimming inside WPF

Testing

Manually testing by opening/closing WPF application and doing actions

Risk

Potentially can introduce some new bugs if RCW written incorrectly. Given that I already have some experience making this kind of changes for WinForms I have doubts. I always can try ask @RussKie or @AaronRobinsonMSFT review this as additional safeguard. Hopefully they would agree, and their help is welcome.

Microsoft Reviewers: Open in CodeFlow

This is minimal change which replace usage built-in COM for IThThreadMgr instance.
Having ComWrappers is important to make dotnet#3811 works.
@kant2002 kant2002 requested a review from a team as a code owner May 20, 2022 07:31
@ghost ghost assigned kant2002 May 20, 2022
@ghost ghost added the PR metadata: Label to tag PRs, to facilitate with triage label May 20, 2022
@ghost ghost requested review from dipeshmsft, singhashish-wpf and SamBent May 20, 2022 07:31
@ghost ghost added the Community Contribution A label for all community Contributions label May 20, 2022
@lindexi
Copy link
Contributor

lindexi commented May 20, 2022

Thank you @kant2002

It may fix #6463


public void AdviseKeyEventSink(int clientId, [MarshalAs(UnmanagedType.Interface)] object obj, [MarshalAs(UnmanagedType.Bool)] bool fForeground)
{
IntPtr unknownPtr = Marshal.GetIUnknownForObject(obj);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaking QI.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How it is leaking here? Are you mean in case of any failures inside unmanaged part, we should release unknownPtr ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or do you mean, once we pass COM pointer to unamanged side we can safely release all instances from unmanaged part?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Marshal.GetIUnknownForObject and Marshal.QueryInterface APIs both should perform an AddRef. If the API being called with the IUnknown instances needs to retain ownership it should call its own AddRef. Which means unless it can be confirmed that the calling API takes over ownership of the IUnknown and will call Release it is a leak.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then I would say I take care of issues. At least I think so

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be this?

IntPtr unknownPtr = default;
try
{
    unknownPtr = Marshal.GetIUnknownForObject(obj);
    ....


public void AdviseKeyEventSink(int clientId, [MarshalAs(UnmanagedType.Interface)] object obj, [MarshalAs(UnmanagedType.Bool)] bool fForeground)
{
IntPtr unknownPtr = Marshal.GetIUnknownForObject(obj);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be this?

IntPtr unknownPtr = default;
try
{
    unknownPtr = Marshal.GetIUnknownForObject(obj);
    ....

@DanFTRX
Copy link

DanFTRX commented Feb 22, 2023

Any movement on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Community Contribution A label for all community Contributions PR metadata: Label to tag PRs, to facilitate with triage
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants