commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mt...@apache.org
Subject svn commit: r1148625 - in /commons/sandbox/runtime/trunk/src/main: java/org/apache/commons/runtime/platform/windows/ native/os/win32/ native/shared/
Date Wed, 20 Jul 2011 06:06:26 GMT
Author: mturk
Date: Wed Jul 20 06:06:24 2011
New Revision: 1148625

URL: http://svn.apache.org/viewvc?rev=1148625&view=rev
Log:
Implement win32 Service reconfiguration 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/ServiceControlManager.java
    commons/sandbox/runtime/trunk/src/main/native/os/win32/scm.c
    commons/sandbox/runtime/trunk/src/main/native/os/win32/service.c
    commons/sandbox/runtime/trunk/src/main/native/shared/string.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=1148625&r1=1148624&r2=1148625&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
Wed Jul 20 06:06:24 2011
@@ -24,6 +24,7 @@ import java.util.List;
 import org.apache.commons.runtime.Errno;
 import org.apache.commons.runtime.Status;
 import org.apache.commons.runtime.SystemException;
+import org.apache.commons.runtime.TimeoutException;
 import org.apache.commons.runtime.util.Utils;
 
 /**
@@ -31,38 +32,31 @@ import org.apache.commons.runtime.util.U
  */
 public final class Service implements Closeable
 {
+    private long    scm;
     private long    handle;
     private String  serviceName;
     private String  displayName;
     private int[]   serviceStatusProcess;
-    private long    prevQueryStatus = 0L;
 
     // Named indexes inside serviceStatusProcess array.
     // They are here just for easier entry access.
-    private static final int     serviceType                =  0;
-    private static final int     currentState               =  1;
-    private static final int     controlsAccepted           =  2;
-    private static final int     win32ExitCode              =  3;
-    private static final int     serviceSpecificExitCode    =  4;
-    private static final int     checkPoint                 =  5;
-    private static final int     waitHint                   =  6;
-    private static final int     processId                  =  7;
-    private static final int     serviceFlags               =  8;
+    private static final int     serviceType                    =  0;
+    private static final int     currentState                   =  1;
+    private static final int     controlsAccepted               =  2;
+    private static final int     win32ExitCode                  =  3;
+    private static final int     serviceSpecificExitCode        =  4;
+    private static final int     checkPoint                     =  5;
+    private static final int     waitHint                       =  6;
+    private static final int     processId                      =  7;
+    private static final int     serviceFlags                   =  8;
     // Following are addition to SERVICE_STATUS_PROCESS structure.
-    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 static final int     startType                      =  9;
+    private static final int     errorControl                   = 10;
 
+    // Private error codes
+    private static final int     ERROR_SERVICE_REQUEST_TIMEOUT  = 1053;
+    private static final int     SERVICE_NO_CHANGE              = 0xFFFFFFFF;
+    private static final String  SERVICES_KEY                   = "SYSTEM\\CurrentControlSet\\Services";
 
     private Service()
     {
@@ -70,24 +64,28 @@ public final class Service implements Cl
     }
 
     /**
-     * Created from the native during services's enum.
+     * Created from the native during services's enum or create.
+     * In case it was called from enum the handle is invalid.
+     * Only in that case Service can call open
      */
-    private Service(String name, String disp, int[] stats, long h)
+    private Service(String name, String disp, int[] stats, long scm, long h)
     {
         serviceName = name;
         displayName = disp;
         serviceStatusProcess = stats;
+        this.scm = scm;
         handle = h;
     }
 
     /**
      * Created from the native during services open.
      */
-    private Service(String name, long h)
+    private Service(String name, long scm, long h)
     {
         serviceName = name;
         displayName = null;
         serviceStatusProcess = new int[16];
+        this.scm = scm;
         handle = h;
     }
 
@@ -178,24 +176,12 @@ public final class Service implements Cl
         handle = 0L;
     }
 
-    private synchronized void queryStatus()
-    {
-        if (handle == 0L)
-            return;
-        long now = System.currentTimeMillis();
-        // Use basic millisecond resolution window
-        //
-        if (now > prevQueryStatus) {
-            Win32.QueryServiceStatusEx(handle, serviceStatusProcess);
-            prevQueryStatus = now;
-        }
-    }
-
     /**
      * Called by the garbage collector when the object is destroyed.
      * The class will free internal resources allocated by the
      * Operating system only if there are no additional references
      * to this object.
+     *
      * @see Object#finalize()
      * @throws Throwable the {@code Exception} raised by this method.
      */
