Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=20296 Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/combase/rpc.c | 47 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-)
diff --git a/dlls/combase/rpc.c b/dlls/combase/rpc.c index 0a86183030a..79f9b0d9c41 100644 --- a/dlls/combase/rpc.c +++ b/dlls/combase/rpc.c @@ -522,6 +522,50 @@ static HRESULT create_server(REFCLSID rclsid, HANDLE *process) return S_OK; }
+static HRESULT create_surrogate_server(REFCLSID rclsid, HANDLE *process) +{ + HKEY key; + HRESULT hr; + WCHAR command[MAX_PATH + 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 {GUID} switch. */ + 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 +590,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; }