1
0
mirror of https://github.com/wine-mirror/wine synced 2024-07-08 03:45:57 +00:00

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 e41c255be6
"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
This commit is contained in:
Alexandros Frantzis 2022-08-30 10:20:42 +03:00 committed by Alexandre Julliard
parent e9de4ae05c
commit 97e018f9a5
2 changed files with 13 additions and 12 deletions

View File

@ -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
{

View File

@ -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 );