Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=20296 Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/combase/rpc.c | 49 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-)
diff --git a/dlls/combase/rpc.c b/dlls/combase/rpc.c index 0a86183030a..40f900175dd 100644 --- a/dlls/combase/rpc.c +++ b/dlls/combase/rpc.c @@ -522,6 +522,52 @@ static HRESULT create_server(REFCLSID rclsid, HANDLE *process) return S_OK; }
+static HRESULT create_surrogate_server(REFCLSID rclsid, HANDLE *process) +{ + static const WCHAR processidW[] = L" /PROCESSID:"; + HKEY key; + HRESULT hr; + WCHAR command[MAX_PATH + ARRAY_SIZE(processidW) + CHARS_IN_GUID]; + DWORD size; + STARTUPINFOW sinfo; + PROCESS_INFORMATION pinfo; + 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; + + size = (MAX_PATH + 1) * sizeof(WCHAR); + ret = RegQueryValueExW(key, L"DllSurrogate", NULL, NULL, (LPBYTE)command, &size); + RegCloseKey(key); + if (ret || !size || !command[0]) + { + TRACE("No value for DllSurrogate key\n"); + wcscpy(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); + + TRACE("Activating surrogate local server %s\n", debugstr_w(command)); + + if (!CreateProcessW(NULL, command, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &sinfo, &pinfo)) + { + WARN("failed to run surrogate local server %s\n", debugstr_w(command)); + return HRESULT_FROM_WIN32(GetLastError()); + } + *process = pinfo.hProcess; + CloseHandle(pinfo.hThread); + + return S_OK; +} + HRESULT rpc_get_local_class_object(REFCLSID rclsid, REFIID riid, void **obj) { PMInterfacePointer objref = NULL; @@ -546,7 +592,8 @@ HRESULT rpc_get_local_class_object(REFCLSID rclsid, REFIID riid, void **obj)
if (tries == 1) { - if ((hr = create_local_service(rclsid)) && (hr = create_server(rclsid, &process)) ) + if ((hr = create_local_service(rclsid)) && (hr = create_server(rclsid, &process)) && + (hr = create_surrogate_server(rclsid, &process)) ) return hr; }