Skip to content

Commit

Permalink
__ComObject doesn't support dynamic interface map (#112375)
Browse files Browse the repository at this point in the history
* __ComObject doesn't support dynamic interface map

In #105965, an interface
was added to __ComObject. This made some previous checks
fail as they were written assuming __ComObject didn't have
any interfaces.
  • Loading branch information
AaronRobinsonMSFT authored Feb 12, 2025
1 parent bc72823 commit 07f8ebd
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 4 deletions.
9 changes: 6 additions & 3 deletions src/coreclr/vm/methodtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -1090,9 +1090,12 @@ class MethodTable
{
LIMITED_METHOD_DAC_CONTRACT;

// currently all ComObjects except
// for __ComObject have dynamic Interface maps
return GetNumInterfaces() > 0 && IsComObjectType() && !ParentEquals(g_pObjectClass);
// All ComObjects except for __ComObject
// have dynamic Interface maps
return GetNumInterfaces() > 0
&& IsComObjectType()
&& !ParentEquals(g_pObjectClass)
&& this != g_pBaseCOMObject;
}
#endif // FEATURE_COMINTEROP

Expand Down
11 changes: 11 additions & 0 deletions src/tests/Interop/COM/NETClients/MiscTypes/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ public static int TestEntryPoint()
return 100;
}

private class InterfaceImpl : Server.Contract.IInterface2
{
}

private static void ValidationTests()
{
Console.WriteLine($"Running {nameof(ValidationTests)} ...");
Expand Down Expand Up @@ -209,6 +213,13 @@ private static void ValidationTests()
var expected = new Guid("{8EFAD956-B33D-46CB-90F4-45F55BA68A96}");
Assert.Equal(expected, miscTypeTesting.Marshal_Variant(expected));
}

Console.WriteLine("-- Interfaces...");
{
var interfaceMaybe = miscTypeTesting.Marshal_Interface(new InterfaceImpl());
Assert.True(interfaceMaybe is Server.Contract.IInterface1);
Assert.True(interfaceMaybe is Server.Contract.IInterface2);
}
}

private static void ValidateNegativeTests()
Expand Down
14 changes: 14 additions & 0 deletions src/tests/Interop/COM/NETServer/MiscTypesTesting.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,18 @@ void Server.Contract.IMiscTypesTesting.Marshal_ByRefVariant(ref object result, o
{
result = value;
}

private class InterfaceImpl : Server.Contract.IInterface2
{
}

Server.Contract.IInterface2 Server.Contract.IMiscTypesTesting.Marshal_Interface(object inst)
{
if (inst is not Server.Contract.IInterface2)
{
throw new InvalidCastException();
}

return new InterfaceImpl();
}
}
29 changes: 29 additions & 0 deletions src/tests/Interop/COM/NativeClients/MiscTypes/MiscTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,35 @@ void ValidationTests()
HRESULT hr = miscTypesTesting->Marshal_Variant(args.Input, &args.Result);
THROW_FAIL_IF_FALSE(hr == 0x80131531); // COR_E_INVALIDOLEVARIANTTYPE
}

::printf("-- Interfaces...\n");
{
struct InterfaceImpl : IInterface2
{
STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject) override
{
if (riid == __uuidof(IInterface1) || riid == __uuidof(IInterface2))
{
*ppvObject = static_cast<IInterface2*>(this);
}
else if (riid == __uuidof(IUnknown))
{
*ppvObject = static_cast<IUnknown*>(this);
}
else
{
*ppvObject = nullptr;
return E_NOINTERFACE;
}
return S_OK;
}
STDMETHOD_(ULONG, AddRef)() override { return 1; }
STDMETHOD_(ULONG, Release)() override { return 1; }
} iface{};
ComSmartPtr<IInterface2> result;
HRESULT hr = miscTypesTesting->Marshal_Interface(&iface, &result);
THROW_IF_FAILED(hr);
}
}

void ValidationByRefTests()
Expand Down
32 changes: 31 additions & 1 deletion src/tests/Interop/COM/NativeServer/MiscTypesTesting.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,20 @@

