ReactOS 0.4.16-dev-2320-ge1853c6
combase_private.h File Reference
#include "winternl.h"
#include "wine/orpc.h"
#include "wine/list.h"
Include dependency graph for combase_private.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  apartment
 
struct  tlsdata
 
struct  class_reg_data
 
struct  ifstub
 
struct  stub_manager
 

Macros

#define DM_EXECUTERPC   (WM_USER + 0) /* WPARAM = 0, LPARAM = (struct dispatch_params *) */
 
#define DM_HOSTOBJECT   (WM_USER + 1) /* WPARAM = 0, LPARAM = (struct host_object_params *) */
 
#define CHARS_IN_GUID   39
 
#define MSHLFLAGSP_REMUNKNOWN   0x80000000
 

Typedefs

typedef enum ifstub_state STUB_STATE
 

Enumerations

enum  tlsdata_flags { OLETLS_UUIDINITIALIZED = 0x2 , OLETLS_DISABLE_OLE1DDE = 0x40 , OLETLS_APARTMENTTHREADED = 0x80 , OLETLS_MULTITHREADED = 0x100 }
 
enum  class_reg_data_origin { CLASS_REG_ACTCTX , CLASS_REG_REGISTRY , CLASS_REG_ACTCTX , CLASS_REG_REGISTRY }
 
enum  ifstub_state {
  STUBSTATE_NORMAL_MARSHALED , STUBSTATE_NORMAL_UNMARSHALED , STUBSTATE_TABLE_WEAK_MARSHALED , STUBSTATE_TABLE_WEAK_UNMARSHALED ,
  STUBSTATE_TABLE_STRONG
}
 

Functions

HRESULT open_key_for_clsid (REFCLSID clsid, const WCHAR *keyname, REGSAM access, HKEY *subkey)
 
HRESULT open_appidkey_from_clsid (REFCLSID clsid, REGSAM access, HKEY *subkey)
 
HRESULT WINAPI InternalTlsAllocData (struct tlsdata **data)
 
BOOL WINAPI InternalIsProcessInitialized (void)
 
static HRESULT com_get_tlsdata (struct tlsdata **data)
 
static struct apartmentcom_get_current_apt (void)
 
HWND apartment_getwindow (const struct apartment *apt)
 
HRESULT apartment_createwindowifneeded (struct apartment *apt)
 
void apartment_freeunusedlibraries (struct apartment *apt, DWORD unload_delay)
 
void apartment_global_cleanup (void)
 
OXID apartment_getoxid (const struct apartment *apt)
 
HRESULT apartment_disconnectproxies (struct apartment *apt)
 
HRESULT rpcss_get_next_seqid (DWORD *id)
 
HRESULT rpc_get_local_class_object (REFCLSID rclsid, REFIID riid, void **obj)
 
HRESULT rpc_register_local_server (REFCLSID clsid, IStream *stream, DWORD flags, unsigned int *cookie)
 
HRESULT rpc_revoke_local_server (unsigned int cookie)
 
HRESULT rpc_create_clientchannel (const OXID *oxid, const IPID *ipid, const OXID_INFO *oxid_info, const IID *iid, DWORD dest_context, void *dest_context_data, IRpcChannelBuffer **chan, struct apartment *apt)
 
HRESULT rpc_create_serverchannel (DWORD dest_context, void *dest_context_data, IRpcChannelBuffer **chan)
 
HRESULT rpc_register_interface (REFIID riid)
 
void rpc_unregister_interface (REFIID riid, BOOL wait)
 
HRESULT rpc_resolve_oxid (OXID oxid, OXID_INFO *oxid_info)
 
void rpc_start_remoting (struct apartment *apt)
 
HRESULT rpc_register_channel_hook (REFGUID rguid, IChannelHook *hook)
 
void rpc_unregister_channel_hooks (void)
 
void rpc_execute_call (struct dispatch_params *params)
 
HRESULT enter_apartment (struct tlsdata *data, DWORD model)
 
void leave_apartment (struct tlsdata *data)
 
void apartment_release (struct apartment *apt)
 
struct apartmentapartment_get_current_or_mta (void)
 
HRESULT apartment_increment_mta_usage (CO_MTA_USAGE_COOKIE *cookie)
 
void apartment_decrement_mta_usage (CO_MTA_USAGE_COOKIE cookie)
 
HRESULT ensure_mta (void)
 
struct apartmentapartment_get_mta (void)
 
HRESULT apartment_get_inproc_class_object (struct apartment *apt, const struct class_reg_data *regdata, REFCLSID rclsid, REFIID riid, DWORD class_context, void **ppv)
 
HRESULT apartment_get_local_server_stream (struct apartment *apt, IStream **ret)
 
IUnknowncom_get_registered_class_object (const struct apartment *apartment, REFCLSID rclsid, DWORD clscontext)
 
void apartment_revoke_all_classes (const struct apartment *apt)
 
struct apartmentapartment_findfromoxid (OXID oxid)
 
struct apartmentapartment_findfromtid (DWORD tid)
 
HRESULT marshal_object (struct apartment *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *object, DWORD dest_context, void *dest_context_data, MSHLFLAGS mshlflags)
 
ULONG stub_manager_int_release (struct stub_manager *stub_manager)
 
struct stub_managerget_stub_manager_from_object (struct apartment *apt, IUnknown *object, BOOL alloc)
 
void stub_manager_disconnect (struct stub_manager *m)
 
ULONG stub_manager_ext_addref (struct stub_manager *m, ULONG refs, BOOL tableweak)
 
ULONG stub_manager_ext_release (struct stub_manager *m, ULONG refs, BOOL tableweak, BOOL last_unlock_releases)
 
struct stub_managerget_stub_manager (struct apartment *apt, OID oid)
 
void stub_manager_release_marshal_data (struct stub_manager *m, ULONG refs, const IPID *ipid, BOOL tableweak)
 
BOOL stub_manager_is_table_marshaled (struct stub_manager *m, const IPID *ipid)
 
BOOL stub_manager_notify_unmarshal (struct stub_manager *m, const IPID *ipid)
 
struct ifstubstub_manager_find_ifstub (struct stub_manager *m, REFIID iid, MSHLFLAGS flags)
 
struct ifstubstub_manager_new_ifstub (struct stub_manager *m, IRpcStubBuffer *sb, REFIID iid, DWORD dest_context, void *dest_context_data, MSHLFLAGS flags)
 
HRESULT ipid_get_dispatch_params (const IPID *ipid, struct apartment **stub_apt, struct stub_manager **manager, IRpcStubBuffer **stub, IRpcChannelBuffer **chan, IID *iid, IUnknown **iface)
 
HRESULT ipid_get_dest_context (const IPID *ipid, MSHCTX *dest_context, void **dest_context_data)
 
HRESULT start_apartment_remote_unknown (struct apartment *apt)
 

Variables

HINSTANCE hProxyDll
 

Macro Definition Documentation

◆ CHARS_IN_GUID

#define CHARS_IN_GUID   39

Definition at line 63 of file combase_private.h.

◆ DM_EXECUTERPC

#define DM_EXECUTERPC   (WM_USER + 0) /* WPARAM = 0, LPARAM = (struct dispatch_params *) */

Definition at line 60 of file combase_private.h.

◆ DM_HOSTOBJECT

#define DM_HOSTOBJECT   (WM_USER + 1) /* WPARAM = 0, LPARAM = (struct host_object_params *) */

Definition at line 61 of file combase_private.h.

◆ MSHLFLAGSP_REMUNKNOWN

#define MSHLFLAGSP_REMUNKNOWN   0x80000000

Definition at line 183 of file combase_private.h.

Typedef Documentation

◆ STUB_STATE

Enumeration Type Documentation

◆ class_reg_data_origin

Enumerator
CLASS_REG_ACTCTX 
CLASS_REG_REGISTRY 
CLASS_REG_ACTCTX 
CLASS_REG_REGISTRY 

Definition at line 139 of file combase_private.h.

140{
143};
@ CLASS_REG_REGISTRY
@ CLASS_REG_ACTCTX

◆ ifstub_state

Enumerator
STUBSTATE_NORMAL_MARSHALED 
STUBSTATE_NORMAL_UNMARSHALED 
STUBSTATE_TABLE_WEAK_MARSHALED 
STUBSTATE_TABLE_WEAK_UNMARSHALED 
STUBSTATE_TABLE_STRONG 

Definition at line 198 of file combase_private.h.

199{
205} STUB_STATE;
@ STUBSTATE_NORMAL_MARSHALED
@ STUBSTATE_TABLE_WEAK_MARSHALED
@ STUBSTATE_NORMAL_UNMARSHALED
@ STUBSTATE_TABLE_STRONG
@ STUBSTATE_TABLE_WEAK_UNMARSHALED
enum ifstub_state STUB_STATE

◆ tlsdata_flags

Enumerator
OLETLS_UUIDINITIALIZED 
OLETLS_DISABLE_OLE1DDE 
OLETLS_APARTMENTTHREADED 
OLETLS_MULTITHREADED 

Definition at line 65 of file combase_private.h.

66{
71};
@ OLETLS_DISABLE_OLE1DDE
@ OLETLS_APARTMENTTHREADED
@ OLETLS_MULTITHREADED
@ OLETLS_UUIDINITIALIZED

Function Documentation

◆ apartment_createwindowifneeded()

HRESULT apartment_createwindowifneeded ( struct apartment apt)

Definition at line 1250 of file apartment.c.

1251{
1252 static INIT_ONCE class_init_once = INIT_ONCE_STATIC_INIT;
1253
1254 if (apt->multi_threaded)
1255 return S_OK;
1256
1257 if (!apt->win)
1258 {
1259 HWND hwnd;
1260
1261 InitOnceExecuteOnce( &class_init_once, register_class, NULL, NULL );
1262
1264 if (!hwnd)
1265 {
1266 ERR("CreateWindow failed with error %ld\n", GetLastError());
1268 }
1269 if (InterlockedCompareExchangePointer((void **)&apt->win, hwnd, NULL))
1270 /* someone beat us to it */
1272 }
1273
1274 return S_OK;
1275}
static const WCHAR aptwinclassW[]
Definition: apartment.c:1224
#define ERR(fmt,...)
Definition: precomp.h:57
#define NULL
Definition: types.h:112
HINSTANCE hProxyDll
Definition: combase.c:40
BOOL WINAPI InitOnceExecuteOnce(_Inout_ PINIT_ONCE InitOnce, _In_ __callback PINIT_ONCE_FN InitFn, _Inout_opt_ PVOID Parameter, _Outptr_opt_result_maybenull_ LPVOID *Context)
Definition: InitOnce.c:12
#define InterlockedCompareExchangePointer
Definition: interlocked.h:144
#define S_OK
Definition: intsafe.h:52
static ATOM register_class(void)
Definition: atl_ax.c:49
BOOL multi_threaded
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
RTL_RUN_ONCE INIT_ONCE
Definition: winbase.h:3680
#define INIT_ONCE_STATIC_INIT
Definition: winbase.h:591
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define HWND_MESSAGE
Definition: winuser.h:1221
#define CreateWindowW(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4418
BOOL WINAPI DestroyWindow(_In_ HWND)

