Progress with opening and closing handles to SCM.
authorRobert Dickenson <robd@reactos.org>
Fri, 27 Dec 2002 14:40:03 +0000 (14:40 +0000)
committerRobert Dickenson <robd@reactos.org>
Fri, 27 Dec 2002 14:40:03 +0000 (14:40 +0000)
svn path=/trunk/; revision=3899

reactos/lib/advapi32/service/scm.c

index 5c52929..df7dce6 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: scm.c,v 1.14 2002/12/26 17:23:27 robd Exp $
+/* $Id: scm.c,v 1.15 2002/12/27 14:40:03 robd Exp $
  * 
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
@@ -6,8 +6,8 @@
  * PURPOSE:         Service control manager functions
  * PROGRAMMER:      Emanuele Aliberti
  * UPDATE HISTORY:
- *     19990413 EA     created
- *     19990515 EA
+ *  19990413 EA created
+ *  19990515 EA
  */
 
 /* INCLUDES ******************************************************************/
 #include <windows.h>
 #include <tchar.h>
 
+#define DBG
+#include <debug.h>
+
 /* FUNCTIONS *****************************************************************/
 
 /**********************************************************************
- *     ChangeServiceConfigA
+ *  ChangeServiceConfigA
  */
 BOOL
 STDCALL
 ChangeServiceConfigA(
-       SC_HANDLE       hService,
-       DWORD           dwServiceType,
-       DWORD           dwStartType,
-       DWORD           dwErrorControl,
-       LPCSTR          lpBinaryPathName,
-       LPCSTR          lpLoadOrderGroup,
-       LPDWORD         lpdwTagId,
-       LPCSTR          lpDependencies,
-       LPCSTR          lpServiceStartName,
-       LPCSTR          lpPassword,
-       LPCSTR          lpDisplayName)
+    SC_HANDLE   hService,
+    DWORD       dwServiceType,
+    DWORD       dwStartType,
+    DWORD       dwErrorControl,
+    LPCSTR      lpBinaryPathName,
+    LPCSTR      lpLoadOrderGroup,
+    LPDWORD     lpdwTagId,
+    LPCSTR      lpDependencies,
+    LPCSTR      lpServiceStartName,
+    LPCSTR      lpPassword,
+    LPCSTR      lpDisplayName)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
 /**********************************************************************
- *     ChangeServiceConfigW
+ *  ChangeServiceConfigW
  */
 BOOL
 STDCALL
 ChangeServiceConfigW(
-       SC_HANDLE       hService,
-       DWORD           dwServiceType,
-       DWORD           dwStartType,
-       DWORD           dwErrorControl,
-       LPCWSTR         lpBinaryPathName,
-       LPCWSTR         lpLoadOrderGroup,
-       LPDWORD         lpdwTagId,
-       LPCWSTR         lpDependencies,
-       LPCWSTR         lpServiceStartName,
-       LPCWSTR         lpPassword,
-       LPCWSTR         lpDisplayName)
+    SC_HANDLE   hService,
+    DWORD       dwServiceType,
+    DWORD       dwStartType,
+    DWORD       dwErrorControl,
+    LPCWSTR     lpBinaryPathName,
+    LPCWSTR     lpLoadOrderGroup,
+    LPDWORD     lpdwTagId,
+    LPCWSTR     lpDependencies,
+    LPCWSTR     lpServiceStartName,
+    LPCWSTR     lpPassword,
+    LPCWSTR     lpDisplayName)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
 /**********************************************************************
- *     CloseServiceHandle
+ *  CloseServiceHandle
  */
 BOOL 
 STDCALL
 CloseServiceHandle(SC_HANDLE hSCObject)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    HANDLE hPipe;
+    DPRINT("CloseServiceHandle() - called.\n");
+//    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+
+    if (!CloseHandle(hPipe)) {
+        SetLastError(ERROR_INVALID_HANDLE);
+        return FALSE;
+    }
+    return TRUE;
 }
 
 
 /**********************************************************************
- *     ControlService
+ *  ControlService
  */
 BOOL
 STDCALL
