Author: mturk
Date: Tue Jul 19 16:17:22 2011
New Revision: 1148427

URL: http://svn.apache.org/viewvc?rev=1148427&view=rev
Log:
Implement more of win32 Service API

Modified:
    
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/AccessRights.java
    
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/java/org/apache/commons/runtime/platform/windows/Win32.java
    commons/sandbox/runtime/trunk/src/main/native/include/acr/misc.h
    commons/sandbox/runtime/trunk/src/main/native/include/acr/string.h
    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/os/win32/winapi.c
    commons/sandbox/runtime/trunk/src/main/native/shared/clazz.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/AccessRights.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/AccessRights.java?rev=1148427&r1=1148426&r2=1148427&view=diff
==============================================================================
--- 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/AccessRights.java
 (original)
+++ 
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/AccessRights.java
 Tue Jul 19 16:17:22 2011
@@ -95,16 +95,4 @@ public final class AccessRights
     public static final int         PAGE_NOCACHE                    = 
0x00000200;
     public static final int         PAGE_WRITECOMBINE               = 
0x00000400;
 
-    /* Service Access rights */
-    public static final int         SERVICE_ALL_ACCESS              = 0xF01FF;
-    public static final int         SERVICE_CHANGE_CONFIG           = 0x0002;
-    public static final int         SERVICE_ENUMERATE_DEPENDENTS    = 0x0008;
-    public static final int         SERVICE_INTERROGATE             = 0x0080;
-    public static final int         SERVICE_PAUSE_CONTINUE          = 0x0040;
-    public static final int         SERVICE_QUERY_CONFIG            = 0x0001;
-    public static final int         SERVICE_QUERY_STATUS            = 0x0004;
-    public static final int         SERVICE_START                   = 0x0010;
-    public static final int         SERVICE_STOP                    = 0x0020;
-    public static final int         SERVICE_USER_DEFINED_CONTROL    = 0x0100;
-
 }

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=1148427&r1=1148426&r2=1148427&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 16:17:22 2011
@@ -16,6 +16,8 @@
 
 package org.apache.commons.runtime.platform.windows;
 
+import java.io.Closeable;
+import java.io.IOException;
 import java.util.EnumSet;
 import java.util.List;
 import org.apache.commons.runtime.Errno;
@@ -26,24 +28,28 @@ import org.apache.commons.runtime.util.U
 /**
  * Service class.
  */