@@ -206,6 +192,18 @@ public final class Service implements Cl
         close();
     }
 
+    public void open(int desiredAccess)
+        throws InvalidHandleException, SystemException
+    {
+        if (scm == 0L)
+            throw new InvalidHandleException();
+        if (handle != 0L)
+            Win32.CloseServiceHandle(handle);
+        handle = Win32.OpenService(scm, serviceName, desiredAccess);
+        if (handle == 0L)
+            throw new SystemException(Errno.msg());
+    }
+
     public String getName()
     {
         return serviceName;
@@ -218,24 +216,31 @@ public final class Service implements Cl
 
     /**
      * Get the current state of the service.
+     * <p>
+     * This method calls the Windows {@code QueryServiceStatusEx} API
+     * so make sure to call this method to get the current state of
+     * all service variables.
+     *</p>
+     *
+     * @return the current state of the service.
      *
      * @see ServiceState
      */
-    public ServiceState getCurrentState()
+    public synchronized ServiceState getCurrentState()
     {
-        queryStatus();
+        if (handle == 0L)
+            return ServiceState.UNKNOWN;
+        Win32.QueryServiceStatusEx(handle, serviceStatusProcess);
         return ServiceState.valueOf(serviceStatusProcess[currentState]);
     }
 
     public int getProcessId()
     {
-        queryStatus();
         return serviceStatusProcess[processId];
     }
 
     public EnumSet<ServiceControlsAccepted>  getControlsAccepted()
     {
-        queryStatus();
         return ServiceControlsAccepted.valueOf(serviceStatusProcess[controlsAccepted]);
     }
 
@@ -246,7 +251,6 @@ public final class Service implements Cl
      */
     public EnumSet<ServiceType> getType()
     {
-        queryStatus();
         return ServiceType.valueOf(serviceStatusProcess[serviceType]);
     }
 
@@ -257,7 +261,6 @@ public final class Service implements Cl
      */
     public ServiceStartType getStartType()
     {
-        queryStatus();
         return ServiceStartType.valueOf(serviceStatusProcess[startType]);
     }
 
@@ -274,7 +277,6 @@ public final class Service implements Cl
      */
     public int getExitCode()
     {
-        queryStatus();
         return serviceStatusProcess[win32ExitCode];
     }
 
@@ -288,7 +290,6 @@ public final class Service implements Cl
      */
     public int getServiceExitCode()
     {
-        queryStatus();
         return serviceStatusProcess[serviceSpecificExitCode];
     }
 
@@ -309,9 +310,205 @@ public final class Service implements Cl
      */
     public int getFlags()
     {
-        queryStatus();
         return serviceStatusProcess[serviceFlags];
+    }
+
+    /**
+     * 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, TimeoutException
+    {
+        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 if (rc == ERROR_SERVICE_REQUEST_TIMEOUT)
+                throw new TimeoutException();
+            else
+                throw new SystemException(Status.describe(rc));
+        }
+    }
+
+    /**
+     * Sends a control code to a service.
+     *
+     * @param c the control code to send.
+     */
+    public void control(ServiceControl c)
+        throws InvalidHandleException, SystemException, TimeoutException
+    {
+        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 if (rc == ERROR_SERVICE_REQUEST_TIMEOUT)
+                throw new TimeoutException();
+            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.
+     * </p>
+     * <p>
+     * The service control manager processes service control notifications in
+     * a serial fashion—it will wait for one service to complete processing a
+     * service control notification before sending the next one.
+     * Because of this, a call to this method will block for {@code 30} seconds
+     * if any service is busy handling a control code. If the busy service still
+     * has not returned from its handler function when the timeout expires,
+     * control fails with {@code TimeoutException}.
+     * </p>
+     *
+     * @param c user-defined control code in range {@code 128 to 255}.
+     */
+    public void control(int c)
+        throws InvalidHandleException, SystemException, TimeoutException
+    {
+        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 if (rc == ERROR_SERVICE_REQUEST_TIMEOUT)
+                throw new TimeoutException();
+            else
+                throw new SystemException(Status.describe(rc));
+        }
+    }
+
+    /**
+     * Marks the specified service for deletion from the service control
+     * manager database.
+     * <p>
+     * This method marks a service for deletion from the service control
+     * manager database. The database entry is not removed until all open
+     * handles to the service have been closed by calls to the
+     * (@code close} method, and the service is not running. A running
+     * service is stopped by a call to the {@code control} function with the
+     * {@code ServiceControl.STOP} control code. If the service cannot be
+     * stopped, the database entry is removed when the system is restarted.
+     * </p>
+     * <p>
+     * The service control manager deletes the service by deleting the service
+     * key and its subkeys from the registry.
+     * </p>
+     *
+     * @throws InvalidHandleException
+     *          if the service is not open.
+     * @throws SecurityException
+     *          if the service does not have the {@code DELETE} access right.
+     */
+    public void delete()
+        throws InvalidHandleException, SystemException
+    {
+        if (handle == 0L)
+            throw new InvalidHandleException();
+        int rc = Win32.DeleteService(handle);
+        if (rc != 0) {
+            if (Status.IS_EACCES(rc))
+                throw new SecurityException(Status.describe(rc));
+            else
+                throw new SystemException(Status.describe(rc));
+        }
+    }
 
+    /**
+     * Changes the service's type.
+     *
+     */
+    public void setType(ServiceType t)
+        throws InvalidHandleException, SystemException
+    {
+        if (handle == 0L)
+            throw new InvalidHandleException();
+        int rc = Win32.ChangeServiceConfig(handle,
+                                           t.valueOf(),
+                                           SERVICE_NO_CHANGE,
+                                           SERVICE_NO_CHANGE,
+                                           null,
+                                           null,
+                                           null,
+                                           null,
+                                           null,
+                                           null);
+        if (rc != 0) {
+            if (Status.IS_EACCES(rc))
+                throw new SecurityException(Status.describe(rc));
+            else
+                throw new SystemException(Status.describe(rc));
+        }
+    }
+
+    /**
+     * Changes the service's start type.
+     *
+     */
+    public void setStartType(ServiceStartType t)
+        throws InvalidHandleException, SystemException
+    {
+        if (handle == 0L)
+            throw new InvalidHandleException();
+        int rc = Win32.ChangeServiceConfig(handle,
+                                           SERVICE_NO_CHANGE,
+                                           t.valueOf(),
+                                           SERVICE_NO_CHANGE,
+                                           null,
+                                           null,
+                                           null,
+                                           null,
+                                           null,
+                                           null);
+        if (rc != 0) {
+            if (Status.IS_EACCES(rc))
+                throw new SecurityException(Status.describe(rc));
+            else
+                throw new SystemException(Status.describe(rc));
+        }
+    }
+
+    /**
+     * Changes the way how service handles error conditions.
+     *
+     */
+    public void setErrorControl(ServiceErrorControl e)
+        throws InvalidHandleException, SystemException
+    {
+        if (handle == 0L)
+            throw new InvalidHandleException();
+        int rc = Win32.ChangeServiceConfig(handle,
+                                           SERVICE_NO_CHANGE,
+                                           SERVICE_NO_CHANGE,
+                                           e.valueOf(),
+                                           null,
+                                           null,
+                                           null,
+                                           null,
+                                           null,
+                                           null);
+        if (rc != 0) {
+            if (Status.IS_EACCES(rc))
+                throw new SecurityException(Status.describe(rc));
+            else
+                throw new SystemException(Status.describe(rc));
+        }
     }
 
     /**
@@ -338,31 +535,54 @@ public final class Service implements Cl
      * @param path the fully-qualified path to the service binary file.
      */
     public void setBinaryPathName(String path)
+        throws InvalidHandleException, SystemException
     {
+        if (handle == 0L)
+            throw new InvalidHandleException();
+        String binaryPathName;
         if (path.indexOf(' ') == -1)
-            sBinaryPathName = path;
+            binaryPathName = path;
         else
-            sBinaryPathName = "\"" + path + "\"";
+            binaryPathName = "\"" + path + "\"";
+        int rc = Win32.ChangeServiceConfig(handle,
+                                           SERVICE_NO_CHANGE,
+                                           SERVICE_NO_CHANGE,
+                                           SERVICE_NO_CHANGE,
+                                           binaryPathName,
+                                           null,
+                                           null,
+                                           null,
+                                           null,
+                                           null);
+        if (rc != 0) {
+            if (Status.IS_EACCES(rc))
+                throw new SecurityException(Status.describe(rc));
+            else
+                throw new SystemException(Status.describe(rc));
+        }
     }
 
     public void setBinaryPathName(File path)
+        throws InvalidHandleException, SystemException
     {
         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)
+    public void setLoadOrderGroup(String group)
         throws InvalidHandleException, SystemException
     {
         if (handle == 0L)
             throw new InvalidHandleException();
-        int nargs = args == null ? 0 : args.length;
-        int rc = Win32.StartService(handle, nargs, args);
+        int rc = Win32.ChangeServiceConfig(handle,
+                                           SERVICE_NO_CHANGE,
+                                           SERVICE_NO_CHANGE,
+                                           SERVICE_NO_CHANGE,
+                                           null,
+                                           group,
+                                           null,
+                                           null,
+                                           null,
+                                           null);
         if (rc != 0) {
             if (Status.IS_EACCES(rc))
                 throw new SecurityException(Status.describe(rc));
@@ -371,17 +591,21 @@ public final class Service implements Cl
         }
     }
 
-    /**
-     * Sends a control code to a service.
-     *
-     * @param c control code.
-     */
-    public void control(ServiceControl c)
+    public void setDependencies(String[] dependencies)
         throws InvalidHandleException, SystemException
     {
         if (handle == 0L)
             throw new InvalidHandleException();
-        int rc = Win32.ControlService(handle, c.valueOf(), serviceStatusProcess);
+        int rc = Win32.ChangeServiceConfig(handle,
+                                           SERVICE_NO_CHANGE,
+                                           SERVICE_NO_CHANGE,
+                                           SERVICE_NO_CHANGE,
+                                           null,
+                                           null,
+                                           dependencies,
+                                           null,
+                                           null,
+                                           null);
         if (rc != 0) {
             if (Status.IS_EACCES(rc))
                 throw new SecurityException(Status.describe(rc));
@@ -390,29 +614,52 @@ public final class Service implements Cl
         }
     }
 
-    /**
-     * 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)
+    public void setLogOn(String username, String password)
         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);
+        int rc = Win32.ChangeServiceConfig(handle,
+                                           SERVICE_NO_CHANGE,
+                                           SERVICE_NO_CHANGE,
+                                           SERVICE_NO_CHANGE,
+                                           null,
+                                           null,
+                                           null,
+                                           username,
+                                           password,
+                                           null);
+        if (rc != 0) {
+            if (Status.IS_EACCES(rc))
+                throw new SecurityException(Status.describe(rc));
+            else
+                throw new SystemException(Status.describe(rc));
+        }
+    }
+
+    public void setDisplayName(String name)
+        throws InvalidHandleException, SystemException
+    {
+        if (handle == 0L)
+            throw new InvalidHandleException();
+        int rc = Win32.ChangeServiceConfig(handle,
+                                           SERVICE_NO_CHANGE,
+                                           SERVICE_NO_CHANGE,
+                                           SERVICE_NO_CHANGE,
+                                           null,
+                                           null,
+                                           null,
+                                           null,
+                                           null,
+                                           name);
         if (rc != 0) {
             if (Status.IS_EACCES(rc))
                 throw new SecurityException(Status.describe(rc));
             else
                 throw new SystemException(Status.describe(rc));
         }
+        displayName = name;
     }
 
+
 }

Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/ServiceControlManager.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/ServiceControlManager.java?rev=1148625&r1=1148624&r2=1148625&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/ServiceControlManager.java
(original)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/ServiceControlManager.java
Wed Jul 20 06:06:24 2011
@@ -25,6 +25,7 @@ import java.util.List;
 import org.apache.commons.runtime.Errno;
 import org.apache.commons.runtime.Status;
 import org.apache.commons.runtime.SystemException;
+import org.apache.commons.runtime.TimeoutException;
 import org.apache.commons.runtime.util.Utils;
 
 
@@ -42,10 +43,10 @@ public class ServiceControlManager imple
                                           throws SystemException;
     private static native int       enum1(long instance, int stype, int sstate,
                                           ArrayList<Service> sset);
-    private static native Service   new0(String name, long hsvc);
+    private static native Service   new0(String name, long hscm, long hsvc);
     private static native Service   new1(String name, String disp,
                                          int serviceType, int startType,
-                                         int errorControl, long hsvc);
+                                         int errorControl, long hscm, long hsvc);
 
     /* Public fields */
     public static final String      SERVICES_ACTIVE_DATABASE        = "ServicesActive";
@@ -167,7 +168,7 @@ public class ServiceControlManager imple
         long svc = Win32.OpenService(handle, name, desiredAccess);
         if (svc == 0L)
             throw new SystemException(Errno.msg());
-        return new0(name, svc);
+        return new0(name, handle, svc);
     }
 
     public Service create(String name, String displayName,
@@ -195,7 +196,8 @@ public class ServiceControlManager imple
         if (svc == 0L)
             throw new SystemException(Errno.msg());
         Service s = new1(name, displayName, serviceType.valueOf(),
-                         startType.valueOf(), errorControl.valueOf(), svc);
+                         startType.valueOf(), errorControl.valueOf(),
+                         handle, svc);
         // TODO: Set additional params from the call
 
         return s;

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/scm.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/scm.c?rev=1148625&r1=1148624&r2=1148625&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/scm.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/scm.c Wed Jul 20 06:06:24 2011
@@ -26,7 +26,7 @@
 /* Service Control Manager windows implementation
  */
 extern jobject
