Package jnacontrib.win32

Source Code of jnacontrib.win32.Win32Service$ServiceControl

/*
* Win32Service.java
*
* Created on 12. September 2007, 12:05
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/

package jnacontrib.win32;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import jnacontrib.jna.Advapi32;
import jnacontrib.jna.WINERROR;
import jnacontrib.jna.WINNT;
import jnacontrib.jna.WINSVC;
import jnacontrib.jna.Advapi32.ENUM_SERVICE_STATUS_PROCESS;
import jnacontrib.jna.Advapi32.QUERY_SERVICE_CONFIG;
import jnacontrib.jna.Advapi32.SERVICE_DESCRIPTION;
import jnacontrib.jna.Advapi32.SERVICE_STATUS_PROCESS;

import org.rzo.yajsw.os.Service;
import org.rzo.yajsw.os.ServiceInfo;
import org.rzo.yajsw.os.ServiceInfoImpl;

import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.Kernel32Util;
import com.sun.jna.ptr.IntByReference;

/**
* Baseclass for a Win32 service.
*/
abstract public class Win32Service
{
  protected String    serviceName;
  private ServiceMain    serviceMain;
  private ServiceControl  serviceControl;
  private Pointer      serviceStatusHandle;
  protected Object    waitObject      = new Object();
  private int        stopTimeout      = 5000;
  private int        startupTimeout    = 30000;
  protected volatile int  checkPoint      = 0;
  private boolean      autoReportStartup  = true;
  private Lock      startupLock      = new ReentrantLock();
  private Condition    startupCondition  = startupLock.newCondition();

  /**
   * Creates a new instance of Win32Service.
   *
   * @param serviceName
   *            internal name of the service
   */
  public Win32Service(String serviceName)
  {
    this.serviceName = serviceName;
  }

  public Win32Service()
  {

  }

  public void setServiceName(String serviceName)
  {
    this.serviceName = serviceName;
  }

  public String getServiceName()
  {
    return serviceName;
  }

  /**
   * Install the service.
   *
   * @param displayName
   *            visible name
   * @param description
   *            description
   * @param dependencies
   *            array of other services to depend on or null
   * @param account
   *            service account or null for LocalSystem
   * @param password
   *            password for service account or null
   * @throws java.lang.Exception
   * @return true on success
   */
  public boolean install(String displayName, String description, String[] dependencies, String account, String password)
  {
    return (install(displayName, description, dependencies, account, password, "java.exe -cp \"" + System.getProperty("java.class.path")
        + "\" -Xrs " + this.getClass().getName(), "AUTO_START", false));
  }

  /**
   * Install the service.
   *
   * @return true on success
   * @param displayName
   *            visible name
   * @param description
   *            description
   * @param dependencies
   *            array of other services to depend on or null
   * @param account
   *            service account or null for LocalSystem
   * @param password
   *            password for service account or null
   * @param command
   *            command line to start the service
   * @throws java.lang.Exception
   */
  public boolean install(String displayName, String description, String[] dependencies, String account, String password, String command,
      String startType, boolean interactive)
  {
    Advapi32 advapi32;
    Advapi32.SERVICE_DESCRIPTION desc;
    Pointer serviceManager, service;
    boolean success = false;
    String dep = "";

    if (dependencies != null)
    {
      for (String s : dependencies)
      {
        dep += s + "\0";
      }
    }
    dep += "\0";

    desc = new Advapi32.SERVICE_DESCRIPTION();
    desc.lpDescription = description;

    advapi32 = Advapi32.INSTANCE;
    serviceManager = openServiceControlManager(null, WINSVC.SC_MANAGER_ALL_ACCESS);

    int winStartType = "DEMAND_START".equals(startType) ? WINSVC.SERVICE_DEMAND_START : WINSVC.SERVICE_AUTO_START;
    int dwServiceType = WINSVC.SERVICE_WIN32_OWN_PROCESS;
    if (interactive)
      dwServiceType |= WINSVC.SERVICE_INTERACTIVE_PROCESS;
    if (serviceManager != null)
    {
      service = advapi32.CreateService(serviceManager, serviceName, displayName, WINSVC.SERVICE_ALL_ACCESS, dwServiceType, winStartType,
          WINSVC.SERVICE_ERROR_NORMAL, command, null, null, dep, account, password);

      if (service != null)
      {
        success = advapi32.ChangeServiceConfig2(service, WINSVC.SERVICE_CONFIG_DESCRIPTION, desc);
        advapi32.CloseServiceHandle(service);
      }
      else
      {
        int err = Kernel32.INSTANCE.GetLastError();
        System.out.println("error during install " + err);
        System.out.println(Kernel32Util.formatMessageFromLastErrorCode(err));
      }

      advapi32.CloseServiceHandle(serviceManager);
    }
    return (success);
  }