-ControlService(SC_HANDLE               hService,
-                  DWORD                        dwControl,
-                  LPSERVICE_STATUS     lpServiceStatus)
+ControlService(SC_HANDLE        hService,
+               DWORD            dwControl,
+               LPSERVICE_STATUS lpServiceStatus)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
 /**********************************************************************
- *     CreateServiceA
+ *  CreateServiceA
  */
 SC_HANDLE
 STDCALL
 CreateServiceA(
-       SC_HANDLE       hSCManager,
-       LPCSTR          lpServiceName,
-       LPCSTR          lpDisplayName,
-       DWORD           dwDesiredAccess,
-       DWORD           dwServiceType,
-       DWORD           dwStartType,
-       DWORD           dwErrorControl,
-       LPCSTR          lpBinaryPathName,
-       LPCSTR          lpLoadOrderGroup,
-       LPDWORD         lpdwTagId,
-       LPCSTR          lpDependencies,
-       LPCSTR          lpServiceStartName,
-       LPCSTR          lpPassword)
+    SC_HANDLE   hSCManager,
+    LPCSTR      lpServiceName,
+    LPCSTR      lpDisplayName,
+    DWORD       dwDesiredAccess,
+    DWORD       dwServiceType,
+    DWORD       dwStartType,
+    DWORD       dwErrorControl,
+    LPCSTR      lpBinaryPathName,
+    LPCSTR      lpLoadOrderGroup,
+    LPDWORD     lpdwTagId,
+    LPCSTR      lpDependencies,
+    LPCSTR      lpServiceStartName,
+    LPCSTR      lpPassword)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return NULL;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return NULL;
 }
 
 
 /**********************************************************************
- *     CreateServiceW
+ *  CreateServiceW
  */
 SC_HANDLE
 STDCALL
 CreateServiceW(
-       SC_HANDLE       hSCManager,
-       LPCWSTR         lpServiceName,
-       LPCWSTR         lpDisplayName,
-       DWORD           dwDesiredAccess,
-       DWORD           dwServiceType,
-       DWORD           dwStartType,
-       DWORD           dwErrorControl,
-       LPCWSTR         lpBinaryPathName,
-       LPCWSTR         lpLoadOrderGroup,
-       LPDWORD         lpdwTagId,
-       LPCWSTR         lpDependencies,
-       LPCWSTR         lpServiceStartName,
-       LPCWSTR         lpPassword)
+    SC_HANDLE   hSCManager,
+    LPCWSTR     lpServiceName,
+    LPCWSTR     lpDisplayName,
+    DWORD       dwDesiredAccess,
+    DWORD       dwServiceType,
+    DWORD       dwStartType,
+    DWORD       dwErrorControl,
+    LPCWSTR     lpBinaryPathName,
+    LPCWSTR     lpLoadOrderGroup,
+    LPDWORD     lpdwTagId,
+    LPCWSTR     lpDependencies,
+    LPCWSTR     lpServiceStartName,
+    LPCWSTR     lpPassword)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return NULL;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return NULL;
 }
 
 
 /**********************************************************************
- *     DeleteService
+ *  DeleteService
  */
 BOOL
 STDCALL
 DeleteService(SC_HANDLE hService)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
 /**********************************************************************
- *     EnumDependentServicesA
+ *  EnumDependentServicesA
  */
 BOOL
 STDCALL
 EnumDependentServicesA(
-       SC_HANDLE               hService,
-       DWORD                   dwServiceState,
-       LPENUM_SERVICE_STATUSA  lpServices,
-       DWORD                   cbBufSize,
-       LPDWORD                 pcbBytesNeeded,
-       LPDWORD                 lpServicesReturned)
+    SC_HANDLE       hService,
+    DWORD           dwServiceState,
+    LPENUM_SERVICE_STATUSA  lpServices,
+    DWORD           cbBufSize,
+    LPDWORD         pcbBytesNeeded,
+    LPDWORD         lpServicesReturned)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
 /**********************************************************************
- *     EnumDependentServicesW
+ *  EnumDependentServicesW
  */
 BOOL
 STDCALL
 EnumDependentServicesW(
-       SC_HANDLE               hService,
-       DWORD                   dwServiceState,
-       LPENUM_SERVICE_STATUSW  lpServices,
-       DWORD                   cbBufSize,
-       LPDWORD                 pcbBytesNeeded,
-       LPDWORD                 lpServicesReturned)
+    SC_HANDLE       hService,
+    DWORD           dwServiceState,
+    LPENUM_SERVICE_STATUSW  lpServices,
+    DWORD           cbBufSize,
+    LPDWORD         pcbBytesNeeded,
+    LPDWORD         lpServicesReturned)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
 /**********************************************************************
- *     EnumServiceGroupW
+ *  EnumServiceGroupW
  *
  * (unknown)
  */
 BOOL
 STDCALL
 EnumServiceGroupW (
-       DWORD   Unknown0,
-       DWORD   Unknown1,
-       DWORD   Unknown2,
-       DWORD   Unknown3,
-       DWORD   Unknown4,
-       DWORD   Unknown5,
-       DWORD   Unknown6,
-       DWORD   Unknown7,
-       DWORD   Unknown8)
+    DWORD   Unknown0,
+    DWORD   Unknown1,
+    DWORD   Unknown2,
+    DWORD   Unknown3,
+    DWORD   Unknown4,
+    DWORD   Unknown5,
+    DWORD   Unknown6,
+    DWORD   Unknown7,
+    DWORD   Unknown8)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
 /**********************************************************************
- *     EnumServicesStatusA
+ *  EnumServicesStatusA
  */
 BOOL
 STDCALL
 EnumServicesStatusA (
-       SC_HANDLE               hSCManager,
-       DWORD                   dwServiceType,
-       DWORD                   dwServiceState,
-       LPENUM_SERVICE_STATUSA  lpServices,
-       DWORD                   cbBufSize,
-       LPDWORD                 pcbBytesNeeded,
-       LPDWORD                 lpServicesReturned,
-       LPDWORD                 lpResumeHandle)
+    SC_HANDLE               hSCManager,
+    DWORD                   dwServiceType,
+    DWORD                   dwServiceState,
+    LPENUM_SERVICE_STATUSA  lpServices,
+    DWORD                   cbBufSize,
+    LPDWORD                 pcbBytesNeeded,
+    LPDWORD                 lpServicesReturned,
+    LPDWORD                 lpResumeHandle)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
 /**********************************************************************
- *     EnumServicesStatusExA
+ *  EnumServicesStatusExA
  */
 BOOL
 STDCALL
