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(a)baikal.ru>
---
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());
--
2.36.1