summaryrefslogtreecommitdiff
path: root/src/vm/interopconverter.h
blob: 21368dd8a3ede531362e8d22f6ddbeadc8e39fc9 (plain)
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// 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.


#ifndef _H_INTEROPCONVERTER_
#define _H_INTEROPCONVERTER_

#include "debugmacros.h"


struct ItfMarshalInfo
{
    enum ItfMarshalFlags
    {
        ITF_MARSHAL_INSP_ITF        = 0x01,  // IInspectable-based interface
        ITF_MARSHAL_SUPPRESS_ADDREF = 0x02,
        ITF_MARSHAL_CLASS_IS_HINT   = 0x04,
        ITF_MARSHAL_DISP_ITF        = 0x08,
        ITF_MARSHAL_USE_BASIC_ITF   = 0x10,
        ITF_MARSHAL_WINRT_SCENARIO  = 0x20,  // WinRT scenario only
    };
    
    TypeHandle      thClass;
    TypeHandle      thItf;
    TypeHandle      thNativeItf;
    DWORD           dwFlags;
};

/*
    enum CreationFlags  // member of RCW struct
    {
        CF_None                 = 0x00,
        CF_SupportsIInspectable = 0x01, // the underlying object supports IInspectable
        CF_SuppressAddRef       = 0x02, // do not AddRef the underlying interface pointer
        CF_IsWeakReference      = 0x04, // mark the RCW as "weak"
        CF_NeedUniqueObject     = 0x08, // always create a new RCW/object even if we have one cached already
        CF_DontResolveClass     = 0x10, // don't attempt to create a strongly typed RCW
    };
*/


/*
01 REQUIRE_IINSPECTABLE         01 ITF_MARSHAL_INSP_ITF         01 CF_SupportsIInspectable 
02 SUPPRESS_ADDREF              02 ITF_MARSHAL_SUPPRESS_ADDREF  
                                                                04 CF_IsWeakReference      
04 CLASS_IS_HINT                04 ITF_MARSHAL_CLASS_IS_HINT
08 UNIQUE_OBJECT                                                08 CF_NeedUniqueObject
                                08 ITF_MARSHAL_DISP_ITF
10 IGNORE_WINRT_AND_SKIP_UNBOXING                               10 CF_DontResolveClass
                                10 ITF_MARSHAL_USE_BASIC_ITF
                                20 ITF_MARSHAL_WINRT_SCENARIO
*/

struct ObjFromComIP
{
    enum flags
    {
        NONE                            = 0x00,
        REQUIRE_IINSPECTABLE            = 0x01, // ITF_MARSHAL_INSP_ITF        = 0x01   // CF_SupportsIInspectable  = 0x01
        SUPPRESS_ADDREF                 = 0x02, // ITF_MARSHAL_SUPPRESS_ADDREF = 0x02   // CF_SuppressAddRef        = 0x02
        CLASS_IS_HINT                   = 0x04, // ITF_MARSHAL_CLASS_IS_HINT   = 0x04
        UNIQUE_OBJECT                   = 0x08,                                         // CF_NeedUniqueObject      = 0x04
        IGNORE_WINRT_AND_SKIP_UNBOXING  = 0x10,                                         // CF_DontResolveClass      = 0x10
    };

    static flags FromItfMarshalInfoFlags(DWORD dwFlags)
    {
        static_assert_no_msg(((DWORD)CLASS_IS_HINT)         == ((DWORD)ItfMarshalInfo::ITF_MARSHAL_CLASS_IS_HINT));
        static_assert_no_msg(((DWORD)REQUIRE_IINSPECTABLE)  == ((DWORD)ItfMarshalInfo::ITF_MARSHAL_INSP_ITF));
        static_assert_no_msg(((DWORD)SUPPRESS_ADDREF)       == ((DWORD)ItfMarshalInfo::ITF_MARSHAL_SUPPRESS_ADDREF));

        DWORD dwResult = (dwFlags & 
                            (ItfMarshalInfo::ITF_MARSHAL_CLASS_IS_HINT|
                             ItfMarshalInfo::ITF_MARSHAL_INSP_ITF|
                             ItfMarshalInfo::ITF_MARSHAL_SUPPRESS_ADDREF));
        return (flags)dwResult;
    }
};