-public final class Service
+public final class Service implements Closeable
 {
+    private long    handle;
     private String  serviceName;
     private String  displayName;
     private int[]   serviceStatusProcess;
 
     // 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;
+
 
     private Service()
     {
@@ -53,14 +59,72 @@ public final class Service
     /**
      * Created from the native during services's enum.
      */
-    private Service(String name, String disp, int[] stats)
+    private Service(String name, String disp, int[] stats, long h)
     {
         serviceName = name;
         displayName = disp;
         serviceStatusProcess = stats;
+        handle = h;
+    }
+
+    /**
+     * Created from the native during services open.
+     */
+    private Service(String name, long h)
+    {
+        serviceName = name;
+        displayName = null;
+        serviceStatusProcess = new int[16];
+        handle = h;
     }
 
     /**
+     * Includes {@link AccessRights#STANDARD_RIGHTS_REQUIRED}
+     * in addition to all access rights in this table.
+     */
+    public static final int         SERVICE_ALL_ACCESS              = 
0x000F01FF;
+    /**
+     * Required to change the service configuration.
+     * Because this grants the caller the right to change the executable
+     * file that the system runs, it should be granted only to administrators.
+     */
+    public static final int         SERVICE_CHANGE_CONFIG           = 
0x00000002;
+    /**
+     * Required to enumerate all the services dependent on the service.
+     */
+    public static final int         SERVICE_ENUMERATE_DEPENDENTS    = 
0x00000008;
+    /**
+     * Required  to ask the service to report its status immediately.
+     */
+    public static final int         SERVICE_INTERROGATE             = 
0x00000080;
+    /**
+     * Required to pause or continue the service.
+     */
+    public static final int         SERVICE_PAUSE_CONTINUE          = 
0x00000040;
+    /**
+     * Required to query the service configuration.
+     */
+    public static final int         SERVICE_QUERY_CONFIG            = 
0x00000001;
+    /**
+     * Required to ask the service control manager about the status of
+     * the service.
+     */
+    public static final int         SERVICE_QUERY_STATUS            = 
0x00000004;
+    /**
+     * Required to start the service.
+     */
+    public static final int         SERVICE_START                   = 
0x00000010;
+    /**
+     * Required to stop the service.
+     */
+    public static final int         SERVICE_STOP                    = 
0x00000020;
+    /**
+     * Required to call the {@code control} method to specify a
+     * user-defined control code.
+     */
+    public static final int         SERVICE_USER_DEFINED_CONTROL    = 
0x00000100;
+
+    /**
      * Creates a new service object
      */
     public Service(String name)
@@ -74,6 +138,45 @@ public final class Service
         serviceStatusProcess = new int[9];
     }
 
+    /**
+     * Free the allocated resource by the Operating system.
+     * <p>
+     * Note that {@code Object.finalize()} method will call
+     * this function. However if the native code can block for
+     * long time explicit {@code close()} should be called.
+     * </p>
+     * @see java.io.Closeable#close()
+     * @throws IOException if an I/O error occurs.
+     */
+    @Override
+    public synchronized void close()
+        throws IOException
+    {
+        if (handle != 0L) {
+            Win32.CloseServiceHandle(handle);
+            handle = 0L;    
+        }    
+    }
+
+    /**
+     * 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.
+     */
+    @Override
+    protected final void finalize()
+        throws Throwable
+    {
+        try {
+            close();
+        } catch (Exception x) {
+            // Ignore exceptions on finalize
+        }
+    }
+
     public String getName()
     {
         return serviceName;
@@ -84,4 +187,5 @@ public final class Service
         return displayName;
     }
     
+    
 }

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=1148427&r1=1148426&r2=1148427&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
 Tue Jul 19 16:17:22 2011
@@ -16,6 +16,9 @@
 
 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.ArrayList;
 import java.util.List;
@@ -29,7 +32,7 @@ import org.apache.commons.runtime.util.U
  * ServiceControlManager manages service control manager database.
  *
  */
