2 * This library is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2.1 of the License, or (at your option) any later version.
7 * This library is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with this library; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 #include "wine/orpc.h"
20 #include "wine/list.h"
22 extern HINSTANCE hProxyDll
;
28 LONG refs
; /* refcount of the apartment (LOCK) */
29 BOOL multi_threaded
; /* multi-threaded or single-threaded apartment? (RO) */
30 DWORD tid
; /* thread id (RO) */
31 OXID oxid
; /* object exporter ID (RO) */
32 LONG ipidc
; /* interface pointer ID counter, starts at 1 (LOCK) */
33 CRITICAL_SECTION cs
; /* thread safety */
34 struct list proxies
; /* imported objects (CS cs) */
35 struct list stubmgrs
; /* stub managers for exported objects (CS cs) */
36 BOOL remunk_exported
; /* has the IRemUnknown interface for this apartment been created yet? (CS cs) */
37 LONG remoting_started
; /* has the RPC system been started for this apartment? (LOCK) */
38 struct list loaded_dlls
; /* list of dlls loaded by this apartment (CS cs) */
39 DWORD host_apt_tid
; /* thread ID of apartment hosting objects of differing threading model (CS cs) */
40 HWND host_apt_hwnd
; /* handle to apartment window of host apartment (CS cs) */
41 struct local_server
*local_server
; /* A marshallable object exposing local servers (CS cs) */
42 BOOL being_destroyed
; /* is currently being destroyed */
44 /* FIXME: OIDs should be given out by RPCSS */
45 OID oidc
; /* object ID counter, starts at 1, zero is invalid OID (CS cs) */
48 HWND win
; /* message window (LOCK) */
49 IMessageFilter
*filter
; /* message filter (CS cs) */
50 BOOL main
; /* is this a main-threaded-apartment? (RO) */
53 struct list usage_cookies
; /* Used for refcount control with CoIncrementMTAUsage()/CoDecrementMTAUsage(). */
56 HRESULT
open_key_for_clsid(REFCLSID clsid
, const WCHAR
*keyname
, REGSAM access
, HKEY
*subkey
) DECLSPEC_HIDDEN
;
57 HRESULT
open_appidkey_from_clsid(REFCLSID clsid
, REGSAM access
, HKEY
*subkey
) DECLSPEC_HIDDEN
;
59 /* DCOM messages used by the apartment window (not compatible with native) */
60 #define DM_EXECUTERPC (WM_USER + 0) /* WPARAM = 0, LPARAM = (struct dispatch_params *) */
61 #define DM_HOSTOBJECT (WM_USER + 1) /* WPARAM = 0, LPARAM = (struct host_object_params *) */
63 #define CHARS_IN_GUID 39
67 OLETLS_UUIDINITIALIZED
= 0x2,
68 OLETLS_DISABLE_OLE1DDE
= 0x40,
69 OLETLS_APARTMENTTHREADED
= 0x80,
70 OLETLS_MULTITHREADED
= 0x100,
73 /* this is what is stored in TEB->ReservedForOle */
76 struct apartment
*apt
;
77 IErrorInfo
*errorinfo
;
78 DWORD thread_seqid
; /* returned with CoGetCurrentProcess */
79 DWORD flags
; /* tlsdata_flags (+0Ch on x86) */
81 DWORD inits
; /* number of times CoInitializeEx called */
82 DWORD ole_inits
; /* number of times OleInitialize called */
83 GUID causality_id
; /* unique identifier for each COM call */
84 LONG pending_call_count_client
; /* number of client calls pending */
85 LONG pending_call_count_server
; /* number of server calls pending */
87 IObjContext
*context_token
; /* (+38h on x86) */
88 IUnknown
*call_state
; /* current call context (+3Ch on x86) */
90 IUnknown
*cancel_object
; /* cancel object set by CoSetCancelObject (+F8h on x86) */
91 IUnknown
*state
; /* see CoSetState */
92 struct list spies
; /* Spies installed with CoRegisterInitializeSpy */
97 extern HRESULT WINAPI
InternalTlsAllocData(struct tlsdata
**data
);
99 static inline HRESULT
com_get_tlsdata(struct tlsdata
**data
)
101 *data
= NtCurrentTeb()->ReservedForOle
;
102 return *data
? S_OK
: InternalTlsAllocData(data
);
105 static inline struct apartment
* com_get_current_apt(void)
107 struct tlsdata
*tlsdata
= NULL
;
108 com_get_tlsdata(&tlsdata
);
112 HWND
apartment_getwindow(const struct apartment
*apt
) DECLSPEC_HIDDEN
;
113 HRESULT
apartment_createwindowifneeded(struct apartment
*apt
) DECLSPEC_HIDDEN
;
114 void apartment_freeunusedlibraries(struct apartment
*apt
, DWORD unload_delay
) DECLSPEC_HIDDEN
;
115 void apartment_global_cleanup(void) DECLSPEC_HIDDEN
;
116 OXID
apartment_getoxid(const struct apartment
*apt
) DECLSPEC_HIDDEN
;
117 HRESULT
apartment_disconnectproxies(struct apartment
*apt
) DECLSPEC_HIDDEN
;
119 /* RpcSs interface */
120 HRESULT
rpcss_get_next_seqid(DWORD
*id
) DECLSPEC_HIDDEN
;
121 HRESULT
rpc_get_local_class_object(REFCLSID rclsid
, REFIID riid
, void **obj
) DECLSPEC_HIDDEN
;
122 HRESULT
rpc_register_local_server(REFCLSID clsid
, IStream
*stream
, DWORD flags
, unsigned int *cookie
) DECLSPEC_HIDDEN
;
123 HRESULT
rpc_revoke_local_server(unsigned int cookie
) DECLSPEC_HIDDEN
;
124 HRESULT
rpc_create_clientchannel(const OXID
*oxid
, const IPID
*ipid
, const OXID_INFO
*oxid_info
, const IID
*iid
,
125 DWORD dest_context
, void *dest_context_data
, IRpcChannelBuffer
**chan
, struct apartment
*apt
) DECLSPEC_HIDDEN
;
126 HRESULT
rpc_create_serverchannel(DWORD dest_context
, void *dest_context_data
, IRpcChannelBuffer
**chan
) DECLSPEC_HIDDEN
;
127 HRESULT
rpc_register_interface(REFIID riid
) DECLSPEC_HIDDEN
;
128 void rpc_unregister_interface(REFIID riid
, BOOL wait
) DECLSPEC_HIDDEN
;
129 HRESULT
rpc_resolve_oxid(OXID oxid
, OXID_INFO
*oxid_info
) DECLSPEC_HIDDEN
;
130 void rpc_start_remoting(struct apartment
*apt
) DECLSPEC_HIDDEN
;
131 HRESULT
rpc_register_channel_hook(REFGUID rguid
, IChannelHook
*hook
) DECLSPEC_HIDDEN
;
132 void rpc_unregister_channel_hooks(void) DECLSPEC_HIDDEN
;
134 struct dispatch_params
;
135 void rpc_execute_call(struct dispatch_params
*params
);
137 enum class_reg_data_origin
143 struct class_reg_data
145 enum class_reg_data_origin origin
;
150 const WCHAR
*module_name
;
151 DWORD threading_model
;
158 HRESULT
enter_apartment(struct tlsdata
*data
, DWORD model
) DECLSPEC_HIDDEN
;
159 void leave_apartment(struct tlsdata
*data
) DECLSPEC_HIDDEN
;
160 void apartment_release(struct apartment
*apt
) DECLSPEC_HIDDEN
;
161 struct apartment
* apartment_get_current_or_mta(void) DECLSPEC_HIDDEN
;
162 HRESULT
apartment_increment_mta_usage(CO_MTA_USAGE_COOKIE
*cookie
) DECLSPEC_HIDDEN
;
163 void apartment_decrement_mta_usage(CO_MTA_USAGE_COOKIE cookie
) DECLSPEC_HIDDEN
;
164 struct apartment
* apartment_get_mta(void) DECLSPEC_HIDDEN
;
165 HRESULT
apartment_get_inproc_class_object(struct apartment
*apt
, const struct class_reg_data
*regdata
,
166 REFCLSID rclsid
, REFIID riid
, DWORD class_context
, void **ppv
) DECLSPEC_HIDDEN
;
167 HRESULT
apartment_get_local_server_stream(struct apartment
*apt
, IStream
**ret
) DECLSPEC_HIDDEN
;
168 IUnknown
*com_get_registered_class_object(const struct apartment
*apartment
, REFCLSID rclsid
,
169 DWORD clscontext
) DECLSPEC_HIDDEN
;
170 void apartment_revoke_all_classes(const struct apartment
*apt
) DECLSPEC_HIDDEN
;
171 struct apartment
* apartment_findfromoxid(OXID oxid
) DECLSPEC_HIDDEN
;
172 struct apartment
* apartment_findfromtid(DWORD tid
) DECLSPEC_HIDDEN
;
174 HRESULT
marshal_object(struct apartment
*apt
, STDOBJREF
*stdobjref
, REFIID riid
, IUnknown
*object
,
175 DWORD dest_context
, void *dest_context_data
, MSHLFLAGS mshlflags
) DECLSPEC_HIDDEN
;
179 /* signal to stub manager that this is a rem unknown object */
180 #define MSHLFLAGSP_REMUNKNOWN 0x80000000
182 /* Thread-safety Annotation Legend:
184 * RO - The value is read only. It never changes after creation, so no
185 * locking is required.
186 * LOCK - The value is written to only using Interlocked* functions.
187 * CS - The value is read or written to inside a critical section.
188 * The identifier following "CS" is the specific critical section that
190 * MUTEX - The value is read or written to with a mutex held.
191 * The identifier following "MUTEX" is the specific mutex that
195 typedef enum ifstub_state
197 STUBSTATE_NORMAL_MARSHALED
,
198 STUBSTATE_NORMAL_UNMARSHALED
,
199 STUBSTATE_TABLE_WEAK_MARSHALED
,
200 STUBSTATE_TABLE_WEAK_UNMARSHALED
,
201 STUBSTATE_TABLE_STRONG
,
204 /* an interface stub */
207 struct list entry
; /* entry in stub_manager->ifstubs list (CS stub_manager->lock) */
208 IRpcStubBuffer
*stubbuffer
; /* RO */
211 IUnknown
*iface
; /* RO */
212 MSHLFLAGS flags
; /* so we can enforce process-local marshalling rules (RO) */
213 IRpcChannelBuffer
*chan
; /* channel passed to IRpcStubBuffer::Invoke (RO) */
216 /* stub managers hold refs on the object and each interface stub */
219 struct list entry
; /* entry in apartment stubmgr list (CS apt->cs) */
220 struct list ifstubs
; /* list of active ifstubs for the object (CS lock) */
221 CRITICAL_SECTION lock
;
222 struct apartment
*apt
; /* owning apt (RO) */
224 ULONG extrefs
; /* number of 'external' references (CS lock) */
225 ULONG refs
; /* internal reference count (CS apt->cs) */
226 ULONG weakrefs
; /* number of weak references (CS lock) */
227 OID oid
; /* apartment-scoped unique identifier (RO) */
228 IUnknown
*object
; /* the object we are managing the stub for (RO) */
229 ULONG next_ipid
; /* currently unused (LOCK) */
230 OXID_INFO oxid_info
; /* string binding, ipid of rem unknown and other information (RO) */
232 IExternalConnection
*extern_conn
;
234 /* We need to keep a count of the outstanding marshals, so we can enforce the
235 * marshalling rules (ie, you can only unmarshal normal marshals once). Note
236 * that these counts do NOT include unmarshalled interfaces, once a stream is
237 * unmarshalled and a proxy set up, this count is decremented.
240 ULONG norm_refs
; /* refcount of normal marshals (CS lock) */
241 BOOL disconnected
; /* CoDisconnectObject has been called (CS lock) */
244 ULONG
stub_manager_int_release(struct stub_manager
*stub_manager
) DECLSPEC_HIDDEN
;
245 struct stub_manager
* get_stub_manager_from_object(struct apartment
*apt
, IUnknown
*object
, BOOL alloc
) DECLSPEC_HIDDEN
;
246 void stub_manager_disconnect(struct stub_manager
*m
) DECLSPEC_HIDDEN
;
247 ULONG
stub_manager_ext_addref(struct stub_manager
*m
, ULONG refs
, BOOL tableweak
) DECLSPEC_HIDDEN
;
248 ULONG
stub_manager_ext_release(struct stub_manager
*m
, ULONG refs
, BOOL tableweak
, BOOL last_unlock_releases
) DECLSPEC_HIDDEN
;
249 struct stub_manager
* get_stub_manager(struct apartment
*apt
, OID oid
) DECLSPEC_HIDDEN
;
250 void stub_manager_release_marshal_data(struct stub_manager
*m
, ULONG refs
, const IPID
*ipid
, BOOL tableweak
) DECLSPEC_HIDDEN
;
251 BOOL
stub_manager_is_table_marshaled(struct stub_manager
*m
, const IPID
*ipid
) DECLSPEC_HIDDEN
;
252 BOOL
stub_manager_notify_unmarshal(struct stub_manager
*m
, const IPID
*ipid
) DECLSPEC_HIDDEN
;
253 struct ifstub
* stub_manager_find_ifstub(struct stub_manager
*m
, REFIID iid
, MSHLFLAGS flags
) DECLSPEC_HIDDEN
;
254 struct ifstub
* stub_manager_new_ifstub(struct stub_manager
*m
, IRpcStubBuffer
*sb
, REFIID iid
, DWORD dest_context
,
255 void *dest_context_data
, MSHLFLAGS flags
) DECLSPEC_HIDDEN
;
256 HRESULT
ipid_get_dispatch_params(const IPID
*ipid
, struct apartment
**stub_apt
,
257 struct stub_manager
**manager
, IRpcStubBuffer
**stub
, IRpcChannelBuffer
**chan
,
258 IID
*iid
, IUnknown
**iface
) DECLSPEC_HIDDEN
;
259 HRESULT
start_apartment_remote_unknown(struct apartment
*apt
) DECLSPEC_HIDDEN
;