Module: wine
Branch: master
Commit: d67b99aef278e9b632a451ebf6a3c2cf2b85ebe2
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d67b99aef278e9b632a451ebf…
Author: Alexandre Julliard <julliard(a)winehq.org>
Date: Thu Oct 17 17:55:03 2013 +0200
ole32: Delay registering the apartment class until needed.
---
dlls/ole32/compobj.c | 60 +++++++++++++++++++++++++-------------------------
1 files changed, 30 insertions(+), 30 deletions(-)
diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
index 4d708c4..dbe1b06 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -1478,18 +1478,44 @@ static HRESULT apartment_hostobject_in_hostapt(
return hr;
}
+static BOOL WINAPI register_class( INIT_ONCE *once, void *param, void **context )
+{
+ WNDCLASSW wclass;
+
+ /* Dispatching to the correct thread in an apartment is done through
+ * window messages rather than RPC transports. When an interface is
+ * marshalled into another apartment in the same process, a window of the
+ * following class is created. The *caller* of CoMarshalInterface (i.e., the
+ * application) is responsible for pumping the message loop in that thread.
+ * The WM_USER messages which point to the RPCs are then dispatched to
+ * apartment_wndproc by the user's code from the apartment in which the
+ * interface was unmarshalled.
+ */
+ memset(&wclass, 0, sizeof(wclass));
+ wclass.lpfnWndProc = apartment_wndproc;
+ wclass.hInstance = hProxyDll;
+ wclass.lpszClassName = wszAptWinClass;
+ RegisterClassW(&wclass);
+ return TRUE;
+}
+
/* create a window for the apartment or return the current one if one has
* already been created */
HRESULT apartment_createwindowifneeded(struct apartment *apt)
{
+ static INIT_ONCE class_init_once = INIT_ONCE_STATIC_INIT;
+
if (apt->multi_threaded)
return S_OK;
if (!apt->win)
{
- HWND hwnd = CreateWindowW(wszAptWinClass, NULL, 0,
- 0, 0, 0, 0,
- HWND_MESSAGE, 0, hProxyDll, NULL);
+ HWND hwnd;
+
+ InitOnceExecuteOnce( &class_init_once, register_class, NULL, NULL );
+
+ hwnd = CreateWindowW(wszAptWinClass, NULL, 0, 0, 0, 0, 0,
+ HWND_MESSAGE, 0, hProxyDll, NULL);
if (!hwnd)
{
ERR("CreateWindow failed with error %d\n", GetLastError());
@@ -1516,31 +1542,6 @@ void apartment_joinmta(void)
COM_CurrentInfo()->apt = MTA;
}
-static void COMPOBJ_InitProcess( void )
-{
- WNDCLASSW wclass;
-
- /* Dispatching to the correct thread in an apartment is done through
- * window messages rather than RPC transports. When an interface is
- * marshalled into another apartment in the same process, a window of the
- * following class is created. The *caller* of CoMarshalInterface (i.e., the
- * application) is responsible for pumping the message loop in that thread.
- * The WM_USER messages which point to the RPCs are then dispatched to
- * apartment_wndproc by the user's code from the apartment in which the
- * interface was unmarshalled.
- */
- memset(&wclass, 0, sizeof(wclass));
- wclass.lpfnWndProc = apartment_wndproc;
- wclass.hInstance = hProxyDll;
- wclass.lpszClassName = wszAptWinClass;
- RegisterClassW(&wclass);
-}
-
-static void COMPOBJ_UninitProcess( void )
-{
- UnregisterClassW(wszAptWinClass, hProxyDll);
-}
-
static void COM_TlsDestroy(void)
{
struct oletls *info = NtCurrentTeb()->ReservedForOle;
@@ -4585,13 +4586,12 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID reserved)
switch(fdwReason) {
case DLL_PROCESS_ATTACH:
hProxyDll = hinstDLL;
- COMPOBJ_InitProcess();
break;
case DLL_PROCESS_DETACH:
if (reserved) break;
release_std_git();
- COMPOBJ_UninitProcess();
+ UnregisterClassW( wszAptWinClass, hProxyDll );
RPC_UnregisterAllChannelHooks();
COMPOBJ_DllList_Free();
DeleteCriticalSection(&csRegisteredClassList);