diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c index 8283312e53b..a06879e5937 100644 --- a/dlls/ole32/compobj.c +++ b/dlls/ole32/compobj.c @@ -236,9 +236,6 @@ static APARTMENT *apartment_construct(DWORD model) { /* FIXME: should be randomly generated by in an RPC call to rpcss */ apt->oxid = ((OXID)GetCurrentProcessId() << 32) | GetCurrentThreadId(); - apt->win = CreateWindowW(wszAptWinClass, NULL, 0, - 0, 0, 0, 0, - 0, 0, OLE32_hInstance, NULL); } else { @@ -422,6 +419,29 @@ static LRESULT CALLBACK apartment_wndproc(HWND hWnd, UINT msg, WPARAM wParam, LP } } +HRESULT apartment_createwindowifneeded(struct apartment *apt) +{ + if (!(apt->model & COINIT_APARTMENTTHREADED)) + return S_OK; + + if (!apt->win) + { + HWND hwnd = CreateWindowW(wszAptWinClass, NULL, 0, + 0, 0, 0, 0, + 0, 0, OLE32_hInstance, NULL); + if (!hwnd) + { + ERR("CreateWindow failed with error %ld\n", GetLastError()); + return HRESULT_FROM_WIN32(GetLastError()); + } + if (InterlockedCompareExchangePointer((PVOID *)&apt->win, hwnd, NULL)) + /* someone beat us to it */ + DestroyWindow(hwnd); + } + + return S_OK; +} + HWND apartment_getwindow(struct apartment *apt) { assert(apt->model & COINIT_APARTMENTTHREADED); diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h index bb54e3ba1aa..2e86a9935d8 100644 --- a/dlls/ole32/compobj_private.h +++ b/dlls/ole32/compobj_private.h @@ -139,7 +139,7 @@ struct apartment DWORD tid; /* thread id (RO) */ OXID oxid; /* object exporter ID (RO) */ LONG ipidc; /* interface pointer ID counter, starts at 1 (LOCK) */ - HWND win; /* message window (RO) */ + HWND win; /* message window (LOCK) */ CRITICAL_SECTION cs; /* thread safety */ LPMESSAGEFILTER filter; /* message filter (CS cs) */ struct list proxies; /* imported objects (CS cs) */ @@ -230,6 +230,7 @@ static inline HRESULT apartment_getoxid(struct apartment *apt, OXID *oxid) *oxid = apt->oxid; return S_OK; } +HRESULT apartment_createwindowifneeded(struct apartment *apt); HWND apartment_getwindow(struct apartment *apt); void apartment_joinmta(void); diff --git a/dlls/ole32/marshal.c b/dlls/ole32/marshal.c index 6b4679d8b5a..313cbd2e9e2 100644 --- a/dlls/ole32/marshal.c +++ b/dlls/ole32/marshal.c @@ -98,6 +98,10 @@ HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnkno if (hr != S_OK) return hr; + hr = apartment_createwindowifneeded(apt); + if (hr != S_OK) + return hr; + hr = IUnknown_QueryInterface(object, riid, (void **)&iobject); if (hr != S_OK) {