diff options
Diffstat (limited to 'src/org/traccar/WindowsService.java')
-rw-r--r-- | src/org/traccar/WindowsService.java | 231 |
1 files changed, 0 insertions, 231 deletions
diff --git a/src/org/traccar/WindowsService.java b/src/org/traccar/WindowsService.java deleted file mode 100644 index 4a8955608..000000000 --- a/src/org/traccar/WindowsService.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright 2018 Anton Tananaev (anton@traccar.org) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar; - -import com.sun.jna.Pointer; -import com.sun.jna.platform.win32.Advapi32; -import com.sun.jna.platform.win32.WinError; -import com.sun.jna.platform.win32.WinNT; -import com.sun.jna.platform.win32.Winsvc; -import com.sun.jna.platform.win32.Winsvc.HandlerEx; -import com.sun.jna.platform.win32.Winsvc.SC_HANDLE; -import com.sun.jna.platform.win32.Winsvc.SERVICE_DESCRIPTION; -import com.sun.jna.platform.win32.Winsvc.SERVICE_MAIN_FUNCTION; -import com.sun.jna.platform.win32.Winsvc.SERVICE_STATUS; -import com.sun.jna.platform.win32.Winsvc.SERVICE_STATUS_HANDLE; -import com.sun.jna.platform.win32.Winsvc.SERVICE_TABLE_ENTRY; -import jnr.posix.POSIXFactory; - -import java.io.File; -import java.net.URISyntaxException; - -public abstract class WindowsService { - - private static final Advapi32 ADVAPI_32 = Advapi32.INSTANCE; - - private final Object waitObject = new Object(); - - private String serviceName; - private ServiceMain serviceMain; - private ServiceControl serviceControl; - private SERVICE_STATUS_HANDLE serviceStatusHandle; - - public WindowsService(String serviceName) { - this.serviceName = serviceName; - } - - public boolean install( - String displayName, String description, String[] dependencies, - String account, String password, String config) throws URISyntaxException { - - String javaHome = System.getProperty("java.home"); - String javaBinary = javaHome + "\\bin\\java.exe"; - - File jar = new File(WindowsService.class.getProtectionDomain().getCodeSource().getLocation().toURI()); - String command = javaBinary - + " -Duser.dir=\"" + jar.getParentFile().getAbsolutePath() + "\"" - + " -jar \"" + jar.getAbsolutePath() + "\"" - + " --service \"" + config + "\""; - - boolean success = false; - StringBuilder dep = new StringBuilder(); - - if (dependencies != null) { - for (String s : dependencies) { - dep.append(s); - dep.append("\0"); - } - } - dep.append("\0"); - - SERVICE_DESCRIPTION desc = new SERVICE_DESCRIPTION(); - desc.lpDescription = description; - - SC_HANDLE serviceManager = openServiceControlManager(null, Winsvc.SC_MANAGER_ALL_ACCESS); - - if (serviceManager != null) { - SC_HANDLE service = ADVAPI_32.CreateService(serviceManager, serviceName, displayName, - Winsvc.SERVICE_ALL_ACCESS, WinNT.SERVICE_WIN32_OWN_PROCESS, WinNT.SERVICE_AUTO_START, - WinNT.SERVICE_ERROR_NORMAL, - command, - null, null, dep.toString(), account, password); - - if (service != null) { - success = ADVAPI_32.ChangeServiceConfig2(service, Winsvc.SERVICE_CONFIG_DESCRIPTION, desc); - ADVAPI_32.CloseServiceHandle(service); - } - ADVAPI_32.CloseServiceHandle(serviceManager); - } - return success; - } - - public boolean uninstall() { - boolean success = false; - - SC_HANDLE serviceManager = openServiceControlManager(null, Winsvc.SC_MANAGER_ALL_ACCESS); - - if (serviceManager != null) { - SC_HANDLE service = ADVAPI_32.OpenService(serviceManager, serviceName, Winsvc.SERVICE_ALL_ACCESS); - - if (service != null) { - success = ADVAPI_32.DeleteService(service); - ADVAPI_32.CloseServiceHandle(service); - } - ADVAPI_32.CloseServiceHandle(serviceManager); - } - return success; - } - - public boolean start() { - boolean success = false; - - SC_HANDLE serviceManager = openServiceControlManager(null, WinNT.GENERIC_EXECUTE); - - if (serviceManager != null) { - SC_HANDLE service = ADVAPI_32.OpenService(serviceManager, serviceName, WinNT.GENERIC_EXECUTE); - - if (service != null) { - success = ADVAPI_32.StartService(service, 0, null); - ADVAPI_32.CloseServiceHandle(service); - } - ADVAPI_32.CloseServiceHandle(serviceManager); - } - - return success; - } - - public boolean stop() { - boolean success = false; - - SC_HANDLE serviceManager = openServiceControlManager(null, WinNT.GENERIC_EXECUTE); - - if (serviceManager != null) { - SC_HANDLE service = Advapi32.INSTANCE.OpenService(serviceManager, serviceName, WinNT.GENERIC_EXECUTE); - - if (service != null) { - SERVICE_STATUS serviceStatus = new SERVICE_STATUS(); - success = Advapi32.INSTANCE.ControlService(service, Winsvc.SERVICE_CONTROL_STOP, serviceStatus); - Advapi32.INSTANCE.CloseServiceHandle(service); - } - Advapi32.INSTANCE.CloseServiceHandle(serviceManager); - } - - return success; - } - - public void init() throws URISyntaxException { - String path = new File( - WindowsService.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getParent(); - - POSIXFactory.getPOSIX().chdir(path); - - serviceMain = new ServiceMain(); - SERVICE_TABLE_ENTRY entry = new SERVICE_TABLE_ENTRY(); - entry.lpServiceName = serviceName; - entry.lpServiceProc = serviceMain; - - Advapi32.INSTANCE.StartServiceCtrlDispatcher((SERVICE_TABLE_ENTRY[]) entry.toArray(2)); - } - - private SC_HANDLE openServiceControlManager(String machine, int access) { - return ADVAPI_32.OpenSCManager(machine, null, access); - } - - private void reportStatus(int status, int win32ExitCode, int waitHint) { - SERVICE_STATUS serviceStatus = new 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; - - ADVAPI_32.SetServiceStatus(serviceStatusHandle, serviceStatus); - } - - public abstract void run(); - - private class ServiceMain implements SERVICE_MAIN_FUNCTION { - - public void callback(int dwArgc, Pointer lpszArgv) { - serviceControl = new ServiceControl(); - serviceStatusHandle = ADVAPI_32.RegisterServiceCtrlHandlerEx(serviceName, serviceControl, null); - - reportStatus(Winsvc.SERVICE_START_PENDING, WinError.NO_ERROR, 3000); - reportStatus(Winsvc.SERVICE_RUNNING, WinError.NO_ERROR, 0); - - Thread.currentThread().setContextClassLoader(WindowsService.class.getClassLoader()); - - run(); - - 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); - } - - } - - private class ServiceControl implements HandlerEx { - - public int callback(int dwControl, int dwEventType, Pointer lpEventData, Pointer lpContext) { - switch (dwControl) { - case Winsvc.SERVICE_CONTROL_STOP: - case Winsvc.SERVICE_CONTROL_SHUTDOWN: - reportStatus(Winsvc.SERVICE_STOP_PENDING, WinError.NO_ERROR, 5000); - synchronized (waitObject) { - waitObject.notifyAll(); - } - break; - default: - break; - } - return WinError.NO_ERROR; - } - - } - -} |