From dfa343ab7c2ab30e214e9408e914cc62d036d23a Mon Sep 17 00:00:00 2001 From: Konstantin Sharon Date: Tue, 9 Feb 2021 14:50:40 +0200 Subject: [PATCH] Add ContextSwitcher and other IIDs. Fix IContextCallback. --- PInvoke/Ole/Ole32/CtxtCall.cs | 33 ++++++++++++++++++++++- UnitTests/PInvoke/Ole/Ole32/Ole32Tests.cs | 7 +++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/PInvoke/Ole/Ole32/CtxtCall.cs b/PInvoke/Ole/Ole32/CtxtCall.cs index a686c4758..168b2a542 100644 --- a/PInvoke/Ole/Ole32/CtxtCall.cs +++ b/PInvoke/Ole/Ole32/CtxtCall.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Vanara.PInvoke @@ -49,7 +50,12 @@ public interface IContextCallback /// // https://docs.microsoft.com/en-us/windows/win32/api/ctxtcall/nf-ctxtcall-icontextcallback-contextcallback [PreserveSig] - HRESULT ContextCallback(PFNCONTEXTCALL pfnCallback, in ComCallData pParam, in Guid riid, int iMethod, [In, Optional] IntPtr pUnk); + HRESULT ContextCallback( + [MarshalAs(UnmanagedType.FunctionPtr)] PFNCONTEXTCALL pfnCallback, + in ComCallData pParam, + in Guid riid, + int iMethod, + [In, Optional] IntPtr pUnk); } /// @@ -66,5 +72,30 @@ public struct ComCallData /// public IntPtr pUserDefined; } + + /// Provides a mechanism to execute a function inside a specific COM+ object context. + /// An instance of this interface for the current context can be obtained using CoGetObjectContext. + // https://docs.microsoft.com/en-us/windows/win32/api/ctxtcall/nn-ctxtcall-icontextcallback + [ComImport, Guid("0000034e-0000-0000-C000-000000000046"), ClassInterface(ClassInterfaceType.None)] + public class ContextSwitcher : IContextCallback + { + /// + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + public virtual extern HRESULT ContextCallback( + [MarshalAs(UnmanagedType.FunctionPtr)] PFNCONTEXTCALL pfnCallback, + in ComCallData pParam, + in Guid riid, + int iMethod, + IntPtr pUnk = new IntPtr()); + } + + /// CLSID_ContextSwitcher + public static readonly Guid CLSID_ContextSwitcher = new Guid(0x0000034e, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); + + /// IID_IEnterActivityWithNoLock + public static readonly Guid IID_IEnterActivityWithNoLock = new Guid(0xd7174f82, 0x36b8, 0x4aa8, 0x80, 0x0a, 0xe9, 0x63, 0xab, 0x2d, 0xfa, 0xb9); + + /// IID_ICallbackWithNoReentrancyToApplicationSTA + public static readonly Guid IID_ICallbackWithNoReentrancyToApplicationSTA = new Guid(0x0a299774, 0x3e4e, 0xfc42, 0x1d, 0x9d, 0x72, 0xce, 0xe1, 0x05, 0xca, 0x57); } } \ No newline at end of file diff --git a/UnitTests/PInvoke/Ole/Ole32/Ole32Tests.cs b/UnitTests/PInvoke/Ole/Ole32/Ole32Tests.cs index d645272b5..33f59ee01 100644 --- a/UnitTests/PInvoke/Ole/Ole32/Ole32Tests.cs +++ b/UnitTests/PInvoke/Ole/Ole32/Ole32Tests.cs @@ -95,5 +95,12 @@ public void IPropSetStorageTest() Assert.That(prvRead[0].Value, Is.EqualTo("VALUE")); } } + + [Test] + public void ContextSwitcher() + { + Assert.AreEqual(CLSID_ContextSwitcher, typeof(ContextSwitcher).GUID); + IContextCallback contextCallback = new ContextSwitcher(); + } } } \ No newline at end of file