1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | |
5 | |
6 | #ifndef _H_INTEROPCONVERTER_ |
7 | #define _H_INTEROPCONVERTER_ |
8 | |
9 | #include "debugmacros.h" |
10 | |
11 | |
12 | struct ItfMarshalInfo |
13 | { |
14 | enum ItfMarshalFlags |
15 | { |
16 | ITF_MARSHAL_INSP_ITF = 0x01, // IInspectable-based interface |
17 | ITF_MARSHAL_SUPPRESS_ADDREF = 0x02, |
18 | ITF_MARSHAL_CLASS_IS_HINT = 0x04, |
19 | ITF_MARSHAL_DISP_ITF = 0x08, |
20 | ITF_MARSHAL_USE_BASIC_ITF = 0x10, |
21 | ITF_MARSHAL_WINRT_SCENARIO = 0x20, // WinRT scenario only |
22 | }; |
23 | |
24 | TypeHandle thClass; |
25 | TypeHandle thItf; |
26 | TypeHandle thNativeItf; |
27 | DWORD dwFlags; |
28 | }; |
29 | |
30 | /* |
31 | enum CreationFlags // member of RCW struct |
32 | { |
33 | CF_None = 0x00, |
34 | CF_SupportsIInspectable = 0x01, // the underlying object supports IInspectable |
35 | CF_SuppressAddRef = 0x02, // do not AddRef the underlying interface pointer |
36 | CF_IsWeakReference = 0x04, // mark the RCW as "weak" |
37 | CF_NeedUniqueObject = 0x08, // always create a new RCW/object even if we have one cached already |
38 | CF_DontResolveClass = 0x10, // don't attempt to create a strongly typed RCW |
39 | }; |
40 | */ |
41 | |
42 | |
43 | /* |
44 | 01 REQUIRE_IINSPECTABLE 01 ITF_MARSHAL_INSP_ITF 01 CF_SupportsIInspectable |
45 | 02 SUPPRESS_ADDREF 02 ITF_MARSHAL_SUPPRESS_ADDREF |
46 | 04 CF_IsWeakReference |
47 | 04 CLASS_IS_HINT 04 ITF_MARSHAL_CLASS_IS_HINT |
48 | 08 UNIQUE_OBJECT 08 CF_NeedUniqueObject |
49 | 08 ITF_MARSHAL_DISP_ITF |
50 | 10 IGNORE_WINRT_AND_SKIP_UNBOXING 10 CF_DontResolveClass |
51 | 10 ITF_MARSHAL_USE_BASIC_ITF |
52 | 20 ITF_MARSHAL_WINRT_SCENARIO |
53 | */ |
54 | |
55 | struct ObjFromComIP |
56 | { |
57 | enum flags |
58 | { |
59 | NONE = 0x00, |
60 | REQUIRE_IINSPECTABLE = 0x01, // ITF_MARSHAL_INSP_ITF = 0x01 // CF_SupportsIInspectable = 0x01 |
61 | SUPPRESS_ADDREF = 0x02, // ITF_MARSHAL_SUPPRESS_ADDREF = 0x02 // CF_SuppressAddRef = 0x02 |
62 | CLASS_IS_HINT = 0x04, // ITF_MARSHAL_CLASS_IS_HINT = 0x04 |
63 | UNIQUE_OBJECT = 0x08, // CF_NeedUniqueObject = 0x04 |
64 | IGNORE_WINRT_AND_SKIP_UNBOXING = 0x10, // CF_DontResolveClass = 0x10 |
65 | }; |
66 | |
67 | static flags FromItfMarshalInfoFlags(DWORD dwFlags) |
68 | { |
69 | static_assert_no_msg(((DWORD)CLASS_IS_HINT) == ((DWORD)ItfMarshalInfo::ITF_MARSHAL_CLASS_IS_HINT)); |
70 | static_assert_no_msg(((DWORD)REQUIRE_IINSPECTABLE) == ((DWORD)ItfMarshalInfo::ITF_MARSHAL_INSP_ITF)); |
71 | static_assert_no_msg(((DWORD)SUPPRESS_ADDREF) == ((DWORD)ItfMarshalInfo::ITF_MARSHAL_SUPPRESS_ADDREF)); |
72 | |
73 | DWORD dwResult = (dwFlags & |
74 | (ItfMarshalInfo::ITF_MARSHAL_CLASS_IS_HINT| |
75 | ItfMarshalInfo::ITF_MARSHAL_INSP_ITF| |
76 | ItfMarshalInfo::ITF_MARSHAL_SUPPRESS_ADDREF)); |
77 | return (flags)dwResult; |
78 | } |
79 | }; |
80 | |
81 | inline ObjFromComIP::flags operator|(ObjFromComIP::flags lhs, ObjFromComIP::flags rhs) |
82 | { |
83 | LIMITED_METHOD_CONTRACT; |
84 | return static_cast<ObjFromComIP::flags>(static_cast<DWORD>(lhs) | static_cast<DWORD>(rhs)); |
85 | } |
86 | inline ObjFromComIP::flags operator|=(ObjFromComIP::flags & lhs, ObjFromComIP::flags rhs) |
87 | { |
88 | LIMITED_METHOD_CONTRACT; |
89 | lhs = static_cast<ObjFromComIP::flags>(static_cast<DWORD>(lhs) | static_cast<DWORD>(rhs)); |
90 | return lhs; |
91 | } |
92 | |
93 | |
94 | // |
95 | // THE FOLLOWING ARE THE MAIN APIS USED BY EVERYONE TO CONVERT BETWEEN |
96 | // OBJECTREFs AND COM IPs |
97 | |
98 | #ifdef FEATURE_COMINTEROP |
99 | |
100 | //-------------------------------------------------------------------------------- |
101 | // The type of COM IP to convert the OBJECTREF to. |
102 | enum ComIpType |
103 | { |
104 | ComIpType_None = 0x0, |
105 | ComIpType_Unknown = 0x1, |
106 | ComIpType_Dispatch = 0x2, |
107 | ComIpType_Both = 0x3, |
108 | ComIpType_OuterUnknown = 0x5, |
109 | ComIpType_Inspectable = 0x8, |
110 | }; |
111 | |
112 | |
113 | //-------------------------------------------------------------------------------- |
114 | // IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, ...); |
115 | // Convert ObjectRef to a COM IP, based on MethodTable* pMT. |
116 | IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, BOOL bSecurityCheck = TRUE, BOOL bEnableCustomizedQueryInterface = TRUE); |
117 | |
118 | |
119 | //-------------------------------------------------------------------------------- |
120 | // IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT); |
121 | // Convert ObjectRef to a COM IP of the requested type. |
122 | IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, |
123 | ComIpType ReqIpType = ComIpType_Unknown, ComIpType *pFetchedIpType = NULL); |
124 | |
125 | |
126 | //-------------------------------------------------------------------------------- |
127 | // IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, REFIID iid); |
128 | // Convert ObjectRef to a COM IP, based on riid. |
129 | IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, REFIID iid, bool throwIfNoComIP = true); |
130 | |
131 | |
132 | //-------------------------------------------------------------------------------- |
133 | // GetObjectRefFromComIP(IUnknown **ppUnk, MethodTable *pMTClass, ...) |
134 | // Converts a COM IP to ObjectRef, pMTClass is the desired RCW type. If bSuppressAddRef and a new RCW is created, |
135 | // *ppUnk will be assigned NULL to signal to the caller that it is no longer responsible for releasing the IP. |
136 | void GetObjectRefFromComIP(OBJECTREF* pObjOut, IUnknown **ppUnk, MethodTable *pMTClass, MethodTable *pItfMT, DWORD dwFlags); // ObjFromComIP::flags |
137 | |
138 | //-------------------------------------------------------------------------------- |
139 | // GetObjectRefFromComIP(IUnknown *pUnk, MethodTable *pMTClass, ...) |
140 | // Converts a COM IP to ObjectRef, pMTClass is the desired RCW type. |
141 | inline void GetObjectRefFromComIP(OBJECTREF* pObjOut, IUnknown *pUnk, MethodTable *pMTClass = NULL, MethodTable *pItfMT = NULL, DWORD dwFlags = ObjFromComIP::NONE) |
142 | { |
143 | WRAPPER_NO_CONTRACT; |
144 | return GetObjectRefFromComIP(pObjOut, &pUnk, pMTClass, pItfMT, dwFlags); |
145 | } |
146 | |
147 | |
148 | //-------------------------------------------------------------------------------- |
149 | // UnMarshalObjectForCurrentDomain |
150 | // unmarshal the managed object for the current domain |
151 | BOOL UnMarshalObjectForCurrentDomain(ADID pObjDomain, ComCallWrapper* pWrap, OBJECTREF* pResult); |
152 | |
153 | #endif // FEATURE_COMINTEROP |
154 | |
155 | #endif // #ifndef _H_INTEROPCONVERTER_ |
156 | |