  /**
   * Uninstall the service.
   *
   * @throws java.lang.Exception
   * @return true on success
   */
  public boolean uninstall()
  {
    Advapi32 advapi32;
    Pointer serviceManager, service;
    boolean success = false;

    advapi32 = Advapi32.INSTANCE;
    serviceManager = openServiceControlManager(null, WINSVC.SC_MANAGER_ALL_ACCESS);

    if (serviceManager != null)
    {
      service = advapi32.OpenService(serviceManager, serviceName, WINSVC.SERVICE_ALL_ACCESS);

      if (service != null)
      {
        success = advapi32.DeleteService(service);
        advapi32.CloseServiceHandle(service);
      }
      advapi32.CloseServiceHandle(serviceManager);
    }
    return (success);
  }

  public static ServiceInfo serviceInfo(String name)
  {
    ServiceInfoImpl result = new ServiceInfoImpl();
    result.setName(name);

    Advapi32 advapi32;
    Pointer serviceManager, service;
    int state = Service.STATE_UNKNOWN;

    advapi32 = Advapi32.INSTANCE;

    serviceManager = openServiceControlManager(null, WINNT.GENERIC_READ);

    if (serviceManager != null)
    {
      state = 0;
      service = advapi32.OpenService(serviceManager, name, WINNT.GENERIC_READ);

      if (service != null)
      {
        IntByReference pcbBytesNeeded = new IntByReference();
        state |= Service.STATE_INSTALLED;
        // get size required
        if (!advapi32.QueryServiceConfig(service, null, 0, pcbBytesNeeded))
        {
          // now get the data
          int cbBufSize = pcbBytesNeeded.getValue();
          Memory buffer = new Memory(cbBufSize);
          buffer.clear();
          if (advapi32.QueryServiceConfig(service, buffer, cbBufSize, pcbBytesNeeded))
          {
            QUERY_SERVICE_CONFIG lpServiceConfig = new QUERY_SERVICE_CONFIG();
            lpServiceConfig.init(buffer);
            if (lpServiceConfig.dwStartType == Advapi32.SERVICE_DISABLED)
              state |= Service.STATE_DISABLED;
            if (lpServiceConfig.dwStartType == Advapi32.SERVICE_BOOT_START | lpServiceConfig.dwStartType == Advapi32.SERVICE_SYSTEM_START
                | lpServiceConfig.dwStartType == Advapi32.SERVICE_AUTO_START)
              state |= Service.STATE_AUTOMATIC;
            if (lpServiceConfig.dwStartType == Advapi32.SERVICE_DEMAND_START)
              state |= Service.STATE_MANUAL;
            if ((lpServiceConfig.dwServiceType & Advapi32.SERVICE_INTERACTIVE_PROCESS) != 0)
              state |= Service.STATE_INTERACTIVE;
            result.setAccount(lpServiceConfig.lpServiceStartName);
            result.setCommand(lpServiceConfig.lpBinaryPathName);
            result.setDependencies(lpServiceConfig.getDependencies());
            result.setDisplayName(lpServiceConfig.lpDisplayName);

          }
          else
          {
            state |= Service.STATE_UNKNOWN;
            System.out.println("Error in QueryServiceConfig: " + Native.getLastError());
          }
        }
        else
        {
          state |= Service.STATE_UNKNOWN;
          System.out.println("Error in QueryServiceConfig: " + Native.getLastError());
        }
        if (!advapi32.QueryServiceStatusEx(service, (byte) advapi32.SC_STATUS_PROCESS_INFO, null, 0, pcbBytesNeeded))
        {
          // now get the data
          int cbBufSize = pcbBytesNeeded.getValue();
          Memory buffer = new Memory(cbBufSize);
          buffer.clear();
          if (advapi32.QueryServiceStatusEx(service, (byte) advapi32.SC_STATUS_PROCESS_INFO, buffer, cbBufSize, pcbBytesNeeded))
          {
            SERVICE_STATUS_PROCESS lpBuffer = new SERVICE_STATUS_PROCESS();
            lpBuffer.init(buffer);
            if (lpBuffer.dwCurrentState == advapi32.SERVICE_RUNNING)
              state |= Service.STATE_RUNNING;
            if (lpBuffer.dwCurrentState == advapi32.SERVICE_PAUSED)
              state |= Service.STATE_PAUSED;
            if (lpBuffer.dwCurrentState == advapi32.SERVICE_START_PENDING)
              state |= Service.STATE_STARTING;
            if (lpBuffer.dwCurrentState == advapi32.SERVICE_STOP_PENDING)
              state |= Service.STATE_STOPPING;
            result.setPid(lpBuffer.dwProcessId);
          }
          else
          {
            state |= Service.STATE_UNKNOWN;
            System.out.println("Error in QueryServiceStatusEx: " + Native.getLastError());
          }
        }
        if (!advapi32.QueryServiceConfig2(service, (byte) advapi32.SERVICE_CONFIG_DESCRIPTION, null, 0, pcbBytesNeeded))
        {
          // now get the data
          int cbBufSize = pcbBytesNeeded.getValue();
          Memory buffer = new Memory(cbBufSize);
          buffer.clear();
          if (advapi32.QueryServiceConfig2(service, (byte) advapi32.SERVICE_CONFIG_DESCRIPTION, buffer, cbBufSize, pcbBytesNeeded))
          {
            SERVICE_DESCRIPTION lpBuffer = new SERVICE_DESCRIPTION();
            lpBuffer.init(buffer);
            result.setDescription(lpBuffer.lpDescription);
          }
          else
          {
            state |= Service.STATE_UNKNOWN;
            System.out.println("Error in QueryServiceStatusEx: " + Native.getLastError());
          }
        }

        else
        {
          state |= Service.STATE_UNKNOWN;
          System.out.println("Error in QueryServiceStatusEx: " + Native.getLastError());
        }

        advapi32.CloseServiceHandle(service);
      }
      advapi32.CloseServiceHandle(serviceManager);
    }
    result.setState(state);

    return result;

  }