class MiscTypesTesting : public UnknownImpl, public IMiscTypesTesting
{
struct InterfaceImpl : public UnknownImpl, public IInterface2
{
public: // IInterface1
public: // IInterface2
public: // IUnknown
STDMETHOD(QueryInterface)(
/* [in] */ REFIID riid,
/* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject)
{
return DoQueryInterface(riid, ppvObject, static_cast<IInterface1 *>(this), static_cast<IInterface2 *>(this));
}

DEFINE_REF_COUNTING();
};
public: // IMiscTypesTesting
DEF_FUNC(Marshal_Variant)(_In_ VARIANT obj, _Out_ VARIANT* result)
{
Expand All @@ -24,6 +38,22 @@ class MiscTypesTesting : public UnknownImpl, public IMiscTypesTesting
return E_NOTIMPL;
}

DEF_FUNC(Marshal_Interface)(_In_ IUnknown* input, _Outptr_ IInterface2** value)
{
HRESULT hr;

IInterface2* ifaceMaybe = nullptr;
hr = input->QueryInterface(__uuidof(IInterface2), (void**)&ifaceMaybe);
if (FAILED(hr))
return hr;
(void)ifaceMaybe->Release();

InterfaceImpl* inst = new InterfaceImpl();
hr = inst->QueryInterface(__uuidof(IInterface2), (void**)value);
(void)inst->Release();
return hr;
}

public: // IUnknown
STDMETHOD(QueryInterface)(
/* [in] */ REFIID riid,
Expand All @@ -33,4 +63,4 @@ class MiscTypesTesting : public UnknownImpl, public IMiscTypesTesting
}

DEFINE_REF_COUNTING();
};
};
17 changes: 17 additions & 0 deletions src/tests/Interop/COM/ServerContracts/Server.Contracts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,20 @@ string Add_BStr(
void Pass_Through_LCID(out int lcid);
}

[ComVisible(true)]
[Guid("4242A2F9-995D-4302-A722-02058CF58158")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IInterface1
{
}

[ComVisible(true)]
[Guid("7AC820FE-E227-4C4D-A8B0-FCA68C459B43")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IInterface2 : IInterface1
{
}

[ComVisible(true)]
[Guid("7FBB8677-BDD0-4E5A-B38B-CA92A4555466")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
Expand All @@ -195,6 +209,9 @@ public interface IMiscTypesTesting
object Marshal_Instance_Variant([MarshalAs(UnmanagedType.LPWStr)] string init);

void Marshal_ByRefVariant(ref object result, object value);

[return: MarshalAs(UnmanagedType.Interface)]
IInterface2 Marshal_Interface([MarshalAs(UnmanagedType.Interface)] object inst);
}

public struct HResult
Expand Down
14 changes: 14 additions & 0 deletions src/tests/Interop/COM/ServerContracts/Server.Contracts.h
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,16 @@ IStringTesting : IUnknown
/*[out]*/ LCID* outLcid) = 0;
};

struct __declspec(uuid("4242A2F9-995D-4302-A722-02058CF58158"))
IInterface1 : IUnknown
{
};

struct __declspec(uuid("7AC820FE-E227-4C4D-A8B0-FCA68C459B43"))
IInterface2 : public IInterface1
{
};

struct __declspec(uuid("7FBB8677-BDD0-4E5A-B38B-CA92A4555466"))
IMiscTypesTesting : IUnknown
{
Expand All @@ -380,6 +390,10 @@ IMiscTypesTesting : IUnknown
virtual HRESULT STDMETHODCALLTYPE Marshal_ByRefVariant (
/*[inout]*/ VARIANT* result,
/*[in]*/ VARIANT value) = 0;

virtual HRESULT STDMETHODCALLTYPE Marshal_Interface (
/*[in]*/ IUnknown* value,
/*[out,ret]*/ IInterface2** iface) = 0;
};

struct __declspec(uuid("592386a5-6837-444d-9de3-250815d18556"))
Expand Down

0 comments on commit 07f8ebd

Please sign in to comment.