inline ObjFromComIP::flags operator|(ObjFromComIP::flags lhs, ObjFromComIP::flags rhs)
{
    LIMITED_METHOD_CONTRACT;
    return static_cast<ObjFromComIP::flags>(static_cast<DWORD>(lhs) | static_cast<DWORD>(rhs));
}
inline ObjFromComIP::flags operator|=(ObjFromComIP::flags & lhs, ObjFromComIP::flags rhs)
{
    LIMITED_METHOD_CONTRACT;
    lhs = static_cast<ObjFromComIP::flags>(static_cast<DWORD>(lhs) | static_cast<DWORD>(rhs));
    return lhs;
}


//
// THE FOLLOWING ARE THE MAIN APIS USED BY EVERYONE TO CONVERT BETWEEN
// OBJECTREFs AND COM IPs

#ifdef FEATURE_COMINTEROP

//--------------------------------------------------------------------------------
// The type of COM IP to convert the OBJECTREF to.
enum ComIpType
{
    ComIpType_None          = 0x0,
    ComIpType_Unknown       = 0x1,
    ComIpType_Dispatch      = 0x2,
    ComIpType_Both          = 0x3,
    ComIpType_OuterUnknown  = 0x5,
    ComIpType_Inspectable   = 0x8,
};


//--------------------------------------------------------------------------------
// GetIUnknownForMarshalByRefInServerDomain
// setup a CCW for Transparent proxy/marshalbyref in the server domain
// either the object is in-proc & the domains match, or its out-of proc
// and we don't care about appdomains
IUnknown* GetIUnknownForMarshalByRefInServerDomain(OBJECTREF* poref);

//--------------------------------------------------------------------------------
// GetIUnknownForTransparentProxy
// delegates the call to the managed implementation in the real proxy

IUnknown* GetIUnknownForTransparentProxy(OBJECTREF* poref, BOOL fIsBeingMarshalled);

//--------------------------------------------------------------------------------
// IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, ...);
// Convert ObjectRef to a COM IP, based on MethodTable* pMT.
IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, BOOL bSecurityCheck = TRUE, BOOL bEnableCustomizedQueryInterface = TRUE);


//--------------------------------------------------------------------------------
// IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT);
// Convert ObjectRef to a COM IP of the requested type.
IUnknown *GetComIPFromObjectRef(OBJECTREF *poref,
    ComIpType ReqIpType = ComIpType_Unknown, ComIpType *pFetchedIpType = NULL);


//--------------------------------------------------------------------------------
// IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, REFIID iid);
// Convert ObjectRef to a COM IP, based on riid.
IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, REFIID iid, bool throwIfNoComIP = true);


//--------------------------------------------------------------------------------
// GetObjectRefFromComIP(IUnknown **ppUnk, MethodTable *pMTClass, ...)
// Converts a COM IP to ObjectRef, pMTClass is the desired RCW type. If bSuppressAddRef and a new RCW is created,
// *ppUnk will be assigned NULL to signal to the caller that it is no longer responsible for releasing the IP.
void GetObjectRefFromComIP(OBJECTREF* pObjOut, IUnknown **ppUnk, MethodTable *pMTClass, MethodTable *pItfMT, DWORD dwFlags); // ObjFromComIP::flags

//--------------------------------------------------------------------------------
// GetObjectRefFromComIP(IUnknown *pUnk, MethodTable *pMTClass, ...)
// Converts a COM IP to ObjectRef, pMTClass is the desired RCW type.
inline void GetObjectRefFromComIP(OBJECTREF* pObjOut, IUnknown *pUnk, MethodTable *pMTClass = NULL, MethodTable *pItfMT = NULL, DWORD dwFlags = ObjFromComIP::NONE)
{
    WRAPPER_NO_CONTRACT;
    return GetObjectRefFromComIP(pObjOut, &pUnk, pMTClass, pItfMT, dwFlags);
}


//--------------------------------------------------------------------------------
// UnMarshalObjectForCurrentDomain
// unmarshal the managed object for the current domain
BOOL UnMarshalObjectForCurrentDomain(ADID pObjDomain, ComCallWrapper* pWrap, OBJECTREF* pResult);

#endif // FEATURE_COMINTEROP

#endif // #ifndef _H_INTEROPCONVERTER_