@@ -248,13 +258,13 @@ EnumServicesStatusExA(SC_HANDLE  hSCManager,
   LPDWORD  lpResumeHandle,
   LPCSTR  pszGroupName)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
 /**********************************************************************
- *     EnumServicesStatusExW
+ *  EnumServicesStatusExW
  */
 BOOL
 STDCALL
@@ -269,113 +279,113 @@ EnumServicesStatusExW(SC_HANDLE  hSCManager,
   LPDWORD  lpResumeHandle,
   LPCWSTR  pszGroupName)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
 /**********************************************************************
- *     EnumServicesStatusW
+ *  EnumServicesStatusW
  */
 BOOL
 STDCALL
 EnumServicesStatusW(
-       SC_HANDLE               hSCManager,
-       DWORD                   dwServiceType,
-       DWORD                   dwServiceState,
-       LPENUM_SERVICE_STATUSW  lpServices,
-       DWORD                   cbBufSize,
-       LPDWORD                 pcbBytesNeeded,
-       LPDWORD                 lpServicesReturned,
-       LPDWORD                 lpResumeHandle)
+    SC_HANDLE               hSCManager,
+    DWORD                   dwServiceType,
+    DWORD                   dwServiceState,
+    LPENUM_SERVICE_STATUSW  lpServices,
+    DWORD                   cbBufSize,
+    LPDWORD                 pcbBytesNeeded,
+    LPDWORD                 lpServicesReturned,
+    LPDWORD                 lpResumeHandle)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
 /**********************************************************************
- *     GetServiceDisplayNameA
+ *  GetServiceDisplayNameA
  */
 BOOL
 STDCALL
 GetServiceDisplayNameA(
-       SC_HANDLE       hSCManager,
-       LPCSTR          lpServiceName,
-       LPSTR           lpDisplayName,
-       LPDWORD         lpcchBuffer)
+    SC_HANDLE   hSCManager,
+    LPCSTR      lpServiceName,
+    LPSTR       lpDisplayName,
+    LPDWORD     lpcchBuffer)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
 /**********************************************************************
- *     GetServiceDisplayNameW
+ *  GetServiceDisplayNameW
  */
 BOOL
 STDCALL
 GetServiceDisplayNameW(
-       SC_HANDLE       hSCManager,
-       LPCWSTR         lpServiceName,
-       LPWSTR          lpDisplayName,
-       LPDWORD         lpcchBuffer)
+    SC_HANDLE   hSCManager,
+    LPCWSTR     lpServiceName,
+    LPWSTR      lpDisplayName,
+    LPDWORD     lpcchBuffer)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
 /**********************************************************************
- *     GetServiceKeyNameA
+ *  GetServiceKeyNameA
  */
 BOOL
 STDCALL
 GetServiceKeyNameA(
-       SC_HANDLE       hSCManager,
-       LPCSTR          lpDisplayName,
-       LPSTR           lpServiceName,
-       LPDWORD         lpcchBuffer)
+    SC_HANDLE   hSCManager,
+    LPCSTR      lpDisplayName,
+    LPSTR       lpServiceName,
+    LPDWORD     lpcchBuffer)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
 /**********************************************************************
- *     GetServiceKeyNameW
+ *  GetServiceKeyNameW
  */
 BOOL
 STDCALL
 GetServiceKeyNameW(
-       SC_HANDLE       hSCManager,
-       LPCWSTR         lpDisplayName,
-       LPWSTR          lpServiceName,
-       LPDWORD         lpcchBuffer)
+    SC_HANDLE   hSCManager,
+    LPCWSTR     lpDisplayName,
+    LPWSTR      lpServiceName,
+    LPDWORD     lpcchBuffer)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 /**********************************************************************
- *     LockServiceDatabase
+ *  LockServiceDatabase
  */
 SC_LOCK
 STDCALL