-public class ServiceControlManager
+public class ServiceControlManager implements Closeable
 {
 
     private long                handle = 0L;
@@ -39,6 +42,10 @@ public class ServiceControlManager
                                           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   new1(String name, String disp,
+                                         int serviceType, int startType,
+                                         int errorControl, long hsvc);
 
     /* Public fields */
     public static final String      SERVICES_ACTIVE_DATABASE        = 
"ServicesActive";
@@ -121,12 +128,83 @@ public class ServiceControlManager
      * Closes a connection to the service control manager on the
      * local computer. The method will invalidate all opened
      * Services connected to this manager.
-     */
-    public void close()
+     * <p>
+     * Note that {@code Object.finalize()} method will call
+     * this function. However if the native code can block for
+     * long time explicit {@code close()} should be called.
+     * </p>
+     * @see java.io.Closeable#close()
+     * @throws IOException if an I/O error occurs.
+     */
+    @Override
+    public synchronized void close()
+        throws IOException
     {
-        if (handle != 0L)
+        if (handle != 0L) {
             Win32.CloseServiceHandle(handle);
-        handle = 0L;
+            handle = 0L;
+        }
+    }
+
+    /**
+     * 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.
+     */
+    @Override
+    protected final void finalize()
+        throws Throwable
+    {
+        try {
+            close();
+        } catch (Exception x) {
+            // Ignore exceptions on finalize
+        }
+    }
+
+    public Service open(String name, int desiredAccess)
+        throws InvalidHandleException, SystemException
+    {
+        if (handle == 0L)
+            throw new InvalidHandleException();
+        long svc = Win32.OpenService(handle, name, desiredAccess);
+        if (svc == 0L)
+            throw new SystemException(Errno.msg());
+        return new0(name, svc);
     }
 
+    public Service create(String name, String displayName,
+                          ServiceType serviceType, ServiceStartType startType,
+                          ServiceErrorControl errorControl,
+                          File binaryPath, String loadOrderGroup,
+                          String[] dependencies,
+                          String username,
+                          String password)
+        throws InvalidHandleException, SystemException
+    {
+
+        if (handle == 0L)
+            throw new InvalidHandleException();
+        // binaryPath is optional
+        String path = binaryPath == null ? null : binaryPath.getPath();
+        long svc = Win32.CreateService(handle, name, displayName, 0,
+                                       serviceType.valueOf(),
+                                       startType.valueOf(),
+                                       errorControl.valueOf(),
+                                       path, loadOrderGroup,
+                                       dependencies,
+                                       username, password);
+        if (svc == 0L)
+            throw new SystemException(Errno.msg());
+        Service s = new1(name, displayName, serviceType.valueOf(),
+                         startType.valueOf(), errorControl.valueOf(), svc);
+        // TODO: Set additional params from the call
+
+        return s;
+    }
+
+
 }

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=1148427&r1=1148426&r2=1148427&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 16:17:22 2011
@@ -75,6 +75,18 @@ final class Win32
     public static native int        QueryServiceStatusEx(long service, int[] 
SERVICE_STATUS_PROCESS);
     public static native int        StartService(long service, int nargs, 
String[] args);
     public static native int        ControlService(long service, int ctl, 
int[] SERVICE_STATUS);
+    public static native long       CreateService(long scm,
+                                                  String serviceName,
+                                                  String displayName,
+                                                  int desiredAccess,
+                                                  int serviceType,
+                                                  int startType,
+                                                  int errorControl,
+                                                  String binaryPathName,
+                                                  String loadOrderGroup,
+                                                  String[] dependencies,
+                                                  String serviceStartName,
+                                                  String password);
 
     public static final int         HEAP_POINTER            = 1;
     public static final int         SLICE_POINTER           = 2;

Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr/misc.h
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr/misc.h?rev=1148427&r1=1148426&r2=1148427&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr/misc.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr/misc.h Tue Jul 19 
16:17:22 2011
@@ -27,11 +27,6 @@ ACR_CLASS_DTOR(ArrayList);
 ACR_CLASS_CTOR(HashSet);
 ACR_CLASS_DTOR(HashSet);
 
