Diff for /libraries/liblutil/ntservice.c between versions 1.21 and 1.21.2.3

version 1.21, 2002/01/04 20:17:43 version 1.21.2.3, 2003/03/03 17:10:06
Line 1 Line 1
 /* $OpenLDAP: pkg/ldap/libraries/liblutil/ntservice.c,v 1.20 2001/12/07 03:03:35 hyc Exp $ */  /* $OpenLDAP: pkg/ldap/libraries/liblutil/ntservice.c,v 1.21.2.2 2003/03/03 16:57:05 kurt Exp $ */
 /*  /*
  * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.   * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file   * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */   */
   
 /*  /*
  * NT Service manager utilities for OpenLDAP services   * NT Service manager utilities for OpenLDAP services
  *      these should NOT be slapd specific, but are  
  */   */
   
 #include "portable.h"  #include "portable.h"
Line 23 Line 22
   
 #include <ldap.h>  #include <ldap.h>
   
 /*  
  * The whole debug implementation is a bit of a hack.  
  * We have to define this LDAP_SLAPD_V macro here since the slap.h  
  * header file isn't included (and really shouldn't be).  
  * TODO: re-implement debug functions so that the debug level can  
  * be passed around instead of having to count on the existence of  
  * ldap_debug, slap_debug, etc.  
  */  
 #define ldap_debug slap_debug  
 LDAP_SLAPD_V (int) slap_debug;  
   
 #include "ldap_log.h"  #include "ldap_log.h"
 #include "ldap_pvt_thread.h"  #include "ldap_pvt_thread.h"
   
Line 45  LDAP_SLAPD_V (int) slap_debug; Line 33  LDAP_SLAPD_V (int) slap_debug;
 #define SCM_NOTIFICATION_INTERVAL       5000  #define SCM_NOTIFICATION_INTERVAL       5000
 #define THIRTY_SECONDS                          (30 * 1000)  #define THIRTY_SECONDS                          (30 * 1000)
   
 int       is_NT_Service = 1;    /* assume this is an NT service until determined that */  int       is_NT_Service;        /* is this is an NT service? */
                                                         /* startup was from the command line */  
   
 SERVICE_STATUS                  SLAPDServiceStatus;  SERVICE_STATUS                  lutil_ServiceStatus;
 SERVICE_STATUS_HANDLE   hSLAPDServiceStatus;  SERVICE_STATUS_HANDLE   hlutil_ServiceStatus;
   
 ldap_pvt_thread_cond_t  started_event,          stopped_event;  ldap_pvt_thread_cond_t  started_event,          stopped_event;
 ldap_pvt_thread_t               start_status_tid,       stop_status_tid;  ldap_pvt_thread_t               start_status_tid,       stop_status_tid;
Line 58  void (*stopfunc)(int); Line 45  void (*stopfunc)(int);
   
 static char *GetLastErrorString( void );  static char *GetLastErrorString( void );
   
 int srv_install(LPCTSTR lpszServiceName, LPCTSTR lpszDisplayName,  int lutil_srv_install(LPCTSTR lpszServiceName, LPCTSTR lpszDisplayName,
                 LPCTSTR lpszBinaryPathName, BOOL auto_start)                  LPCTSTR lpszBinaryPathName, int auto_start)
 {  {
         HKEY            hKey;          HKEY            hKey;
         DWORD           dwValue, dwDisposition;          DWORD           dwValue, dwDisposition;
         SC_HANDLE       schSCManager, schService;          SC_HANDLE       schSCManager, schService;
           char *sp = strchr( lpszBinaryPathName, ' ');
   
           if ( sp ) *sp = '\0';
         fprintf( stderr, "The install path is %s.\n", lpszBinaryPathName );          fprintf( stderr, "The install path is %s.\n", lpszBinaryPathName );
           if ( sp ) *sp = ' ';
         if ((schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CONNECT|SC_MANAGER_CREATE_SERVICE ) ) != NULL )          if ((schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CONNECT|SC_MANAGER_CREATE_SERVICE ) ) != NULL )
         {          {
                 if ((schService = CreateService(                   if ((schService = CreateService( 
Line 83  int srv_install(LPCTSTR lpszServiceName, Line 73  int srv_install(LPCTSTR lpszServiceName,
                         CloseServiceHandle(schService);                          CloseServiceHandle(schService);
                         CloseServiceHandle(schSCManager);                          CloseServiceHandle(schSCManager);
   
                         sprintf( regpath, "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\%s",                          snprintf( regpath, sizeof regpath,
                                   "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\%s",
                                 lpszServiceName );                                  lpszServiceName );
                         /* Create the registry key for event logging to the Windows NT event log. */                          /* Create the registry key for event logging to the Windows NT event log. */
                         if ( RegCreateKeyEx(HKEY_LOCAL_MACHINE,                           if ( RegCreateKeyEx(HKEY_LOCAL_MACHINE, 
Line 95  int srv_install(LPCTSTR lpszServiceName, Line 86  int srv_install(LPCTSTR lpszServiceName,
                                 RegCloseKey(hKey);                                  RegCloseKey(hKey);
                                 return(0);                                  return(0);
                         }                          }
                           if ( sp ) *sp = '\0';
                         if ( RegSetValueEx(hKey, "EventMessageFile", 0, REG_EXPAND_SZ, lpszBinaryPathName, strlen(lpszBinaryPathName) + 1) != ERROR_SUCCESS)                          if ( RegSetValueEx(hKey, "EventMessageFile", 0, REG_EXPAND_SZ, lpszBinaryPathName, strlen(lpszBinaryPathName) + 1) != ERROR_SUCCESS)
                         {                          {
                                 fprintf( stderr, "RegSetValueEx(EventMessageFile) failed. GetLastError=%lu (%s)\n", GetLastError(), GetLastErrorString() );                                  fprintf( stderr, "RegSetValueEx(EventMessageFile) failed. GetLastError=%lu (%s)\n", GetLastError(), GetLastErrorString() );
Line 125  int srv_install(LPCTSTR lpszServiceName, Line 117  int srv_install(LPCTSTR lpszServiceName,
 }  }
   
   
 int srv_remove(LPCTSTR lpszServiceName, LPCTSTR lpszBinaryPathName)  int lutil_srv_remove(LPCTSTR lpszServiceName, LPCTSTR lpszBinaryPathName)
 {  {
         SC_HANDLE schSCManager, schService;          SC_HANDLE schSCManager, schService;
   
Line 158  int srv_remove(LPCTSTR lpszServiceName, Line 150  int srv_remove(LPCTSTR lpszServiceName,
 }  }
   
   
   #if 0 /* unused */
 DWORD  DWORD
 svc_installed (LPTSTR lpszServiceName, LPTSTR lpszBinaryPathName)  svc_installed (LPTSTR lpszServiceName, LPTSTR lpszBinaryPathName)
 {  {
Line 208  svc_running (LPTSTR lpszServiceName) Line 201  svc_running (LPTSTR lpszServiceName)
         CloseServiceHandle(scm);          CloseServiceHandle(scm);
         return(rc);          return(rc);
 }  }
   #endif
   
 static void *start_status_routine( void *ptr )  static void *start_status_routine( void *ptr )
 {  {
Line 225  static void *start_status_routine( void Line 218  static void *start_status_routine( void
                                 /* the object that we were waiting for has been destroyed (ABANDONED) or                                  /* the object that we were waiting for has been destroyed (ABANDONED) or
                                  * signalled (TIMEOUT_0). We can assume that the startup process is                                   * signalled (TIMEOUT_0). We can assume that the startup process is
                                  * complete and tell the Service Control Manager that we are now runnng */                                   * complete and tell the Service Control Manager that we are now runnng */
                                 SLAPDServiceStatus.dwCurrentState       = SERVICE_RUNNING;                                  lutil_ServiceStatus.dwCurrentState      = SERVICE_RUNNING;
                                 SLAPDServiceStatus.dwWin32ExitCode      = NO_ERROR;                                  lutil_ServiceStatus.dwWin32ExitCode     = NO_ERROR;
                                 SLAPDServiceStatus.dwCheckPoint++;                                  lutil_ServiceStatus.dwCheckPoint++;
                                 SLAPDServiceStatus.dwWaitHint           = 1000;                                  lutil_ServiceStatus.dwWaitHint          = 1000;
                                 SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);                                  SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
                                 done = 1;                                  done = 1;
                                 break;                                  break;
                         case WAIT_TIMEOUT:                          case WAIT_TIMEOUT:
                                 /* We've waited for the required time, so send an update to the Service Control                                   /* We've waited for the required time, so send an update to the Service Control 
                                  * Manager saying to wait again. */                                   * Manager saying to wait again. */
                                 SLAPDServiceStatus.dwCheckPoint++;                                  lutil_ServiceStatus.dwCheckPoint++;
                                 SLAPDServiceStatus.dwWaitHint = SCM_NOTIFICATION_INTERVAL * 2;                                  lutil_ServiceStatus.dwWaitHint = SCM_NOTIFICATION_INTERVAL * 2;
                                 SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);                                  SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
                                 break;                                  break;
                         case WAIT_FAILED:                          case WAIT_FAILED:
                                 /* theres been some problem with WaitForSingleObject so tell the Service                                  /* theres been some problem with WaitForSingleObject so tell the Service
                                  * Control Manager to wait 30 seconds before deploying its assasin and                                    * Control Manager to wait 30 seconds before deploying its assasin and 
                                  * then leave the thread. */                                   * then leave the thread. */
                                 SLAPDServiceStatus.dwCheckPoint++;                                  lutil_ServiceStatus.dwCheckPoint++;
                                 SLAPDServiceStatus.dwWaitHint = THIRTY_SECONDS;                                  lutil_ServiceStatus.dwWaitHint = THIRTY_SECONDS;
                                 SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);                                  SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
                                 done = 1;                                  done = 1;
                                 break;                                  break;
                 }                  }
Line 277  static void *stop_status_routine( void * Line 270  static void *stop_status_routine( void *
                         case WAIT_TIMEOUT:                          case WAIT_TIMEOUT:
                                 /* We've waited for the required time, so send an update to the Service Control                                   /* We've waited for the required time, so send an update to the Service Control 
                                  * Manager saying to wait again. */                                   * Manager saying to wait again. */
                                 SLAPDServiceStatus.dwCheckPoint++;                                  lutil_ServiceStatus.dwCheckPoint++;
                                 SLAPDServiceStatus.dwWaitHint = SCM_NOTIFICATION_INTERVAL * 2;                                  lutil_ServiceStatus.dwWaitHint = SCM_NOTIFICATION_INTERVAL * 2;
                                 SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);                                  SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
                                 break;                                  break;
                         case WAIT_FAILED:                          case WAIT_FAILED:
                                 /* theres been some problem with WaitForSingleObject so tell the Service                                  /* theres been some problem with WaitForSingleObject so tell the Service
                                  * Control Manager to wait 30 seconds before deploying its assasin and                                    * Control Manager to wait 30 seconds before deploying its assasin and 
                                  * then leave the thread. */                                   * then leave the thread. */
                                 SLAPDServiceStatus.dwCheckPoint++;                                  lutil_ServiceStatus.dwCheckPoint++;
                                 SLAPDServiceStatus.dwWaitHint = THIRTY_SECONDS;                                  lutil_ServiceStatus.dwWaitHint = THIRTY_SECONDS;
                                 SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);                                  SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
                                 done = 1;                                  done = 1;
                                 break;                                  break;
                 }                  }
Line 298  static void *stop_status_routine( void * Line 291  static void *stop_status_routine( void *
   
   
   
 void WINAPI SLAPDServiceCtrlHandler( IN DWORD Opcode)  void WINAPI lutil_ServiceCtrlHandler( IN DWORD Opcode)
 {  {
         switch (Opcode)          switch (Opcode)
         {          {
         case SERVICE_CONTROL_STOP:          case SERVICE_CONTROL_STOP:
         case SERVICE_CONTROL_SHUTDOWN:          case SERVICE_CONTROL_SHUTDOWN:
   
                 Debug( LDAP_DEBUG_TRACE, "Service Shutdown ordered\n", 0, 0, 0 );                  lutil_ServiceStatus.dwCurrentState      = SERVICE_STOP_PENDING;
                 SLAPDServiceStatus.dwCurrentState       = SERVICE_STOP_PENDING;                  lutil_ServiceStatus.dwCheckPoint++;
                 SLAPDServiceStatus.dwCheckPoint++;                  lutil_ServiceStatus.dwWaitHint          = SCM_NOTIFICATION_INTERVAL * 2;
                 SLAPDServiceStatus.dwWaitHint           = SCM_NOTIFICATION_INTERVAL * 2;                  SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
                 SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);  
   
                 ldap_pvt_thread_cond_init( &stopped_event );                  ldap_pvt_thread_cond_init( &stopped_event );
                 if ( stopped_event == NULL )                  if ( stopped_event == NULL )
                 {                  {
                         /* the event was not created. We will ask the service control manager for 30                          /* the event was not created. We will ask the service control manager for 30
                          * seconds to shutdown */                           * seconds to shutdown */
                         SLAPDServiceStatus.dwCheckPoint++;                          lutil_ServiceStatus.dwCheckPoint++;
                         SLAPDServiceStatus.dwWaitHint           = THIRTY_SECONDS;                          lutil_ServiceStatus.dwWaitHint          = THIRTY_SECONDS;
                         SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);                          SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
                 }                  }
                 else                  else
                 {                  {
Line 333  void WINAPI SLAPDServiceCtrlHandler( IN Line 325  void WINAPI SLAPDServiceCtrlHandler( IN
                                  * service stopping is proceeding.                                    * service stopping is proceeding. 
                                  * tell the Service Control Manager to wait another 30 seconds before deploying its                                   * tell the Service Control Manager to wait another 30 seconds before deploying its
                                  * assasin.  */                                   * assasin.  */
                                 SLAPDServiceStatus.dwCheckPoint++;                                  lutil_ServiceStatus.dwCheckPoint++;
                                 SLAPDServiceStatus.dwWaitHint = THIRTY_SECONDS;                                  lutil_ServiceStatus.dwWaitHint = THIRTY_SECONDS;
                                 SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);                                  SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
                         }                          }
                 }                  }
                 stopfunc( -1 );                  stopfunc( -1 );
                 break;                  break;
   
         case SERVICE_CONTROL_INTERROGATE:          case SERVICE_CONTROL_INTERROGATE:
                 SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);                  SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
                 break;                  break;
         }          }
         return;          return;
 }  }
   
 void *getRegParam( char *svc, char *value )  void *lutil_getRegParam( char *svc, char *value )
 {  {
         HKEY hkey;          HKEY hkey;
         char path[255];          char path[255];
Line 357  void *getRegParam( char *svc, char *valu Line 349  void *getRegParam( char *svc, char *valu
         DWORD valLen = sizeof( vValue );          DWORD valLen = sizeof( vValue );
   
         if ( svc != NULL )          if ( svc != NULL )
                 sprintf ( path, "SOFTWARE\\%s", svc );                  snprintf ( path, sizeof path, "SOFTWARE\\%s", svc );
         else          else
                 strcpy (path, "SOFTWARE\\OpenLDAP\\Parameters" );                  snprintf ( path, sizeof path, "SOFTWARE\\OpenLDAP\\Parameters" );
                   
         if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, path, 0, KEY_READ, &hkey ) != ERROR_SUCCESS )          if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, path, 0, KEY_READ, &hkey ) != ERROR_SUCCESS )
         {          {
                 /*Debug( LDAP_DEBUG_ANY, "RegOpenKeyEx() %s\n", GetLastErrorString(), 0, 0); */  
                 return NULL;                  return NULL;
         }          }
   
         if ( RegQueryValueEx( hkey, value, NULL, &vType, vValue, &valLen ) != ERROR_SUCCESS )          if ( RegQueryValueEx( hkey, value, NULL, &vType, vValue, &valLen ) != ERROR_SUCCESS )
         {          {
                 /*Debug( LDAP_DEBUG_ANY, "RegQueryValueEx() %s\n", GetLastErrorString(), 0, 0 );*/  
                 RegCloseKey( hkey );                  RegCloseKey( hkey );
                 return NULL;                  return NULL;
         }          }
Line 386  void *getRegParam( char *svc, char *valu Line 376  void *getRegParam( char *svc, char *valu
         return (void*)NULL;          return (void*)NULL;
 }  }
   
 void LogSlapdStartedEvent( char *svc, int slap_debug, char *configfile, char *urls )  void lutil_LogStartedEvent( char *svc, int slap_debug, char *configfile, char *urls )
 {  {
         char *Inserts[5];          char *Inserts[5];
         WORD i = 0, j;          WORD i = 0, j;
Line 398  void LogSlapdStartedEvent( char *svc, in Line 388  void LogSlapdStartedEvent( char *svc, in
         itoa( slap_debug, Inserts[i++], 10 );          itoa( slap_debug, Inserts[i++], 10 );
         Inserts[i++] = strdup( configfile );          Inserts[i++] = strdup( configfile );
         Inserts[i++] = strdup( urls ? urls : "ldap:///" );          Inserts[i++] = strdup( urls ? urls : "ldap:///" );
         Inserts[i++] = strdup( is_NT_Service ? "svc" : "cmd" );  
   
         ReportEvent( hEventLog, EVENTLOG_INFORMATION_TYPE, 0,          ReportEvent( hEventLog, EVENTLOG_INFORMATION_TYPE, 0,
                 MSG_SLAPD_STARTED, NULL, i, 0, (LPCSTR *) Inserts, NULL );                  MSG_SVC_STARTED, NULL, i, 0, (LPCSTR *) Inserts, NULL );
   
         for ( j = 0; j < i; j++ )          for ( j = 0; j < i; j++ )
                 ldap_memfree( Inserts[j] );                  ldap_memfree( Inserts[j] );
Line 410  void LogSlapdStartedEvent( char *svc, in Line 399  void LogSlapdStartedEvent( char *svc, in
   
   
   
 void LogSlapdStoppedEvent( char *svc )  void lutil_LogStoppedEvent( char *svc )
 {  {
         HANDLE hEventLog;          HANDLE hEventLog;
                   
         hEventLog = RegisterEventSource( NULL, svc );          hEventLog = RegisterEventSource( NULL, svc );
         ReportEvent( hEventLog, EVENTLOG_INFORMATION_TYPE, 0,          ReportEvent( hEventLog, EVENTLOG_INFORMATION_TYPE, 0,
                 MSG_SLAPD_STOPPED, NULL, 0, 0, NULL, NULL );                  MSG_SVC_STOPPED, NULL, 0, 0, NULL, NULL );
         DeregisterEventSource( hEventLog );          DeregisterEventSource( hEventLog );
 }  }
   
   
 void CommenceStartupProcessing( LPCTSTR lpszServiceName,  void lutil_CommenceStartupProcessing( char *lpszServiceName,
                                                            void (*stopper)(int) )                                                             void (*stopper)(int) )
 {  {
         hSLAPDServiceStatus = RegisterServiceCtrlHandler( lpszServiceName, (LPHANDLER_FUNCTION)SLAPDServiceCtrlHandler);          hlutil_ServiceStatus = RegisterServiceCtrlHandler( lpszServiceName, (LPHANDLER_FUNCTION)lutil_ServiceCtrlHandler);
   
         stopfunc = stopper;          stopfunc = stopper;
   
         /* initialize the Service Status structure */          /* initialize the Service Status structure */
         SLAPDServiceStatus.dwServiceType                                = SERVICE_WIN32_OWN_PROCESS;          lutil_ServiceStatus.dwServiceType                               = SERVICE_WIN32_OWN_PROCESS;
         SLAPDServiceStatus.dwCurrentState                               = SERVICE_START_PENDING;          lutil_ServiceStatus.dwCurrentState                              = SERVICE_START_PENDING;
         SLAPDServiceStatus.dwControlsAccepted                   = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;          lutil_ServiceStatus.dwControlsAccepted                  = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
         SLAPDServiceStatus.dwWin32ExitCode                              = NO_ERROR;          lutil_ServiceStatus.dwWin32ExitCode                             = NO_ERROR;
         SLAPDServiceStatus.dwServiceSpecificExitCode    = 0;          lutil_ServiceStatus.dwServiceSpecificExitCode   = 0;
         SLAPDServiceStatus.dwCheckPoint                                 = 1;          lutil_ServiceStatus.dwCheckPoint                                        = 1;
         SLAPDServiceStatus.dwWaitHint                                   = SCM_NOTIFICATION_INTERVAL * 2;          lutil_ServiceStatus.dwWaitHint                                  = SCM_NOTIFICATION_INTERVAL * 2;
   
         SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);          SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
   
         /* start up a thread to keep sending SERVICE_START_PENDING to the Service Control Manager          /* start up a thread to keep sending SERVICE_START_PENDING to the Service Control Manager
          * until the slapd listener is completed and listening. Only then should we send            * until the slapd listener is completed and listening. Only then should we send 
Line 448  void CommenceStartupProcessing( LPCTSTR Line 437  void CommenceStartupProcessing( LPCTSTR
                 /* failed to create the event to determine when the startup process is complete so                  /* failed to create the event to determine when the startup process is complete so
                  * tell the Service Control Manager to wait another 30 seconds before deploying its                   * tell the Service Control Manager to wait another 30 seconds before deploying its
                  * assasin  */                   * assasin  */
                 SLAPDServiceStatus.dwCheckPoint++;                  lutil_ServiceStatus.dwCheckPoint++;
                 SLAPDServiceStatus.dwWaitHint = THIRTY_SECONDS;                  lutil_ServiceStatus.dwWaitHint = THIRTY_SECONDS;
                 SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);                  SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
         }          }
         else          else
         {          {
Line 465  void CommenceStartupProcessing( LPCTSTR Line 454  void CommenceStartupProcessing( LPCTSTR
                          * service startup is proceeding.                            * service startup is proceeding. 
                          * tell the Service Control Manager to wait another 30 seconds before deploying its                           * tell the Service Control Manager to wait another 30 seconds before deploying its
                          * assasin.  */                           * assasin.  */
                         SLAPDServiceStatus.dwCheckPoint++;                          lutil_ServiceStatus.dwCheckPoint++;
                         SLAPDServiceStatus.dwWaitHint = THIRTY_SECONDS;                          lutil_ServiceStatus.dwWaitHint = THIRTY_SECONDS;
                         SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);                          SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
                 }                  }
         }          }
 }  }
   
 void ReportSlapdShutdownComplete(  )  void lutil_ReportShutdownComplete(  )
 {  {
         if ( is_NT_Service )          if ( is_NT_Service )
         {          {
Line 485  void ReportSlapdShutdownComplete(  ) Line 474  void ReportSlapdShutdownComplete(  )
                 if (ldap_pvt_thread_join( stop_status_tid, (void *) NULL ) == -1)                  if (ldap_pvt_thread_join( stop_status_tid, (void *) NULL ) == -1)
                         ldap_pvt_thread_sleep( SCM_NOTIFICATION_INTERVAL / 2 );                          ldap_pvt_thread_sleep( SCM_NOTIFICATION_INTERVAL / 2 );
   
                 SLAPDServiceStatus.dwCurrentState = SERVICE_STOPPED;                  lutil_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
                 SLAPDServiceStatus.dwCheckPoint++;                  lutil_ServiceStatus.dwCheckPoint++;
                 SLAPDServiceStatus.dwWaitHint = SCM_NOTIFICATION_INTERVAL;                  lutil_ServiceStatus.dwWaitHint = SCM_NOTIFICATION_INTERVAL;
                 SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);                  SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
         }          }
 }  }
   

Removed from v.1.21  
changed lines
  Added in v.1.21.2.3


______________
© Copyright 1998-2020, OpenLDAP Foundation, info@OpenLDAP.org