You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2011/04/30 17:27:42 UTC
svn commit: r1098121 - in /commons/sandbox/runtime/trunk/src/main:
java/org/apache/commons/runtime/platform/windows/ native/os/win32/
test/org/apache/commons/runtime/
Author: mturk
Date: Sat Apr 30 15:27:42 2011
New Revision: 1098121
URL: http://svn.apache.org/viewvc?rev=1098121&view=rev
Log:
Finish win32 Registry api
Added:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/Registry.java (with props)
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/RegistryKey.java
commons/sandbox/runtime/trunk/src/main/native/os/win32/registry.c
commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestRegistry.java
Added: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/Registry.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/Registry.java?rev=1098121&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/Registry.java (added)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/Registry.java Sat Apr 30 15:27:42 2011
@@ -0,0 +1,73 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.commons.runtime.platform.windows;
+
+import java.io.Closeable;
+import java.io.Flushable;
+import java.io.IOException;
+import java.io.SyncFailedException;
+import java.util.EnumSet;
+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.util.Utils;
+
+/**
+ * Registry key class.
+ * <p>
+ * An application can use handles to these keys as entry points to the
+ * registry. These handles are valid for all implementations of the
+ * registry, although the use of the handles may vary from platform to
+ * platform. In addition, other predefined handles have been defined
+ * for specific platforms. The following are handles to the predefined
+ * keys.
+ * </p>
+ */
+public final class Registry
+{
+
+ private Registry()
+ {
+ }
+
+
+ private static native int unlink0(long key, String name, boolean onlyIfEmpty);
+ /**
+ * Delete the Registry subkey
+ * @param root Root key, one of HKEY_*
+ * @param name Subkey to delete
+ * @param onlyIfEmpty If true will not delete a key if
+ * it contains any subkeys or values
+ * @return {@code true} if the function succeeds.
+ */
+ public static boolean delete(RegistryKey root, String name, boolean onlyIfEmpty)
+ throws NullPointerException, IOException
+ {
+ if (name == null)
+ throw new NullPointerException();
+ long hKey = root.handle();
+ if (hKey == 0L || hKey == -1L)
+ throw new InvalidHandleException();
+ int rc = unlink0(hKey, name, onlyIfEmpty);
+ if (rc == 0)
+ return true;
+ else
+ return false;
+ }
+
+}
Propchange: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/Registry.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/RegistryKey.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/RegistryKey.java?rev=1098121&r1=1098120&r2=1098121&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/RegistryKey.java (original)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/windows/RegistryKey.java Sat Apr 30 15:27:42 2011
@@ -21,6 +21,7 @@ import java.io.Flushable;
import java.io.IOException;
import java.io.SyncFailedException;
import java.util.EnumSet;
+import java.util.List;
import org.apache.commons.runtime.Errno;
import org.apache.commons.runtime.Status;
import org.apache.commons.runtime.SystemException;
@@ -37,7 +38,7 @@ import org.apache.commons.runtime.util.U
* keys.
* </p>
*/
-public class RegistryKey implements Closeable, Flushable
+public final class RegistryKey implements Closeable, Flushable
{
/** Registry entries subordinate to this key define types (or classes)
@@ -209,6 +210,7 @@ public class RegistryKey implements Clos
private static native byte[] gets2(long key, String name);
private static native int gets3(long key, String name, int[] pval);
private static native int gets4(long key, String name, long[] pval);
+ private static native int unlink0(long key, String name);
public RegistryKey open(String name, EnumSet<RegistryKeyAccessRights> mode)
throws NullPointerException, IOException, SystemException
@@ -346,4 +348,131 @@ public class RegistryKey implements Clos
return rp[0];
}
+ private static native String[] enum0(long key);
+ private static native String[] enum1(long key);
+
+ /**
+ * Enumerate the Registry subkeys
+ * @return Array of all subkey names
+ */
+ public String[] getKeys()
+ throws NullPointerException, IOException
+ {
+ if (hKey == 0L || hKey == -1L)
+ throw new InvalidHandleException();
+ String[] s = enum0(hKey);
+
+ return s;
+ }
+
+ /**
+ * Enumerate the Registry values
+ * @return Array of all value names
+ */
+ public String[] getValues()
+ throws NullPointerException, IOException
+ {
+ if (hKey == 0L || hKey == -1L)
+ throw new InvalidHandleException();
+ String[] s = enum1(hKey);
+
+ return s;
+ }
+
+ private static native int setv0(long key, String name, String value);
+ private static native int setv1(long key, String name, int value);
+ private static native int setv2(long key, String name, long value);
+ private static native int setv3(long key, String name, byte[] value);
+ private static native int setv4(long key, String name, char[] value);
+
+ public void setValue(String name, String value)
+ throws NullPointerException, IOException
+ {
+ if (name == null || value == null)
+ throw new NullPointerException();
+ if (hKey == 0L || hKey == -1L)
+ throw new InvalidHandleException();
+ if (hKey == 0L || hKey == -1L)
+ throw new InvalidHandleException();
+ int rc = setv0(hKey, name, value);
+ if (rc != 0)
+ throw new IOException(Status.describe(rc));
+ }
+
+ public void setValue(String name, byte[] value)
+ throws NullPointerException, IOException
+ {
+ if (name == null || value == null)
+ throw new NullPointerException();
+ if (hKey == 0L || hKey == -1L)
+ throw new InvalidHandleException();
+ if (hKey == 0L || hKey == -1L)
+ throw new InvalidHandleException();
+ int rc = setv3(hKey, name, value);
+ if (rc != 0)
+ throw new IOException(Status.describe(rc));
+ }
+
+ public void setValue(String name, List<String> value)
+ throws NullPointerException, IOException
+ {
+ if (name == null || value == null)
+ throw new NullPointerException();
+ if (hKey == 0L || hKey == -1L)
+ throw new InvalidHandleException();
+ if (hKey == 0L || hKey == -1L)
+ throw new InvalidHandleException();
+ char[] msz = Utils.stringArrayToCharBlock(value);
+ int rc = setv4(hKey, name, msz);
+ if (rc != 0)
+ throw new IOException(Status.describe(rc));
+ }
+
+ public void setValue(String name, int value)
+ throws NullPointerException, IOException
+ {
+ if (name == null)
+ throw new NullPointerException();
+ if (hKey == 0L || hKey == -1L)
+ throw new InvalidHandleException();
+ if (hKey == 0L || hKey == -1L)
+ throw new InvalidHandleException();
+ int rc = setv1(hKey, name, value);
+ if (rc != 0)
+ throw new IOException(Status.describe(rc));
+ }
+
+ public void setValue(String name, long value)
+ throws NullPointerException, IOException
+ {
+ if (name == null)
+ throw new NullPointerException();
+ if (hKey == 0L || hKey == -1L)
+ throw new InvalidHandleException();
+ if (hKey == 0L || hKey == -1L)
+ throw new InvalidHandleException();
+ int rc = setv2(hKey, name, value);
+ if (rc != 0)
+ throw new IOException(Status.describe(rc));
+ }
+
+ /**
+ * Delete the Registry value
+ * @param name The name of the value to delete
+ * @return {@code true} if the function succeeds.
+ */
+ public boolean deleteValue(String name)
+ throws NullPointerException, IOException
+ {
+ if (name == null)
+ throw new NullPointerException();
+ if (hKey == 0L || hKey == -1L)
+ throw new InvalidHandleException();
+ int rc = unlink0(hKey, name);
+ if (rc == 0)
+ return true;
+ else
+ return false;
+ }
+
}
Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/registry.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/registry.c?rev=1098121&r1=1098120&r2=1098121&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/registry.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/registry.c Sat Apr 30 15:27:42 2011
@@ -15,14 +15,14 @@
*/
#include "acr/error.h"
-#include "acr/jniapi.h"
#include "acr/memory.h"
#include "acr/iodefs.h"
#include "acr/port.h"
+#include "acr/jniapi.h"
#include "acr/clazz.h"
#include "acr/string.h"
#include "arch_opts.h"
-
+#include <shlwapi.h>
static REGSAM regsam_translate(int nsam)
{
@@ -170,7 +170,7 @@ ACR_WIN_EXPORT(jstring, RegistryKey, get
rc = ACR_ENOMEM;
}
else {
- rc = RegQueryValueExW(hkey, J2S(name), 0, &rt, (LPBYTE)ss, &rs);
+ rc = RegQueryValueExW(hkey, J2S(name), 0, 0, (LPBYTE)ss, &rs);
if (rc == 0) {
if (rt == REG_EXPAND_SZ) {
DWORD xl = ExpandEnvironmentStringsW(ss, ss, rs);
@@ -220,7 +220,7 @@ ACR_WIN_EXPORT(jcharArray, RegistryKey,
rc = ACR_ENOMEM;
}
else {
- rc = RegQueryValueExW(hkey, J2S(name), 0, &rt, (LPBYTE)ss, &rs);
+ rc = RegQueryValueExW(hkey, J2S(name), 0, 0, (LPBYTE)ss, &rs);
if (rc == 0) {
(*env)->SetCharArrayRegion(env, r, 0, (jsize)rs, ss);
}
@@ -259,7 +259,7 @@ ACR_WIN_EXPORT(jbyteArray, RegistryKey,
rc = ACR_ENOMEM;
}
else {
- rc = RegQueryValueExW(hkey, J2S(name), 0, &rt, (LPBYTE)ss, &rs);
+ rc = RegQueryValueExW(hkey, J2S(name), 0, 0, (LPBYTE)ss, &rs);
if (rc == 0) {
(*env)->SetByteArrayRegion(env, r, 0, (jsize)rs, ss);
}
@@ -291,7 +291,7 @@ ACR_WIN_EXPORT(jint, RegistryKey, gets3)
if (rc == 0) {
if (rt == REG_DWORD && rs == 4) {
jint rv;
- rc = RegQueryValueExW(hkey, J2S(name), 0, &rt, (LPBYTE)&rt, &rs);
+ rc = RegQueryValueExW(hkey, J2S(name), 0, 0, (LPBYTE)&rt, &rs);
if (rc == 0) {
(*env)->SetIntArrayRegion(env, pval, 0, 1, &rv);
}
@@ -315,17 +315,270 @@ ACR_WIN_EXPORT(jint, RegistryKey, gets4)
WITH_WSTR(name) {
rc = RegQueryValueExW(hkey, J2S(name), 0, &rt, 0, &rs);
if (rc == 0) {
+ jlong rv;
if (rt == REG_QWORD && rs == 8) {
- jlong rv;
- rc = RegQueryValueExW(hkey, J2S(name), 0, &rt, (LPBYTE)&rt, &rs);
- if (rc == 0) {
- (*env)->SetLongArrayRegion(env, pval, 0, 1, &rv);
- }
+ rc = RegQueryValueExW(hkey, J2S(name), 0, 0, (LPBYTE)&rv, &rs);
+ }
+ else if (rt == REG_DWORD && rs == 4) {
+ DWORD rd;
+ rc = RegQueryValueExW(hkey, J2S(name), 0, 0, (LPBYTE)&rd, &rs);
+ rv = rd;
}
else {
rc = ACR_EFTYPE;
}
+ if (rc == 0) {
+ (*env)->SetLongArrayRegion(env, pval, 0, 1, &rv);
+ }
+ }
+ } DONE_WITH_STR(name);
+ return rc;
+}
+
+#define MAX_VALUE_NAME 4096
+
+ACR_WIN_EXPORT(jobjectArray, RegistryKey, enum0)(JNI_STDARGS, jlong key)
+{
+ HKEY hkey = J2P(key, HKEY);
+ LONG rc;
+ jobjectArray v = 0;
+ jsize cnt = 0;
+
+ WCHAR achKey[MAX_PATH];
+ WCHAR achClass[MAX_PATH] = L"";
+ DWORD cchClassName = MAX_PATH;
+ DWORD cSubKeys;
+ DWORD cbMaxSubKey;
+ DWORD cchMaxClass;
+ DWORD cValues;
+ DWORD cchMaxValue;
+ DWORD cbMaxValueData;
+ DWORD cbSecurityDescriptor;
+ FILETIME ftLastWriteTime;
+
+ DWORD cchValue = MAX_VALUE_NAME;
+
+ rc = RegQueryInfoKeyW(hkey,
+ achClass,
+ &cchClassName,
+ 0,
+ &cSubKeys,
+ &cbMaxSubKey,
+ &cchMaxClass,
+ &cValues,
+ &cchMaxValue,
+ &cbMaxValueData,
+ &cbSecurityDescriptor,
+ &ftLastWriteTime);
+ if (rc != ERROR_SUCCESS) {
+ ACR_SAVE_ERROR(rc);
+ return 0;
+ }
+ cnt = cSubKeys;
+ if (cnt) {
+ jsize idx = 0;
+ v = AcrNewCoreObjectArray(env, ACR_CC_STRING, cnt);
+ if (v == 0)
+ return 0;
+ for (idx = 0; idx < cnt; idx++) {
+ jstring s;
+ DWORD achKeyLen = MAX_PATH;
+ rc = RegEnumKeyExW(hkey,
+ idx,
+ achKey,
+ &achKeyLen,
+ 0,
+ 0,
+ 0,
+ &ftLastWriteTime);
+ if (rc == 0) {
+ s = WSTR_TO_JSTRING(achKey);
+ if (s != 0) {
+ (*env)->SetObjectArrayElement(env, v, idx, s);
+ if (IS_EXCEPTION_PENDING(env))
+ return 0;
+ (*env)->DeleteLocalRef(env, s);
+ }
+ else
+ return 0;
+ }
}
+ }
+ return v;
+}
+
+ACR_WIN_EXPORT(jobjectArray, RegistryKey, enum1)(JNI_STDARGS, jlong key)
+{
+ HKEY hkey = J2P(key, HKEY);
+ LONG rc;
+ jobjectArray v = 0;
+ jsize cnt = 0;
+
+ WCHAR achClass[MAX_PATH] = L"";
+ DWORD cchClassName = MAX_PATH;
+ DWORD cSubKeys;
+ DWORD cbMaxSubKey;
+ DWORD cchMaxClass;
+ DWORD cValues;
+ DWORD cchMaxValue;
+ DWORD cbMaxValueData;
+ DWORD cbSecurityDescriptor;
+ FILETIME ftLastWriteTime;
+
+ WCHAR achValue[MAX_VALUE_NAME];
+ DWORD cchValue = MAX_VALUE_NAME;
+
+ /* Get the class name and the value count. */
+ rc = RegQueryInfoKeyW(hkey,
+ achClass,
+ &cchClassName,
+ 0,
+ &cSubKeys,
+ &cbMaxSubKey,
+ &cchMaxClass,
+ &cValues,
+ &cchMaxValue,
+ &cbMaxValueData,
+ &cbSecurityDescriptor,
+ &ftLastWriteTime);
+ if (rc != ERROR_SUCCESS) {
+ ACR_SAVE_ERROR(rc);
+ return 0;
+ }
+ cnt = cValues;
+ if (cnt) {
+ jsize idx = 0;
+ v = AcrNewCoreObjectArray(env, ACR_CC_STRING, cnt);
+ if (v == 0)
+ return 0;
+ for (idx = 0; idx < cnt; idx++) {
+ jstring s;
+ cchValue = MAX_VALUE_NAME;
+ achValue[0] = L'\0';
+ rc = RegEnumValueW(hkey, idx,
+ achValue,
+ &cchValue,
+ 0,
+ 0,
+ 0,
+ 0);
+ if (rc == 0) {
+ s = WSTR_TO_JSTRING(achValue);
+ if (s != 0) {
+ (*env)->SetObjectArrayElement(env, v, idx, s);
+ if (IS_EXCEPTION_PENDING(env))
+ return 0;
+ (*env)->DeleteLocalRef(env, s);
+ }
+ else
+ return 0;
+ }
+ }
+ }
+ return v;
+}
+
+ACR_WIN_EXPORT(jint, RegistryKey, setv0)(JNI_STDARGS, jlong key,
+ jstring name, jstring val)
+{
+ jint rc = ACR_EINVAL;
+ HKEY hkey = J2P(key, HKEY);
+ DWORD len;
+
+ WITH_WSTR(name) {
+ WITH_WSTR(val) {
+ len = (DWORD)(wcslen(J2S(val)) + 1) * 2;
+ rc = RegSetValueExW(hkey, J2S(name), 0, REG_SZ,
+ (CONST BYTE *)J2S(val), len);
+ } DONE_WITH_STR(val);
+ } DONE_WITH_STR(name);
+ return rc;
+}
+
+ACR_WIN_EXPORT(jint, RegistryKey, setv1)(JNI_STDARGS, jlong key,
+ jstring name, jint val)
+{
+ jint rc = ACR_EINVAL;
+ HKEY hkey = J2P(key, HKEY);
+
+ WITH_WSTR(name) {
+ rc = RegSetValueExW(hkey, J2S(name), 0, REG_DWORD,
+ (CONST BYTE *)&val, 4);
+ } DONE_WITH_STR(name);
+ return rc;
+}
+
+ACR_WIN_EXPORT(jint, RegistryKey, setv2)(JNI_STDARGS, jlong key,
+ jstring name, jlong val)
+{
+ jint rc = ACR_EINVAL;
+ HKEY hkey = J2P(key, HKEY);
+
+ WITH_WSTR(name) {
+ rc = RegSetValueExW(hkey, J2S(name), 0, REG_DWORD,
+ (CONST BYTE *)&val, 8);
+ } DONE_WITH_STR(name);
+ return rc;
+}
+
+ACR_WIN_EXPORT(jint, RegistryKey, setv3)(JNI_STDARGS, jlong key,
+ jstring name, jbyteArray val)
+{
+ jint rc = ACR_EINVAL;
+ HKEY hkey = J2P(key, HKEY);
+ DWORD len;
+ BYTE *jba;
+
+ WITH_WSTR(name) {
+ len = (*env)->GetArrayLength(env, val);
+ jba = (*env)->GetPrimitiveArrayCritical(env, val, 0);
+ rc = RegSetValueExW(hkey, J2S(name), 0, REG_BINARY, jba, len);
+ (*env)->ReleasePrimitiveArrayCritical(env, val, jba, 0);
+ } DONE_WITH_STR(name);
+ return rc;
+}
+
+ACR_WIN_EXPORT(jint, RegistryKey, setv4)(JNI_STDARGS, jlong key,
+ jstring name, jcharArray val)
+{
+ jint rc = ACR_EINVAL;
+ HKEY hkey = J2P(key, HKEY);
+ DWORD len;
+ BYTE *jba;
+
+ WITH_WSTR(name) {
+ len = (*env)->GetArrayLength(env, val);
+ jba = (*env)->GetPrimitiveArrayCritical(env, val, 0);
+ rc = RegSetValueExW(hkey, J2S(name), 0, REG_MULTI_SZ, jba, len * 2);
+ (*env)->ReleasePrimitiveArrayCritical(env, val, jba, 0);
+ } DONE_WITH_STR(name);
+ return rc;
+}
+
+ACR_WIN_EXPORT(jint, RegistryKey, unlink0)(JNI_STDARGS, jlong key,
+ jstring name)
+{
+ jint rc = ACR_EINVAL;
+ HKEY hkey = J2P(key, HKEY);
+
+ WITH_WSTR(name) {
+ rc = RegDeleteValueW(hkey, J2S(name));
+ } DONE_WITH_STR(name);
+ return rc;
+}
+
+ACR_WIN_EXPORT(jint, Registry, unlink0)(JNI_STDARGS, jlong key,
+ jstring name,
+ jboolean empty)
+{
+ jint rc = ACR_EINVAL;
+ HKEY hkey = J2P(key, HKEY);
+
+ WITH_WSTR(name) {
+ if (empty == JNI_TRUE)
+ rc = SHDeleteEmptyKeyW(hkey, J2S(name));
+ else
+ rc = SHDeleteKeyW(hkey, J2S(name));
} DONE_WITH_STR(name);
return rc;
}
Modified: commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestRegistry.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestRegistry.java?rev=1098121&r1=1098120&r2=1098121&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestRegistry.java (original)
+++ commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestRegistry.java Sat Apr 30 15:27:42 2011
@@ -65,7 +65,38 @@ public class TestRegistry extends Assert
RegistryKey key = RegistryKey.LocalMachine.open("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion");
assertNotNull(key);
assertEquals(key.getValueType("InstallDate"), RegistryValueType.DWORD);
- long val = key.getLongValue("InstallDate");
+ String val = key.getValue("InstallDate");
+ }
+
+ @Test(groups = { "windows" })
+ public void enumKeys()
+ throws Exception
+ {
+ RegistryKey key = RegistryKey.LocalMachine.open("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion");
+ assertNotNull(key);
+ String[] keys = key.getKeys();
+ assertTrue(keys.length > 10);
+ }
+
+ @Test(groups = { "windows" })
+ public void enumValues()
+ throws Exception
+ {
+ RegistryKey key = RegistryKey.LocalMachine.open("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion");
+ assertNotNull(key);
+ String[] vals = key.getValues();
+ assertTrue(vals.length > 10);
+ }
+
+ @Test(groups = { "windows" })
+ public void createValues()
+ throws Exception
+ {
+ RegistryKey key = RegistryKey.CurrentUser.create("SOFTWARE\\Apache Group\\CommonsTest\\Runtime");
+ assertNotNull(key);
+ key.setValue("TestString", "Some Value");
+ key.close();
+ Registry.delete(RegistryKey.CurrentUser, "SOFTWARE\\Apache Group\\CommonsTest", false);
}
}