-AcrNewServiceObject(JNI_STDENV, LPENUM_SERVICE_STATUS_PROCESSW, jlong);
+AcrNewServiceObject(JNI_STDENV, LPENUM_SERVICE_STATUS_PROCESSW, jlong, jlong);
 
 typedef struct svc_enum_t svc_enum_t;
 struct svc_enum_t {
@@ -189,7 +189,7 @@ ACR_WIN_EXPORT(jint, ServiceControlManag
         DWORD i, idx = 0;
         lpService = (LPENUM_SERVICE_STATUS_PROCESSW)list->data;
         for (i = 0; i < list->size; i++) {
-            jobject s = AcrNewServiceObject(env, lpService, 0LL);
+            jobject s = AcrNewServiceObject(env, lpService, hscm, 0LL);
             if (s != 0)
                 AcrArrayListAdd(env, sset, s);
             else

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/service.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/service.c?rev=1148625&r1=1148624&r2=1148625&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/service.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/service.c Wed Jul 20 06:06:24 2011
@@ -37,13 +37,13 @@ J_DECLARE_CLAZZ = {
 J_DECLARE_M_ID(0000) = {
     0,
     "<init>",
-    "(Ljava/lang/String;Ljava/lang/String;[IJ)V"
+    "(Ljava/lang/String;Ljava/lang/String;[IJJ)V"
 };
 
 J_DECLARE_M_ID(0001) = {
     0,
     "<init>",
-    "(Ljava/lang/String;J)V"
+    "(Ljava/lang/String;JJ)V"
 };
 
 ACR_CLASS_CTOR(Win32Service)
@@ -63,7 +63,7 @@ ACR_CLASS_DTOR(Win32Service)
 }
 
 jobject
-AcrNewServiceObject(JNI_STDENV, LPENUM_SERVICE_STATUS_PROCESSW ss, jlong hsvc)
+AcrNewServiceObject(JNI_STDENV, LPENUM_SERVICE_STATUS_PROCESSW ss, jlong hscm, jlong hsvc)
 {
     jobject si = 0;
     jstring name;
@@ -91,7 +91,7 @@ AcrNewServiceObject(JNI_STDENV, LPENUM_S
     (*env)->SetIntArrayRegion(env, stats, 0, 16, ja);
     /* Create the object -> new Service(String,String,int[])
      */
-    si = (*env)->NewObject(env, _clazzn.i, J4MID(0000), name, desc, stats, hsvc);
+    si = (*env)->NewObject(env, _clazzn.i, J4MID(0000), name, desc, stats, hscm, hsvc);
     /* Delete local references cause we are probably
      * invoked inside the loop
      */
@@ -104,9 +104,10 @@ finally:
 }
 
 ACR_WIN_EXPORT(jobject, ServiceControlManager, new0)(JNI_STDARGS,
-                                                     jstring name, jlong hsvc)
+                                                     jstring name,
+                                                     jlong hscm, jlong hsvc)
 {
-    return (*env)->NewObject(env, _clazzn.i, J4MID(0001), name, hsvc);
+    return (*env)->NewObject(env, _clazzn.i, J4MID(0001), name, hscm, hsvc);
 }
 
 ACR_WIN_EXPORT(jobject, ServiceControlManager, new1)(JNI_STDARGS,
@@ -114,6 +115,7 @@ ACR_WIN_EXPORT(jobject, ServiceControlMa
                                                      jint serviceType,
                                                      jint startType,
                                                      jint errorControl,
+                                                     jlong hscm,
                                                      jlong hsvc)
 {
     jintArray stats;
@@ -127,5 +129,5 @@ ACR_WIN_EXPORT(jobject, ServiceControlMa
     if ((stats = (*env)->NewIntArray(env, 16)) == 0)
         return 0;
     (*env)->SetIntArrayRegion(env, stats, 0, 16, ja);
-    return (*env)->NewObject(env, _clazzn.i, J4MID(0000), name, disp, stats, hsvc);
+    return (*env)->NewObject(env, _clazzn.i, J4MID(0000), name, disp, stats, hscm, hsvc);
 }

Modified: commons/sandbox/runtime/trunk/src/main/native/shared/string.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/string.c?rev=1148625&r1=1148624&r2=1148625&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/string.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/string.c Wed Jul 20 06:06:24 2011
@@ -145,6 +145,8 @@ static const jchar _cp_1252[256] = {
     0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
 };
 
+extern char *
+acr_zero_string_ptr;
 int
 acr_native_codepage = -1;
 
@@ -180,6 +182,14 @@ static char *get_string_iso_8859_1(JNI_S
     char *rv;
 
     sl = (*env)->GetStringLength(env, str);
+    if (sl == 0) {
+        if (b != 0) {
+            b[0] = '\0';
+            return b;
+        }
+        else
+            return acr_zero_string_ptr;
+    }
     if (b && sl < ACR_PBUFF_LEN)
         rv = b;
     else {
@@ -770,6 +780,14 @@ static char *get_string_utf_8(JNI_STDENV
     char *rv;
 
     sl = (*env)->GetStringLength(env, str);
+    if (sl == 0) {
+        if (b != 0) {
+            b[0] = '\0';
+            return b;
+        }
+        else
+            return acr_zero_string_ptr;
+    }
     nl = sl * 3;
     if (b && nl < ACR_PBUFF_LEN)
         rv = b;
@@ -821,6 +839,15 @@ static char *get_string_default(JNI_STDE
         return 0;
     else {
         jint len = (*env)->GetArrayLength(env, sb);
+        if (len == 0) {
+            (*env)->DeleteLocalRef(env, sb);
+            if (b != 0) {
+                b[0] = '\0';
+                return b;
+            }
+            else
+                return acr_zero_string_ptr;
+        }
         if (b && len < ACR_PBUFF_LEN) {
             /* Use provided stack storage */
             rv = b;
@@ -978,6 +1005,14 @@ AcrGetJavaStringW(JNI_STDENV, jstring st
         return 0;
     }
     sl = (*env)->GetStringLength(env, str);
+    if (sl == 0) {
+        if (b != 0) {
+            b[0] = L'\0';
+            return b;
+        }
+        else
+            return (wchar_t *)acr_zero_string_ptr;
+    }
     if (b && sl < ACR_MBUFF_LEN)
         rv = b;
     else {
@@ -1317,7 +1352,7 @@ AcrMszJavaStringArrayW(JNI_STDENV, jobje
             chr = (*env)->GetStringChars(env, str, 0);
             if (chr == 0) {
                 AcrFree(ret);
-                return 0;                    
+                return 0;
             }
             memcpy(p, chr, len * sizeof(jchar));
             (*env)->ReleaseStringChars(env, str, chr);



Mime
View raw message