summaryrefslogtreecommitdiff
path: root/src/vm/interoputil.inl
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/interoputil.inl')
-rw-r--r--src/vm/interoputil.inl79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/vm/interoputil.inl b/src/vm/interoputil.inl
new file mode 100644
index 0000000000..80cd8f496d
--- /dev/null
+++ b/src/vm/interoputil.inl
@@ -0,0 +1,79 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+//
+#include "comcallablewrapper.h"
+
+#ifndef DACCESS_COMPILE
+inline BOOL ComInterfaceSlotIs(IUnknown* pUnk, int slot, LPVOID pvFunction)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ FORBID_FAULT;
+ MODE_ANY;
+ SO_TOLERANT;
+ PRECONDITION(CheckPointer(pUnk));
+ }
+ CONTRACTL_END;
+
+ LPVOID pvRetVal = (*((LPVOID**)pUnk))[slot];
+
+ return (pvRetVal == (LPVOID)GetEEFuncEntryPoint(pvFunction));
+}
+
+//Helpers
+// Is the tear-off a CLR created tear-off
+inline BOOL IsInProcCCWTearOff(IUnknown* pUnk)
+{
+ WRAPPER_NO_CONTRACT;
+ return ComInterfaceSlotIs(pUnk, 0, Unknown_QueryInterface) ||
+ ComInterfaceSlotIs(pUnk, 0, Unknown_QueryInterface_IErrorInfo) ||
+ ComInterfaceSlotIs(pUnk, 0, Unknown_QueryInterface_ICCW);
+}
+
+// is the tear-off represent one of the standard interfaces such as IProvideClassInfo, IErrorInfo etc.
+inline BOOL IsSimpleTearOff(IUnknown* pUnk)
+{
+ WRAPPER_NO_CONTRACT;
+ return ComInterfaceSlotIs(pUnk, TEAR_OFF_SLOT, TEAR_OFF_SIMPLE);
+}
+
+// Is the tear-off represent the inner unknown or the original unknown for the object
+inline BOOL IsInnerUnknown(IUnknown* pUnk)
+{
+ WRAPPER_NO_CONTRACT;
+ return ComInterfaceSlotIs(pUnk, TEAR_OFF_SLOT, TEAR_OFF_SIMPLE_INNER);
+}
+
+// Is this one of our "standard" ComCallWrappers
+inline BOOL IsStandardTearOff(IUnknown* pUnk)
+{
+ WRAPPER_NO_CONTRACT;
+ return ComInterfaceSlotIs(pUnk, TEAR_OFF_SLOT, TEAR_OFF_STANDARD);
+}
+
+// Convert an IUnknown to CCW, does not handle aggregation and ICustomQI.
+FORCEINLINE ComCallWrapper* MapIUnknownToWrapper(IUnknown* pUnk)
+{
+ CONTRACT (ComCallWrapper*)
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ SO_TOLERANT;
+ PRECONDITION(CheckPointer(pUnk, NULL_OK));
+ }
+ CONTRACT_END;
+
+ if (IsStandardTearOff(pUnk))
+ RETURN ComCallWrapper::GetWrapperFromIP(pUnk);
+
+ if (IsSimpleTearOff(pUnk) || IsInnerUnknown(pUnk))
+ RETURN SimpleComCallWrapper::GetWrapperFromIP(pUnk)->GetMainWrapper();
+
+ RETURN NULL;
+}
+#endif // !DACCESS_COMPILE