1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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
|