Referenced by apartment_get_or_create(), apartment_hostobject_thread(), and marshal_object().

◆ apartment_decrement_mta_usage()

void apartment_decrement_mta_usage ( CO_MTA_USAGE_COOKIE  cookie)

Definition at line 1199 of file apartment.c.

1200{
1201 struct mta_cookie *mta_cookie = (struct mta_cookie *)cookie;
1202
1204
1205 if (mta)
1206 {
1207 struct mta_cookie *cur;
1208
1209 LIST_FOR_EACH_ENTRY(cur, &mta->usage_cookies, struct mta_cookie, entry)
1210 {
1211 if (mta_cookie == cur)
1212 {
1213 list_remove(&cur->entry);
1214 free(cur);
1216 break;
1217 }
1218 }
1219 }
1220
1222}
static struct apartment * mta
Definition: apartment.c:50
void apartment_release(struct apartment *apt)
Definition: apartment.c:444
static CRITICAL_SECTION apt_cs
Definition: apartment.c:54
static void list_remove(struct list_entry *entry)
Definition: list.h:90
#define free
Definition: debug_ros.c:5
FxCollectionEntry * cur
uint32_t entry
Definition: isohybrid.c:63
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
Definition: cookie.c:34
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)

Referenced by CoDecrementMTAUsage(), com_cleanup_tlsdata(), and leave_apartment().

◆ apartment_disconnectproxies()

HRESULT apartment_disconnectproxies ( struct apartment apt)

Definition at line 1992 of file marshal.c.

1993{
1994 struct proxy_manager *proxy;
1995
1997 {
1999 }
2000
2001 return S_OK;
2002}
static void proxy_manager_disconnect(struct proxy_manager *This)
Definition: marshal.c:1802
int proxy
Definition: main.c:67
struct list proxies

Referenced by apartment_release().

◆ apartment_findfromoxid()

struct apartment * apartment_findfromoxid ( OXID  oxid)

Definition at line 635 of file apartment.c.

636{
637 struct apartment *result = NULL, *apt;
638
641 {
642 if (apt->oxid == oxid)
643 {
644 result = apt;
646 break;
647 }
648 }
650
651 return result;
652}
static DWORD apartment_addref(struct apartment *apt)
Definition: apartment.c:542
static struct list apts
Definition: apartment.c:52
GLuint64EXT * result
Definition: glext.h:11304

Referenced by ipid_to_ifstub(), std_release_marshal_data(), and std_unmarshal_interface().

◆ apartment_findfromtid()

struct apartment * apartment_findfromtid ( DWORD  tid)

Definition at line 657 of file apartment.c.

658{
659 struct apartment *result = NULL, *apt;
660
663 {
664 if (apt != mta && apt->tid == tid)
665 {
666 result = apt;
668 break;
669 }
670 }
671
672 if (!result && mta && mta->tid == tid)
673 {
674 result = mta;
676 }
677
679
680 return result;
681}
static TfClientId tid

Referenced by ipid_to_ifstub().

◆ apartment_freeunusedlibraries()

void apartment_freeunusedlibraries ( struct apartment apt,
DWORD  unload_delay 
)

Definition at line 403 of file apartment.c.

404{
406
409 {
410 if (entry->dll->DllCanUnloadNow && (entry->dll->DllCanUnloadNow() == S_OK))
411 {
412 DWORD real_delay = delay;
413
414 if (real_delay == INFINITE)
415 {
416 /* DLLs that return multi-threaded objects aren't unloaded
417 * straight away to cope for programs that have races between
418 * last object destruction and threads in the DLLs that haven't
419 * finished, despite DllCanUnloadNow returning S_OK */
420 if (entry->multi_threaded)
421 real_delay = 10 * 60 * 1000; /* 10 minutes */
422 else
423 real_delay = 0;
424 }
425
426 if (!real_delay || (entry->unload_time && ((int)(GetTickCount() - entry->unload_time) > 0)))
427 {
428 list_remove(&entry->entry);
430 free(entry);
431 }
432 else
433 {
434 entry->unload_time = GetTickCount() + real_delay;
435 if (!entry->unload_time) entry->unload_time = 1;
436 }
437 }
438 else if (entry->unload_time)
439 entry->unload_time = 0;
440 }
442}
static void apartment_release_dll(struct opendll *entry, BOOL free_entry)
Definition: apartment.c:189
#define TRUE
Definition: types.h:120
ULONG WINAPI DECLSPEC_HOTPATCH GetTickCount(void)
Definition: sync.c:182
#define INFINITE
Definition: serial.h:102
unsigned long DWORD
Definition: ntddk_ex.h:95
static unsigned __int64 next
Definition: rand_nt.c:6
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
struct list loaded_dlls
CRITICAL_SECTION cs

Referenced by apartment_release(), and CoFreeUnusedLibrariesEx().

◆ apartment_get_current_or_mta()

struct apartment * apartment_get_current_or_mta ( void  )

◆ apartment_get_inproc_class_object()

HRESULT apartment_get_inproc_class_object ( struct apartment apt,
const struct class_reg_data regdata,
REFCLSID  rclsid,
REFIID  riid,
DWORD  class_context,
void **  ppv 
)

Definition at line 1031 of file apartment.c.

1033{
1035 BOOL apartment_threaded;
1036
1037 if (!(class_context & CLSCTX_PS_DLL))
1038 {
1039 enum comclass_threadingmodel model = get_threading_model(regdata);
1040
1041 if (model == ThreadingModel_Apartment)
1042 {
1043 apartment_threaded = TRUE;
1044 if (apt->multi_threaded)
1045 return apartment_hostobject_in_hostapt(apt, FALSE, FALSE, regdata, rclsid, riid, ppv);
1046 }
1047 else if (model == ThreadingModel_Free)
1048 {
1049 apartment_threaded = FALSE;
1050 if (!apt->multi_threaded)
1051 return apartment_hostobject_in_hostapt(apt, TRUE, FALSE, regdata, rclsid, riid, ppv);
1052 }
1053 /* everything except "Apartment", "Free" and "Both" */
1054 else if (model != ThreadingModel_Both)
1055 {
1056 apartment_threaded = TRUE;
1057 /* everything else is main-threaded */
1058 if (model != ThreadingModel_No)
1059 FIXME("unrecognised threading model %d for object %s, should be main-threaded?\n", model, debugstr_guid(rclsid));
1060
1061 if (apt->multi_threaded || !apt->main)
1062 return apartment_hostobject_in_hostapt(apt, FALSE, TRUE, regdata, rclsid, riid, ppv);
1063 }
1064 else
1065 apartment_threaded = FALSE;
1066 }
1067 else
1068 apartment_threaded = !apt->multi_threaded;
1069
1071 {
1072 /* failure: CLSID is not found in registry */
1073 WARN("class %s not registered inproc\n", debugstr_guid(rclsid));
1074 return REGDB_E_CLASSNOTREG;
1075 }
1076
1077 return apartment_getclassobject(apt, dllpath, apartment_threaded, rclsid, riid, ppv);
1078}
static BOOL get_object_dll_path(const struct class_reg_data *regdata, WCHAR *dst, DWORD dstlen)
Definition: apartment.c:712
static HRESULT apartment_getclassobject(struct apartment *apt, LPCWSTR dllpath, BOOL apartment_threaded, REFCLSID rclsid, REFIID riid, void **ppv)
Definition: apartment.c:760
comclass_threadingmodel
Definition: apartment.c:42
@ ThreadingModel_No
Definition: apartment.c:45
@ ThreadingModel_Both
Definition: apartment.c:46
@ ThreadingModel_Free
Definition: apartment.c:44
@ ThreadingModel_Apartment
Definition: apartment.c:43
static enum comclass_threadingmodel get_threading_model(const struct class_reg_data *data)
Definition: apartment.c:1006
static HRESULT apartment_hostobject_in_hostapt(struct apartment *apt, BOOL multi_threaded, BOOL main_apartment, const struct class_reg_data *regdata, REFCLSID rclsid, REFIID riid, void **ppv)
Definition: apartment.c:899
#define ARRAY_SIZE(A)
Definition: main.h:20
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define FALSE
Definition: types.h:117
#define MAX_PATH
Definition: compat.h:34
unsigned int BOOL
Definition: ntddk_ex.h:94
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define debugstr_guid
Definition: kernel32.h:35
WCHAR dllpath[MAX_PATH]
#define REGDB_E_CLASSNOTREG
Definition: winerror.h:3801
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by com_get_class_object().

◆ apartment_get_local_server_stream()

HRESULT apartment_get_local_server_stream ( struct apartment apt,
IStream **  ret 
)

Definition at line 315 of file apartment.c.