  public int state()
  {
    Advapi32 advapi32;
    Pointer serviceManager, service;
    int result = Service.STATE_UNKNOWN;

    advapi32 = Advapi32.INSTANCE;

    serviceManager = openServiceControlManager(null, WINNT.GENERIC_READ);
    // System.out.println("Win32Service.state() serviceManager "+serviceManager);

    if (serviceManager != null)
    {
      result = 0;
      service = advapi32.OpenService(serviceManager, serviceName, WINNT.GENERIC_READ);
      // System.out.println("Win32Service.state() service "+service);

      if (service != null)
      {
        IntByReference pcbBytesNeeded = new IntByReference();
        result |= Service.STATE_INSTALLED;
        // get size required
        if (!advapi32.QueryServiceConfig(service, null, 0, pcbBytesNeeded))
        {
          // now get the data
          int cbBufSize = pcbBytesNeeded.getValue();
          if (cbBufSize > 8192)
            cbBufSize = 8192;
          Memory buffer = new Memory(cbBufSize);
          buffer.clear();
          if (advapi32.QueryServiceConfig(service, buffer, cbBufSize, pcbBytesNeeded))
          {
            QUERY_SERVICE_CONFIG lpServiceConfig = new QUERY_SERVICE_CONFIG();
            lpServiceConfig.init(buffer);
            if (lpServiceConfig.dwStartType == Advapi32.SERVICE_DISABLED)
              result |= Service.STATE_DISABLED;
            if (lpServiceConfig.dwStartType == Advapi32.SERVICE_BOOT_START | lpServiceConfig.dwStartType == Advapi32.SERVICE_SYSTEM_START
                | lpServiceConfig.dwStartType == Advapi32.SERVICE_AUTO_START)
              result |= Service.STATE_AUTOMATIC;
            if (lpServiceConfig.dwStartType == Advapi32.SERVICE_DEMAND_START)
              result |= Service.STATE_MANUAL;
            if ((lpServiceConfig.dwServiceType & Advapi32.SERVICE_INTERACTIVE_PROCESS) != 0)
              result |= Service.STATE_INTERACTIVE;

          }
          else
          {
            result |= Service.STATE_UNKNOWN;
            int error = Native.getLastError();
            System.out.println("Error getting buffer size in QueryServiceConfig: " + error + " " + Kernel32Util.formatMessageFromLastErrorCode(error));
          }
        }
        else
        {
          result |= Service.STATE_UNKNOWN;
          int error = Native.getLastError();
          System.out.println("Error in QueryServiceConfig: " + error + " " + Kernel32Util.formatMessageFromLastErrorCode(error));
        }
        if (!advapi32.QueryServiceStatusEx(service, (byte) advapi32.SC_STATUS_PROCESS_INFO, null, 0, pcbBytesNeeded))
        {
          // now get the data
          int cbBufSize = pcbBytesNeeded.getValue();
          Memory buffer = new Memory(cbBufSize);
          buffer.clear();
          if (advapi32.QueryServiceStatusEx(service, (byte) advapi32.SC_STATUS_PROCESS_INFO, buffer, cbBufSize, pcbBytesNeeded))
          {
            SERVICE_STATUS_PROCESS lpBuffer = new SERVICE_STATUS_PROCESS();
            lpBuffer.init(buffer);
            if (lpBuffer.dwCurrentState == advapi32.SERVICE_RUNNING)
              result |= Service.STATE_RUNNING;
            if (lpBuffer.dwCurrentState == advapi32.SERVICE_PAUSED)
              result |= Service.STATE_PAUSED;
            // System.out.println("Win32Service.state() dwCurrentState "+lpBuffer.dwCurrentState);

          }
          else
          {
            result |= Service.STATE_UNKNOWN;
            int error = Native.getLastError();
            System.out.println("Error getting buffer size in QueryServiceStatusEx: " + error + " " + Kernel32Util.formatMessageFromLastErrorCode(error));
          }
        }
        else
        {
          result |= Service.STATE_UNKNOWN;
          int error = Native.getLastError();
          System.out.println("Error in QueryServiceStatusEx: " + error + " " + Kernel32Util.formatMessageFromLastErrorCode(error));
        }

        advapi32.CloseServiceHandle(service);
      }
      advapi32.CloseServiceHandle(serviceManager);
    }

    return result;

  }

