From 97e018f9a5f0ba360920747362f2e1270c0406b4 Mon Sep 17 00:00:00 2001 From: Alexandros Frantzis Date: Tue, 30 Aug 2022 10:20:42 +0300 Subject: [PATCH] msvfw32: Use window name to determine if window is created using MCIWndCreate. The current version of the code incorrectly assumes that the lpszClass member of CREATESTRUCT passed with WM_CREATE will point to the same memory used for the CreateWindowEx class name parameter. MCIWND_Create uses this assumption to perform a pointer comparison on the class name to determine whether the MCI window is being created using MCIWndCreateA/W and should therefore expect a unicode path parameter. As a side effect of commit e41c255be6ba66d1eec7affe674b8cc7699226b8 "win32u: Use send_message_timeout for WM_CREATE and WM_NCCREATE" the CREATESTRUCT lpszClass member started pointing to different memory, breaking the current implementation of MCIWND_Create(). This commit fixes the problem by changing MCIWndCreateA/W to use an internal window name, unlikely to be used by normal applications, which can then be checked in MCIWND_Create to determine if the MCI window is being created using MCIWndCreateA/W. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53578 --- dlls/msvfw32/mciwnd.c | 9 ++++++--- dlls/msvfw32/tests/mciwnd.c | 16 +++++++--------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/dlls/msvfw32/mciwnd.c b/dlls/msvfw32/mciwnd.c index 8799293f7c9..e5f387a0bab 100644 --- a/dlls/msvfw32/mciwnd.c +++ b/dlls/msvfw32/mciwnd.c @@ -38,6 +38,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(mci); extern HMODULE MSVFW32_hModule; static const WCHAR mciWndClassW[] = {'M','C','I','W','n','d','C','l','a','s','s',0}; +static const WCHAR mciWndNameW[] = {'M','C','I','W','n','d','C','r','e','a','t','e', + 'W','i','n','e','I','n','t','e','r','n','a','l', 0}; typedef struct { @@ -113,7 +115,7 @@ HWND VFWAPIV MCIWndCreateW(HWND hwndParent, HINSTANCE hInstance, else dwStyle |= WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX; - return CreateWindowExW(0, mciWndClassW, NULL, + return CreateWindowExW(0, mciWndClassW, mciWndNameW, dwStyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, 300, 0, hwndParent, 0, hInstance, (LPVOID)szFile); @@ -314,8 +316,9 @@ static LRESULT MCIWND_Create(HWND hWnd, LPCREATESTRUCTW cs) else lParam = (LPARAM)cs->lpCreateParams; - /* If it's our internal class pointer, file name is a unicode string */ - if (cs->lpszClass == mciWndClassW) + /* If it's our internal window name, we are being called from MCIWndCreateA/W, + * so file name is a unicode string */ + if (!lstrcmpW(cs->lpszName, mciWndNameW)) SendMessageW(hWnd, MCIWNDM_OPENW, 0, lParam); else { diff --git a/dlls/msvfw32/tests/mciwnd.c b/dlls/msvfw32/tests/mciwnd.c index 915624b2eeb..8bf4c103a6c 100644 --- a/dlls/msvfw32/tests/mciwnd.c +++ b/dlls/msvfw32/tests/mciwnd.c @@ -160,7 +160,7 @@ static struct { const WCHAR* expectedW; /* output */ unsigned open_msg; - enum {NO_MATCH, PTR_ANSI_MATCH, PTR_UNICODE_MATCH, ANSI_MATCH, UNICODE_MATCH, TODO_WINE = 0x40} match; + enum {NO_MATCH, PTR_ANSI_MATCH, PTR_UNICODE_MATCH, ANSI_MATCH, UNICODE_MATCH } match; } wnd_creation; static WNDPROC old_MCIWndProc; @@ -217,7 +217,7 @@ static void test_window_create(unsigned line, const char* fname, HWND parent, HWND window; char error[200]; LRESULT ret; - BOOL expect_ansi = (match & ~TODO_WINE) == PTR_ANSI_MATCH || (match & ~TODO_WINE) == ANSI_MATCH; + BOOL expect_ansi = match == PTR_ANSI_MATCH || match == ANSI_MATCH; MultiByteToWideChar(CP_ACP, 0, fname, -1, fnameW, ARRAY_SIZE(fnameW)); @@ -247,15 +247,13 @@ static void test_window_create(unsigned line, const char* fname, HWND parent, parent, 0, hinst, expect_ansi ? (LPVOID)fname : (LPVOID)fnameW); } ok_(__FILE__, line)(window != NULL, "Failed to create an MCIWnd window\n"); - ok_(__FILE__, line)(wnd_creation.match == (match & ~TODO_WINE), "unexpected match %u\n", wnd_creation.match); - todo_wine_if(match & TODO_WINE) + ok_(__FILE__, line)(wnd_creation.match == match, "unexpected match %u\n", wnd_creation.match); ok_(__FILE__, line)((expect_ansi && wnd_creation.open_msg == MCIWNDM_OPENA) || (!expect_ansi && wnd_creation.open_msg == MCIWNDM_OPENW), "bad open message %u %s%u\n", match, wnd_creation.open_msg >= WM_USER ? "WM_USER+" : "", wnd_creation.open_msg >= WM_USER ? wnd_creation.open_msg - WM_USER : wnd_creation.open_msg); ret = SendMessageA(window, MCIWNDM_GETERRORA, sizeof(error), (LPARAM)error); - todo_wine_if(match & TODO_WINE) ok_(__FILE__, line)(!ret || broken(ret == ERROR_INVALID_HANDLE) /* w2003std, w2008s64 */, "Unexpected error %Id\n", ret); DestroyWindow(window); @@ -275,8 +273,8 @@ static void test_MCIWndCreate(void) hook = SetWindowsHookExW( WH_CBT, hook_proc, NULL, GetCurrentThreadId() ); - test_window_create( __LINE__, fname, NULL, TRUE, TRUE, UNICODE_MATCH | TODO_WINE ); - test_window_create( __LINE__, fname, NULL, TRUE, FALSE, PTR_UNICODE_MATCH | TODO_WINE ); + test_window_create( __LINE__, fname, NULL, TRUE, TRUE, UNICODE_MATCH ); + test_window_create( __LINE__, fname, NULL, TRUE, FALSE, PTR_UNICODE_MATCH ); test_window_create( __LINE__, fname, NULL, FALSE, TRUE, PTR_ANSI_MATCH ); test_window_create( __LINE__, fname, NULL, FALSE, FALSE, PTR_ANSI_MATCH ); @@ -286,8 +284,8 @@ static void test_MCIWndCreate(void) ok(parent != NULL, "Failed to create a window\n"); ok(!IsWindowUnicode(parent), "Expecting ansi parent window\n"); - test_window_create( __LINE__, fname, parent, TRUE, TRUE, UNICODE_MATCH | TODO_WINE ); - test_window_create( __LINE__, fname, parent, TRUE, FALSE, PTR_UNICODE_MATCH | TODO_WINE ); + test_window_create( __LINE__, fname, parent, TRUE, TRUE, UNICODE_MATCH ); + test_window_create( __LINE__, fname, parent, TRUE, FALSE, PTR_UNICODE_MATCH ); test_window_create( __LINE__, fname, parent, FALSE, TRUE, PTR_ANSI_MATCH ); test_window_create( __LINE__, fname, parent, FALSE, FALSE, PTR_ANSI_MATCH );