Dmitry Timoshkov : combase: Execute local server for correct architecture in a WoW64 setup.
Alexandre Julliard
julliard at winehq.org
Mon Jul 4 16:43:32 CDT 2022
Module: wine
Branch: master
Commit: 3c9720f4a6b2ffd873c886da53f045709fe98b67
URL: https://source.winehq.org/git/wine.git/?a=commit;h=3c9720f4a6b2ffd873c886da53f045709fe98b67
Author: Dmitry Timoshkov <dmitry at baikal.ru>
Date: Mon Jun 27 12:49:11 2022 +0300
combase: Execute local server for correct architecture in a WoW64 setup.
Based on implementation of create_surrogate_server().
This patch makes 64-bit application work with its own shipped 32-bit COM server.
Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/combase/rpc.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/dlls/combase/rpc.c b/dlls/combase/rpc.c
index 3a171dbb324..c51b59de4bf 100644
--- a/dlls/combase/rpc.c
+++ b/dlls/combase/rpc.c
@@ -477,6 +477,9 @@ static HRESULT create_server(REFCLSID rclsid, HANDLE *process)
{
static const WCHAR embeddingW[] = L" -Embedding";
HKEY key;
+ int arch = (sizeof(void *) > sizeof(int)) ? 64 : 32;
+ REGSAM opposite = (arch == 64) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY;
+ BOOL is_wow64 = FALSE, is_opposite = FALSE;
HRESULT hr;
WCHAR command[MAX_PATH + ARRAY_SIZE(embeddingW)];
DWORD size = (MAX_PATH+1) * sizeof(WCHAR);
@@ -484,7 +487,14 @@ static HRESULT create_server(REFCLSID rclsid, HANDLE *process)
PROCESS_INFORMATION pinfo;
LONG ret;
+ TRACE("Attempting to start server for %s\n", debugstr_guid(rclsid));
+
hr = open_key_for_clsid(rclsid, L"LocalServer32", KEY_READ, &key);
+ if (FAILED(hr) && (arch == 64 || (IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64)))
+ {
+ hr = open_key_for_clsid(rclsid, L"LocalServer32", opposite | KEY_READ, &key);
+ is_opposite = TRUE;
+ }
if (FAILED(hr))
{
ERR("class %s not registered\n", debugstr_guid(rclsid));
@@ -510,7 +520,19 @@ static HRESULT create_server(REFCLSID rclsid, HANDLE *process)
/* FIXME: Win2003 supports a ServerExecutable value that is passed into
* CreateProcess */
- if (!CreateProcessW(NULL, command, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &sinfo, &pinfo))
+ if (is_opposite)
+ {
+ void *cookie;
+ Wow64DisableWow64FsRedirection(&cookie);
+ if (!CreateProcessW(NULL, command, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &sinfo, &pinfo))
+ {
+ WARN("failed to run local server %s\n", debugstr_w(command));
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ }
+ Wow64RevertWow64FsRedirection(cookie);
+ if (FAILED(hr)) return hr;
+ }
+ else if (!CreateProcessW(NULL, command, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &sinfo, &pinfo))
{
WARN("failed to run local server %s\n", debugstr_w(command));
return HRESULT_FROM_WIN32(GetLastError());
More information about the wine-cvs
mailing list