  /**
   * Ask the ServiceControlManager to start the service.
   *
   * @return true on success
   */
  public boolean start()
  {
    Advapi32 advapi32;
    Pointer serviceManager, service;
    boolean success = false;

    advapi32 = Advapi32.INSTANCE;

    serviceManager = openServiceControlManager(null, WINNT.GENERIC_EXECUTE);
    // System.out.println("service.start() serviceManager "+serviceManager);

    if (serviceManager != null)
    {
      service = advapi32.OpenService(serviceManager, serviceName, WINNT.GENERIC_EXECUTE);
      // System.out.println("service.start() service "+service);

      if (service != null)
      {
        success = advapi32.StartService(service, 0, null);
        // System.out.println("service.start() StartService "+success);
        advapi32.CloseServiceHandle(service);
      }
      advapi32.CloseServiceHandle(serviceManager);
    }

    return (success);
  }

  /**
   * Ask the ServiceControlManager to stop the service.
   *
   * @return true on success
   */
  public boolean stop() throws Exception
  {
    Advapi32 advapi32;
    Pointer serviceManager, service;
    Advapi32.SERVICE_STATUS serviceStatus;
    boolean success = false;

    advapi32 = Advapi32.INSTANCE;

    serviceManager = openServiceControlManager(null, WINNT.GENERIC_EXECUTE);

    if (serviceManager != null)
    {
      service = advapi32.OpenService(serviceManager, serviceName, WINNT.GENERIC_EXECUTE);

      if (service != null)
      {
        serviceStatus = new Advapi32.SERVICE_STATUS();
        success = advapi32.ControlService(service, WINSVC.SERVICE_CONTROL_STOP, serviceStatus);
        advapi32.CloseServiceHandle(service);
      }
      advapi32.CloseServiceHandle(serviceManager);
    }

    return (success);
  }

  /**
   * Initialize the service, connect to the ServiceControlManager.
   */
  public void init()
  {
    Advapi32 advapi32;
    // Advapi32.SERVICE_TABLE_ENTRY[] entries = new
    // Advapi32.SERVICE_TABLE_ENTRY[2];
    Advapi32.SERVICE_TABLE_ENTRY entry;

    serviceMain = new ServiceMain();
    advapi32 = Advapi32.INSTANCE;
    entry = new Advapi32.SERVICE_TABLE_ENTRY();
    entry.size();
    entry.lpServiceName = serviceName;
    entry.lpServiceProc = serviceMain;
    entry.write();

    if (!advapi32.StartServiceCtrlDispatcher(entry.toArray(2)))
    {
      log("error in StartServiceCtrlDispatcher");
      int err = Native.getLastError();
      log(err + ":" + Kernel32Util.formatMessageFromLastErrorCode(err));
    }
  }

