Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/combase/rpc.c | 48 +++++++++++++++++++++++++++++---------
programs/dllhost/dllhost.c | 2 ++
2 files changed, 39 insertions(+), 11 deletions(-)
diff --git a/dlls/combase/rpc.c b/dlls/combase/rpc.c
index 40f900175dd..f620339f19e 100644
--- a/dlls/combase/rpc.c
+++ b/dlls/combase/rpc.c
@@ -526,18 +526,24 @@ static HRESULT create_surrogate_server(REFCLSID rclsid, HANDLE *process)
{
static const WCHAR processidW[] = L" /PROCESSID:";
HKEY key;
+ int arch = (sizeof(void *) > sizeof(int)) ? 64 : 32;
+ REGSAM opposite = (arch == 64) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY;
+ BOOL is_wow64 = FALSE;
HRESULT hr;
WCHAR command[MAX_PATH + ARRAY_SIZE(processidW) + CHARS_IN_GUID];
DWORD size;
- STARTUPINFOW sinfo;
- PROCESS_INFORMATION pinfo;
+ STARTUPINFOW si;
+ PROCESS_INFORMATION pi;
LONG ret;
TRACE("Attempting to start surrogate server for %s\n", debugstr_guid(rclsid));
hr = open_appidkey_from_clsid(rclsid, KEY_READ, &key);
- if (FAILED(hr))
- return hr;
+ if (FAILED(hr) && (arch == 64 || (IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64)))
+ {
+ hr = open_appidkey_from_clsid(rclsid, opposite | KEY_READ, &key);
+ if (FAILED(hr)) return hr;
+ }
size = (MAX_PATH + 1) * sizeof(WCHAR);
ret = RegQueryValueExW(key, L"DllSurrogate", NULL, NULL, (LPBYTE)command, &size);
@@ -545,25 +551,45 @@ static HRESULT create_surrogate_server(REFCLSID rclsid, HANDLE *process)
if (ret || !size || !command[0])
{
TRACE("No value for DllSurrogate key\n");
- wcscpy(command, L"dllhost.exe");
+
+ if ((sizeof(void *) == 8 || is_wow64) && opposite == KEY_WOW64_32KEY)
+ GetSystemWow64DirectoryW(command, MAX_PATH - ARRAY_SIZE(L"\\dllhost.exe"));
+ else
+ GetSystemDirectoryW(command, MAX_PATH - ARRAY_SIZE(L"\\dllhost.exe"));
+
+ wcscat(command, L"\\dllhost.exe");
}
/* Surrogate EXE servers are started with the /PROCESSID:{GUID} switch. */
wcscat(command, processidW);
StringFromGUID2(rclsid, command + wcslen(command), CHARS_IN_GUID);
- memset(&sinfo, 0, sizeof(sinfo));
- sinfo.cb = sizeof(sinfo);
+ memset(&si, 0, sizeof(si));
+ si.cb = sizeof(si);
TRACE("Activating surrogate local server %s\n", debugstr_w(command));
- if (!CreateProcessW(NULL, command, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &sinfo, &pinfo))
+ if (is_wow64 && arch == 64)
+ {
+ void *cookie;
+ Wow64DisableWow64FsRedirection(&cookie);
+ if (!CreateProcessW(NULL, command, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &si, &pi))
+ {
+ WARN("failed to run surrogate local server %s\n", debugstr_w(command));
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ }
+ Wow64RevertWow64FsRedirection(cookie);
+ }
+ else if (!CreateProcessW(NULL, command, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &si, &pi))
{
WARN("failed to run surrogate local server %s\n", debugstr_w(command));
- return HRESULT_FROM_WIN32(GetLastError());
+ hr = HRESULT_FROM_WIN32(GetLastError());
}
- *process = pinfo.hProcess;
- CloseHandle(pinfo.hThread);
+
+ if (FAILED(hr)) return hr;
+
+ *process = pi.hProcess;
+ CloseHandle(pi.hThread);
return S_OK;
}
diff --git a/programs/dllhost/dllhost.c b/programs/dllhost/dllhost.c
index dc89c978510..83700826f8b 100644
--- a/programs/dllhost/dllhost.c
+++ b/programs/dllhost/dllhost.c
@@ -327,6 +327,8 @@ int WINAPI wWinMain(HINSTANCE hinst, HINSTANCE previnst, LPWSTR cmdline, int sho
CLSID clsid;
struct surrogate surrogate;
+ TRACE("Running as %u-bit\n", (int)sizeof(void *) * 8);
+
if (wcsnicmp(cmdline, L"/PROCESSID:", 11))
return 0;
--
2.35.1