[PATCH 2/3] Add support for window class redirection with SxS manifest
Nikolay Sivov
bunglehead at gmail.com
Thu Dec 17 14:52:10 CST 2009
---
dlls/user32/class.c | 20 ++++++++++++
dlls/user32/controls.h | 1 +
dlls/user32/win.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 103 insertions(+), 0 deletions(-)
diff --git a/dlls/user32/class.c b/dlls/user32/class.c
index e8ca0e5..da0167d 100644
--- a/dlls/user32/class.c
+++ b/dlls/user32/class.c
@@ -384,6 +384,25 @@ static CLASS *CLASS_RegisterClass( LPCWSTR name, HINSTANCE hInstance, BOOL local
return classPtr;
}
+/***********************************************************************
+ * is_class_redirectable
+ *
+ * Checks if class redirection through SxS is available for this class.
+ */
+BOOL is_class_redirectable( LPCWSTR className, ACTCTX_SECTION_KEYED_DATA *data )
+{
+ ACTCTX_SECTION_KEYED_DATA key_data = { sizeof(key_data) };
+
+ if (get_int_atom_value(className)) return FALSE;
+
+ if (!data) data = &key_data;
+
+ return FindActCtxSectionStringW(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX,
+ NULL,
+ ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION,
+ className,
+ data);
+}
/***********************************************************************
* register_builtin
@@ -395,6 +414,7 @@ static void register_builtin( const struct builtin_class_descr *descr )
{
CLASS *classPtr;
+ if (is_class_redirectable( descr->name, NULL )) return;
if (!(classPtr = CLASS_RegisterClass( descr->name, user32_module, FALSE,
descr->style, 0, descr->extra ))) return;
diff --git a/dlls/user32/controls.h b/dlls/user32/controls.h
index e7aa408..36a427d 100644
--- a/dlls/user32/controls.h
+++ b/dlls/user32/controls.h
@@ -125,6 +125,7 @@ extern WNDPROC get_class_winproc( struct tagCLASS *class ) DECLSPEC_HIDDEN;
extern struct dce *get_class_dce( struct tagCLASS *class ) DECLSPEC_HIDDEN;
extern struct dce *set_class_dce( struct tagCLASS *class, struct dce *dce ) DECLSPEC_HIDDEN;
extern void CLASS_FreeModuleClasses( HMODULE16 hModule ) DECLSPEC_HIDDEN;
+extern BOOL is_class_redirectable( LPCWSTR className, ACTCTX_SECTION_KEYED_DATA *data ) DECLSPEC_HIDDEN;
/* defwnd proc */
extern HBRUSH DEFWND_ControlColor( HDC hDC, UINT ctlType ) DECLSPEC_HIDDEN;
diff --git a/dlls/user32/win.c b/dlls/user32/win.c
index 9712beb..cdc9f6d 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -1063,6 +1063,85 @@ static void dump_window_styles( DWORD style, DWORD exstyle )
#undef DUMPED_EX_STYLES
}
+/***********************************************************************
+ * notify_class_redirection
+ *
+ * Tries to redirect specified window class to SxS module that claims to
+ * support it.
+ */
+static BOOL notify_class_redirection( LPCWSTR className )
+{
+ ASSEMBLY_FILE_DETAILED_INFORMATION *file_info;
+ ACTCTX_SECTION_KEYED_DATA key_data = { sizeof(key_data) };
+ ACTIVATION_CONTEXT_QUERY_INDEX query_index;
+ SIZE_T size;
+ BOOL ret;
+
+ PREGISTERCLASSNAMEW pRegisterClassNameW;
+ HMODULE mod;
+
+ TRACE("%s\n", wine_dbgstr_w(className));
+
+ if (!is_class_redirectable(className, &key_data)) return TRUE;
+
+ TRACE("string %s found\n", wine_dbgstr_w(className));
+ TRACE("hActCtx=%p, ulAssemblyRosterIndex=%u\n",
+ key_data.hActCtx, key_data.ulAssemblyRosterIndex);
+
+ query_index.ulAssemblyIndex = key_data.ulAssemblyRosterIndex - 1;
+ /* assuming single file SxS modules */
+ query_index.ulFileIndexInAssembly = 0;
+ size = 0;
+ ret = QueryActCtxW(0, key_data.hActCtx,
+ &query_index,
+ FileInformationInAssemblyOfAssemblyInActivationContext,
+ NULL, 0, &size);
+
+ if (ret || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ {
+ ReleaseActCtx(key_data.hActCtx);
+ return TRUE;
+ }
+
+ file_info = HeapAlloc(GetProcessHeap(), 0, size);
+ if (!file_info) return TRUE;
+
+ ret = QueryActCtxW(0, key_data.hActCtx,
+ &query_index,
+ FileInformationInAssemblyOfAssemblyInActivationContext,
+ file_info, size, NULL);
+
+ ReleaseActCtx(key_data.hActCtx);
+ if (!ret)
+ {
+ HeapFree(GetProcessHeap(), 0, file_info);
+ return TRUE;
+ }
+
+ TRACE("class redirection module found (%s)\n", wine_dbgstr_w(file_info->lpFileName));
+
+ if (!(mod = LoadLibraryW(file_info->lpFileName)))
+ {
+ WARN("failed to get module handle for (%s)\n", wine_dbgstr_w(file_info->lpFileName));
+ HeapFree(GetProcessHeap(), 0, file_info);
+ return TRUE;
+ }
+
+ if (!(pRegisterClassNameW = (void*)GetProcAddress(mod, "RegisterClassNameW")))
+ {
+ WARN("RegisterClassNameW() symbol not found in (%s)\n", wine_dbgstr_w(file_info->lpFileName));
+ ret = TRUE;
+ goto out;
+ }
+
+ /* native isn't protected from exception here too */
+ ret = pRegisterClassNameW(className);
+
+out:
+ HeapFree(GetProcessHeap(), 0, file_info);
+ FreeLibrary(mod);
+ return ret;
+}
/***********************************************************************
* WIN_CreateWindowEx
@@ -1197,6 +1276,9 @@ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module,
else
cs->dwExStyle &= ~WS_EX_WINDOWEDGE;
+ /* Try window class redirection */
+ if (!notify_class_redirection( className )) return 0;
+
/* Create the window structure */
if (!(wndPtr = create_window_handle( parent, owner, className, module, unicode )))
--
1.5.6.5
--=-qdNhBdLRm72yfSMvbvRg--
More information about the wine-patches
mailing list