316{
317 HRESULT hr = S_OK;
318
320
321 if (!apt->local_server)
322 {
323 struct local_server *obj;
324
325 obj = malloc(sizeof(*obj));
326 if (obj)
327 {
328 obj->IServiceProvider_iface.lpVtbl = &local_server_vtbl;
329 obj->refcount = 1;
330 obj->apt = apt;
331
332 hr = CreateStreamOnHGlobal(0, TRUE, &obj->marshal_stream);
333 if (SUCCEEDED(hr))
334 {
335 hr = CoMarshalInterface(obj->marshal_stream, &IID_IServiceProvider, (IUnknown *)&obj->IServiceProvider_iface,
336 MSHCTX_LOCAL, NULL, MSHLFLAGS_TABLESTRONG);
337 if (FAILED(hr))
338 IStream_Release(obj->marshal_stream);
339 }
340
341 if (SUCCEEDED(hr))
342 apt->local_server = obj;
343 else
344 free(obj);
345 }
346 else
348 }
349
350 if (SUCCEEDED(hr))
351 hr = IStream_Clone(apt->local_server->marshal_stream, ret);
352
354
355 if (FAILED(hr))
356 ERR("Failed: %#lx\n", hr);
357
358 return hr;
359}
static const IServiceProviderVtbl local_server_vtbl
Definition: apartment.c:307
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define malloc
Definition: debug_ros.c:4
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL delete_on_release, IStream **stream)
HRESULT WINAPI CoMarshalInterface(IStream *stream, REFIID riid, IUnknown *unk, DWORD dest_context, void *pvDestContext, DWORD mshlFlags)
Definition: marshal.c:483
return ret
Definition: mutex.c:146
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
HRESULT hr
Definition: shlfolder.c:183
struct local_server * local_server
struct apartment * apt
Definition: apartment.c:230

Referenced by CoRegisterClassObject().

◆ apartment_get_mta()

struct apartment * apartment_get_mta ( void  )

Definition at line 607 of file apartment.c.

608{
609 struct apartment *apt;
610
612
613 if ((apt = mta))
614 apartment_addref(apt);
615
617
618 return apt;
619}

Referenced by apartment_get_current_or_mta(), CoGetApartmentType(), and ipid_to_ifstub().

◆ apartment_getoxid()

OXID apartment_getoxid ( const struct apartment apt)

Definition at line 1284 of file apartment.c.

1285{
1286 return apt->oxid;
1287}

Referenced by ClientRpcChannelBuffer_IsCorrectApartment(), marshal_object(), rpc_create_clientchannel(), and std_unmarshal_interface().

◆ apartment_getwindow()

HWND apartment_getwindow ( const struct apartment apt)

Definition at line 1278 of file apartment.c.

1279{
1280 assert(!apt->multi_threaded);
1281 return apt->win;
1282}
#define assert(_expr)
Definition: assert.h:32

Referenced by apartment_hostobject_in_hostapt(), apartment_hostobject_thread(), ClientRpcChannelBuffer_GetBuffer(), and dispatch_rpc().

◆ apartment_global_cleanup()

void apartment_global_cleanup ( void  )

Definition at line 1289 of file apartment.c.

1290{
1291 if (apt_win_class)
1295}
static void apartment_release_dlls(void)
Definition: apartment.c:206
static ATOM apt_win_class
Definition: apartment.c:1225
#define MAKEINTATOM(i)
Definition: winbase.h:1220
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
BOOL WINAPI UnregisterClassW(_In_ LPCWSTR, HINSTANCE)

Referenced by DllMain().

◆ apartment_increment_mta_usage()

HRESULT apartment_increment_mta_usage ( CO_MTA_USAGE_COOKIE *  cookie)

Definition at line 1175 of file apartment.c.

1176{
1177 struct mta_cookie *mta_cookie;
1178
1179 *cookie = NULL;
1180
1181 if (!(mta_cookie = malloc(sizeof(*mta_cookie))))
1182 return E_OUTOFMEMORY;
1183
1185
1186 if (mta)
1188 else
1190 list_add_head(&mta->usage_cookies, &mta_cookie->entry);
1191
1193
1194 *cookie = (CO_MTA_USAGE_COOKIE)mta_cookie;
1195
1196 return S_OK;
1197}
static struct apartment * apartment_construct(DWORD model)
Definition: apartment.c:362
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
@ COINIT_MULTITHREADED
Definition: objbase.h:280

Referenced by CoIncrementMTAUsage(), and ensure_mta().

◆ apartment_release()

void apartment_release ( struct apartment apt)

Definition at line 444 of file apartment.c.

445{
446 DWORD refcount;
447
449
450 refcount = InterlockedDecrement(&apt->refs);
451 TRACE("%s: after = %ld\n", wine_dbgstr_longlong(apt->oxid), refcount);
452
453 if (apt->being_destroyed)
454 {
456 return;
457 }
458
459 /* destruction stuff that needs to happen under global */
460 if (!refcount)
461 {
462 apt->being_destroyed = TRUE;
463 if (apt == mta) mta = NULL;
464 else if (apt == main_sta) main_sta = NULL;
465 list_remove(&apt->entry);
466 }
467
469
470 if (!refcount)
471 {
472 struct list *cursor, *cursor2;
473
474 TRACE("destroying apartment %p, oxid %s\n", apt, wine_dbgstr_longlong(apt->oxid));
475
476 if (apt->local_server)
477 {
478 struct local_server *local_server = apt->local_server;
480
481 memset(&zero, 0, sizeof(zero));
482 IStream_Seek(local_server->marshal_stream, zero, STREAM_SEEK_SET, NULL);
484 IStream_Release(local_server->marshal_stream);
486
487 apt->local_server = NULL;
489 IServiceProvider_Release(&local_server->IServiceProvider_iface);
490 }
491
492 /* Release the references to the registered class objects */
494
495 /* no locking is needed for this apartment, because no other thread
496 * can access it at this point */
497
499
500 if (apt->win) DestroyWindow(apt->win);
501 if (apt->host_apt_tid) PostThreadMessageW(apt->host_apt_tid, WM_QUIT, 0, 0);
502
503 LIST_FOR_EACH_SAFE(cursor, cursor2, &apt->stubmgrs)
504 {
505 struct stub_manager *stubmgr = LIST_ENTRY(cursor, struct stub_manager, entry);
506 /* release the implicit reference given by the fact that the
507 * stub has external references (it must do since it is in the
508 * stub manager list in the apartment and all non-apartment users
509 * must have a ref on the apartment and so it cannot be destroyed).
510 */
512 }
513
514 /* if this assert fires, then another thread took a reference to a
515 * stub manager without taking a reference to the containing
516 * apartment, which it must do. */
517 assert(list_empty(&apt->stubmgrs));
518
519 if (apt->filter) IMessageFilter_Release(apt->filter);
520
521 /* free as many unused libraries as possible... */
523
524 /* ... and free the memory for the apartment loaded dll entry and
525 * release the dll list reference without freeing the library for the
526 * rest */
527 while ((cursor = list_head(&apt->loaded_dlls)))
528 {
533 }
534
535 apt->cs.DebugInfo->Spare[0] = 0;
537
538 free(apt);
539 }
540}
void apartment_freeunusedlibraries(struct apartment *apt, DWORD delay)
Definition: apartment.c:403
static struct apartment * main_sta
Definition: apartment.c:51
#define InterlockedDecrement
Definition: armddk.h:52
static int list_empty(struct list_entry *head)
Definition: list.h:58
Definition: list.h:37
HRESULT apartment_disconnectproxies(struct apartment *apt)
Definition: marshal.c:1992
ULONG stub_manager_int_release(struct stub_manager *stub_manager)
Definition: stubmanager.c:309
void apartment_revoke_all_classes(const struct apartment *apt)
Definition: combase.c:3089
HRESULT WINAPI CoReleaseMarshalData(IStream *stream)
Definition: marshal.c:673
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
const char cursor[]
Definition: icontest.c:13
#define LIST_FOR_EACH_SAFE(cursor, cursor2, list)
Definition: list.h:192
#define memset(x, y, z)
Definition: compat.h:39
int zero
Definition: sehframes.cpp:29
#define TRACE(s)
Definition: solgame.cpp:4
PRTL_CRITICAL_SECTION_DEBUG DebugInfo
Definition: rtltypes.h:1450
struct opendll * dll
Definition: apartment.c:90
struct list entry
BOOL being_destroyed
Definition: list.h:15
IServiceProvider IServiceProvider_iface
Definition: apartment.c:228
IStream * marshal_stream
Definition: apartment.c:231
struct apartment * apt
#define LIST_ENTRY(type)
Definition: queue.h:175
#define WM_QUIT
Definition: winuser.h:1651
BOOL WINAPI PostThreadMessageW(_In_ DWORD, _In_ UINT, _In_ WPARAM, _In_ LPARAM)

Referenced by apartment_decrement_mta_usage(), apartment_hostobject_in_hostapt(), ClientIdentity_QueryMultipleInterfaces(), ClientRpcChannelBuffer_GetBuffer(), ClientRpcChannelBuffer_SendReceive(), CoDisconnectObject(), CoGetApartmentType(), CoLockObjectExternal(), com_cleanup_tlsdata(), com_get_class_object(), CoRegisterClassObject(), CoRevokeClassObject(), dispatch_rpc(), InternalIsProcessInitialized(), ipid_get_dest_context(), ipid_to_ifstub(), leave_apartment(), proxy_manager_get_remunknown(), RemUnknown_RemAddRef(), RemUnknown_RemQueryInterface(), RemUnknown_RemRelease(), std_release_marshal_data(), std_unmarshal_interface(), and StdMarshalImpl_MarshalInterface().

◆ apartment_revoke_all_classes()

void apartment_revoke_all_classes ( const struct apartment apt)

Definition at line 3089 of file combase.c.

3090{
3091 struct registered_class *cur, *cur2;
3092
3094
3096 {
3097 if (cur->apartment_id == apt->oxid)
3099 }
3100
3102}
static void com_revoke_class_object(struct registered_class *entry)
Definition: combase.c:3062
static CRITICAL_SECTION registered_classes_cs
Definition: combase.c:135
static struct list registered_classes
Definition: combase.c:133

Referenced by apartment_release().

◆ com_get_current_apt()

static struct apartment * com_get_current_apt ( void  )
inlinestatic

◆ com_get_registered_class_object()

IUnknown * com_get_registered_class_object ( const struct apartment apartment,
REFCLSID  rclsid,
DWORD  clscontext 
)

Definition at line 144 of file combase.c.

145{
146 struct registered_class *cur;
147 IUnknown *object = NULL;
148
150
152 {
153 if ((apt->oxid == cur->apartment_id) &&
154 (clscontext & cur->clscontext) &&
155 IsEqualGUID(&cur->clsid, rclsid))
156 {
157 object = cur->object;
158 IUnknown_AddRef(cur->object);
159 break;
160 }
161 }
162
164
165 return object;
166}
static IUnknown DWORD clscontext
Definition: compobj.c:82
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
PMInterfacePointer object
Definition: rpcss_main.c:51

Referenced by com_get_class_object(), CoRegisterClassObject(), and local_server_QueryService().

