1
0
mirror of https://github.com/wine-mirror/wine synced 2024-07-01 07:14:31 +00:00

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@baikal.ru>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Dmitry Timoshkov 2022-06-27 12:49:11 +03:00 committed by Alexandre Julliard
parent 9ba69dce36
commit 3c9720f4a6

View File

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