-LockServiceDatabase(SC_HANDLE  hSCManager)
+LockServiceDatabase(SC_HANDLE   hSCManager)
 {
-       SetLastError (ERROR_CALL_NOT_IMPLEMENTED);
-       return NULL;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return NULL;
 }
 
 
 /**********************************************************************
- *     OpenSCManagerA
+ *  OpenSCManagerA
  */
 SC_HANDLE STDCALL
 OpenSCManagerA(LPCSTR lpMachineName,
-              LPCSTR lpDatabaseName,
-              DWORD dwDesiredAccess)
+           LPCSTR lpDatabaseName,
+           DWORD dwDesiredAccess)
 {
   SC_HANDLE Handle;
   UNICODE_STRING MachineNameW;
@@ -383,306 +393,345 @@ OpenSCManagerA(LPCSTR lpMachineName,
   ANSI_STRING MachineNameA;
   ANSI_STRING DatabaseNameA;
 
+  DPRINT("OpenSCManagerA(%x, %x, %d)\n", lpMachineName, lpDatabaseName, dwDesiredAccess);
+
   RtlInitAnsiString(&MachineNameA, (LPSTR)lpMachineName);
-  RtlAnsiStringToUnicodeString(&MachineNameW,
-                               &MachineNameA,
-                               TRUE);
+  RtlAnsiStringToUnicodeString(&MachineNameW, &MachineNameA, TRUE);
   RtlInitAnsiString(&DatabaseNameA, (LPSTR)lpDatabaseName);
-  RtlAnsiStringToUnicodeString(&DatabaseNameW,
-                               &DatabaseNameA,
-                               TRUE);
+  RtlAnsiStringToUnicodeString(&DatabaseNameW, &DatabaseNameA, TRUE);
 
-  Handle = OpenSCManagerW(MachineNameW.Buffer,
-                         DatabaseNameW.Buffer,
-                         dwDesiredAccess);
+  Handle = OpenSCManagerW(lpMachineName ? MachineNameW.Buffer : NULL,
+              lpDatabaseName ? DatabaseNameW.Buffer : NULL,
+              dwDesiredAccess);
 
-  RtlFreeHeap(GetProcessHeap(),
-             0,
-             MachineNameW.Buffer);
-  RtlFreeHeap(GetProcessHeap(),
-             0,
-             DatabaseNameW.Buffer);
-
-  return(Handle);
+  RtlFreeHeap(GetProcessHeap(), 0, MachineNameW.Buffer);
+  RtlFreeHeap(GetProcessHeap(), 0, DatabaseNameW.Buffer);
+  return Handle;
 }
 
 
 /**********************************************************************
- *     OpenSCManagerW
+ *  OpenSCManagerW
  */
 SC_HANDLE STDCALL OpenSCManagerW(LPCWSTR lpMachineName,
-                                                                LPCWSTR lpDatabaseName,
-                                                                DWORD dwDesiredAccess)
-{
-       HANDLE hPipe;
-       DWORD dwMode;
-       DWORD dwWait;
-       BOOL fSuccess;
-       HANDLE hStartEvent;
-       LPWSTR lpszPipeName = L"\\\\.\\pipe\\Ntsvcs";
-       
-       if(lpMachineName == NULL || wcslen(lpMachineName) == 0)
-       {
-               if(lpDatabaseName != NULL && wcscmp(lpDatabaseName, SERVICES_ACTIVE_DATABASEW) != 0)
-               { return(NULL); }
-
-               // Only connect to scm when event "SvcctrlStartEvent_A3725DX" is signaled
-               hStartEvent = OpenEvent(SYNCHRONIZE, FALSE, _T("SvcctrlStartEvent_A3725DX"));
-               if(hStartEvent == NULL)
-               {
-                       SetLastError(ERROR_DATABASE_DOES_NOT_EXIST);
-                       return (NULL);
-               }
-               dwWait = WaitForSingleObject(hStartEvent, INFINITE);
-               if(dwWait == WAIT_FAILED)
-               {
-                       SetLastError(ERROR_ACCESS_DENIED);
-                       return (NULL);
-               }
-               CloseHandle(hStartEvent);
-               
-               // Try to open a named pipe; wait for it, if necessary
-               while(1)
-               {
-                       hPipe = CreateFileW(lpszPipeName,     // pipe name
-                               dwDesiredAccess,
-                               0,                // no sharing
-                               NULL,             // no security attributes
-                               OPEN_EXISTING,    // opens existing pipe
-                               0,                // default attributes
-                               NULL);            // no template file
-                       
-                       // Break if the pipe handle is valid
-                       if(hPipe != INVALID_HANDLE_VALUE)
-                               break;
-                       
-                       // Exit if an error other than ERROR_PIPE_BUSY occurs
-                       if(GetLastError()!= ERROR_PIPE_BUSY)
-                       { return(NULL); }
-                       
-                       // All pipe instances are busy, so wait for 20 seconds
-                       if(!WaitNamedPipeW(lpszPipeName, 20000))
-                       { return(NULL); }
-               }
-               
-               // The pipe connected; change to message-read mode
-               dwMode = PIPE_READMODE_MESSAGE;
-               fSuccess = SetNamedPipeHandleState(
-                       hPipe,    // pipe handle
-                       &dwMode,  // new pipe mode
-                       NULL,     // don't set maximum bytes
-                       NULL);    // don't set maximum time
-               if(!fSuccess)
-               {
-                       CloseHandle(hPipe);
-                       return(NULL);
-               }
+                                 LPCWSTR lpDatabaseName,
+                                 DWORD dwDesiredAccess)
+{
+    HANDLE hPipe;
+    DWORD dwMode;
+    DWORD dwWait;
+    BOOL fSuccess;
+    HANDLE hStartEvent;
+    LPWSTR lpszPipeName = L"\\\\.\\pipe\\Ntsvcs";
+    
+    DPRINT("OpenSCManagerW(%x, %x, %d)\n", lpMachineName, lpDatabaseName, dwDesiredAccess);
+
+    if (lpMachineName == NULL || wcslen(lpMachineName) == 0) {
+        if (lpDatabaseName != NULL && wcscmp(lpDatabaseName, SERVICES_ACTIVE_DATABASEW) != 0) { 
+            DPRINT("OpenSCManagerW() - Invalid parameters.\n");
+            return NULL; 
+        }
+
+        DPRINT("OpenSCManagerW() - OpenEvent(\"SvcctrlStartEvent_A3725DX\")\n");
+
+        // Only connect to scm when event "SvcctrlStartEvent_A3725DX" is signaled
+        hStartEvent = OpenEvent(SYNCHRONIZE, FALSE, _T("SvcctrlStartEvent_A3725DX"));
+        if (hStartEvent == NULL) {
+            SetLastError(ERROR_DATABASE_DOES_NOT_EXIST);
+            DPRINT("OpenSCManagerW() - Failed to Open Event \"SvcctrlStartEvent_A3725DX\".\n");
+            return NULL;
+        }
+
+        DPRINT("OpenSCManagerW() - Waiting forever on event handle: %x\n", hStartEvent);
+
+#if 1
+        dwWait = WaitForSingleObject(hStartEvent, INFINITE);
+        if (dwWait == WAIT_FAILED) {
+            DPRINT("OpenSCManagerW() - Wait For Start Event failed.\n");
+            SetLastError(ERROR_ACCESS_DENIED);
+            return NULL;
+        }
+#else
+        {
+            DWORD Count;
+
+   /* wait for event creation (by SCM) for max. 20 seconds */
+   for (Count = 0; Count < 20; Count++)
+     {
+        dwWait = WaitForSingleObject(hStartEvent, 1000);
+        if (dwWait == WAIT_FAILED) {
+            DPRINT("OpenSCManagerW() - Wait For Start Event failed.\n");
+            Sleep(1000);
+        } else {
+            break;
+        }
+     }
+   
+   if (dwWait == WAIT_FAILED)
+     {
+       DbgPrint("WL: Failed to wait on event \"SvcctrlStartEvent_A3725DX\"\n");
+     }
+
+        }
+#endif
+
+        DPRINT("OpenSCManagerW() - Closing handle to event...\n");
+        
+        CloseHandle(hStartEvent);
+        
+        // Try to open a named pipe; wait for it, if necessary
+        while (1) {
+            DWORD dwLastError;
+            DPRINT("OpenSCManagerW() - attempting to open named pipe to SCM.\n");
+            hPipe = CreateFileW(lpszPipeName,     // pipe name
+                dwDesiredAccess,
+                0,                // no sharing
+                NULL,             // no security attributes
+                OPEN_EXISTING,    // opens existing pipe
+                0,                // default attributes
+                NULL);            // no template file
+            
+            DPRINT("OpenSCManagerW() - handle to named pipe: %x\n", hPipe);
+            // Break if the pipe handle is valid
+            if (hPipe != INVALID_HANDLE_VALUE) {
+                break;
+            }
+            
+            // Exit if an error other than ERROR_PIPE_BUSY occurs
+            dwLastError = GetLastError();
+            if (dwLastError != ERROR_PIPE_BUSY) { 
+                DPRINT("OpenSCManagerW() - returning at 4, dwLastError %d\n", dwLastError);
+                return NULL;
+            }
+            
+            // All pipe instances are busy, so wait for 20 seconds
+            if (!WaitNamedPipeW(lpszPipeName, 20000)) { 
+                DPRINT("OpenSCManagerW() - Failed on WaitNamedPipeW(...).\n");
+                return NULL;
+            }
+        }
+        
+        // The pipe connected; change to message-read mode
+        dwMode = PIPE_READMODE_MESSAGE;
+        fSuccess = SetNamedPipeHandleState(
+            hPipe,    // pipe handle
+            &dwMode,  // new pipe mode
+            NULL,     // don't set maximum bytes
+            NULL);    // don't set maximum time
+        if (!fSuccess) {
+            CloseHandle(hPipe);
+            DPRINT("OpenSCManagerW() - Failed on SetNamedPipeHandleState(...).\n");
+            return NULL;
+        }
 #if 0
-               // Send a message to the pipe server
-               lpvMessage = (argc > 1) ? argv[1] : "default message";
-               
-               fSuccess = WriteFile(
-                       hPipe,                  // pipe handle
-                       lpvMessage,             // message
-                       strlen(lpvMessage) + 1, // message length
-                       &cbWritten,             // bytes written
-                       NULL);                  // not overlapped
-               if(!fSuccess)
-               {
-                       CloseHandle(hPipe);
-                       return(NULL);
-               }
-               
-               do
-               {
-                       // Read from the pipe
-                       fSuccess = ReadFile(
-                               hPipe,    // pipe handle
-                               chBuf,    // buffer to receive reply
-                               512,      // size of buffer
-                               &cbRead,  // number of bytes read
-                               NULL);    // not overlapped
-                       
-                       if(! fSuccess && GetLastError() != ERROR_MORE_DATA)
-                               break;
-                       
-                       // Reply from the pipe is written to STDOUT.
-                       if(!WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), chBuf, cbRead, &cbWritten, NULL))
-                               break;
-               } while(!fSuccess);  // repeat loop if ERROR_MORE_DATA
-               
-               //CloseHandle(hPipe);
+        // Send a message to the pipe server
+        lpvMessage = (argc > 1) ? argv[1] : "default message";
+        
+        fSuccess = WriteFile(
+            hPipe,                  // pipe handle
+            lpvMessage,             // message
+            strlen(lpvMessage) + 1, // message length
+            &cbWritten,             // bytes written
+            NULL);                  // not overlapped
+        if (!fSuccess) {
+            CloseHandle(hPipe);
+            DPRINT("OpenSCManagerW() - Failed to write to pipe.\n");
+            return NULL;
+        }
+        
+        do {
+            DPRINT("OpenSCManagerW() - in I/O loop to SCM...\n");
+            // Read from the pipe
+            fSuccess = ReadFile(
+                hPipe,    // pipe handle
+                chBuf,    // buffer to receive reply
+                512,      // size of buffer
+                &cbRead,  // number of bytes read
+                NULL);    // not overlapped
+            
+            if (!fSuccess && GetLastError() != ERROR_MORE_DATA) {
+                break;
+            }
+            
+            // Reply from the pipe is written to STDOUT.
+            if (!WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), chBuf, cbRead, &cbWritten, NULL)) {
+                break;
+            }
+        } while(!fSuccess);  // repeat loop if ERROR_MORE_DATA
+        
+        DPRINT("OpenSCManagerW() - I/O loop completed.\n");
+        //CloseHandle(hPipe);
 #endif
