Skip to content

Misinterpretation of VT_INT/UINT in new COM interop #97363

@weltkante

Description

@weltkante

Description

Comments in the new Variant Marshalling code and unit test indicate a misunderstanding of VT_INT/VT_UINT as meaning IntPtr/UIntPtr, however as far as I can tell the actual implementation for unmanaged-to-managed conversions (same file) is correctly implementing it like classic interop as Int32/UInt32. The comment in the Windows headers indicates that this is the int/long difference in C/C++ which both are 32 bit on x64 Windows, unlike in C#, so always treating it as 32 bit should be correct unless you expect compatibility with different ABIs than x86/x64 (for example I don't know what the situation is on ARM64)

For what its worth these types do appear in the typelib of ActiveX controls depending on int vs. long usage, I came across it in the Microsoft RDP Client ActiveX control (mstscax.dll, part of the Windows installation) while doing a proof-of-concept implementation using it in .NET Core. For example in the OnFocusReleased event of the non-dual IDispatch event interface the argument is specified as VT_INT instead of VT_I4 while other events like OnLogonError use long instead of int and have the usual VT_I4. However I haven't yet seen VT_INT passed at runtime during IDispatch event handling, OnFocusReleased seems to get passed VT_I4 instead in my tests.

/cc @jkoritzinsky @AaronRobinsonMSFT

Reproduction Steps

Review of Variant Marshaller implementation and commit #93635

VT_INT appearing in the type library of mstscax.dll from a normal Windows installation

Expected behavior

Unit tests and comments do not misinterpret VT_INT/VT_UINT semantics.

Actual behavior

Comments and unit test in source code indicate an incorrect mapping of VT_INT/VT_UINT.

The practical implementation of unmanaged-to-managed mappings seems to differ from comments and unit tests, so is unlikely to have introduced actual bugs.

Regression?

VT_INT/VT_UINT works in classic COM interop and map to Int32/UInt32

Known Workarounds

not necessary as far as I can tell, worst case a custom marshaller could be used

Configuration

64-bit .NET 9.0.0-alpha.1.23617.4

Other information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions