ReactOS 0.4.16-dev-2320-ge1853c6
apartment.c File Reference
#include <stdarg.h>
#include <assert.h>
#include "windef.h"
#include "winbase.h"
#include "servprov.h"
#include "combase_private.h"
#include "wine/debug.h"
#include "wine/list.h"
Include dependency graph for apartment.c:

Go to the source code of this file.

Classes

struct  opendll
 
struct  apartment_loaded_dll
 
struct  local_server
 
struct  host_object_params
 
struct  host_thread_params
 
struct  mta_cookie
 

Macros

#define COBJMACROS
 

Typedefs

typedef HRESULT(WINAPIDllGetClassObjectFunc) (REFCLSID clsid, REFIID iid, void **obj)
 
typedef HRESULT(WINAPIDllCanUnloadNowFunc) (void)
 

Enumerations

enum  comclass_threadingmodel {
  ThreadingModel_Apartment = 1 , ThreadingModel_Free = 2 , ThreadingModel_No = 3 , ThreadingModel_Both = 4 ,
  ThreadingModel_Neutral = 5 , ThreadingModel_Apartment = 1 , ThreadingModel_Free = 2 , ThreadingModel_No = 3 ,
  ThreadingModel_Both = 4 , ThreadingModel_Neutral = 5 , ThreadingModel_Apartment = 1 , ThreadingModel_Free = 2 ,
  ThreadingModel_No = 3 , ThreadingModel_Both = 4 , ThreadingModel_Neutral = 5
}
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (ole)
 
static struct opendllapartment_get_dll (const WCHAR *library_name)
 
static HRESULT apartment_add_dll (const WCHAR *library_name, struct opendll **ret)
 
static void apartment_release_dll (struct opendll *entry, BOOL free_entry)
 
static void apartment_release_dlls (void)
 
static struct local_serverimpl_from_IServiceProvider (IServiceProvider *iface)
 
static HRESULT WINAPI local_server_QueryInterface (IServiceProvider *iface, REFIID riid, void **obj)
 
static ULONG WINAPI local_server_AddRef (IServiceProvider *iface)
 
static ULONG WINAPI local_server_Release (IServiceProvider *iface)
 
static HRESULT WINAPI local_server_QueryService (IServiceProvider *iface, REFGUID guid, REFIID riid, void **obj)
 
HRESULT apartment_get_local_server_stream (struct apartment *apt, IStream **ret)
 
static struct apartmentapartment_construct (DWORD model)
 
void apartment_freeunusedlibraries (struct apartment *apt, DWORD delay)
 
void apartment_release (struct apartment *apt)
 
static DWORD apartment_addref (struct apartment *apt)
 
static struct apartmentapartment_get_or_create (DWORD model)
 
struct apartmentapartment_get_mta (void)
 
struct apartmentapartment_get_current_or_mta (void)
 
struct apartmentapartment_findfromoxid (OXID oxid)
 
struct apartmentapartment_findfromtid (DWORD tid)
 
static struct apartmentapartment_findmain (void)
 
static BOOL get_object_dll_path (const struct class_reg_data *regdata, WCHAR *dst, DWORD dstlen)
 
static HRESULT apartment_getclassobject (struct apartment *apt, LPCWSTR dllpath, BOOL apartment_threaded, REFCLSID rclsid, REFIID riid, void **ppv)
 
static HRESULT apartment_hostobject (struct apartment *apt, const struct host_object_params *params)
 
static DWORD CALLBACK apartment_hostobject_thread (void *p)
 
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)
 
static enum comclass_threadingmodel get_threading_model (const struct class_reg_data *data)
 
HRESULT apartment_get_inproc_class_object (struct apartment *apt, const struct class_reg_data *regdata, REFCLSID rclsid, REFIID riid, DWORD class_context, void **ppv)
 
static LRESULT CALLBACK apartment_wndproc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 
static BOOL apartment_is_model (const struct apartment *apt, DWORD model)
 
HRESULT enter_apartment (struct tlsdata *data, DWORD model)
 
void leave_apartment (struct tlsdata *data)
 
HRESULT apartment_increment_mta_usage (CO_MTA_USAGE_COOKIE *cookie)
 
void apartment_decrement_mta_usage (CO_MTA_USAGE_COOKIE cookie)
 
static BOOL WINAPI register_class (INIT_ONCE *once, void *param, void **context)
 
HRESULT apartment_createwindowifneeded (struct apartment *apt)
 
HWND apartment_getwindow (const struct apartment *apt)
 
OXID apartment_getoxid (const struct apartment *apt)
 
void apartment_global_cleanup (void)
 
HRESULT ensure_mta (void)
 

Variables

static struct apartmentmta
 
static struct apartmentmain_sta
 
static struct list apts = LIST_INIT(apts)
 
static CRITICAL_SECTION apt_cs = { &apt_cs_debug, -1, 0, 0, 0, 0 }
 
static CRITICAL_SECTION_DEBUG apt_cs_debug
 
static struct list dlls = LIST_INIT(dlls)
 
static CRITICAL_SECTION dlls_cs = { &dlls_cs_debug, -1, 0, 0, 0, 0 }
 
static CRITICAL_SECTION_DEBUG dlls_cs_debug
 
static const IServiceProviderVtbl local_server_vtbl
 
static const WCHAR aptwinclassW [] = L"OleMainThreadWndClass"
 
static ATOM apt_win_class
 

Macro Definition Documentation

◆ COBJMACROS

#define COBJMACROS

Definition at line 29 of file apartment.c.

Typedef Documentation

◆ DllCanUnloadNowFunc

typedef HRESULT(WINAPI * DllCanUnloadNowFunc) (void)

Definition at line 75 of file apartment.c.

◆ DllGetClassObjectFunc

typedef HRESULT(WINAPI * DllGetClassObjectFunc) (REFCLSID clsid, REFIID iid, void **obj)

Definition at line 74 of file apartment.c.

Enumeration Type Documentation

◆ comclass_threadingmodel

Enumerator
ThreadingModel_Apartment 
ThreadingModel_Free 
ThreadingModel_No 
ThreadingModel_Both 
ThreadingModel_Neutral 
ThreadingModel_Apartment 
ThreadingModel_Free 
ThreadingModel_No 
ThreadingModel_Both 
ThreadingModel_Neutral 
ThreadingModel_Apartment 
ThreadingModel_Free 
ThreadingModel_No 
ThreadingModel_Both 
ThreadingModel_Neutral 

Definition at line 41 of file apartment.c.

42{
48};
@ ThreadingModel_No
Definition: apartment.c:45
@ ThreadingModel_Both
Definition: apartment.c:46
@ ThreadingModel_Neutral
Definition: apartment.c:47
@ ThreadingModel_Free
Definition: apartment.c:44
@ ThreadingModel_Apartment
Definition: apartment.c:43

Function Documentation

◆ apartment_add_dll()

static HRESULT apartment_add_dll ( const WCHAR library_name,
struct opendll **  ret 
)
static

Definition at line 115 of file apartment.c.

116{
117 struct opendll *entry;
118 int len;
119 HRESULT hr = S_OK;
123
124 TRACE("%s\n", debugstr_w(library_name));
125
127 if (*ret) return S_OK;
128
129 /* Load outside of dlls lock to avoid dependency on the loader lock */
131 if (!hLibrary)
132 {
133 ERR("couldn't load in-process dll %s\n", debugstr_w(library_name));
134 /* failure: DLL could not be loaded */
135 return E_ACCESSDENIED; /* FIXME: or should this be CO_E_DLLNOTFOUND? */
136 }
137
138 /* DllCanUnloadNow is optional */
139 DllCanUnloadNow = (void *)GetProcAddress(hLibrary, "DllCanUnloadNow");
140 DllGetClassObject = (void *)GetProcAddress(hLibrary, "DllGetClassObject");
142 {
143 /* failure: the dll did not export DllGetClassObject */
144 ERR("couldn't find function DllGetClassObject in %s\n", debugstr_w(library_name));
146 return CO_E_DLLNOTFOUND;
147 }
148
150
152 if (*ret)
153 {
154 /* another caller to this function already added the dll while we
155 * weren't in the critical section */
157 }
158 else
159 {
161 entry = malloc(sizeof(*entry));
162 if (entry)
163 entry->library_name = malloc((len + 1) * sizeof(WCHAR));
164 if (entry && entry->library_name)
165 {
166 memcpy(entry->library_name, library_name, (len + 1)*sizeof(WCHAR));
167 entry->library = hLibrary;
168 entry->refs = 1;
169 entry->DllCanUnloadNow = DllCanUnloadNow;
170 entry->DllGetClassObject = DllGetClassObject;
171 list_add_tail(&dlls, &entry->entry);
172 *ret = entry;
173 }
174 else
175 {
176 free(entry);
179 }
180 }
181
183
184 return hr;
185}
HRESULT(WINAPI * DllCanUnloadNowFunc)(void)
Definition: apartment.c:75
static struct list dlls
Definition: apartment.c:63
static CRITICAL_SECTION dlls_cs
Definition: apartment.c:65
HRESULT(WINAPI * DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, void **obj)
Definition: apartment.c:74
static struct opendll * apartment_get_dll(const WCHAR *library_name)
Definition: apartment.c:95
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
#define ERR(fmt,...)
Definition: precomp.h:57
HMODULE hLibrary
Definition: odbccp32.c:12
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define GetProcAddress(x, y)
Definition: compat.h:753
#define FreeLibrary(x)
Definition: compat.h:748
#define lstrlenW
Definition: compat.h:750
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
Definition: loader.c:288
return ret
Definition: mutex.c:146
GLenum GLsizei len
Definition: glext.h:6722
#define S_OK
Definition: intsafe.h:52
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_w
Definition: kernel32.h:32
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, LPVOID *ppvOut)
Definition: msctf.cpp:566
HRESULT WINAPI DllCanUnloadNow(void)
Definition: msctf.cpp:558
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
LPWSTR library_name
Definition: apartment.c:80
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define LOAD_WITH_ALTERED_SEARCH_PATH
Definition: winbase.h:340
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define E_ACCESSDENIED
Definition: winerror.h:4116
#define CO_E_DLLNOTFOUND
Definition: winerror.h:3924
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by apartment_getclassobject().

◆ apartment_addref()

static DWORD apartment_addref ( struct apartment apt)
static

Definition at line 542 of file apartment.c.

543{
544 DWORD refs = InterlockedIncrement(&apt->refs);
545 TRACE("%s: before = %ld\n", wine_dbgstr_longlong(apt->oxid), refs - 1);
546 return refs;
547}
#define InterlockedIncrement
Definition: armddk.h:53
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
unsigned long DWORD
Definition: ntddk_ex.h:95

Referenced by apartment_findfromoxid(), apartment_findfromtid(), apartment_findmain(), apartment_get_current_or_mta(), apartment_get_mta(), apartment_get_or_create(), and apartment_increment_mta_usage().

◆ apartment_construct()

static struct apartment * apartment_construct ( DWORD  model)
static

Definition at line 362 of file apartment.c.

363{
364 struct apartment *apt;
365
366 TRACE("creating new apartment, model %ld\n", model);
367
368 apt = calloc(1, sizeof(*apt));
369 apt->tid = GetCurrentThreadId();
370
371 list_init(&apt->proxies);
372 list_init(&apt->stubmgrs);
373 list_init(&apt->loaded_dlls);
375 apt->ipidc = 0;
376 apt->refs = 1;
377 apt->remunk_exported = FALSE;
378 apt->oidc = 1;
380 apt->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": apartment");
381
383
384 if (apt->multi_threaded)
385 {
386 /* FIXME: should be randomly generated by in an RPC call to rpcss */
387 apt->oxid = ((OXID)GetCurrentProcessId() << 32) | 0xcafe;
388 }
389 else
390 {
391 /* FIXME: should be randomly generated by in an RPC call to rpcss */
392 apt->oxid = ((OXID)GetCurrentProcessId() << 32) | GetCurrentThreadId();
393 }
394
395 TRACE("Created apartment on OXID %s\n", wine_dbgstr_longlong(apt->oxid));
396
397 list_add_head(&apts, &apt->entry);
398
399 return apt;
400}
static struct list apts
Definition: apartment.c:52
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
static void list_init(struct list_entry *head)
Definition: list.h:51
#define FALSE
Definition: types.h:117
BOOL WINAPI InitializeCriticalSectionEx(OUT LPCRITICAL_SECTION lpCriticalSection, IN DWORD dwSpinCount, IN DWORD flags)
Definition: sync.c:107
UINT64 OXID
Definition: marshal.c:86
@ COINIT_APARTMENTTHREADED
Definition: objbase.h:279
#define calloc
Definition: rosglue.h:14
PRTL_CRITICAL_SECTION_DEBUG DebugInfo
Definition: rtltypes.h:1450
struct list proxies
struct list entry
struct list loaded_dlls
CRITICAL_SECTION cs
struct list usage_cookies
BOOL remunk_exported
struct list stubmgrs
BOOL multi_threaded
#define DWORD_PTR
Definition: treelist.c:76
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1156
#define RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO
Definition: winnt_old.h:1152

Referenced by apartment_get_or_create(), and apartment_increment_mta_usage().

◆ 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 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
static ATOM register_class(void)
Definition: atl_ax.c:49
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
FxCollectionEntry * cur
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
Definition: cookie.c:34

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

◆ 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
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_findmain()

static struct apartment * apartment_findmain ( void  )
static

Definition at line 686 of file apartment.c.

687{
688 struct apartment *result;
689
691
694
696
697 return result;
698}
static struct apartment * main_sta
Definition: apartment.c:51

Referenced by apartment_hostobject_in_hostapt().

◆ apartment_freeunusedlibraries()

void apartment_freeunusedlibraries ( struct apartment apt,
DWORD  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
static unsigned __int64 next
Definition: rand_nt.c:6
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204

Referenced by apartment_release(), and CoFreeUnusedLibrariesEx().

◆ apartment_get_current_or_mta()

struct apartment * apartment_get_current_or_mta ( void  )

◆ apartment_get_dll()

static struct opendll * apartment_get_dll ( const WCHAR library_name)
static

Definition at line 95 of file apartment.c.

96{
97 struct opendll *ptr, *ret = NULL;
98
101 {
102 if (!wcsicmp(library_name, ptr->library_name) &&
103 (InterlockedIncrement(&ptr->refs) != 1) /* entry is being destroyed if == 1 */)
104 {
105 ret = ptr;
106 break;
107 }
108 }
110
111 return ret;
112}
#define wcsicmp
Definition: compat.h:15
static PVOID ptr
Definition: dispmode.c:27

Referenced by apartment_add_dll().

◆ 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
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 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

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
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
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
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_get_or_create()

static struct apartment * apartment_get_or_create ( DWORD  model)
static

Definition at line 550 of file apartment.c.

551{
552 struct apartment *apt = com_get_current_apt();
553 struct tlsdata *data;
554
555 if (!apt)
556 {
558
559 if (model & COINIT_APARTMENTTHREADED)
560 {
562
563 apt = apartment_construct(model);
564 if (!main_sta)
565 {
566 main_sta = apt;
567 apt->main = TRUE;
568 TRACE("Created main-threaded apartment with OXID %s\n", wine_dbgstr_longlong(apt->oxid));
569 }
570
572 if (model & COINIT_DISABLE_OLE1DDE)
574
576
577 if (apt->main)
579 }
580 else
581 {
583
584 /* The multi-threaded apartment (MTA) contains zero or more threads interacting
585 * with free threaded (ie thread safe) COM objects. There is only ever one MTA
586 * in a process */
587 if (mta)
588 {
589 TRACE("entering the multithreaded apartment %s\n", wine_dbgstr_longlong(mta->oxid));
591 }
592 else
593 mta = apartment_construct(model);
594
596
597 apt = mta;
598
600 }
601 data->apt = apt;
602 }
603
604 return apt;
605}
HRESULT apartment_createwindowifneeded(struct apartment *apt)
Definition: apartment.c:1250
static struct apartment * apartment_construct(DWORD model)
Definition: apartment.c:362
@ OLETLS_DISABLE_OLE1DDE
@ OLETLS_APARTMENTTHREADED
@ OLETLS_MULTITHREADED
static HRESULT com_get_tlsdata(struct tlsdata **data)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
@ COINIT_DISABLE_OLE1DDE
Definition: objbase.h:281
struct apartment * apt

Referenced by enter_apartment().

◆ apartment_getclassobject()

static HRESULT apartment_getclassobject ( struct apartment apt,
LPCWSTR  dllpath,
BOOL  apartment_threaded,
REFCLSID  rclsid,
REFIID  riid,
void **  ppv 
)
static

Definition at line 760 of file apartment.c.

763{
764 HRESULT hr = S_OK;
765 BOOL found = FALSE;
767
768 if (!wcsicmp(dllpath, L"ole32.dll"))
769 {
770 HRESULT (WINAPI *p_ole32_DllGetClassObject)(REFCLSID clsid, REFIID riid, void **obj);
771
772 p_ole32_DllGetClassObject = (void *)GetProcAddress(GetModuleHandleW(L"ole32.dll"), "DllGetClassObject");
773
774 /* we don't need to control the lifetime of this dll, so use the local
775 * implementation of DllGetClassObject directly */
776 TRACE("calling ole32!DllGetClassObject\n");
777 hr = p_ole32_DllGetClassObject(rclsid, riid, ppv);
778
779 if (hr != S_OK)
780 ERR("DllGetClassObject returned error %#lx for dll %s\n", hr, debugstr_w(dllpath));
781
782 return hr;
783 }
784
786
788 if (!wcsicmp(dllpath, apartment_loaded_dll->dll->library_name))
789 {
790 TRACE("found %s already loaded\n", debugstr_w(dllpath));
791 found = TRUE;
792 break;
793 }
794
795 if (!found)
796 {
800 if (SUCCEEDED(hr))
801 {
805 if (FAILED(hr))
807 }
808 if (SUCCEEDED(hr))
809 {
810 TRACE("added new loaded dll %s\n", debugstr_w(dllpath));
812 }
813 }
814
816
817 if (SUCCEEDED(hr))
818 {
819 /* one component being multi-threaded overrides any number of
820 * apartment-threaded components */
821 if (!apartment_threaded)
823
824 TRACE("calling DllGetClassObject %p\n", apartment_loaded_dll->dll->DllGetClassObject);
825 /* OK: get the ClassObject */
826 hr = apartment_loaded_dll->dll->DllGetClassObject(rclsid, riid, ppv);
827
828 if (hr != S_OK)
829 ERR("DllGetClassObject returned error %#lx for dll %s\n", hr, debugstr_w(dllpath));
830 }
831
832 return hr;
833}
static HRESULT apartment_add_dll(const WCHAR *library_name, struct opendll **ret)
Definition: apartment.c:115
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
#define L(x)
Definition: resources.c:13
const CLSID * clsid
Definition: msctf.cpp:50
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
struct opendll * dll
Definition: apartment.c:90
struct list entry
Definition: apartment.c:89
#define HRESULT
Definition: msvc.h:7
#define WINAPI
Definition: msvc.h:6

Referenced by apartment_get_inproc_class_object(), and apartment_hostobject().

◆ 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_hostobject()

static HRESULT apartment_hostobject ( struct apartment apt,
const struct host_object_params params 
)
static

Definition at line 1080 of file apartment.c.

1081{
1082 static const LARGE_INTEGER llZero;
1085 HRESULT hr;
1086
1087 TRACE("clsid %s, iid %s\n", debugstr_guid(&params->clsid), debugstr_guid(&params->iid));
1088
1090 {
1091 /* failure: CLSID is not found in registry */
1092 WARN("class %s not registered inproc\n", debugstr_guid(&params->clsid));
1093 return REGDB_E_CLASSNOTREG;
1094 }
1095
1096 hr = apartment_getclassobject(apt, dllpath, params->apartment_threaded, &params->clsid, &params->iid, (void **)&object);
1097 if (FAILED(hr))
1098 return hr;
1099
1100 hr = CoMarshalInterface(params->stream, &params->iid, object, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
1101 if (FAILED(hr))
1102 IUnknown_Release(object);
1103 IStream_Seek(params->stream, llZero, STREAM_SEEK_SET, NULL);
1104
1105 return hr;
1106}
GLenum const GLfloat * params
Definition: glext.h:5645
static const LARGE_INTEGER llZero
Definition: moniker.c:1425

Referenced by apartment_hostobject_thread(), and apartment_wndproc().

◆ apartment_hostobject_in_hostapt()

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 
)
static

Definition at line 899 of file apartment.c.

901{
903 HWND apartment_hwnd = NULL;
904 DWORD apartment_tid = 0;
905 HRESULT hr;
906
907 if (!multi_threaded && main_apartment)
908 {
909 struct apartment *host_apt = apartment_findmain();
910 if (host_apt)
911 {
912 apartment_hwnd = apartment_getwindow(host_apt);
913 apartment_release(host_apt);
914 }
915 }
916
917 if (!apartment_hwnd)
918 {
920
921 if (!apt->host_apt_tid)
922 {
923 struct host_thread_params thread_params;
924 HANDLE handles[2];
925 DWORD wait_value;
926
927 thread_params.threading_model = multi_threaded ? COINIT_MULTITHREADED : COINIT_APARTMENTTHREADED;
928 handles[0] = thread_params.ready_event = CreateEventW(NULL, FALSE, FALSE, NULL);
929 thread_params.apartment_hwnd = NULL;
930 handles[1] = CreateThread(NULL, 0, apartment_hostobject_thread, &thread_params, 0, &apt->host_apt_tid);
931 if (!handles[1])
932 {
935 return E_OUTOFMEMORY;
936 }
937 wait_value = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
940 if (wait_value == WAIT_OBJECT_0)
941 apt->host_apt_hwnd = thread_params.apartment_hwnd;
942 else
943 {
945 return E_OUTOFMEMORY;
946 }
947 }
948
949 if (multi_threaded || !main_apartment)
950 {
952 apartment_tid = apt->host_apt_tid;
953 }
954
956 }
957
958 /* another thread may have become the main apartment in the time it took
959 * us to create the thread for the host apartment */
960 if (!apartment_hwnd && !multi_threaded && main_apartment)
961 {
962 struct apartment *host_apt = apartment_findmain();
963 if (host_apt)
964 {
965 apartment_hwnd = apartment_getwindow(host_apt);
966 apartment_release(host_apt);
967 }
968 }
969
970 params.regdata = *regdata;
971 params.clsid = *rclsid;
972 params.iid = *riid;
974 if (FAILED(hr))
975 return hr;
976 params.apartment_threaded = !multi_threaded;
977 if (multi_threaded)
978 {
979 params.hr = S_OK;
981 if (!PostThreadMessageW(apartment_tid, DM_HOSTOBJECT, 0, (LPARAM)&params))
983 else
984 {
986 hr = params.hr;
987 }
988 CloseHandle(params.event);
989 }
990 else
991 {
992 if (!apartment_hwnd)
993 {
994 ERR("host apartment didn't create window\n");
996 }
997 else
998 hr = SendMessageW(apartment_hwnd, DM_HOSTOBJECT, 0, (LPARAM)&params);
999 }
1000 if (SUCCEEDED(hr))
1002 IStream_Release(params.stream);
1003 return hr;
1004}
static struct apartment * apartment_findmain(void)
Definition: apartment.c:686
HWND apartment_getwindow(const struct apartment *apt)
Definition: apartment.c:1278
static DWORD CALLBACK apartment_hostobject_thread(void *p)
Definition: apartment.c:847
#define DM_HOSTOBJECT
HRESULT WINAPI CoUnmarshalInterface(IStream *stream, REFIID riid, void **ppv)
Definition: marshal.c:793
#define CloseHandle
Definition: compat.h:739
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
LONG_PTR LPARAM
Definition: minwindef.h:175
@ COINIT_MULTITHREADED
Definition: objbase.h:280
DWORD host_apt_tid
HWND host_apt_hwnd
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:587
static EFI_HANDLE * handles
Definition: uefidisk.c:118
#define WAIT_OBJECT_0
Definition: winbase.h:383
BOOL WINAPI PostThreadMessageW(_In_ DWORD, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)

Referenced by apartment_get_inproc_class_object().

◆ apartment_hostobject_thread()

static DWORD CALLBACK apartment_hostobject_thread ( void p)
static

Definition at line 847 of file apartment.c.

848{
849 struct host_thread_params *params = p;
850 MSG msg;
851 HRESULT hr;
852 struct apartment *apt;
853
854 TRACE("\n");
855
856 hr = CoInitializeEx(NULL, params->threading_model);
857 if (FAILED(hr)) return hr;
858
859 apt = com_get_current_apt();
860 if (params->threading_model == COINIT_APARTMENTTHREADED)
861 {
863 params->apartment_hwnd = apartment_getwindow(apt);
864 }
865 else
866 params->apartment_hwnd = NULL;
867
868 /* force the message queue to be created before signaling parent thread */
870
871 SetEvent(params->ready_event);
872 params = NULL; /* can't touch params after here as it may be invalid */
873
874 while (GetMessageW(&msg, NULL, 0, 0))
875 {
876 if (!msg.hwnd && (msg.message == DM_HOSTOBJECT))
877 {
878 struct host_object_params *obj_params = (struct host_object_params *)msg.lParam;
879 obj_params->hr = apartment_hostobject(apt, obj_params);
880 SetEvent(obj_params->event);
881 }
882 else
883 {
886 }
887 }
888
889 TRACE("exiting\n");
890
892
893 return S_OK;
894}
static HRESULT apartment_hostobject(struct apartment *apt, const struct host_object_params *params)
Definition: apartment.c:1080
#define msg(x)
Definition: auth_time.c:54
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(void *reserved, DWORD model)
Definition: combase.c:2803
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: combase.c:2842
GLfloat GLfloat p
Definition: glext.h:8902
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:669
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
BOOL WINAPI TranslateMessage(_In_ const MSG *)
BOOL WINAPI GetMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
BOOL WINAPI PeekMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)
#define WM_USER
Definition: winuser.h:1923
#define PM_NOREMOVE
Definition: winuser.h:1206

Referenced by apartment_hostobject_in_hostapt().

◆ 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}

Referenced by CoIncrementMTAUsage(), and ensure_mta().

◆ apartment_is_model()

static BOOL apartment_is_model ( const struct apartment apt,
DWORD  model 
)
static

Definition at line 1124 of file apartment.c.

1125{
1126 return (apt->multi_threaded == !(model & COINIT_APARTMENTTHREADED));
1127}

Referenced by enter_apartment().

◆ 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
#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
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
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

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_release_dll()

static void apartment_release_dll ( struct opendll entry,
BOOL  free_entry 
)
static

Definition at line 189 of file apartment.c.

190{
191 if (!InterlockedDecrement(&entry->refs) && free_entry)
192 {
194 list_remove(&entry->entry);
196
197 TRACE("freeing %p\n", entry->library);
198 FreeLibrary(entry->library);
199
200 free(entry->library_name);
201 free(entry);
202 }
203}

Referenced by apartment_freeunusedlibraries(), and apartment_release().

◆ apartment_release_dlls()

static void apartment_release_dlls ( void  )
static

Definition at line 206 of file apartment.c.

207{
208 struct opendll *entry, *cursor2;
210 LIST_FOR_EACH_ENTRY_SAFE(entry, cursor2, &dlls, struct opendll, entry)
211 {
212 list_remove(&entry->entry);
213 free(entry->library_name);
214 free(entry);
215 }
218}

Referenced by apartment_global_cleanup().

◆ apartment_wndproc()

static LRESULT CALLBACK apartment_wndproc ( HWND  hWnd,
UINT  msg,
WPARAM  wParam,
LPARAM  lParam 
)
static

Definition at line 1110 of file apartment.c.

1111{
1112 switch (msg)
1113 {
1114 case DM_EXECUTERPC:
1116 return 0;
1117 case DM_HOSTOBJECT:
1119 default:
1120 return DefWindowProcW(hWnd, msg, wParam, lParam);
1121 }
1122}
HWND hWnd
Definition: settings.c:17
void rpc_execute_call(struct dispatch_params *params)
Definition: rpc.c:1874
#define DM_EXECUTERPC
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)

Referenced by register_class().

◆ 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
#define S_FALSE
Definition: winerror.h:3451
#define RPC_E_CHANGED_MODE
Definition: winerror.h:3554

Referenced by CoInitializeEx(), and dispatch_rpc().

◆ get_object_dll_path()

static BOOL get_object_dll_path ( const struct class_reg_data regdata,
WCHAR dst,
DWORD  dstlen 
)
static

Definition at line 712 of file apartment.c.

713{
714 DWORD ret;
715
716 if (regdata->origin == CLASS_REG_REGISTRY)
717 {
718 DWORD keytype;
720 DWORD dwLength = dstlen * sizeof(WCHAR);
721
722 if ((ret = RegQueryValueExW(regdata->u.hkey, NULL, NULL, &keytype, (BYTE*)src, &dwLength)) == ERROR_SUCCESS)
723 {
724 if (keytype == REG_EXPAND_SZ)
725 {
727 }
728 else
729 {
730 const WCHAR *quote_start;
731 quote_start = wcschr(src, '\"');
732 if (quote_start)
733 {
734 const WCHAR *quote_end = wcschr(quote_start + 1, '\"');
735 if (quote_end)
736 {
737 memmove(src, quote_start + 1, (quote_end - quote_start - 1) * sizeof(WCHAR));
738 src[quote_end - quote_start - 1] = '\0';
739 }
740 }
742 }
743 }
744 return !ret;
745 }
746 else
747 {
749
750 *dst = 0;
751 ActivateActCtx(regdata->u.actctx.hactctx, &cookie);
752 ret = SearchPathW(NULL, regdata->u.actctx.module_name, L".dll", dstlen, dst, NULL);
754 return *dst != 0;
755 }
756}
@ CLASS_REG_REGISTRY
#define ERROR_MORE_DATA
Definition: dderror.h:13
#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
#define wcschr
Definition: compat.h:17
#define lstrcpynW
Definition: compat.h:738
static DWORD DWORD * dwLength
Definition: fusion.c:86
BOOL WINAPI DeactivateActCtx(IN DWORD dwFlags, IN ULONG_PTR ulCookie)
Definition: actctx.c:268
BOOL WINAPI ActivateActCtx(IN HANDLE hActCtx, OUT PULONG_PTR ulCookie)
Definition: actctx.c:237
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:520
DWORD WINAPI SearchPathW(IN LPCWSTR lpPath OPTIONAL, IN LPCWSTR lpFileName, IN LPCWSTR lpExtension OPTIONAL, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart OPTIONAL)
Definition: path.c:1298
GLenum src
Definition: glext.h:6340
GLenum GLenum dst
Definition: glext.h:6340
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
static DWORD dstlen
Definition: directory.c:51
#define REG_EXPAND_SZ
Definition: nt_native.h:1497
union class_reg_data::@323 u
enum class_reg_data_origin origin
struct class_reg_data::@323::@324 actctx
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned char BYTE
Definition: xxhash.c:193