-               return(hPipe);
-       }
-       else
-       {
-               /* FIXME: Connect to remote SCM */
-               return(NULL);
-       }
+        DPRINT("OpenSCManagerW() - success, returning handle to pipe %x\n", hPipe);
+        return hPipe;
+    } else {
+        /* FIXME: Connect to remote SCM */
+        DPRINT("OpenSCManagerW() - FIXME: Connect to remote SCM not implemented.\n");
+        return NULL;
+    }
 }
 
 
 /**********************************************************************
- *     OpenServiceA
+ *  OpenServiceA
  */
 SC_HANDLE STDCALL
 OpenServiceA(SC_HANDLE hSCManager,
-            LPCSTR  lpServiceName,
-            DWORD dwDesiredAccess)
+         LPCSTR  lpServiceName,
+         DWORD dwDesiredAccess)
 {
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return(NULL);
+  return NULL;
 }
 
 
 /**********************************************************************
- *     OpenServiceW
+ *  OpenServiceW
  */
 SC_HANDLE
 STDCALL
 OpenServiceW(
-       SC_HANDLE       hSCManager,
-       LPCWSTR         lpServiceName,
-       DWORD           dwDesiredAccess
-       )
+    SC_HANDLE   hSCManager,
+    LPCWSTR     lpServiceName,
+    DWORD       dwDesiredAccess
+    )
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return NULL;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return NULL;
 }
 
 
 /**********************************************************************
- *     PrivilegedServiceAuditAlarmA
+ *  PrivilegedServiceAuditAlarmA
  */
 BOOL
 STDCALL
 PrivilegedServiceAuditAlarmA(
-       LPCSTR          SubsystemName,
-       LPCSTR          ServiceName,
-       HANDLE          ClientToken,
-       PPRIVILEGE_SET  Privileges,
-       BOOL            AccessGranted)
+    LPCSTR      SubsystemName,
+    LPCSTR      ServiceName,
+    HANDLE      ClientToken,
+    PPRIVILEGE_SET  Privileges,
+    BOOL        AccessGranted)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
 /**********************************************************************
- *     PrivilegedServiceAuditAlarmW
+ *  PrivilegedServiceAuditAlarmW
  */
 BOOL
 STDCALL
 PrivilegedServiceAuditAlarmW(
-       LPCWSTR         SubsystemName,
-       LPCWSTR         ServiceName,
-       HANDLE          ClientToken,
-       PPRIVILEGE_SET  Privileges,
-       BOOL            AccessGranted)
+    LPCWSTR     SubsystemName,
+    LPCWSTR     ServiceName,
+    HANDLE      ClientToken,
+    PPRIVILEGE_SET  Privileges,
+    BOOL        AccessGranted)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return 1;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return 1;
 }
 
 
 /**********************************************************************
- *     QueryServiceConfigA
+ *  QueryServiceConfigA
  */
 BOOL
 STDCALL
 QueryServiceConfigA(
-       SC_HANDLE               hService,
-       LPQUERY_SERVICE_CONFIGA lpServiceConfig,
-       DWORD                   cbBufSize,
-       LPDWORD                 pcbBytesNeeded)
+    SC_HANDLE       hService,
+    LPQUERY_SERVICE_CONFIGA lpServiceConfig,
+    DWORD           cbBufSize,
+    LPDWORD         pcbBytesNeeded)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
 /**********************************************************************
- *     QueryServiceConfigW
+ *  QueryServiceConfigW
  */
 BOOL
 STDCALL
 QueryServiceConfigW(
-       SC_HANDLE               hService,
-       LPQUERY_SERVICE_CONFIGW lpServiceConfig,
-       DWORD                   cbBufSize,
-       LPDWORD                 pcbBytesNeeded)
+    SC_HANDLE       hService,
+    LPQUERY_SERVICE_CONFIGW lpServiceConfig,
+    DWORD                   cbBufSize,
+    LPDWORD                 pcbBytesNeeded)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
 /**********************************************************************
- *     QueryServiceLockStatusA
+ *  QueryServiceLockStatusA
  */
 BOOL
 STDCALL
 QueryServiceLockStatusA(
-       SC_HANDLE                       hSCManager,
-       LPQUERY_SERVICE_LOCK_STATUSA    lpLockStatus,
-       DWORD                           cbBufSize,
-       LPDWORD                         pcbBytesNeeded)
+    SC_HANDLE           hSCManager,
+    LPQUERY_SERVICE_LOCK_STATUSA    lpLockStatus,
+    DWORD               cbBufSize,
+    LPDWORD             pcbBytesNeeded)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
 /**********************************************************************
- *     QueryServiceLockStatusW
+ *  QueryServiceLockStatusW
  */
 BOOL
 STDCALL
 QueryServiceLockStatusW(
-       SC_HANDLE                       hSCManager,
-       LPQUERY_SERVICE_LOCK_STATUSW    lpLockStatus,
-       DWORD                           cbBufSize,
-       LPDWORD                         pcbBytesNeeded)
+    SC_HANDLE           hSCManager,
+    LPQUERY_SERVICE_LOCK_STATUSW    lpLockStatus,
+    DWORD               cbBufSize,
+    LPDWORD             pcbBytesNeeded)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
 /**********************************************************************
- *     QueryServiceObjectSecurity
+ *  QueryServiceObjectSecurity
  */
 BOOL
 STDCALL
 QueryServiceObjectSecurity(
-       SC_HANDLE               hService,
-       SECURITY_INFORMATION    dwSecurityInformation,
-       PSECURITY_DESCRIPTOR    lpSecurityDescriptor,
-       DWORD                   cbBufSize,
-       LPDWORD                 pcbBytesNeeded)
+    SC_HANDLE       hService,
+    SECURITY_INFORMATION    dwSecurityInformation,
+    PSECURITY_DESCRIPTOR    lpSecurityDescriptor,
+    DWORD           cbBufSize,
+    LPDWORD         pcbBytesNeeded)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
 /**********************************************************************
- *     QueryServiceStatus
+ *  QueryServiceStatus
  */
 BOOL
 STDCALL
 QueryServiceStatus(
-       SC_HANDLE               hService,
-       LPSERVICE_STATUS        lpServiceStatus)
+    SC_HANDLE       hService,
+    LPSERVICE_STATUS    lpServiceStatus)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
 /**********************************************************************
- *     QueryServiceStatusEx
+ *  QueryServiceStatusEx
  */
 BOOL
 STDCALL