◆ com_get_tlsdata()

◆ ensure_mta()

HRESULT ensure_mta ( void  )

Definition at line 1297 of file apartment.c.

1298{
1299 struct apartment *apt;
1300 struct tlsdata *data;
1301 HRESULT hr;
1302
1303 if (FAILED(hr = com_get_tlsdata(&data)))
1304 return hr;
1305 if ((apt = data->apt) && (data->implicit_mta_cookie || apt->multi_threaded))
1306 return S_OK;
1307
1309 if (apt || mta)
1310 hr = apartment_increment_mta_usage(&data->implicit_mta_cookie);
1311 else
1314
1315 if (FAILED(hr))
1316 {
1317 ERR("Failed, hr %#lx.\n", hr);
1318 return hr;
1319 }
1320 return S_OK;
1321}
#define CO_E_NOTINITIALIZED
HRESULT apartment_increment_mta_usage(CO_MTA_USAGE_COOKIE *cookie)
Definition: apartment.c:1175

Referenced by RoGetActivationFactory().

◆ enter_apartment()

HRESULT enter_apartment ( struct tlsdata data,
DWORD  model 
)

Definition at line 1129 of file apartment.c.

1130{
1131 HRESULT hr = S_OK;
1132
1133 if (!data->apt)
1134 {
1135 if (!apartment_get_or_create(model))
1136 return E_OUTOFMEMORY;
1137 }
1138 else if (!apartment_is_model(data->apt, model))
1139 {
1140 WARN("Attempt to change threading model of this apartment from %s to %s\n",
1141 data->apt->multi_threaded ? "multi-threaded" : "apartment threaded",
1142 model & COINIT_APARTMENTTHREADED ? "apartment threaded" : "multi-threaded" );
1143 return RPC_E_CHANGED_MODE;
1144 }
1145 else
1146 hr = S_FALSE;
1147
1148 data->inits++;
1149
1150 return hr;
1151}
static struct apartment * apartment_get_or_create(DWORD model)
Definition: apartment.c:550
static BOOL apartment_is_model(const struct apartment *apt, DWORD model)
Definition: apartment.c:1124
@ COINIT_APARTMENTTHREADED
Definition: objbase.h:279
#define S_FALSE
Definition: winerror.h:3451
#define RPC_E_CHANGED_MODE
Definition: winerror.h:3554

Referenced by CoInitializeEx(), and dispatch_rpc().

◆ get_stub_manager()

struct stub_manager * get_stub_manager ( struct apartment apt,
OID  oid 
)

Definition at line 381 of file stubmanager.c.

382{
383 struct stub_manager *result = NULL, *m;
384
386 LIST_FOR_EACH_ENTRY(m, &apt->stubmgrs, struct stub_manager, entry)
387 {
388 if (m->oid == oid)
389 {
390 result = m;
392 break;
393 }
394 }
396
397 if (result)
398 TRACE("found %p for oid %s\n", result, wine_dbgstr_longlong(oid));
399 else
400 TRACE("not found for oid %s\n", wine_dbgstr_longlong(oid));
401
402 return result;
403}
const GLfloat * m
Definition: glext.h:10848
static ULONG stub_manager_int_addref(struct stub_manager *m)
Definition: stubmanager.c:295

Referenced by std_release_marshal_data(), and std_unmarshal_interface().

◆ get_stub_manager_from_object()

struct stub_manager * get_stub_manager_from_object ( struct apartment apt,
IUnknown object,
BOOL  alloc 
)

Definition at line 335 of file stubmanager.c.

336{
337 struct stub_manager *result = NULL, *m;
340
341 hres = IUnknown_QueryInterface(obj, &IID_IUnknown, (void**)&object);
342 if (FAILED(hres))
343 {
344 ERR("QueryInterface(IID_IUnknown failed): %#lx\n", hres);
345 return NULL;
346 }
347
349 LIST_FOR_EACH_ENTRY(m, &apt->stubmgrs, struct stub_manager, entry)
350 {
351 if (m->object == object)
352 {
353 result = m;
355 break;
356 }
357 }
359
360 if (result)
361 {
362 TRACE("found %p for object %p\n", result, object);
363 }
364 else if (alloc)
365 {
366 TRACE("not found, creating new stub manager...\n");
367 result = new_stub_manager(apt, object);
368 }
369 else
370 {
371 TRACE("not found for object %p\n", object);
372 }
373
374 IUnknown_Release(object);
375 return result;
376}
const GUID IID_IUnknown
HRESULT hres
Definition: protocol.c:465
#define alloc
Definition: rosglue.h:13
IUnknown * object
static struct stub_manager * new_stub_manager(struct apartment *apt, IUnknown *object)
Definition: stubmanager.c:178

Referenced by CoDisconnectObject(), CoLockObjectExternal(), and marshal_object().

◆ InternalIsProcessInitialized()

BOOL WINAPI InternalIsProcessInitialized ( void  )

Definition at line 391 of file combase.c.

392{
393 struct apartment *apt;
394
395 if (!(apt = apartment_get_current_or_mta()))
396 return FALSE;
398
399 return TRUE;
400}
struct apartment * apartment_get_current_or_mta(void)
Definition: apartment.c:623

◆ InternalTlsAllocData()

HRESULT WINAPI InternalTlsAllocData ( struct tlsdata **  data)

Definition at line 405 of file combase.c.

406{
407 if (!(*data = calloc(1, sizeof(**data))))
408 return E_OUTOFMEMORY;
409
410 list_init(&(*data)->spies);
411 NtCurrentTeb()->ReservedForOle = *data;
412
413 return S_OK;
414}
static void list_init(struct list_entry *head)
Definition: list.h:51
#define calloc
Definition: rosglue.h:14

Referenced by com_get_tlsdata().

◆ ipid_get_dest_context()

HRESULT ipid_get_dest_context ( const IPID ipid,
MSHCTX *  dest_context,
void **  dest_context_data 
)

Definition at line 557 of file stubmanager.c.

558{
559 struct stub_manager *stubmgr;
560 struct ifstub *ifstub;
561 struct apartment *apt;
562 void *data;
563 HRESULT hr;
564 DWORD ctx;
565
566 hr = ipid_to_ifstub(ipid, &apt, &stubmgr, &ifstub);
567 if (hr != S_OK) return RPC_E_DISCONNECTED;
568
569 hr = IRpcChannelBuffer_GetDestCtx(ifstub->chan, &ctx, &data);
570 if (SUCCEEDED(hr))
571 {
572 *dest_context = ctx;
573 *dest_context_data = data;
574 }
575
578
579 return hr;
580}
IRpcChannelBuffer * chan
ULONG stub_manager_int_release(struct stub_manager *m)
Definition: stubmanager.c:309
static HRESULT ipid_to_ifstub(const IPID *ipid, struct apartment **stub_apt, struct stub_manager **stubmgr_ret, struct ifstub **ifstub)
Definition: stubmanager.c:496
#define RPC_E_DISCONNECTED
Definition: winerror.h:3556

Referenced by std_unmarshal_interface().

◆ ipid_get_dispatch_params()

HRESULT ipid_get_dispatch_params ( const IPID ipid,
struct apartment **  stub_apt,
struct stub_manager **  manager,
IRpcStubBuffer **  stub,
IRpcChannelBuffer **  chan,
IID iid,
IUnknown **  iface 
)

Definition at line 530 of file stubmanager.c.

533{
534 struct stub_manager *stubmgr;
535 struct ifstub *ifstub;
536 struct apartment *apt;
537 HRESULT hr;
538
539 hr = ipid_to_ifstub(ipid, &apt, &stubmgr, &ifstub);
540 if (hr != S_OK) return RPC_E_DISCONNECTED;
541
543 IRpcStubBuffer_AddRef(*stub);
544 *chan = ifstub->chan;
545 IRpcChannelBuffer_AddRef(*chan);
546 *stub_apt = apt;
547 *iid = ifstub->iid;
548 *iface = ifstub->iface;
549
550 if (manager)
551 *manager = stubmgr;
552 else
554 return S_OK;
555}
Definition: stubgen.c:11
IUnknown * iface
IRpcStubBuffer * stubbuffer

Referenced by ClientRpcChannelBuffer_GetBuffer(), and dispatch_rpc().

◆ leave_apartment()

void leave_apartment ( struct tlsdata data)

Definition at line 1153 of file apartment.c.

1154{
1155 if (!--data->inits)
1156 {
1157 if (data->ole_inits)
1158 WARN( "Uninitializing apartment while Ole is still initialized\n" );
1159 apartment_release(data->apt);
1160 if (data->implicit_mta_cookie)
1161 {
1162 apartment_decrement_mta_usage(data->implicit_mta_cookie);
1163 data->implicit_mta_cookie = NULL;
1164 }
1165 data->apt = NULL;
1167 }
1168}
void apartment_decrement_mta_usage(CO_MTA_USAGE_COOKIE cookie)
Definition: apartment.c:1199

Referenced by CoUninitialize(), and dispatch_rpc().

◆ marshal_object()

HRESULT marshal_object ( struct apartment apt,
STDOBJREF stdobjref,
REFIID  riid,
IUnknown object,
DWORD  dest_context,
void dest_context_data,
MSHLFLAGS  mshlflags 
)

Definition at line 870 of file marshal.c.

