Commit 3c9720f4 authored by Dmitry Timoshkov's avatar Dmitry Timoshkov Committed by Alexandre Julliard

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: 's avatarDmitry Timoshkov <dmitry@baikal.ru> Signed-off-by: 's avatarHuw Davies <huw@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 9ba69dce
...@@ -477,6 +477,9 @@ static HRESULT create_server(REFCLSID rclsid, HANDLE *process) ...@@ -477,6 +477,9 @@ static HRESULT create_server(REFCLSID rclsid, HANDLE *process)
{ {
static const WCHAR embeddingW[] = L" -Embedding"; static const WCHAR embeddingW[] = L" -Embedding";
HKEY key; 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; HRESULT hr;
WCHAR command[MAX_PATH + ARRAY_SIZE(embeddingW)]; WCHAR command[MAX_PATH + ARRAY_SIZE(embeddingW)];
DWORD size = (MAX_PATH+1) * sizeof(WCHAR); DWORD size = (MAX_PATH+1) * sizeof(WCHAR);
...@@ -484,7 +487,14 @@ static HRESULT create_server(REFCLSID rclsid, HANDLE *process) ...@@ -484,7 +487,14 @@ static HRESULT create_server(REFCLSID rclsid, HANDLE *process)
PROCESS_INFORMATION pinfo; PROCESS_INFORMATION pinfo;
LONG ret; LONG ret;
TRACE("Attempting to start server for %s\n", debugstr_guid(rclsid));
hr = open_key_for_clsid(rclsid, L"LocalServer32", KEY_READ, &key); 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)) if (FAILED(hr))
{ {
ERR("class %s not registered\n", debugstr_guid(rclsid)); ERR("class %s not registered\n", debugstr_guid(rclsid));
...@@ -510,9 +520,21 @@ static HRESULT create_server(REFCLSID rclsid, HANDLE *process) ...@@ -510,9 +520,21 @@ static HRESULT create_server(REFCLSID rclsid, HANDLE *process)
/* FIXME: Win2003 supports a ServerExecutable value that is passed into /* FIXME: Win2003 supports a ServerExecutable value that is passed into
* CreateProcess */ * CreateProcess */
if (is_opposite)
{
void *cookie;
Wow64DisableWow64FsRedirection(&cookie);
if (!CreateProcessW(NULL, command, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &sinfo, &pinfo)) if (!CreateProcessW(NULL, command, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &sinfo, &pinfo))
{ {
WARN("failed to run local server %s\n", debugstr_w(command)); 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()); return HRESULT_FROM_WIN32(GetLastError());
} }
*process = pinfo.hProcess; *process = pinfo.hProcess;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment