Author: mturk
Date: Tue Jul 19 21:37:40 2011
New Revision: 1148552
URL: http://svn.apache.org/viewvc?rev=1148552&view=rev
Log:
Implement more of win32 Service API
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/Service.java
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/ServiceControl.java
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/Win32.java
commons/sandbox/runtime/trunk/src/main/native/os/win32/winapi.c
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/Service.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/Service.java?rev=1148552&r1=1148551&r2=1148552&view=diff
==============================================================================
---
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/Service.java
(original)
+++
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/Service.java
Tue Jul 19 21:37:40 2011
@@ -17,6 +17,7 @@
package org.apache.commons.runtime.platform.windows;
import java.io.Closeable;
+import java.io.File;
import java.io.IOException;
import java.util.EnumSet;
import java.util.List;
@@ -34,7 +35,7 @@ public final class Service implements Cl
private String serviceName;
private String displayName;
private int[] serviceStatusProcess;
- private long currentQueryWindow = 0L;
+ private long prevQueryStatus = 0L;
// Named indexes inside serviceStatusProcess array.
// They are here just for easier entry access.
@@ -51,6 +52,17 @@ public final class Service implements Cl
private static final int startType = 9;
private static final int errorControl = 10;
+ // Parameters for the ChangeServiceConfig
+ private String sBinaryPathName = null;
+ private String sLoadOrderGroup = null;
+ private String[] sDependencies = null;
+ private String sServiceStartName = null;
+ private String sPassword = null;
+ private String sDisplayName = null;
+ private int sServiceType = -1;
+ private int sStartType = -1;
+ private int sErrorControl = -1;
+
private Service()
{
@@ -170,12 +182,12 @@ public final class Service implements Cl
{
if (handle == 0L)
return;
- long now = System.nanoTime();
- // Use one millisecond query window
+ long now = System.currentTimeMillis();
+ // Use basic millisecond resolution window
//
- if (now > (currentQueryWindow + 1000000)) {
+ if (now > prevQueryStatus) {
Win32.QueryServiceStatusEx(handle, serviceStatusProcess);
- currentQueryWindow = now;
+ prevQueryStatus = now;
}
}
@@ -301,4 +313,106 @@ public final class Service implements Cl
return serviceStatusProcess[serviceFlags];
}
+
+ /**
+ * Sets the fully-qualified path to the service binary file.
+ * <p>
+ * If the path contains a space, it must be quoted so that it is
+ * correctly interpreted. For example,
+ * {@code "d:\\my share\\myservice.exe"} should be specified as
+ * {@code "\"d:\\my share\\myservice.exe\""}.
+ * </p>
+ * <p>
+ * The path can also include arguments for an auto-start service.
+ * For example, {@code "d:\\myshare\\myservice.exe arg1 arg2"}.
+ * These arguments are passed to the service entry point
+ * (typically the main function).
+ * </p>
+ * <p>
+ * If you specify a path on another computer, the share must be accessible
+ * by the computer account of the local computer because this is the
security
+ * context used in the remote call. However, this requirement allows any
+ * potential vulnerabilities in the remote computer to affect the local
+ * computer. Therefore, it is best to use a local file.
+ *
+ * @param path the fully-qualified path to the service binary file.
+ */
+ public void setBinaryPathName(String path)
+ {
+ if (path.indexOf(' ') == -1)
+ sBinaryPathName = path;
+ else
+ sBinaryPathName = "\"" + path + "\"";
+ }
+
+ public void setBinaryPathName(File path)
+ {
+ setBinaryPathName(path.getPath());
+ }
+
+ /**
+ * Starts a service.
+ *
+ * @param args strings to be passed to the {@code ServiceMain} function for
+ * the service as arguments.
+ */
+ public void start(String[] args)
+ throws InvalidHandleException, SystemException
+ {
+ if (handle == 0L)
+ throw new InvalidHandleException();
+ int nargs = args == null ? 0 : args.length;
+ int rc = Win32.StartService(handle, nargs, args);
+ if (rc != 0) {
+ if (Status.IS_EACCES(rc))
+ throw new SecurityException(Status.describe(rc));
+ else
+ throw new SystemException(Status.describe(rc));
+ }
+ }
+
+ /**
+ * Sends a control code to a service.
+ *
+ * @param c control code.
+ */
+ public void control(ServiceControl c)
+ throws InvalidHandleException, SystemException
+ {
+ if (handle == 0L)
+ throw new InvalidHandleException();
+ int rc = Win32.ControlService(handle, c.valueOf(),
serviceStatusProcess);
+ if (rc != 0) {
+ if (Status.IS_EACCES(rc))
+ throw new SecurityException(Status.describe(rc));
+ else
+ throw new SystemException(Status.describe(rc));
+ }
+ }
+
+ /**
+ * Sends a user-defined control code to a service.
+ * <p>
+ * The service defines the action associated with the control code.
+ * The service handle must have the {@code SERVICE_USER_DEFINED_CONTROL}
+ * access right.
+ *
+ * @param c user-defined control code in range {@code 128 to 255}.
+ */
+ public void control(int c)
+ throws InvalidHandleException, SystemException
+ {
+ if (handle == 0L)
+ throw new InvalidHandleException();
+ if (c < 128 || c > 255)
+ throw new IllegalArgumentException("control code must be in range
from 128 to 255");
+ int rc = Win32.ControlService(handle, c, serviceStatusProcess);
+ if (rc != 0) {
+ if (Status.IS_EACCES(rc))
+ throw new SecurityException(Status.describe(rc));
+ else
+ throw new SystemException(Status.describe(rc));
+ }
+ }
+
}
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/ServiceControl.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/ServiceControl.java?rev=1148552&r1=1148551&r2=1148552&view=diff
==============================================================================
---
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/ServiceControl.java
(original)
+++
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/ServiceControl.java
Tue Jul 19 21:37:40 2011
@@ -80,7 +80,7 @@ public enum ServiceControl
if (e.value == value)
return e;
}
- if (value > USER.value)
+ if (value > 127 && value < 256)
return USER;
else
return UNKNOWN;
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/Win32.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/Win32.java?rev=1148552&r1=1148551&r2=1148552&view=diff
==============================================================================
---
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/Win32.java
(original)
+++
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/Win32.java
Tue Jul 19 21:37:40 2011
@@ -90,6 +90,22 @@ final class Win32
String[] dependencies,
String serviceStartName,
String password);
+ public static native int ChangeServiceConfig(long svc,
+ int serviceType,
+ int startType,
+ int errorControl,
+ String binaryPathName,
+ String loadOrderGroup,
+ String[] dependencies,
+ String serviceStartName,
+ String password,
+ String displayName);
+ /**
+ * Simplified version of ChangeServiceConfig2 API call
+ * that uses SERVICE_CONFIG_DESCRIPTION infoLevel
+ */
+ public static native int ChangeServiceConfig2(long svc,
+ String description);
public static final int HEAP_POINTER = 1;
public static final int SLICE_POINTER = 2;
Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/winapi.c
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/winapi.c?rev=1148552&r1=1148551&r2=1148552&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/winapi.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/winapi.c Tue Jul 19
21:37:40 2011
@@ -375,3 +375,58 @@ ACR_WIN_EXPORT(jlong, Win32, CreateServi
return P2J(svc);
}
+
+ACR_WIN_EXPORT(jint, Win32, ChangeServiceConfig)(JNI_STDARGS, jlong hsvc,
+ jint stype, jint sstart,
+ jint errc, jstring path, jstring
ldgrp,
+ jobjectArray deps, jstring user,
+ jstring password, jstring display)
+{
+ int rc = 0;
+ SC_HANDLE svc = J2P(hsvc, SC_HANDLE);
+
+ WITH_DWCS(display) {
+ WITH_DWCS(path) {
+ WITH_DWCS(ldgrp) {
+ WITH_DWCS(user) {
+ WITH_DWCS(password) {
+ wchar_t *wdeps = AcrMszJavaStringArrayW(env, deps);
+ /* Call the real API */
+ if (!ChangeServiceConfigW(svc,
+ stype,
+ sstart,
+ errc,
+ J2S(path),
+ J2S(ldgrp),
+ 0,
+ wdeps,
+ J2S(user),
+ J2S(password),
+ J2S(display)))
+ rc = ACR_GET_OS_ERROR();
+ AcrFree(wdeps);
+ } DONE_WITH_STR(password);
+ } DONE_WITH_STR(user);
+ } DONE_WITH_STR(ldgrp);
+ } DONE_WITH_STR(path);
+ } DONE_WITH_STR(display);
+
+ return rc;
+}
+
+ACR_WIN_EXPORT(jint, Win32, ChangeServiceConfig2)(JNI_STDARGS, jlong hsvc,
+ jstring description)
+{
+ int rc = 0;
+ SC_HANDLE svc = J2P(hsvc, SC_HANDLE);
+
+ WITH_WSTR(description) {
+ SERVICE_DESCRIPTION desc = { J2S(description) };
+ if (!ChangeServiceConfig2W(svc,
+ SERVICE_CONFIG_DESCRIPTION,
+ &desc))
+ rc = ACR_GET_OS_ERROR();
+ } DONE_WITH_STR(description);
+
+ return rc;
+}