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
12struct 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/*
4401 REQUIRE_IINSPECTABLE 01 ITF_MARSHAL_INSP_ITF 01 CF_SupportsIInspectable
4502 SUPPRESS_ADDREF 02 ITF_MARSHAL_SUPPRESS_ADDREF
46 04 CF_IsWeakReference
4704 CLASS_IS_HINT 04 ITF_MARSHAL_CLASS_IS_HINT
4808 UNIQUE_OBJECT 08 CF_NeedUniqueObject
49 08 ITF_MARSHAL_DISP_ITF
5010 IGNORE_WINRT_AND_SKIP_UNBOXING 10 CF_DontResolveClass
51 10 ITF_MARSHAL_USE_BASIC_ITF
52 20 ITF_MARSHAL_WINRT_SCENARIO
53*/
54
55struct 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
81inline 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}
86inline 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.
102enum 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.
116IUnknown *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.
122IUnknown *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.
129IUnknown *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.
136void 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.
141inline 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
151BOOL UnMarshalObjectForCurrentDomain(ADID pObjDomain, ComCallWrapper* pWrap, OBJECTREF* pResult);
152
153#endif // FEATURE_COMINTEROP
154
155#endif // #ifndef _H_INTEROPCONVERTER_
156