From: Mark Harmstone Subject: [PATCH] user32: Support activation context class redirection in CreateWindow. Message-Id: <5517311A.2080908@burntcomma.com> Date: Sat, 28 Mar 2015 22:54:18 +0000 This patch implements the class redirection feature of activation contexts, as used by version 6 of comctl32. Among other things, this is a necessary step in fixing the behaviour seen in bug 38124. --- dlls/user32/win.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/dlls/user32/win.c b/dlls/user32/win.c index 8ff3ebd..fe8c397 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -55,6 +55,17 @@ static CRITICAL_SECTION_DEBUG critsect_debug = }; static CRITICAL_SECTION surfaces_section = { &critsect_debug, -1, 0, 0, 0, 0 }; +/* from dlls/ntdll/actctx.c */ +struct wndclass_redirect_data +{ + ULONG size; + DWORD res; + ULONG name_len; + ULONG name_offset; + ULONG module_len; + ULONG module_offset; +}; + /**********************************************************************/ /* helper for Get/SetWindowLong */ @@ -1292,6 +1303,39 @@ static void dump_window_styles( DWORD style, DWORD exstyle ) #undef DUMPED_EX_STYLES } +static BOOL get_redir_class_name(LPCWSTR className, LPWSTR redirClassName, int len) +{ + ATOM classatom; + ACTCTX_SECTION_KEYED_DATA askd; + WCHAR classNameStr[256]; + struct wndclass_redirect_data* wcrd; + + classatom = get_int_atom_value(className); + if (classatom) + GlobalGetAtomNameW(classatom, classNameStr, sizeof(classNameStr) / sizeof(*classNameStr)); + else + strcpyW(classNameStr, className); + + askd.cbSize = sizeof(askd); + if (FindActCtxSectionStringW(0, NULL, ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, classNameStr, &askd)) { + wcrd = askd.lpData; + + if (wcrd->name_len == 0) + return FALSE; + + if (wcrd->name_len > len) { + WARN("Redirected class name too long for buffer\n"); + return FALSE; + } + + memcpy(redirClassName, (unsigned char*)askd.lpData + wcrd->name_offset, wcrd->name_len); + redirClassName[wcrd->name_len / sizeof(WCHAR)] = 0; + + return TRUE; + } + + return FALSE; +} /*********************************************************************** * WIN_CreateWindowEx @@ -1308,6 +1352,7 @@ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module, MDICREATESTRUCTW mdi_cs; CBT_CREATEWNDW cbtc; CREATESTRUCTW cbcs; + WCHAR redirClassName[256]; TRACE("%s %s ex=%08x style=%08x %d,%d %dx%d parent=%p menu=%p inst=%p params=%p\n", unicode ? debugstr_w(cs->lpszName) : debugstr_a((LPCSTR)cs->lpszName), @@ -1444,6 +1489,23 @@ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module, /* Create the window structure */ + wndPtr = NULL; + + if (get_redir_class_name(className, redirClassName, sizeof(redirClassName))) + { + WNDCLASSW wc; + + TRACE("Redirecting %s to %s\n", debugstr_w(className), debugstr_w(redirClassName)); + + wndPtr = create_window_handle( parent, owner, redirClassName, module, unicode ); + + if (GetLastError() == ERROR_INVALID_HANDLE && GetClassInfoW( 0, redirClassName, &wc )) + wndPtr = create_window_handle( parent, owner, redirClassName, module, unicode ); + + if (!wndPtr) + WARN("Could not create window of class %s\n", debugstr_w(redirClassName)); + } + if (!(wndPtr = create_window_handle( parent, owner, className, module, unicode ))) { WNDCLASSW wc;