872{
873 struct stub_manager *manager;
874 struct ifstub *ifstub;
875 BOOL tablemarshal;
876 HRESULT hr;
877
878 stdobjref->oxid = apartment_getoxid(apt);
879
881 if (hr != S_OK)
882 return hr;
883
884 if (!(manager = get_stub_manager_from_object(apt, object, TRUE)))
885 return E_OUTOFMEMORY;
886
887 stdobjref->flags = SORF_NULL;
888 if (mshlflags & MSHLFLAGS_TABLEWEAK)
889 stdobjref->flags |= SORFP_TABLEWEAK;
890 if (mshlflags & MSHLFLAGS_NOPING)
891 stdobjref->flags |= SORF_NOPING;
892 stdobjref->oid = manager->oid;
893
894 tablemarshal = ((mshlflags & MSHLFLAGS_TABLESTRONG) || (mshlflags & MSHLFLAGS_TABLEWEAK));
895
896 /* make sure ifstub that we are creating is unique */
897 ifstub = stub_manager_find_ifstub(manager, riid, mshlflags);
898 if (!ifstub) {
900
901 /* IUnknown doesn't require a stub buffer, because it never goes out on
902 * the wire */
904 {
905 IPSFactoryBuffer *psfb;
906
907 hr = get_facbuf_for_iid(riid, &psfb);
908 if (hr == S_OK) {
909 hr = IPSFactoryBuffer_CreateStub(psfb, riid, manager->object, &stub);
910 IPSFactoryBuffer_Release(psfb);
911 if (hr != S_OK)
912 ERR("Failed to create an IRpcStubBuffer from IPSFactory for %s with error %#lx\n",
914 }else {
915 WARN("couldn't get IPSFactory buffer for interface %s\n", debugstr_guid(riid));
917 }
918
919 }
920
921 if (hr == S_OK) {
922 ifstub = stub_manager_new_ifstub(manager, stub, riid, dest_context, dest_context_data, mshlflags);
923 if (!ifstub)
925 }
926 if (stub) IRpcStubBuffer_Release(stub);
927
928 if (hr != S_OK) {
930 /* destroy the stub manager if it has no ifstubs by releasing
931 * zero external references */
932 stub_manager_ext_release(manager, 0, FALSE, TRUE);
933 return hr;
934 }
935 }
936
937 if (!tablemarshal)
938 {
939 stdobjref->cPublicRefs = NORMALEXTREFS;
940 stub_manager_ext_addref(manager, stdobjref->cPublicRefs, FALSE);
941 }
942 else
943 {
944 stdobjref->cPublicRefs = 0;
945 if (mshlflags & MSHLFLAGS_TABLESTRONG)
946 stub_manager_ext_addref(manager, 1, FALSE);
947 else
948 stub_manager_ext_addref(manager, 0, TRUE);
949 }
950
951 /* FIXME: check return value */
953
954 stdobjref->ipid = ifstub->ipid;
955
957 return S_OK;
958}
HRESULT apartment_createwindowifneeded(struct apartment *apt)
Definition: apartment.c:1250
OXID apartment_getoxid(const struct apartment *apt)
Definition: apartment.c:1284
struct ifstub * stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, REFIID iid, DWORD dest_context, void *dest_context_data, MSHLFLAGS flags)
Definition: stubmanager.c:71
ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL tableweak, BOOL last_unlock_releases)
Definition: stubmanager.c:437
struct stub_manager * get_stub_manager_from_object(struct apartment *apt, IUnknown *object, BOOL alloc)
Definition: stubmanager.c:335
struct ifstub * stub_manager_find_ifstub(struct stub_manager *m, REFIID iid, MSHLFLAGS flags)
Definition: stubmanager.c:156
HRESULT rpc_register_interface(REFIID riid)
Definition: rpc.c:2086
ULONG stub_manager_ext_addref(struct stub_manager *m, ULONG refs, BOOL tableweak)
Definition: stubmanager.c:406
#define SORFP_TABLEWEAK
Definition: marshal.c:48
#define NORMALEXTREFS
Definition: marshal.c:45
static HRESULT get_facbuf_for_iid(REFIID riid, IPSFactoryBuffer **facbuf)
Definition: marshal.c:858
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
OXID oxid
Definition: marshal.c:93
ULONG flags
Definition: marshal.c:91
IPID ipid
Definition: marshal.c:95
ULONG cPublicRefs
Definition: marshal.c:92
#define E_NOINTERFACE
Definition: winerror.h:3479

Referenced by RemUnknown_RemQueryInterface(), start_apartment_remote_unknown(), and StdMarshalImpl_MarshalInterface().

◆ open_appidkey_from_clsid()

HRESULT open_appidkey_from_clsid ( REFCLSID  clsid,
REGSAM  access,
HKEY subkey 
)

Definition at line 353 of file combase.c.

354{
355 static const WCHAR appidkeyW[] = L"AppId\\";
356 DWORD res;
358 WCHAR keyname[ARRAY_SIZE(appidkeyW) + CHARS_IN_GUID];
359 DWORD size;
360 HKEY hkey;
361 DWORD type;
362 HRESULT hr;
363
364 /* read the AppID value under the class's key */
366 if (FAILED(hr))
367 return hr;
368
369 size = sizeof(buf);
370 res = RegQueryValueExW(hkey, L"AppId", NULL, &type, (LPBYTE)buf, &size);
371 RegCloseKey(hkey);
373 return REGDB_E_KEYMISSING;
374 else if (res != ERROR_SUCCESS || type!=REG_SZ)
375 return REGDB_E_READREGDB;
376
377 lstrcpyW(keyname, appidkeyW);
378 lstrcatW(keyname, buf);
379 res = open_classes_key(HKEY_CLASSES_ROOT, keyname, access, subkey);
381 return REGDB_E_KEYMISSING;
382 else if (res != ERROR_SUCCESS)
383 return REGDB_E_READREGDB;
384
385 return S_OK;
386}
#define RegCloseKey(hKey)
Definition: registry.h:49
#define CHARS_IN_GUID
#define ERROR_SUCCESS
Definition: deptool.c:10
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
HRESULT open_key_for_clsid(REFCLSID clsid, const WCHAR *keyname, REGSAM access, HKEY *subkey)
Definition: combase.c:320
static LSTATUS open_classes_key(HKEY hkey, const WCHAR *name, REGSAM access, HKEY *retkey)
Definition: combase.c:297
#define lstrcpyW
Definition: compat.h:749
#define L(x)
Definition: resources.c:13
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint res
Definition: glext.h:9613
GLsizeiptr size
Definition: glext.h:5919
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
#define REG_SZ
Definition: layer.c:22
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
const CLSID * clsid
Definition: msctf.cpp:50
unsigned char * LPBYTE
Definition: typedefs.h:53
#define REGDB_E_READREGDB
Definition: winerror.h:3797
#define REGDB_E_KEYMISSING
Definition: winerror.h:3799
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10

Referenced by create_local_service(), and create_surrogate_server().

◆ open_key_for_clsid()

HRESULT open_key_for_clsid ( REFCLSID  clsid,
const WCHAR keyname,
REGSAM  access,
HKEY subkey 
)

Definition at line 320 of file combase.c.

321{
322 static const WCHAR clsidW[] = L"CLSID\\";
324 LONG res;
325 HKEY key;
326
330
332 return REGDB_E_CLASSNOTREG;
333 else if (res != ERROR_SUCCESS)
334 return REGDB_E_READREGDB;
335
336 if (!keyname)
337 {
338 *subkey = key;
339 return S_OK;
340 }
341
342 res = open_classes_key(key, keyname, access, subkey);
345 return REGDB_E_KEYMISSING;
346 else if (res != ERROR_SUCCESS)
347 return REGDB_E_READREGDB;
348
349 return S_OK;
350}
static const WCHAR clsidW[]
INT WINAPI StringFromGUID2(REFGUID guid, LPOLESTR str, INT cmax)
Definition: combase.c:1525
#define lstrlenW
Definition: compat.h:750
long LONG
Definition: pedump.c:60
Definition: copy.c:22

Referenced by CoGetTreatAsClass(), com_get_class_object(), create_server(), create_surrogate_server(), open_appidkey_from_clsid(), and ProgIDFromCLSID().

◆ rpc_create_clientchannel()

HRESULT rpc_create_clientchannel ( const OXID oxid,
const IPID ipid,
const OXID_INFO *  oxid_info,
const IID iid,
DWORD  dest_context,
void dest_context_data,
IRpcChannelBuffer **  chan,
struct apartment apt 
)

Definition at line 1642 of file rpc.c.

