[PATCH 0/2] MR10605: wmvcore: Initialize COM in async_reader_callback_thread().
From: Paul Gofman <pgofman@codeweavers.com> --- dlls/wmvcore/tests/wmvcore.c | 58 ++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c index bbc37c525f3..fe0d8d89b3c 100644 --- a/dlls/wmvcore/tests/wmvcore.c +++ b/dlls/wmvcore/tests/wmvcore.c @@ -4305,10 +4305,68 @@ static void test_sync_reader_allocator_failure(void) ok(ret, "Failed to delete %s, error %lu.\n", debugstr_w(filename), GetLastError()); } +static void test_async_reader_com_init(void) +{ + const WCHAR *filename = load_resource(L"test.wmv"); + APTTYPEQUALIFIER qualifier; + struct callback callback; + IWMReader *reader; + APTTYPE type; + HRESULT hr; + + hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); + ok(hr == S_OK, "failed to init com\n"); + CoUninitialize(); + hr = CoGetApartmentType(&type, &qualifier); + ok(hr == CO_E_NOTINITIALIZED, "got %#lx.\n", hr); + + hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); + ok(hr == S_OK, "failed to init com\n"); + hr = CoGetApartmentType(&type, &qualifier); + ok(hr == S_OK, "got %#lx.\n", hr); + ok(type == APTTYPE_MTA, "got %d.\n", type); + ok(qualifier == APTTYPEQUALIFIER_NONE, "got %d.\n", qualifier); + + callback_init(&callback, NULL); + + hr = WMCreateReader(NULL, 0, &reader); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IWMReader_Open(reader, filename, &callback.IWMReaderCallback_iface, (void **)0xdeadbeef); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + wait_opened_callback(&callback); + + CoUninitialize(); + hr = CoGetApartmentType(&type, &qualifier); + todo_wine ok(hr == S_OK, "got %#lx.\n", hr); + todo_wine ok(type == APTTYPE_MTA, "got %d.\n", type); + todo_wine ok(qualifier == APTTYPEQUALIFIER_IMPLICIT_MTA, "got %d.\n", qualifier); + + hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); + ok(hr == S_OK, "failed to init com\n"); + + SetEvent(callback.expect_started); + hr = IWMReader_Start(reader, 0, 0, 1, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IWMReader_Close(reader); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + IWMReader_Release(reader); + + callback_cleanup(&callback); + + DeleteFileW(filename); + + CoUninitialize(); +} + START_TEST(wmvcore) { HRESULT hr; + /* Keep this test before CoInitialize(). */ + test_async_reader_com_init(); + hr = CoInitialize(0); ok(hr == S_OK, "failed to init com\n"); if(hr != S_OK) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10605
From: Paul Gofman <pgofman@codeweavers.com> --- dlls/wmvcore/Makefile.in | 2 +- dlls/wmvcore/async_reader.c | 3 +++ dlls/wmvcore/tests/wmvcore.c | 6 +++--- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/dlls/wmvcore/Makefile.in b/dlls/wmvcore/Makefile.in index 8dc574d43d5..7f3a8553f62 100644 --- a/dlls/wmvcore/Makefile.in +++ b/dlls/wmvcore/Makefile.in @@ -1,6 +1,6 @@ MODULE = wmvcore.dll IMPORTLIB = wmvcore -IMPORTS = kernel32 +IMPORTS = kernel32 combase DELAYIMPORTS = winegstreamer EXTRADLLFLAGS = -Wb,--prefer-native diff --git a/dlls/wmvcore/async_reader.c b/dlls/wmvcore/async_reader.c index ef657d561ba..c41bd96cd6c 100644 --- a/dlls/wmvcore/async_reader.c +++ b/dlls/wmvcore/async_reader.c @@ -358,6 +358,8 @@ static DWORD WINAPI async_reader_callback_thread(void *arg) struct list *entry; HRESULT hr = S_OK; + CoInitializeEx(NULL, COINIT_MULTITHREADED); + IWMReaderCallback_OnStatus(reader->callback, WMT_OPENED, S_OK, WMT_TYPE_DWORD, (BYTE *)&zero, reader->context); @@ -418,6 +420,7 @@ static DWORD WINAPI async_reader_callback_thread(void *arg) LeaveCriticalSection(&reader->callback_cs); + CoUninitialize(); TRACE("Reader is stopping; exiting.\n"); return 0; } diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c index fe0d8d89b3c..f839c47b935 100644 --- a/dlls/wmvcore/tests/wmvcore.c +++ b/dlls/wmvcore/tests/wmvcore.c @@ -4338,9 +4338,9 @@ static void test_async_reader_com_init(void) CoUninitialize(); hr = CoGetApartmentType(&type, &qualifier); - todo_wine ok(hr == S_OK, "got %#lx.\n", hr); - todo_wine ok(type == APTTYPE_MTA, "got %d.\n", type); - todo_wine ok(qualifier == APTTYPEQUALIFIER_IMPLICIT_MTA, "got %d.\n", qualifier); + ok(hr == S_OK, "got %#lx.\n", hr); + ok(type == APTTYPE_MTA, "got %d.\n", type); + ok(qualifier == APTTYPEQUALIFIER_IMPLICIT_MTA, "got %d.\n", qualifier); hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); ok(hr == S_OK, "failed to init com\n"); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10605
That helps Deadly Premonition which completely uninitializes (multithreaded) COM aparetnemt on main thread at some moment which results in some dlls loaded with combase being unloaded which leads to a crash. The wmvcore's thread is the one alive at that moment and, as the included test shows, should have COM initialized, so MTA doesn't get destroyed. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10605#note_135568
This merge request was approved by Elizabeth Figura. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10605
participants (3)
-
Elizabeth Figura (@zfigura) -
Paul Gofman -
Paul Gofman (@gofman)