Referenced by apartment_get_inproc_class_object(), and apartment_hostobject().

◆ get_threading_model()

static enum comclass_threadingmodel get_threading_model ( const struct class_reg_data data)
static

Definition at line 1006 of file apartment.c.

1007{
1008 if (data->origin == CLASS_REG_REGISTRY)
1009 {
1010 WCHAR threading_model[10 /* lstrlenW(L"apartment")+1 */];
1011 DWORD dwLength = sizeof(threading_model);
1012 DWORD keytype;
1013 DWORD ret;
1014
1015 ret = RegQueryValueExW(data->u.hkey, L"ThreadingModel", NULL, &keytype, (BYTE*)threading_model, &dwLength);
1016 if ((ret != ERROR_SUCCESS) || (keytype != REG_SZ))
1017 threading_model[0] = '\0';
1018
1019 if (!wcsicmp(threading_model, L"Apartment")) return ThreadingModel_Apartment;
1020 if (!wcsicmp(threading_model, L"Free")) return ThreadingModel_Free;
1021 if (!wcsicmp(threading_model, L"Both")) return ThreadingModel_Both;
1022
1023 /* there's not specific handling for this case */
1024 if (threading_model[0]) return ThreadingModel_Neutral;
1025 return ThreadingModel_No;
1026 }
1027 else
1028 return data->u.actctx.threading_model;
1029}
#define REG_SZ
Definition: layer.c:22

Referenced by apartment_get_inproc_class_object().

◆ impl_from_IServiceProvider()

static struct local_server * impl_from_IServiceProvider ( IServiceProvider iface)
inlinestatic

Definition at line 234 of file apartment.c.

235{
236 return CONTAINING_RECORD(iface, struct local_server, IServiceProvider_iface);
237}
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by local_server_AddRef(), local_server_QueryInterface(), local_server_QueryService(), and local_server_Release().

◆ 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().

◆ local_server_AddRef()

static ULONG WINAPI local_server_AddRef ( IServiceProvider iface)
static

Definition at line 260 of file apartment.c.

261{
264
265 TRACE("%p, refcount %ld\n", iface, refcount);
266
267 return refcount;
268}
static struct local_server * impl_from_IServiceProvider(IServiceProvider *iface)
Definition: apartment.c:234
long LONG
Definition: pedump.c:60
LONG refcount
Definition: apartment.c:229

◆ local_server_QueryInterface()

static HRESULT WINAPI local_server_QueryInterface ( IServiceProvider iface,
REFIID  riid,
void **  obj 
)
static

Definition at line 239 of file apartment.c.

240{
242
243 TRACE("%p, %s, %p\n", iface, debugstr_guid(riid), obj);
244
246 IsEqualGUID(riid, &IID_IServiceProvider))
247 {
249 }
250 else
251 {
252 *obj = NULL;
253 return E_NOINTERFACE;
254 }
255
256 IUnknown_AddRef((IUnknown *)*obj);
257 return S_OK;
258}
const GUID IID_IUnknown
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define E_NOINTERFACE
Definition: winerror.h:3479

◆ local_server_QueryService()

