[RPCRT4] Sync with Wine Staging 1.9.23. CORE-12409
[reactos.git] / reactos / dll / win32 / rpcrt4 / rpc_epmap.c
index b7ee205..b299643 100644 (file)
@@ -21,6 +21,9 @@
  */
 
 #include "precomp.h"
+
+#include <winsvc.h>
+
 #include "epm_towers.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
@@ -65,32 +68,52 @@ static const struct epm_endpoints
 
 static BOOL start_rpcss(void)
 {
-    PROCESS_INFORMATION pi;
-    STARTUPINFOW si;
-    WCHAR cmd[MAX_PATH];
-    static const WCHAR rpcss[] = {'\\','r','p','c','s','s','.','e','x','e',0};
-    BOOL rslt;
-    void *redir;
+    static const WCHAR rpcssW[] = {'R','p','c','S','s',0};
+    SC_HANDLE scm, service;
+    SERVICE_STATUS_PROCESS status;
+    BOOL ret = FALSE;
 
     TRACE("\n");
 
-    ZeroMemory(&si, sizeof(STARTUPINFOA));
-    si.cb = sizeof(STARTUPINFOA);
-    GetSystemDirectoryW( cmd, MAX_PATH - sizeof(rpcss)/sizeof(WCHAR) );
-    lstrcatW( cmd, rpcss );
-
-    Wow64DisableWow64FsRedirection( &redir );
-    rslt = CreateProcessW( cmd, cmd, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &si, &pi );
-    Wow64RevertWow64FsRedirection( redir );
-
-    if (rslt)
+    if (!(scm = OpenSCManagerW( NULL, NULL, 0 )))
+    {
+        ERR( "failed to open service manager\n" );
+        return FALSE;
+    }
+    if (!(service = OpenServiceW( scm, rpcssW, SERVICE_START | SERVICE_QUERY_STATUS )))
+    {
+        ERR( "failed to open RpcSs service\n" );
+        CloseServiceHandle( scm );
+        return FALSE;
+    }
+    if (StartServiceW( service, 0, NULL ) || GetLastError() == ERROR_SERVICE_ALREADY_RUNNING)
     {
-        CloseHandle(pi.hProcess);
-        CloseHandle(pi.hThread);
-        Sleep(100);
+        ULONGLONG start_time = GetTickCount64();
+        do
+        {
+            DWORD dummy;
+
+            if (!QueryServiceStatusEx( service, SC_STATUS_PROCESS_INFO,
+                                       (BYTE *)&status, sizeof(status), &dummy ))
+                break;
+            if (status.dwCurrentState == SERVICE_RUNNING)
+            {
+                ret = TRUE;
+                break;
+            }
+            if (GetTickCount64() - start_time > 30000) break;
+            Sleep( 100 );
+
+        } while (status.dwCurrentState == SERVICE_START_PENDING);
+
+        if (status.dwCurrentState != SERVICE_RUNNING)
+            WARN( "RpcSs failed to start %u\n", status.dwCurrentState );
     }
+    else ERR( "failed to start RpcSs service\n" );
 
-    return rslt;
+    CloseServiceHandle( service );
+    CloseServiceHandle( scm );
+    return ret;
 }
 
 static inline BOOL is_epm_destination_local(RPC_BINDING_HANDLE handle)