  public void setStopTimeout(int t)
  {
    stopTimeout = t;
  }

  public int getStopTimeout()
  {
    return stopTimeout;
  }

  public void reportStartup()
  {
    reportStatus(WINSVC.SERVICE_RUNNING, WINERROR.NO_ERROR, 0);

    onStart();

    try
    {
      synchronized (waitObject)
      {
        waitObject.wait();
      }
    }
    catch (InterruptedException ex)
    {
    }
    reportStatus(WINSVC.SERVICE_STOPPED, WINERROR.NO_ERROR, 0);

    // Avoid returning from ServiceMain, which will cause a crash
    // See http://support.microsoft.com/kb/201349, which recommends
    // having init() wait for this thread.
    // Waiting on this thread in init() won't fix the crash, though.
    // System.exit(0);

  }

  /**
   * Get a handle to the ServiceControlManager.
   *
   * @param machine
   *            name of the machine or null for localhost
   * @param access
   *            access flags
   * @return handle to ServiceControlManager or null when failed
   */
  static private Pointer openServiceControlManager(String machine, int access)
  {
    Pointer handle = null;
    Advapi32 advapi32;

    advapi32 = Advapi32.INSTANCE;
    handle = advapi32.OpenSCManager(machine, null, access);
    if (handle == null)
    {
      int err = Native.getLastError();
      System.out.println("Error in OpenSCManager: " + Integer.toHexString(err));
      if (err == 5)
        System.out.println("Access denied: please check the user credentials");
    }

    return (handle);
  }

  static public Map<String, ENUM_SERVICE_STATUS_PROCESS> enumerateServices(String machine)
  {
    Map<String, ENUM_SERVICE_STATUS_PROCESS> result = new HashMap();
    // Open the Service Control Manager
    Pointer sc = openServiceControlManager(machine, WINSVC.SC_MANAGER_ENUMERATE_SERVICE);

    // Check if OpenSCManager returns NULL. Otherwise proceed
    if (sc != null && !sc.equals(null))
    {
      Memory service_data = null;
      int service_data_size = 0;
      int infoLevel = WINSVC.SC_ENUM_PROCESS_INFO;
      boolean retVal;
      IntByReference bytesNeeded = new IntByReference(0);
      IntByReference srvCount = new IntByReference(0);
      IntByReference resumeHandle = new IntByReference(0);
      int srvType = WINSVC.SERVICE_WIN32;
      int srvState = WINSVC.SERVICE_STATE_ALL;

      // Call EnumServicesStatus with null data and data_size == 0, so we
      // get the required memory size
      retVal = Advapi32.INSTANCE.EnumServicesStatusExW(sc, infoLevel, srvType, srvState, service_data, service_data_size, bytesNeeded,
          srvCount, resumeHandle, null);

      int err = Native.getLastError();
      // EnumServicesStatus should need more memory space
      if ((!retVal) || err == WINERROR.ERROR_MORE_DATA)
      {
        int bytesCount = bytesNeeded.getValue();
        service_data = new Memory(bytesCount);
        service_data.clear();
        service_data_size = bytesCount;
        // System.out.println(resumeHandle.getValue());
        resumeHandle.setValue(0);
        retVal = Advapi32.INSTANCE.EnumServicesStatusExW(sc, infoLevel, srvType, srvState, service_data, service_data_size, bytesNeeded,
            srvCount, resumeHandle, null);
        if (!retVal)
        {
          err = Native.getLastError();
          System.out.println("Error in EnumServicesStatusExA " + Integer.toHexString(err));
          return null;
        }
      }
      else
        return null;

      ENUM_SERVICE_STATUS_PROCESS serviceStatus = new ENUM_SERVICE_STATUS_PROCESS();
      serviceStatus.init(service_data);
      for (int i = 0; i < srvCount.getValue(); i++)
      {
        result.put(serviceStatus.getServiceName().toLowerCase(), serviceStatus);
        serviceStatus = serviceStatus.next();
      }
    }

    // Close the SC_HANLDE returned by OpenSCManager
    Advapi32.INSTANCE.CloseServiceHandle(sc);

    return result;
  }