static HRESULT WINAPI local_server_QueryService ( IServiceProvider iface,
REFGUID  guid,
REFIID  riid,
void **  obj 
)
static

Definition at line 286 of file apartment.c.

287{
289 struct apartment *apt = com_get_current_apt();
290 HRESULT hr = E_FAIL;
291 IUnknown *unk;
292
293 TRACE("%p, %s, %s, %p\n", iface, debugstr_guid(guid), debugstr_guid(riid), obj);
294
295 if (!local_server->apt)
296 return E_UNEXPECTED;
297
298 if ((unk = com_get_registered_class_object(apt, guid, CLSCTX_LOCAL_SERVER)))
299 {
300 hr = IUnknown_QueryInterface(unk, riid, obj);
301 IUnknown_Release(unk);
302 }
303
304 return hr;
305}
#define E_FAIL
Definition: ddrawi.h:102
IUnknown * com_get_registered_class_object(const struct apartment *apt, REFCLSID rclsid, DWORD clscontext)
Definition: combase.c:144
GUID guid
Definition: version.c:147
#define E_UNEXPECTED
Definition: winerror.h:3528

◆ local_server_Release()

static ULONG WINAPI local_server_Release ( IServiceProvider iface)
static

Definition at line 270 of file apartment.c.

271{
274
275 TRACE("%p, refcount %ld\n", iface, refcount);
276
277 if (!refcount)
278 {
281 }
282
283 return refcount;
284}

◆ register_class()

static BOOL WINAPI register_class ( INIT_ONCE once,
void param,
void **  context 
)
static

Definition at line 1227 of file apartment.c.

1228{
1229 WNDCLASSW wclass;
1230
1231 /* Dispatching to the correct thread in an apartment is done through
1232 * window messages rather than RPC transports. When an interface is
1233 * marshalled into another apartment in the same process, a window of the
1234 * following class is created. The *caller* of CoMarshalInterface (i.e., the
1235 * application) is responsible for pumping the message loop in that thread.
1236 * The WM_USER messages which point to the RPCs are then dispatched to
1237 * apartment_wndproc by the user's code from the apartment in which the
1238 * interface was unmarshalled.
1239 */
1240 memset(&wclass, 0, sizeof(wclass));
1242 wclass.hInstance = hProxyDll;
1243 wclass.lpszClassName = aptwinclassW;
1244 apt_win_class = RegisterClassW(&wclass);
1245 return TRUE;
1246}
static LRESULT CALLBACK apartment_wndproc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: apartment.c:1110
LPCWSTR lpszClassName
Definition: winuser.h:3287
HINSTANCE hInstance
Definition: winuser.h:3282
WNDPROC lpfnWndProc
Definition: winuser.h:3279
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( ole  )

Variable Documentation

◆ apt_cs

◆ apt_cs_debug

CRITICAL_SECTION_DEBUG apt_cs_debug
static
Initial value:
=
{
0, 0, &apt_cs,
0, 0, { (DWORD_PTR)(__FILE__ ": apt_cs") }
}
static CRITICAL_SECTION_DEBUG apt_cs_debug
Definition: apartment.c:55

Definition at line 55 of file apartment.c.

◆ apt_win_class

ATOM apt_win_class
static

Definition at line 1225 of file apartment.c.

Referenced by apartment_global_cleanup(), and register_class().

◆ apts

◆ aptwinclassW

const WCHAR aptwinclassW[] = L"OleMainThreadWndClass"
static

Definition at line 1224 of file apartment.c.

Referenced by apartment_createwindowifneeded(), and register_class().

◆ dlls

◆ dlls_cs

static CRITICAL_SECTION dlls_cs = { &dlls_cs_debug, -1, 0, 0, 0, 0 }
static

◆ dlls_cs_debug

CRITICAL_SECTION_DEBUG dlls_cs_debug
static
Initial value:
=
{
0, 0, &dlls_cs,
0, 0, { (DWORD_PTR)(__FILE__ ": dlls_cs") }
}
static CRITICAL_SECTION_DEBUG dlls_cs_debug
Definition: apartment.c:66

Definition at line 66 of file apartment.c.

◆ local_server_vtbl

const IServiceProviderVtbl local_server_vtbl
static
Initial value:
=
{
}
static HRESULT WINAPI local_server_QueryInterface(IServiceProvider *iface, REFIID riid, void **obj)
Definition: apartment.c:239
static HRESULT WINAPI local_server_QueryService(IServiceProvider *iface, REFGUID guid, REFIID riid, void **obj)
Definition: apartment.c:286
static ULONG WINAPI local_server_Release(IServiceProvider *iface)
Definition: apartment.c:270
static ULONG WINAPI local_server_AddRef(IServiceProvider *iface)
Definition: apartment.c:260

Definition at line 307 of file apartment.c.

Referenced by apartment_get_local_server_stream().

◆ main_sta

struct apartment* main_sta
static

Definition at line 51 of file apartment.c.

Referenced by apartment_findmain(), apartment_get_or_create(), and apartment_release().

◆ mta