1646{
1648 WCHAR endpoint[200];
1651 LPWSTR string_binding;
1652
1653 /* FIXME: get the endpoint from oxid_info->psa instead */
1655
1656 TRACE("proxy pipe: connecting to endpoint: %s\n", debugstr_w(endpoint));
1657
1659 NULL,
1661 NULL,
1662 endpoint,
1663 NULL,
1664 &string_binding);
1665
1666 if (status == RPC_S_OK)
1667 {
1668 status = RpcBindingFromStringBindingW(string_binding, &bind);
1669
1670 if (status == RPC_S_OK)
1671 {
1672 IPID ipid2 = *ipid; /* why can't RpcBindingSetObject take a const? */
1673 status = RpcBindingSetObject(bind, &ipid2);
1674 if (status != RPC_S_OK)
1676 }
1677
1678 RpcStringFreeW(&string_binding);
1679 }
1680
1681 if (status != RPC_S_OK)
1682 {
1683 ERR("Couldn't get binding for endpoint %s, status = %ld\n", debugstr_w(endpoint), status);
1684 return HRESULT_FROM_WIN32(status);
1685 }
1686
1687 This = malloc(sizeof(*This));
1688 if (!This)
1689 {
1691 return E_OUTOFMEMORY;
1692 }
1693
1694 This->super.IRpcChannelBuffer_iface.lpVtbl = &ClientRpcChannelBufferVtbl;
1695 This->super.refs = 1;
1696 This->super.dest_context = dest_context;
1697 This->super.dest_context_data = dest_context_data;
1698 This->bind = bind;
1699 This->oxid = apartment_getoxid(apt);
1700 This->server_pid = oxid_info->dwPid;
1701 This->event = NULL;
1702 This->iid = *iid;
1703
1704 *chan = &This->super.IRpcChannelBuffer_iface;
1705
1706 return S_OK;
1707}
static void get_rpc_endpoint(LPWSTR endpoint, const OXID *oxid)
Definition: rpc.c:80
static const IRpcChannelBufferVtbl ClientRpcChannelBufferVtbl
Definition: rpc.c:1617
static WCHAR rpctransportW[]
Definition: rpc.c:70
#define debugstr_w
Definition: kernel32.h:32
RPC_STATUS WINAPI RpcBindingFromStringBindingW(RPC_WSTR StringBinding, RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:862
RPC_STATUS WINAPI RpcStringBindingComposeW(RPC_WSTR ObjUuid, RPC_WSTR Protseq, RPC_WSTR NetworkAddr, RPC_WSTR Endpoint, RPC_WSTR Options, RPC_WSTR *StringBinding)
Definition: rpc_binding.c:493
RPC_STATUS WINAPI RpcBindingFree(RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:769
RPC_STATUS WINAPI RpcBindingSetObject(RPC_BINDING_HANDLE Binding, UUID *ObjectUuid)
Definition: rpc_binding.c:810
#define RPC_S_OK
Definition: rpcnterr.h:22
RPC_STATUS WINAPI RpcStringFreeW(RPC_WSTR *String)
Definition: rpcrt4_main.c:181
long RPC_STATUS
Definition: rpc.h:48
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
Definition: nis.h:10
Definition: ps.c:97
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by unmarshal_object().

◆ rpc_create_serverchannel()

HRESULT rpc_create_serverchannel ( DWORD  dest_context,
void dest_context_data,
IRpcChannelBuffer **  chan 
)

Definition at line 1709 of file rpc.c.

1710{
1711 RpcChannelBuffer *This = malloc(sizeof(*This));
1712 if (!This)
1713 return E_OUTOFMEMORY;
1714
1715 This->IRpcChannelBuffer_iface.lpVtbl = &ServerRpcChannelBufferVtbl;
1716 This->refs = 1;
1717 This->dest_context = dest_context;
1718 This->dest_context_data = dest_context_data;
1719
1720 *chan = &This->IRpcChannelBuffer_iface;
1721
1722 return S_OK;
1723}
static const IRpcChannelBufferVtbl ServerRpcChannelBufferVtbl
Definition: rpc.c:1629

Referenced by stub_manager_new_ifstub().

◆ rpc_execute_call()

void rpc_execute_call ( struct dispatch_params params)

Definition at line 1874 of file rpc.c.

1875{
1877 RPC_MESSAGE *msg = (RPC_MESSAGE *)params->msg;
1878 char *original_buffer = msg->Buffer;
1879 ORPCTHIS orpcthis;
1880 ORPC_EXTENT_ARRAY orpc_ext_array;
1881 WIRE_ORPC_EXTENT *first_wire_orpc_extent;
1882 GUID old_causality_id;
1883 struct tlsdata *tlsdata;
1884 struct apartment *apt;
1885
1887 return;
1888
1889 apt = com_get_current_apt();
1890
1891 /* handle ORPCTHIS and server extensions */
1892
1893 params->hr = unmarshal_ORPCTHIS(msg, &orpcthis, &orpc_ext_array, &first_wire_orpc_extent);
1894 if (params->hr != S_OK)
1895 {
1896 msg->Buffer = original_buffer;
1897 goto exit;
1898 }
1899
1901 if (!message_state)
1902 {
1903 params->hr = E_OUTOFMEMORY;
1904 msg->Buffer = original_buffer;
1905 goto exit;
1906 }
1907
1908 message_state->prefix_data_len = (char *)msg->Buffer - original_buffer;
1909 message_state->binding_handle = msg->Handle;
1910 message_state->bypass_rpcrt = params->bypass_rpcrt;
1911
1914 message_state->channel_hook_info.uCausality = orpcthis.cid;
1916 message_state->channel_hook_info.iMethod = msg->ProcNum;
1917 message_state->channel_hook_info.pObject = params->iface;
1918
1919 if (orpcthis.extensions && first_wire_orpc_extent &&
1920 orpcthis.extensions->size)
1921 ChannelHooks_ServerNotify(&message_state->channel_hook_info, msg->DataRepresentation, first_wire_orpc_extent, orpcthis.extensions->size);
1922
1923 msg->Handle = message_state;
1924 msg->BufferLength -= message_state->prefix_data_len;
1925
1926 /* call message filter */
1927
1928 if (apt->filter)
1929 {
1930 DWORD handlecall;
1931 INTERFACEINFO interface_info;
1932 CALLTYPE calltype;
1933
1934 interface_info.pUnk = params->iface;
1935 interface_info.iid = params->iid;
1936 interface_info.wMethod = msg->ProcNum;
1937
1938 if (IsEqualGUID(&orpcthis.cid, &tlsdata->causality_id))
1939 calltype = CALLTYPE_NESTED;
1940 else if (tlsdata->pending_call_count_server == 0)
1941 calltype = CALLTYPE_TOPLEVEL;
1942 else
1943 calltype = CALLTYPE_TOPLEVEL_CALLPENDING;
1944
1945 handlecall = IMessageFilter_HandleInComingCall(apt->filter,
1946 calltype,
1948 0 /* FIXME */,
1950 TRACE("IMessageFilter_HandleInComingCall returned %ld\n", handlecall);
1951 switch (handlecall)
1952 {
1953 case SERVERCALL_REJECTED:
1955 goto exit_reset_state;
1956 case SERVERCALL_RETRYLATER:
1957#if 0 /* FIXME: handle retries on the client side before enabling this code */
1958 params->hr = RPC_E_RETRY;
1959 goto exit_reset_state;
1960#else
1961 FIXME("retry call later not implemented\n");
1962 break;
1963#endif
1964 case SERVERCALL_ISHANDLED:
1965 default:
1966 break;
1967 }
1968 }
1969
1970 /* invoke the method */
1971
1972 /* save the old causality ID - note: any calls executed while processing
1973 * messages received during the SendReceive will appear to originate from
1974 * this call - this should be checked with what Windows does */
1975 old_causality_id = tlsdata->causality_id;
1976 tlsdata->causality_id = orpcthis.cid;
1978 params->hr = IRpcStubBuffer_Invoke(params->stub, params->msg, params->chan);
1980 tlsdata->causality_id = old_causality_id;
1981
1982 /* the invoke allocated a new buffer, so free the old one */
1983 if (message_state->bypass_rpcrt && original_buffer != msg->Buffer)
1984 free(original_buffer);
1985
1986exit_reset_state:
1987 message_state = msg->Handle;
1988 msg->Handle = message_state->binding_handle;
1989 msg->Buffer = (char *)msg->Buffer - message_state->prefix_data_len;
1990 msg->BufferLength += message_state->prefix_data_len;
1991
1992exit:
1994 if (params->handle) SetEvent(params->handle);
1995}
#define msg(x)
Definition: auth_time.c:54
#define UlongToHandle(ul)
Definition: basetsd.h:91
static HRESULT unmarshal_ORPCTHIS(RPC_MESSAGE *msg, ORPCTHIS *orpcthis, ORPC_EXTENT_ARRAY *orpc_ext_array, WIRE_ORPC_EXTENT **first_wire_orpc_extent)
Definition: rpc.c:1780
static void ChannelHooks_ServerNotify(SChannelHookCallInfo *info, DWORD lDataRep, WIRE_ORPC_EXTENT *first_wire_orpc_extent, ULONG extension_count)
Definition: rpc.c:821
GLenum const GLfloat * params
Definition: glext.h:5645
if(dx< 0)
Definition: linetemp.h:194
#define exit(n)
Definition: config.h:202
SChannelHookCallInfo channel_hook_info
Definition: rpc.c:123
ULONG prefix_data_len
Definition: rpc.c:122
BOOL bypass_rpcrt
Definition: rpc.c:124
RPC_BINDING_HANDLE binding_handle
Definition: rpc.c:121
LONG pending_call_count_server
GUID causality_id
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:669
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1156
#define RPC_E_RETRY
Definition: winerror.h:3557
#define RPC_E_CALL_REJECTED
Definition: winerror.h:3530

Referenced by apartment_wndproc(), and dispatch_rpc().

◆ rpc_get_local_class_object()

HRESULT rpc_get_local_class_object ( REFCLSID  rclsid,
REFIID  riid,
void **  obj 
)

Definition at line 629 of file rpc.c.

630{
631 PMInterfacePointer objref = NULL;
634 ULARGE_INTEGER newpos;
636 int tries = 0;
638 HRESULT hr;
639 static const int MAXTRIES = 30; /* 30 seconds */
640
641 TRACE("clsid %s, riid %s\n", debugstr_guid(rclsid), debugstr_guid(riid));
642
643 while (tries++ < MAXTRIES)
644 {
645 DWORD index, start_ticks;
646 HANDLE process = 0;
647
648 if (SUCCEEDED(hr = rpcss_get_class_object(rclsid, &objref)))
649 break;
650
651 if (tries == 1)
652 {
653 if ((hr = create_local_service(rclsid)) && (hr = create_server(rclsid, &process)) &&
654 (hr = create_surrogate_server(rclsid, &process)) )
655 return hr;
656 }
657
658 /* Wait for one second, even if messages arrive. */
659 start_ticks = GetTickCount();
660 do
661 {
662 if (SUCCEEDED(CoWaitForMultipleHandles(0, 1000, (process != 0), &process, &index)) && process && !index)
663 {
664 WARN("Server for %s failed to start.\n", debugstr_guid(rclsid));
666 return E_NOINTERFACE;
667 }
668 } while (GetTickCount() - start_ticks < 1000);
669
671 }
672
673 if (!objref || tries >= MAXTRIES)
674 return E_NOINTERFACE;
675
677 hr = IStream_Write(stream, objref->abData, objref->ulCntData, &length);
678
679 MIDL_user_free(objref);
680
681 if (SUCCEEDED(hr))
682 {
683 seekto.QuadPart = 0;
684 IStream_Seek(stream, seekto, STREAM_SEEK_SET, &newpos);
685
686 TRACE("Unmarshalling local server.\n");
687 hr = CoUnmarshalInterface(stream, &IID_IServiceProvider, (void **)&local_server);
688 if (SUCCEEDED(hr))
689 {
690 hr = IServiceProvider_QueryService(local_server, rclsid, riid, obj);
691 IServiceProvider_Release(local_server);
692 }
693 }
694
695 if (stream)
696 IStream_Release(stream);
697
698 return hr;
699}
#define index(s, c)
Definition: various.h:29
HRESULT WINAPI CoWaitForMultipleHandles(DWORD flags, DWORD timeout, ULONG handle_count, HANDLE *handles, DWORD *index)
Definition: combase.c:2067
HRESULT WINAPI CoUnmarshalInterface(IStream *stream, REFIID riid, void **ppv)
Definition: marshal.c:793
static HRESULT create_server(REFCLSID rclsid, HANDLE *process)
Definition: rpc.c:480
static HRESULT create_local_service(REFCLSID rclsid)
Definition: rpc.c:428
static HRESULT create_surrogate_server(REFCLSID rclsid, HANDLE *process)
Definition: rpc.c:550
void __RPC_USER MIDL_user_free(void *p)
Definition: rpc.c:179
static HRESULT rpcss_get_class_object(REFCLSID rclsid, PMInterfacePointer *objref)
Definition: rpc.c:382
#define CloseHandle
Definition: compat.h:739
GLuint index
Definition: glext.h:6031
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
#define seekto(pos, errstr)
Definition: mkdosfs.c:1613
Definition: parse.h:23
uint32_t ULONG
Definition: typedefs.h:59

Referenced by com_get_class_object().

◆ rpc_register_channel_hook()

HRESULT rpc_register_channel_hook ( REFGUID  rguid,
IChannelHook hook 
)

Definition at line 971 of file rpc.c.

972{
974
975 entry = malloc(sizeof(*entry));
976 if (!entry)
977 return E_OUTOFMEMORY;
978
979 entry->id = *rguid;
980 entry->hook = hook;
981 IChannelHook_AddRef(hook);
982
986
987 return S_OK;
988}
@ hook
Definition: SystemMenu.c:35
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static CRITICAL_SECTION csChannelHook
Definition: rpc.c:61
static struct list channel_hooks
Definition: rpc.c:60
Definition: rpc.c:163

Referenced by CoRegisterChannelHook().

◆ rpc_register_interface()

HRESULT rpc_register_interface ( REFIID  riid)

Definition at line 2086 of file rpc.c.

2087{
2088 struct registered_if *rif;
2089 BOOL found = FALSE;
2090 HRESULT hr = S_OK;
2091
2092 TRACE("(%s)\n", debugstr_guid(riid));
2093
2096 {
2098 {
2099 rif->refs++;
2100 found = TRUE;
2101 break;
2102 }
2103 }
2104 if (!found)
2105 {
2106 TRACE("Creating new interface\n");
2107
2108 rif = calloc(1, sizeof(*rif));
2109 if (rif)
2110 {
2112
2113 rif->refs = 1;
2114 rif->If.Length = sizeof(RPC_SERVER_INTERFACE);
2115 /* RPC interface ID = COM interface ID */
2116 rif->If.InterfaceId.SyntaxGUID = *riid;
2118 /* all other fields are 0, including the version asCOM objects
2119 * always have a version of 0.0 */
2121 (RPC_IF_HANDLE)&rif->If,
2122 NULL, NULL,
2125 NULL);
2126 if (status == RPC_S_OK)
2128 else
2129 {
2130 ERR("RpcServerRegisterIfEx failed with error %ld\n", status);
2131 free(rif);
2133 }
2134 }
2135 else
2136 hr = E_OUTOFMEMORY;
2137 }
2139 return hr;
2140}
static RPC_DISPATCH_TABLE rpc_dispatch
Definition: rpc.c:48
static CRITICAL_SECTION csRegIf
Definition: rpc.c:51
static struct list registered_interfaces
Definition: rpc.c:50
RPC_STATUS WINAPI RpcServerRegisterIfEx(RPC_IF_HANDLE IfSpec, UUID *MgrTypeUuid, RPC_MGR_EPV *MgrEpv, UINT Flags, UINT MaxCalls, RPC_IF_CALLBACK_FN *IfCallbackFn)
Definition: rpc_server.c:1125
#define RPC_C_LISTEN_MAX_CALLS_DEFAULT
Definition: rpcdce.h:122
#define RPC_IF_AUTOLISTEN
Definition: rpcdce.h:313
#define RPC_IF_OLE
Definition: rpcdce.h:314
struct _RPC_SERVER_INTERFACE RPC_SERVER_INTERFACE
unsigned int Length
Definition: rpcdcep.h:103
RPC_SYNTAX_IDENTIFIER InterfaceId
Definition: rpcdcep.h:104
PRPC_DISPATCH_TABLE DispatchTable
Definition: rpcdcep.h:106
DWORD refs
Definition: rpc.c:75
struct list entry
Definition: rpc.c:74
RPC_SERVER_INTERFACE If
Definition: rpc.c:76

Referenced by marshal_object().

◆ rpc_register_local_server()

HRESULT rpc_register_local_server ( REFCLSID  clsid,
IStream stream,
DWORD  flags,
unsigned int cookie 
)

Definition at line 701 of file rpc.c.

702{
703 MInterfacePointer *obj;
704 const void *ptr;
705 HGLOBAL hmem;
706 SIZE_T size;
707 HRESULT hr;
708
709 TRACE("%s, %#lx\n", debugstr_guid(clsid), flags);
710
712 if (FAILED(hr)) return hr;
713
714 size = GlobalSize(hmem);
715 if (!(obj = malloc(FIELD_OFFSET(MInterfacePointer, abData[size]))))
716 return E_OUTOFMEMORY;
717 obj->ulCntData = size;
718 ptr = GlobalLock(hmem);
719 memcpy(obj->abData, ptr, size);
720 GlobalUnlock(hmem);
721
723
724 free(obj);
725
726 return hr;
727}
HRESULT WINAPI GetHGlobalFromStream(IStream *stream, HGLOBAL *phglobal)
static HRESULT rpcss_server_register(REFCLSID clsid, DWORD flags, MInterfacePointer *obj, unsigned int *cookie)
Definition: rpc.c:368
GLbitfield flags
Definition: glext.h:7161
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
static ERESOURCE GlobalLock
Definition: sys_arch.c:8
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
ULONG_PTR SIZE_T
Definition: typedefs.h:80

Referenced by CoRegisterClassObject().

◆ rpc_resolve_oxid()

HRESULT rpc_resolve_oxid ( OXID  oxid,
OXID_INFO *  oxid_info 
)

Definition at line 2165 of file rpc.c.

2166{
2167 TRACE("%s\n", wine_dbgstr_longlong(oxid));
2168
2169 oxid_info->dwTid = 0;
2170 oxid_info->dwPid = 0;
2171 oxid_info->dwAuthnHint = RPC_C_AUTHN_LEVEL_NONE;
2172 /* FIXME: this is a hack around not having an OXID resolver yet -
2173 * this function should contact the machine's OXID resolver and then it
2174 * should give us the IPID of the IRemUnknown interface */
2175 oxid_info->ipidRemUnknown.Data1 = 0xffffffff;
2176 oxid_info->ipidRemUnknown.Data2 = 0xffff;
2177 oxid_info->ipidRemUnknown.Data3 = 0xffff;
2178 memcpy(oxid_info->ipidRemUnknown.Data4, &oxid, sizeof(OXID));
2179 oxid_info->psa = NULL /* FIXME */;
2180
2181 return S_OK;
2182}
UINT64 OXID
Definition: marshal.c:86
#define RPC_C_AUTHN_LEVEL_NONE
Definition: rpcdce.h:146

Referenced by proxy_manager_construct().

◆ rpc_revoke_local_server()

HRESULT rpc_revoke_local_server ( unsigned int  cookie)

Definition at line 375 of file rpc.c.

376{
380}
static RPC_BINDING_HANDLE get_irpcss_handle(void)
Definition: rpc.c:256
#define RPCSS_CALL_START
Definition: rpc.c:290
#define RPCSS_CALL_END
Definition: rpc.c:295
HRESULT __cdecl irpcss_server_revoke(handle_t h, unsigned int cookie)
Definition: rpcss_main.c:92

Referenced by com_revoke_class_object().

◆ rpc_start_remoting()

void rpc_start_remoting ( struct apartment apt)

Definition at line 2186 of file rpc.c.

2187{
2189 {
2190 WCHAR endpoint[200];
2192
2194
2198 endpoint,
2199 NULL);
2200 if (status != RPC_S_OK)
2201 ERR("Couldn't register endpoint %s\n", debugstr_w(endpoint));
2202
2203 /* FIXME: move remote unknown exporting into this function */
2204 }
2206}
#define InterlockedExchange
Definition: armddk.h:54
HRESULT start_apartment_remote_unknown(struct apartment *apt)
Definition: stubmanager.c:838
RPC_STATUS WINAPI RpcServerUseProtseqEpW(RPC_WSTR Protseq, UINT MaxCalls, RPC_WSTR Endpoint, LPVOID SecurityDescriptor)
Definition: rpc_server.c:927
#define RPC_C_PROTSEQ_MAX_REQS_DEFAULT
Definition: rpcdce.h:123
LONG remoting_started

Referenced by StdMarshalImpl_MarshalInterface().

◆ rpc_unregister_channel_hooks()

void rpc_unregister_channel_hooks ( void  )

◆ rpc_unregister_interface()

void rpc_unregister_interface ( REFIID  riid,
BOOL  wait 
)

Definition at line 2143 of file rpc.c.

2144{
2145 struct registered_if *rif;
2148 {
2150 {
2151 if (!--rif->refs)
2152 {
2154 list_remove(&rif->entry);
2155 free(rif);
2156 }
2157 break;
2158 }
2159 }
2161}
RPC_STATUS WINAPI RpcServerUnregisterIf(RPC_IF_HANDLE IfSpec, UUID *MgrTypeUuid, UINT WaitForCallsToComplete)
Definition: rpc_server.c:1202

Referenced by stub_manager_delete_ifstub(), and stub_manager_disconnect().

◆ rpcss_get_next_seqid()

HRESULT rpcss_get_next_seqid ( DWORD id)

Definition at line 308 of file rpc.c.

309{
313}
HRESULT __cdecl irpcss_get_thread_seq_id(handle_t h, DWORD *id)
Definition: rpcss_main.c:144

Referenced by CoGetCurrentProcess().

◆ start_apartment_remote_unknown()

HRESULT start_apartment_remote_unknown ( struct apartment apt)

Definition at line 838 of file stubmanager.c.

839{
840 IRemUnknown *pRemUnknown;
841 HRESULT hr = S_OK;
842
844 if (!apt->remunk_exported)
845 {
846 /* create the IRemUnknown object */
847 hr = RemUnknown_Construct(&pRemUnknown);
848 if (hr == S_OK)
849 {
850 STDOBJREF stdobjref; /* dummy - not used */
851 /* register it with the stub manager */
852 hr = marshal_object(apt, &stdobjref, &IID_IRemUnknown, (IUnknown *)pRemUnknown,
853 MSHCTX_DIFFERENTMACHINE, NULL, MSHLFLAGS_NORMAL|MSHLFLAGSP_REMUNKNOWN);
854 /* release our reference to the object as the stub manager will manage the life cycle for us */
855 IRemUnknown_Release(pRemUnknown);
856 if (hr == S_OK)
857 apt->remunk_exported = TRUE;
858 }
859 }
861 return hr;
862}
#define MSHLFLAGSP_REMUNKNOWN
HRESULT marshal_object(struct apartment *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *object, DWORD dest_context, void *dest_context_data, MSHLFLAGS mshlflags)
Definition: marshal.c:870
static const IID IID_IRemUnknown
Definition: marshal.c:129
BOOL remunk_exported
static HRESULT RemUnknown_Construct(IRemUnknown **ppRemUnknown)
Definition: stubmanager.c:662

Referenced by rpc_start_remoting().

◆ stub_manager_disconnect()

void stub_manager_disconnect ( struct stub_manager m)

Definition at line 242 of file stubmanager.c.

243{
244 struct ifstub *ifstub;
245
246 EnterCriticalSection(&m->lock);
247 if (!m->disconnected)
248 {
249 LIST_FOR_EACH_ENTRY(ifstub, &m->ifstubs, struct ifstub, entry)
251
252 m->disconnected = TRUE;
253 }
254 LeaveCriticalSection(&m->lock);
255}
void rpc_unregister_interface(REFIID riid, BOOL wait)
Definition: rpc.c:2143

Referenced by CoDisconnectObject().

◆ stub_manager_ext_addref()

ULONG stub_manager_ext_addref ( struct stub_manager m,
ULONG  refs,
BOOL  tableweak 
)

Definition at line 406 of file stubmanager.c.

407{
408 BOOL first_extern_ref;
409 ULONG rc;
410
411 EnterCriticalSection(&m->lock);
412
413 first_extern_ref = refs && !m->extrefs;
414
415 /* make sure we don't overflow extrefs */
416 refs = min(refs, (ULONG_MAX-1 - m->extrefs));
417 rc = (m->extrefs += refs);
418
419 if (tableweak)
420 rc += ++m->weakrefs;
421
422 LeaveCriticalSection(&m->lock);
423
424 TRACE("added %lu refs to %p (oid %s), rc is now %lu\n", refs, m, wine_dbgstr_longlong(m->oid), rc);
425
426 /*
427 * NOTE: According to tests, creating a stub causes two AddConnection calls followed by
428 * one ReleaseConnection call (with fLastReleaseCloses=FALSE).
429 */
430 if(first_extern_ref && m->extern_conn)
431 IExternalConnection_AddConnection(m->extern_conn, EXTCONN_STRONG, 0);
432
433 return rc;
434}
#define ULONG_MAX
Definition: limits.h:31
#define min(a, b)
Definition: monoChain.cc:55

Referenced by CoLockObjectExternal(), marshal_object(), and RemUnknown_RemAddRef().

◆ stub_manager_ext_release()

ULONG stub_manager_ext_release ( struct stub_manager m,
ULONG  refs,
BOOL  tableweak,
BOOL  last_unlock_releases 
)

Definition at line 437 of file stubmanager.c.

438{
439 BOOL last_extern_ref;
440 ULONG rc;
441
442 EnterCriticalSection(&m->lock);
443
444 /* make sure we don't underflow extrefs */
445 refs = min(refs, m->extrefs);
446 rc = (m->extrefs -= refs);
447
448 if (tableweak)
449 --m->weakrefs;
450 if (!last_unlock_releases)
451 rc += m->weakrefs;
452
453 last_extern_ref = refs && !m->extrefs;
454
455 LeaveCriticalSection(&m->lock);
456
457 TRACE("removed %lu refs from %p (oid %s), rc is now %lu\n", refs, m, wine_dbgstr_longlong(m->oid), rc);
458
459 if (last_extern_ref && m->extern_conn)
460 IExternalConnection_ReleaseConnection(m->extern_conn, EXTCONN_STRONG, 0, last_unlock_releases);
461
462 if (rc == 0)
463 if (!(m->extern_conn && last_unlock_releases && m->weakrefs))
465
466 return rc;
467}

Referenced by CoLockObjectExternal(), marshal_object(), RemUnknown_RemRelease(), std_unmarshal_interface(), and stub_manager_release_marshal_data().

◆ stub_manager_find_ifstub()

struct ifstub * stub_manager_find_ifstub ( struct stub_manager m,
REFIID  iid,
MSHLFLAGS  flags 
)

Definition at line 156 of file stubmanager.c.

157{
158 struct ifstub *result = NULL;
159 struct ifstub *ifstub;
160
161 EnterCriticalSection(&m->lock);
162 LIST_FOR_EACH_ENTRY( ifstub, &m->ifstubs, struct ifstub, entry )
163 {
164 if (IsEqualIID(iid, &ifstub->iid) && (ifstub->flags == flags))
165 {
166 result = ifstub;
167 break;
168 }
169 }
170 LeaveCriticalSection(&m->lock);
171
172 return result;
173}
MSHLFLAGS flags

Referenced by marshal_object().

◆ stub_manager_int_release()

ULONG stub_manager_int_release ( struct stub_manager stub_manager)

Definition at line 309 of file stubmanager.c.

310{
311 ULONG refs;
312 struct apartment *apt = m->apt;
313
315 refs = --m->refs;
316
317 TRACE("after %ld\n", refs);
318
319 /* remove from apartment so no other thread can access it... */
320 if (!refs)
321 list_remove(&m->entry);
322
324
325 /* ... so now we can delete it without being inside the apartment critsec */
326 if (!refs)
328
329 return refs;
330}
static void stub_manager_delete(struct stub_manager *m)
Definition: stubmanager.c:258

Referenced by apartment_release(), CoDisconnectObject(), CoLockObjectExternal(), dispatch_rpc(), ipid_get_dest_context(), ipid_get_dispatch_params(), marshal_object(), RemUnknown_RemAddRef(), RemUnknown_RemQueryInterface(), RemUnknown_RemRelease(), std_release_marshal_data(), std_unmarshal_interface(), and stub_manager_ext_release().

◆ stub_manager_is_table_marshaled()

BOOL stub_manager_is_table_marshaled ( struct stub_manager m,
const IPID ipid 
)

Definition at line 630 of file stubmanager.c.

631{
633
634 assert(ifstub);
635
636 return ifstub->flags & (MSHLFLAGS_TABLESTRONG | MSHLFLAGS_TABLEWEAK);
637}
static struct ifstub * stub_manager_ipid_to_ifstub(struct stub_manager *m, const IPID *ipid)
Definition: stubmanager.c:138

Referenced by std_unmarshal_interface().

◆ stub_manager_new_ifstub()

struct ifstub * stub_manager_new_ifstub ( struct stub_manager m,
IRpcStubBuffer sb,
REFIID  iid,
DWORD  dest_context,
void dest_context_data,
MSHLFLAGS  flags 
)

Definition at line 71 of file stubmanager.c.

73{
74 struct ifstub *stub;
75 HRESULT hr;
76
77 TRACE("oid=%s, stubbuffer=%p, iid=%s, dest_context=%lx\n", wine_dbgstr_longlong(m->oid), sb,
78 debugstr_guid(iid), dest_context);
79
80 stub = calloc(1, sizeof(struct ifstub));
81 if (!stub) return NULL;
82
83 hr = IUnknown_QueryInterface(m->object, iid, (void **)&stub->iface);
84 if (hr != S_OK)
85 {
86 free(stub);
87 return NULL;
88 }
89
90 hr = rpc_create_serverchannel(dest_context, dest_context_data, &stub->chan);
91 if (hr != S_OK)
92 {
93 IUnknown_Release(stub->iface);
94 free(stub);
95 return NULL;
96 }
97
98 stub->stubbuffer = sb;
99 if (sb) IRpcStubBuffer_AddRef(sb);
100
101 stub->flags = flags;
102 stub->iid = *iid;
103
104 /* FIXME: find a cleaner way of identifying that we are creating an ifstub
105 * for the remunknown interface */
107 stub->ipid = m->oxid_info.ipidRemUnknown;
108 else
109 generate_ipid(m, &stub->ipid);
110
111 EnterCriticalSection(&m->lock);
112 list_add_head(&m->ifstubs, &stub->entry);
113 /* every normal marshal is counted so we don't allow more than we should */
114 if (flags & MSHLFLAGS_NORMAL) m->norm_refs++;
115 LeaveCriticalSection(&m->lock);
116
117 TRACE("ifstub %p created with ipid %s\n", stub, debugstr_guid(&stub->ipid));
118
119 return stub;
120}
HRESULT rpc_create_serverchannel(DWORD dest_context, void *dest_context_data, IRpcChannelBuffer **chan)
Definition: rpc.c:1709
superblock * sb
Definition: btrfs.c:4261
struct _stub stub
static HRESULT generate_ipid(struct stub_manager *m, IPID *ipid)
Definition: stubmanager.c:53

Referenced by marshal_object().

◆ stub_manager_notify_unmarshal()

BOOL stub_manager_notify_unmarshal ( struct stub_manager m,
const IPID ipid 
)

Definition at line 583 of file stubmanager.c.

584{
585 BOOL ret = TRUE;
586 struct ifstub *ifstub;
587
589 {
590 ERR("attempted unmarshal of unknown IPID %s\n", debugstr_guid(ipid));
591 return FALSE;
592 }
593
594 EnterCriticalSection(&m->lock);
595
596 /* track normal marshals so we can enforce rules whilst in-process */
597 if (ifstub->flags & MSHLFLAGS_NORMAL)
598 {
599 if (m->norm_refs)
600 m->norm_refs--;
601 else
602 {
603 ERR("attempted invalid normal unmarshal, norm_refs is zero\n");
604 ret = FALSE;
605 }
606 }
607
608 LeaveCriticalSection(&m->lock);
609
610 return ret;
611}

Referenced by std_unmarshal_interface().

◆ stub_manager_release_marshal_data()

void stub_manager_release_marshal_data ( struct stub_manager m,
ULONG  refs,
const IPID ipid,
BOOL  tableweak 
)

Definition at line 614 of file stubmanager.c.

615{
616 struct ifstub *ifstub;
617
619 return;
620
621 if (ifstub->flags & MSHLFLAGS_TABLEWEAK)
622 refs = 0;
623 else if (ifstub->flags & MSHLFLAGS_TABLESTRONG)
624 refs = 1;
625
626 stub_manager_ext_release(m, refs, tableweak, !tableweak);
627}
ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL tableweak, BOOL last_unlock_releases)
Definition: stubmanager.c:437

Referenced by std_release_marshal_data().

Variable Documentation

◆ hProxyDll

HINSTANCE hProxyDll
extern

Definition at line 40 of file combase.c.