[PATCH 4/6] combase: Start surrogate local server when required.

Dmitry Timoshkov dmitry at baikal.ru
Wed Mar 9 01:45:56 CST 2022


Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=20296
Signed-off-by: Dmitry Timoshkov <dmitry at 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;
         }
 
-- 
2.35.1




More information about the wine-devel mailing list