-#if defined(WINDOWS)
-ACR_CLASS_CTOR(Service);
-ACR_CLASS_DTOR(Service);
-#endif
-
 int     AcrArrayListAdd(JNI_STDARGS, jobject e);
 int     AcrArrayListEnsureCapacity(JNI_STDARGS, jint size);
 int     AcrHashSetAdd(JNI_STDARGS, jobject e);

Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr/string.h
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr/string.h?rev=1148427&r1=1148426&r2=1148427&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr/string.h 
(original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr/string.h Tue Jul 
19 16:17:22 2011
@@ -51,6 +51,12 @@
     if (_s##V == 0 && V != 0) goto _e##V;
 #endif
 
+#define WITH_DWCS(V)                                                        \
+    do {                                                                    \
+    wchar_t *_b##V = 0;                                                     \
+    wchar_t *_s##V = AcrGetJavaStringW(env, V, _b##V);                      \
+    if (_s##V == 0 && V != 0) goto _e##V;
+
 #define WITH_WSTR(V)                                                        \
     do {                                                                    \
     wchar_t  _b##V[ACR_MBUFF_SIZ];                                          \
@@ -230,6 +236,8 @@ AcrNewJavaMszArrayW(JNI_STDENV, const wc
 #if defined(WINDOWS)
 wchar_t *
 AcrGetNativePathW(JNI_STDENV, jstring str, wchar_t *b);
+wchar_t *
+AcrMszJavaStringArrayW(JNI_STDENV, jobjectArray arr);
 #endif
 
 /** Convert n to string

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=1148427&r1=1148426&r2=1148427&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 Tue Jul 19 
16:17:22 2011
@@ -26,7 +26,7 @@
 /* Service Control Manager windows implementation
  */
 extern jobject
-AcrNewServiceObject(JNI_STDENV, LPENUM_SERVICE_STATUS_PROCESSW ss);
+AcrNewServiceObject(JNI_STDENV, LPENUM_SERVICE_STATUS_PROCESSW, 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);
+            jobject s = AcrNewServiceObject(env, lpService, 0LL);
             if (s != 0)
                 AcrArrayListAdd(env, sset, s);
             else
@@ -207,3 +207,4 @@ finally:
     free_list(head);
     return rc;
 }
+

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=1148427&r1=1148426&r2=1148427&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 Tue Jul 19 
16:17:22 2011
@@ -37,36 +37,43 @@ J_DECLARE_CLAZZ = {
 J_DECLARE_M_ID(0000) = {
     0,
     "<init>",
-    "(Ljava/lang/String;Ljava/lang/String;[I)V"
+    "(Ljava/lang/String;Ljava/lang/String;[IJ)V"
 };
 
-ACR_CLASS_CTOR(Service)
+J_DECLARE_M_ID(0001) = {
+    0,
+    "<init>",
+    "(Ljava/lang/String;J)V"
+};
+
+ACR_CLASS_CTOR(Win32Service)
 {
     if (AcrLoadClass(env, &_clazzn, 0) == JNI_FALSE)
         return JNI_FALSE;
     J_LOAD_METHOD(0000);
+    J_LOAD_METHOD(0001);
 
     _clazzn.u = 1;
     return JNI_TRUE;
 }
 
-ACR_CLASS_DTOR(Service)
+ACR_CLASS_DTOR(Win32Service)
 {
     AcrUnloadClass(env, &_clazzn);
 }
 
 jobject
-AcrNewServiceObject(JNI_STDENV, LPENUM_SERVICE_STATUS_PROCESSW ss)
+AcrNewServiceObject(JNI_STDENV, LPENUM_SERVICE_STATUS_PROCESSW ss, jlong hsvc)
 {
     jobject si = 0;
     jstring name;
     jstring desc = 0;
-    jobjectArray stats;
-    jint ja[9];
+    jintArray stats;
+    jint i, ja[16];
 
     if ((name = AcrNewJavaStringW(env, ss->lpServiceName)) == 0)
         goto finally;
-    if ((stats = (*env)->NewIntArray(env, 9)) == 0)
+    if ((stats = (*env)->NewIntArray(env, 16)) == 0)
         goto finally;
     if (ss->lpDisplayName != 0 && *(ss->lpDisplayName) != 0)
         desc = AcrNewJavaStringW(env, ss->lpDisplayName);
@@ -79,10 +86,12 @@ AcrNewServiceObject(JNI_STDENV, LPENUM_S
     ja[6] = ss->ServiceStatusProcess.dwWaitHint;
     ja[7] = ss->ServiceStatusProcess.dwProcessId;
     ja[8] = ss->ServiceStatusProcess.dwServiceFlags;
-    (*env)->SetIntArrayRegion(env, stats, 0, 9, ja);
+    for (i = 9; i < 16; i++)
+        ja[i] = SERVICE_NO_CHANGE;
+    (*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);
+    si = (*env)->NewObject(env, _clazzn.i, J4MID(0000), name, desc, stats, 
hsvc);
     /* Delete local references cause we are probably
      * invoked inside the loop
      */
@@ -94,3 +103,29 @@ finally:
     return si;
 }
 
+ACR_WIN_EXPORT(jobject, ServiceControlManager, new0)(JNI_STDARGS,
+                                                     jstring name, jlong hsvc)
+{
+    return (*env)->NewObject(env, _clazzn.i, J4MID(0001), name, hsvc);
+}
+
+ACR_WIN_EXPORT(jobject, ServiceControlManager, new1)(JNI_STDARGS,
+                                                     jstring name, jstring 
disp,
+                                                     jint serviceType,
+                                                     jint startType,
+                                                     jint errorControl,
+                                                     jlong hsvc)
+{
+    jintArray stats;
+    jint i, ja[16];
+
+    for (i = 1; i < 16; i++)
+        ja[i] = SERVICE_NO_CHANGE;
+    ja[0]  = serviceType;
+    ja[9]  = startType;
+    ja[10] = errorControl;
+    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);
+}

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=1148427&r1=1148426&r2=1148427&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 
16:17:22 2011
@@ -276,7 +276,7 @@ ACR_WIN_EXPORT(jint, Win32, StartService
     }
     if (!StartServiceW(svc, nargs, wargs))
         rc = ACR_GET_OS_ERROR();
-    AcrFree(wargs);
+    AcrFreeStringArray(wargs);
     return rc;
 }
 
@@ -320,3 +320,47 @@ ACR_WIN_EXPORT(jint, Win32, DeleteServic
         return 0;
 }
 
+ACR_WIN_EXPORT(jlong, Win32, CreateService)(JNI_STDARGS, jlong hscm,
+                                            jstring name, jstring display,
+                                            jint acc, jint stype, jint sstart,
+                                            jint errc, jstring path, jstring 
ldgrp,
+                                            jobjectArray deps, jstring user,
+                                            jstring password)
+{
+    int rc = 0;
+    SC_HANDLE svc = 0;
+    SC_HANDLE scm = J2P(hscm, SC_HANDLE);
+
+    WITH_DWCS(name) {
+    WITH_DWCS(display) {
+    WITH_DWCS(path) {
+    WITH_DWCS(ldgrp) {
+    WITH_DWCS(user) {
+    WITH_DWCS(password) {
+        wchar_t *wdeps = AcrMszJavaStringArrayW(env, deps);
+
+        svc = CreateServiceW(scm,
+                             J2S(name),
+                             J2S(display),
+                             acc,
+                             stype,
+                             sstart,
+                             errc,
+                             J2S(path),
+                             J2S(ldgrp),
+                             0,
+                             wdeps,
+                             J2S(user),
+                             J2S(password));
+        if (svc == 0)
+            ACR_SAVE_OS_ERROR();
+        AcrFree(wdeps);
+    } DONE_WITH_STR(password);
+    } DONE_WITH_STR(user);
+    } DONE_WITH_STR(ldgrp);
+    } DONE_WITH_STR(path);
+    } DONE_WITH_STR(display);
+    } DONE_WITH_STR(name);
+
+    return P2J(svc);
+}

Modified: commons/sandbox/runtime/trunk/src/main/native/shared/clazz.c
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/clazz.c?rev=1148427&r1=1148426&r2=1148427&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/clazz.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/clazz.c Tue Jul 19 
16:17:22 2011
@@ -216,6 +216,11 @@ AcrInitCoreClasses(JNI_STDENV)
     return JNI_TRUE;
 }
 
+#if defined(WINDOWS)
+ACR_CLASS_CTOR(Win32Service);
+ACR_CLASS_DTOR(Win32Service);
+#endif
+
 jboolean
 AcrLoadRuntimeClasses(JNI_STDENV)
 {
@@ -226,8 +231,8 @@ AcrLoadRuntimeClasses(JNI_STDENV)
     ACR_CLASS_LOAD(SlicePointer);
     ACR_CLASS_LOAD(FileDescriptor);
 
-#ifdef WIN32
-    ACR_CLASS_LOAD(Service);
+#if defined(WINDOWS)
+    ACR_CLASS_LOAD(Win32Service);
 #endif
     return JNI_TRUE;
 }
@@ -249,8 +254,8 @@ AcrUnloadRuntimeClasses(JNI_STDENV)
     ACR_CLASS_UNLOAD(Object);
     ACR_CLASS_UNLOAD(Class);
     ACR_CLASS_UNLOAD(Unsafe);
-#ifdef WIN32
-
+#if defined(WINDOWS)
+    ACR_CLASS_UNLOAD(Win32Service);
 #endif
     AcrReleaseExceptionClasses(env);
 }

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=1148427&r1=1148426&r2=1148427&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/string.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/string.c Tue Jul 19 
16:17:22 2011
@@ -1119,11 +1119,11 @@ AcrNewJavaMszArrayW(JNI_STDENV, const wc
 {
     jcharArray r = 0;
     int len;
-    
+
     if ((len = wcszlen(s, 0)) == 0)
         return 0;
     if ((r = (*env)->NewCharArray(env, len)) == 0)
-        return 0;    
+        return 0;
 #if CC_SIZEOF_WCHAR_T == 2
      (*env)->SetCharArrayRegion(env, r, 0, len, (jchar *)s);
 #else
@@ -1133,7 +1133,7 @@ AcrNewJavaMszArrayW(JNI_STDENV, const wc
         for (i = 0; i < len; i++) {
             /* Simply assign utf32 to utf16 */
             cc[i] = (jchar)s[i];
-        }        
+        }
         (*env)->SetCharArrayRegion(env, r, 0, len, cc);
     }
     else {
@@ -1281,6 +1281,60 @@ AcrGetJavaStringArrayW(JNI_STDENV, jobje
     return ret;
 }
 
+#if defined(WINDOWS)
+wchar_t *
+AcrMszJavaStringArrayW(JNI_STDENV, jobjectArray arr)
+{
+    wchar_t *p, *ret = 0;
+    jsize  cnt;
+    jsize  i;
+    jsize  len = 2;
+
+    if (IS_JOBJECT_NULL(arr))
+        return 0;
+
+    cnt = (*env)->GetArrayLength(env, arr);
+    if (cnt == 0)
+        return 0;
+    for (i = 0; i < cnt; i++) {
+        jstring str = (*env)->GetObjectArrayElement(env, arr, i);
+        if (str != 0) {
+            len += ((*env)->GetStringLength(env, str) + 1);
+            (*env)->DeleteLocalRef(env, str);
+        }
+        else {
+            return 0;
+        }
+    }
+    p = ret = ACR_MALLOC(wchar_t, len);
+    if (ret == 0)
+        return 0;
+    for (i = 0; i < cnt; i++) {
+        jstring str = (*env)->GetObjectArrayElement(env, arr, i);
+        if (str != 0) {
+            const jchar *chr;
+            len = (*env)->GetStringLength(env, str);
+            chr = (*env)->GetStringChars(env, str, 0);
+            if (chr == 0) {
+                AcrFree(ret);
+                return 0;                    
+            }
+            memcpy(p, chr, len * sizeof(jchar));
+            (*env)->ReleaseStringChars(env, str, chr);
+            (*env)->DeleteLocalRef(env, str);
+            p += len;
+            *(p++) = 0;
+        }
+        else {
+            AcrFree(ret);
+            return 0;
+        }
+    }
+    *p = 0;
+    return ret;
+}
+#endif
+
 ACR_JNI_EXPORT(jcharArray, Unsafe, getchr0)(JNI_STDARGS, jstring str)
 {
     if (J4FLD_OFF(0000) != INVALID_FIELD_OFFSET) {
@@ -1332,7 +1386,7 @@ ACR_JNI_EXPORT(jint, TestString, test1)(
 
 ACR_JNI_EXPORT(jint, TestString, test2)(JNI_STDARGS, jcharArray c)
 {
-#if CC_SIZEOF_WCHAR_T == 2    
+#if CC_SIZEOF_WCHAR_T == 2
     int rv;
     int len;
     jchar *jca;


Reply via email to