From d67b99aef278e9b632a451ebf6a3c2cf2b85ebe2 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 17 Oct 2013 17:55:03 +0200 Subject: [PATCH] ole32: Delay registering the apartment class until needed. --- dlls/ole32/compobj.c | 60 ++++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c index 4d708c4be7a..dbe1b060d38 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); -- 2.11.4.GIT