  /**
   * Report service status to the ServiceControlManager.
   *
   * @param status
   *            status
   * @param win32ExitCode
   *            exit code
   * @param waitHint
   *            time to wait
   */
  protected void reportStatus(int status, int win32ExitCode, int waitHint)
  {
    Advapi32 advapi32;
    Advapi32.SERVICE_STATUS serviceStatus;

    advapi32 = Advapi32.INSTANCE;
    serviceStatus = new Advapi32.SERVICE_STATUS();
    serviceStatus.dwServiceType = WINNT.SERVICE_WIN32_OWN_PROCESS;
    serviceStatus.dwControlsAccepted = WINSVC.SERVICE_ACCEPT_STOP | WINSVC.SERVICE_ACCEPT_SHUTDOWN;
    serviceStatus.dwWin32ExitCode = win32ExitCode;
    serviceStatus.dwWaitHint = waitHint;
    serviceStatus.dwCurrentState = status;
    serviceStatus.dwCheckPoint = checkPoint;
    log("reporting status " + checkPoint);

    advapi32.SetServiceStatus(serviceStatusHandle, serviceStatus);
  }

  /**
   * Called when service is starting.
   */
  public abstract void onStart();

  /*
   * Called when service should stop.
   */
  public abstract void onStop();

  public abstract void log(String txt);

  /**
   * Implementation of the service main function.
   */
  private class ServiceMain implements Advapi32.SERVICE_MAIN_FUNCTION
  {

    /**
     * Called when the service is starting.
     *
     * @param dwArgc
     *            number of arguments
     * @param lpszArgv
     *            pointer to arguments
     */
    public void callback(int dwArgc, Pointer lpszArgv)
    {
      Advapi32 advapi32;

      advapi32 = Advapi32.INSTANCE;

      log("+ ServiceMain callback");
      serviceControl = new ServiceControl();
      serviceStatusHandle = advapi32.RegisterServiceCtrlHandlerEx(serviceName, serviceControl, null);

      // if we are waiting for application to report startup
      if (!autoReportStartup)
        try
        {
          // report the startup time
          reportStatus(WINSVC.SERVICE_START_PENDING, WINERROR.NO_ERROR, startupTimeout);
          // wait for application to send startup notification
          startupLock.lock();
          if (!startupCondition.await(startupTimeout, TimeUnit.MILLISECONDS))
          {
            log("service startup timeout -> aborting");
            System.exit(999);
          }
        }
        catch (InterruptedException e)
        {
          e.printStackTrace();
        }
        finally
        {
          startupLock.unlock();
        }
      else
        // if we are not waiting for the application, give us at most 5
        // seconds to report startup
        reportStatus(WINSVC.SERVICE_START_PENDING, WINERROR.NO_ERROR, 5000);

      // this method will hang until the service terminates
      reportStartup();

    }
  }

  /**
   * Implementation of the service control function.
   */
  private class ServiceControl implements Advapi32.HandlerEx
  {

    /**
     * Called when the service get a control code.
     *
     * @param dwControl
     * @param dwEventType
     * @param lpEventData
     * @param lpContext
     */
    public int callback(int dwControl, int dwEventType, Pointer lpEventData, Pointer lpContext)
    {
      log("received service control " + dwControl);
      switch (dwControl)
      {
      case WINSVC.SERVICE_CONTROL_STOP:
      case WINSVC.SERVICE_CONTROL_SHUTDOWN:
        checkPoint = 1;
        reportStatus(WINSVC.SERVICE_STOP_PENDING, WINERROR.NO_ERROR, stopTimeout);
        onStop();
      }
      return WINERROR.NO_ERROR;
    }
  }

  public int getStartupTimeout()
  {
    return startupTimeout;
  }

  public boolean isAutoReportStartup()
  {
    return autoReportStartup;
  }

  public void setStartupTimeout(int startupTimeout)
  {
    this.startupTimeout = startupTimeout;
  }

  public void setAutoReportStartup(boolean autoReportStartup)
  {
    this.autoReportStartup = autoReportStartup;
  }

  public void notifyStartup()
  {
    try
    {
      startupLock.lock();
      startupCondition.signal();
    }
    finally
    {
      startupLock.unlock();
    }
  }
}
TOP

Related Classes of jnacontrib.win32.Win32Service$ServiceControl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.