Signed-off-by: Zebediah Figura z.figura12@gmail.com --- v2: Add a short Sleep() to avoid test failures.
dlls/comsvcs/tests/dispenser.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
diff --git a/dlls/comsvcs/tests/dispenser.c b/dlls/comsvcs/tests/dispenser.c index 187800ec6a..6fae802ef0 100644 --- a/dlls/comsvcs/tests/dispenser.c +++ b/dlls/comsvcs/tests/dispenser.c @@ -24,6 +24,7 @@ #include "winbase.h" #include "ole2.h" #include "comsvcs.h" +#include "msxml.h"
#include "wine/test.h"
@@ -141,6 +142,17 @@ static const struct IDispenserDriverVtbl driver_vtbl =
static IDispenserDriver DispenserDriver = { &driver_vtbl };
+static DWORD WINAPI com_thread(void *arg) +{ + IUnknown *unk; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&unk); + if (hr == S_OK) IUnknown_Release(unk); + + return hr; +} + static void create_dispenser(void) { static const WCHAR pool0[] = {'S','C','.','P','o','o','l',' ','0',' ','0',0}; @@ -149,7 +161,9 @@ static void create_dispenser(void) HRESULT hr; IDispenserManager *dispenser = NULL; IHolder *holder1 = NULL, *holder2 = NULL, *holder3 = NULL; + HANDLE thread; RESID resid; + DWORD ret; BSTR str;
hr = CoCreateInstance( &CLSID_DispenserManager, NULL, CLSCTX_ALL, &IID_IDispenserManager, (void**)&dispenser); @@ -160,9 +174,23 @@ static void create_dispenser(void) return; }
+ thread = CreateThread(NULL, 0, com_thread, NULL, 0, NULL); + ok(!WaitForSingleObject(thread, 1000), "wait failed\n"); + GetExitCodeThread(thread, &ret); + ok(ret == CO_E_NOTINITIALIZED, "got unexpected hr %#x\n", ret); + hr = IDispenserManager_RegisterDispenser(dispenser, &DispenserDriver, pool0, &holder1); ok(hr == S_OK, "got 0x%08x\n", hr);
+ /* The above call creates an MTA thread, but we need to wait for it to + * actually initialize. */ + Sleep(200); + thread = CreateThread(NULL, 0, com_thread, NULL, 0, NULL); + ok(!WaitForSingleObject(thread, 1000), "wait failed\n"); + GetExitCodeThread(thread, &ret); +todo_wine + ok(ret == S_OK, "got unexpected hr %#x\n", ret); + hr = IDispenserManager_RegisterDispenser(dispenser, &DispenserDriver, pool0, &holder2); ok(hr == S_OK, "got 0x%08x\n", hr); ok(holder1 != holder2, "same holder object returned\n");
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46581 Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/comsvcs/main.c | 27 ++++++++++++++++++++++++--- dlls/comsvcs/tests/dispenser.c | 1 - 2 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/dlls/comsvcs/main.c b/dlls/comsvcs/main.c index d7831cff6c..af9487b314 100644 --- a/dlls/comsvcs/main.c +++ b/dlls/comsvcs/main.c @@ -40,7 +40,7 @@ typedef struct dispensermanager { IDispenserManager IDispenserManager_iface; LONG ref; - + HANDLE mta_thread, mta_stop_event; } dispensermanager;
typedef struct holder @@ -264,12 +264,27 @@ static ULONG WINAPI dismanager_Release(IDispenserManager *iface)
if (!ref) { - heap_free(This); + if (This->mta_thread) + { + SetEvent(This->mta_stop_event); + WaitForSingleObject(This->mta_thread, INFINITE); + CloseHandle(This->mta_stop_event); + CloseHandle(This->mta_thread); + } + heap_free(This); }
return ref; }
+static DWORD WINAPI mta_thread_proc(void *arg) +{ + CoInitializeEx(NULL, COINIT_MULTITHREADED); + WaitForSingleObject(arg, INFINITE); + CoUninitialize(); + return 0; +} + static HRESULT WINAPI dismanager_RegisterDispenser(IDispenserManager *iface, IDispenserDriver *driver, LPCOLESTR name, IHolder **dispenser) { @@ -283,6 +298,12 @@ static HRESULT WINAPI dismanager_RegisterDispenser(IDispenserManager *iface, IDi
hr = create_holder(driver, dispenser);
+ if (!This->mta_thread) + { + This->mta_stop_event = CreateEventA(NULL, TRUE, FALSE, NULL); + This->mta_thread = CreateThread(NULL, 0, mta_thread_proc, This->mta_stop_event, 0, NULL); + } + TRACE("<-- 0x%08x, %p\n", hr, *dispenser);
return hr; @@ -313,7 +334,7 @@ static HRESULT WINAPI comsvcscf_CreateInstance(IClassFactory *cf,IUnknown* outer
TRACE("(%p %s %p)\n", outer, debugstr_guid(riid), object);
- dismanager = heap_alloc(sizeof(*dismanager)); + dismanager = heap_alloc_zero(sizeof(*dismanager)); if (!dismanager) { *object = NULL; diff --git a/dlls/comsvcs/tests/dispenser.c b/dlls/comsvcs/tests/dispenser.c index 6fae802ef0..7af38d05a5 100644 --- a/dlls/comsvcs/tests/dispenser.c +++ b/dlls/comsvcs/tests/dispenser.c @@ -188,7 +188,6 @@ static void create_dispenser(void) thread = CreateThread(NULL, 0, com_thread, NULL, 0, NULL); ok(!WaitForSingleObject(thread, 1000), "wait failed\n"); GetExitCodeThread(thread, &ret); -todo_wine ok(ret == S_OK, "got unexpected hr %#x\n", ret);
hr = IDispenserManager_RegisterDispenser(dispenser, &DispenserDriver, pool0, &holder2);