@@ -692,52 +741,52 @@ QueryServiceStatusEx(SC_HANDLE  hService,
   DWORD  cbBufSize,
   LPDWORD  pcbBytesNeeded)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
 /**********************************************************************
- *     StartServiceA
+ *  StartServiceA
  */
 BOOL
 STDCALL
 StartServiceA(
-       SC_HANDLE       hService,
-       DWORD           dwNumServiceArgs,
-       LPCSTR          *lpServiceArgVectors)
+    SC_HANDLE   hService,
+    DWORD       dwNumServiceArgs,
+    LPCSTR      *lpServiceArgVectors)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
 
 
 /**********************************************************************
- *     StartServiceW
+ *  StartServiceW
  */
 BOOL
 STDCALL
 StartServiceW(
-       SC_HANDLE       hService,
-       DWORD           dwNumServiceArgs,
-       LPCWSTR         *lpServiceArgVectors)
+    SC_HANDLE   hService,
+    DWORD       dwNumServiceArgs,
+    LPCWSTR     *lpServiceArgVectors)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
 /**********************************************************************
- *     UnlockServiceDatabase
+ *  UnlockServiceDatabase
  */
 BOOL
 STDCALL
-UnlockServiceDatabase(SC_LOCK  ScLock)
+UnlockServiceDatabase(SC_LOCK   ScLock)
 {
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }