1
package processing.app.windows;
3
import java.io.UnsupportedEncodingException;
4
import java.util.HashMap;
5
import java.util.TreeMap;
6
import java.util.TreeSet;
8
import com.sun.jna.ptr.IntByReference;
11
* Methods for accessing the Windows Registry. Only String and DWORD values supported at the moment.
13
public class Registry {
14
public static enum REGISTRY_ROOT_KEY{CLASSES_ROOT, CURRENT_USER, LOCAL_MACHINE, USERS};
15
private final static HashMap<REGISTRY_ROOT_KEY, Integer> rootKeyMap = new HashMap<REGISTRY_ROOT_KEY, Integer>();
18
rootKeyMap.put(REGISTRY_ROOT_KEY.CLASSES_ROOT, WINREG.HKEY_CLASSES_ROOT);
19
rootKeyMap.put(REGISTRY_ROOT_KEY.CURRENT_USER, WINREG.HKEY_CURRENT_USER);
20
rootKeyMap.put(REGISTRY_ROOT_KEY.LOCAL_MACHINE, WINREG.HKEY_LOCAL_MACHINE);
21
rootKeyMap.put(REGISTRY_ROOT_KEY.USERS, WINREG.HKEY_USERS);
27
* @param args arguments
28
* @throws java.lang.Exception on error
30
public static void main(String[] args) throws Exception {
34
* Gets one of the root keys.
39
private static int getRegistryRootKey(REGISTRY_ROOT_KEY key) {
41
IntByReference pHandle;
44
advapi32 = Advapi32.INSTANCE;
45
pHandle = new IntByReference();
47
if(advapi32.RegOpenKeyEx(rootKeyMap.get(key), null, 0, 0, pHandle) == WINERROR.ERROR_SUCCESS) {
48
handle = pHandle.getValue();
56
* @param rootKey root key
57
* @param subKeyName name of the key
58
* @param access access mode
59
* @return handle to the key or 0
61
private static int openKey(REGISTRY_ROOT_KEY rootKey, String subKeyName, int access) {
63
IntByReference pHandle;
66
advapi32 = Advapi32.INSTANCE;
67
rootKeyHandle = getRegistryRootKey(rootKey);
68
pHandle = new IntByReference();
70
if(advapi32.RegOpenKeyEx(rootKeyHandle, subKeyName, 0, access, pHandle) == WINERROR.ERROR_SUCCESS) {
71
return(pHandle.getValue());
79
* Converts a Windows buffer to a Java String.
82
* @throws java.io.UnsupportedEncodingException on error
85
private static String convertBufferToString(byte[] buf) throws UnsupportedEncodingException {
86
return(new String(buf, 0, buf.length - 2, "UTF-16LE"));
90
* Converts a Windows buffer to an int.
95
private static int convertBufferToInt(byte[] buf) {
96
return(((int)(buf[0] & 0xff)) + (((int)(buf[1] & 0xff)) << 8) + (((int)(buf[2] & 0xff)) << 16) + (((int)(buf[3] & 0xff)) << 24));
100
* Read a String value.
102
* @param rootKey root key
103
* @param subKeyName key name
104
* @param name value name
105
* @throws java.io.UnsupportedEncodingException on error
106
* @return String or null
108
public static String getStringValue(REGISTRY_ROOT_KEY rootKey, String subKeyName, String name) throws UnsupportedEncodingException {
110
IntByReference pType, lpcbData;
111
byte[] lpData = new byte[1];
115
advapi32 = Advapi32.INSTANCE;
116
pType = new IntByReference();
117
lpcbData = new IntByReference();
118
handle = openKey(rootKey, subKeyName, WINNT.KEY_READ);
122
if(advapi32.RegQueryValueEx(handle, name, null, pType, lpData, lpcbData) == WINERROR.ERROR_MORE_DATA) {
123
lpData = new byte[lpcbData.getValue()];
125
if(advapi32.RegQueryValueEx(handle, name, null, pType, lpData, lpcbData) == WINERROR.ERROR_SUCCESS) {
126
ret = convertBufferToString(lpData);
129
advapi32.RegCloseKey(handle);
139
* @param rootKey root key
140
* @param subKeyName key name
141
* @param name value name
143
public static int getIntValue(REGISTRY_ROOT_KEY rootKey, String subKeyName, String name) {
145
IntByReference pType, lpcbData;
146
byte[] lpData = new byte[1];
150
advapi32 = Advapi32.INSTANCE;
151
pType = new IntByReference();
152
lpcbData = new IntByReference();
153
handle = openKey(rootKey, subKeyName, WINNT.KEY_READ);
157
if(advapi32.RegQueryValueEx(handle, name, null, pType, lpData, lpcbData) == WINERROR.ERROR_MORE_DATA) {
158
lpData = new byte[lpcbData.getValue()];
160
if(advapi32.RegQueryValueEx(handle, name, null, pType, lpData, lpcbData) == WINERROR.ERROR_SUCCESS) {
161
ret = convertBufferToInt(lpData);
164
advapi32.RegCloseKey(handle);
172
* @param rootKey root key
173
* @param subKeyName key name
174
* @param name value name
175
* @return true on success
177
public static boolean deleteValue(REGISTRY_ROOT_KEY rootKey, String subKeyName, String name) {
182
advapi32 = Advapi32.INSTANCE;
184
handle = openKey(rootKey, subKeyName, WINNT.KEY_READ | WINNT.KEY_WRITE);
187
if(advapi32.RegDeleteValue(handle, name) == WINERROR.ERROR_SUCCESS) {
190
advapi32.RegCloseKey(handle);
196
* Writes a String value.
198
* @param rootKey root key
199
* @param subKeyName key name
200
* @param name value name
202
* @throws java.io.UnsupportedEncodingException on error
203
* @return true on success
205
public static boolean setStringValue(REGISTRY_ROOT_KEY rootKey, String subKeyName, String name, String value) throws UnsupportedEncodingException {
211
// appears to be Java 1.6 syntax, removing [fry]
212
//data = Arrays.copyOf(value.getBytes("UTF-16LE"), value.length() * 2 + 2);
213
data = new byte[value.length() * 2 + 2];
214
byte[] src = value.getBytes("UTF-16LE");
215
System.arraycopy(src, 0, data, 0, src.length);
217
advapi32 = Advapi32.INSTANCE;
218
handle = openKey(rootKey, subKeyName, WINNT.KEY_READ | WINNT.KEY_WRITE);
221
if(advapi32.RegSetValueEx(handle, name, 0, WINNT.REG_SZ, data, data.length) == WINERROR.ERROR_SUCCESS) {
224
advapi32.RegCloseKey(handle);
230
* Writes an int value.
233
* @return true on success
234
* @param rootKey root key
235
* @param subKeyName key name
236
* @param name value name
239
public static boolean setIntValue(REGISTRY_ROOT_KEY rootKey, String subKeyName, String name, int value) {
246
data[0] = (byte)(value & 0xff);
247
data[1] = (byte)((value >> 8) & 0xff);
248
data[2] = (byte)((value >> 16) & 0xff);
249
data[3] = (byte)((value >> 24) & 0xff);
250
advapi32 = Advapi32.INSTANCE;
251
handle = openKey(rootKey, subKeyName, WINNT.KEY_READ | WINNT.KEY_WRITE);
255
if(advapi32.RegSetValueEx(handle, name, 0, WINNT.REG_DWORD, data, data.length) == WINERROR.ERROR_SUCCESS) {
258
advapi32.RegCloseKey(handle);
264
* Check for existence of a value.
266
* @param rootKey root key
267
* @param subKeyName key name
268
* @param name value name
269
* @return true if exists
271
public static boolean valueExists(REGISTRY_ROOT_KEY rootKey, String subKeyName, String name) {
273
IntByReference pType, lpcbData;
274
byte[] lpData = new byte[1];
278
advapi32 = Advapi32.INSTANCE;
279
pType = new IntByReference();
280
lpcbData = new IntByReference();
281
handle = openKey(rootKey, subKeyName, WINNT.KEY_READ);
285
if(advapi32.RegQueryValueEx(handle, name, null, pType, lpData, lpcbData) != WINERROR.ERROR_FILE_NOT_FOUND) {
291
advapi32.RegCloseKey(handle);
299
* @param rootKey root key
300
* @param parent name of parent key
301
* @param name key name
302
* @return true on success
304
public static boolean createKey(REGISTRY_ROOT_KEY rootKey, String parent, String name) {
306
IntByReference hkResult, dwDisposition;
310
advapi32 = Advapi32.INSTANCE;
311
hkResult = new IntByReference();
312
dwDisposition = new IntByReference();
313
handle = openKey(rootKey, parent, WINNT.KEY_READ);
317
if(advapi32.RegCreateKeyEx(handle, name, 0, null, WINNT.REG_OPTION_NON_VOLATILE, WINNT.KEY_READ, null,
318
hkResult, dwDisposition) == WINERROR.ERROR_SUCCESS) {
320
advapi32.RegCloseKey(hkResult.getValue());
325
advapi32.RegCloseKey(handle);
333
* @param rootKey root key
334
* @param parent name of parent key
335
* @param name key name
336
* @return true on success
338
public static boolean deleteKey(REGISTRY_ROOT_KEY rootKey, String parent, String name) {
343
advapi32 = Advapi32.INSTANCE;
344
handle = openKey(rootKey, parent, WINNT.KEY_READ);
348
if(advapi32.RegDeleteKey(handle, name) == WINERROR.ERROR_SUCCESS) {
354
advapi32.RegCloseKey(handle);
360
* Get all sub keys of a key.
362
* @param rootKey root key
363
* @param parent key name
364
* @return array with all sub key names
366
public static String[] getSubKeys(REGISTRY_ROOT_KEY rootKey, String parent) {
368
int handle = 0, dwIndex;
370
IntByReference lpcName;
371
WINBASE.FILETIME lpftLastWriteTime;
372
TreeSet<String> subKeys = new TreeSet<String>();
374
advapi32 = Advapi32.INSTANCE;
375
handle = openKey(rootKey, parent, WINNT.KEY_READ);
376
lpName = new char[256];
377
lpcName = new IntByReference(256);
378
lpftLastWriteTime = new WINBASE.FILETIME();
383
while(advapi32.RegEnumKeyEx(handle, dwIndex, lpName, lpcName, null,
384
null, null, lpftLastWriteTime) == WINERROR.ERROR_SUCCESS) {
385
subKeys.add(new String(lpName, 0, lpcName.getValue()));
386
lpcName.setValue(256);
389
advapi32.RegCloseKey(handle);
392
return(subKeys.toArray(new String[]{}));
396
* Get all values under a key.
398
* @param rootKey root key
399
* @param key jey name
400
* @throws java.io.UnsupportedEncodingException on error
401
* @return TreeMap with name and value pairs
403
public static TreeMap<String, Object> getValues(REGISTRY_ROOT_KEY rootKey, String key) throws UnsupportedEncodingException {
405
int handle = 0, dwIndex, result = 0;
408
IntByReference lpcchValueName, lpType, lpcbData;
410
TreeMap<String, Object> values = new TreeMap<String, Object>(String.CASE_INSENSITIVE_ORDER);
412
advapi32 = Advapi32.INSTANCE;
413
handle = openKey(rootKey, key, WINNT.KEY_READ);
414
lpValueName = new char[16384];
415
lpcchValueName = new IntByReference(16384);
416
lpType = new IntByReference();
417
lpData = new byte[1];
418
lpcbData = new IntByReference();
424
lpcbData.setValue(0);
425
result = advapi32.RegEnumValue(handle, dwIndex, lpValueName, lpcchValueName, null,
426
lpType, lpData, lpcbData);
428
if(result == WINERROR.ERROR_MORE_DATA) {
429
lpData = new byte[lpcbData.getValue()];
430
lpcchValueName = new IntByReference(16384);
431
result = advapi32.RegEnumValue(handle, dwIndex, lpValueName, lpcchValueName, null,
432
lpType, lpData, lpcbData);
434
if(result == WINERROR.ERROR_SUCCESS) {
435
name = new String(lpValueName, 0, lpcchValueName.getValue());
437
switch(lpType.getValue()) {
439
values.put(name, convertBufferToString(lpData));
441
case WINNT.REG_DWORD:
442
values.put(name, convertBufferToInt(lpData));
450
} while(result == WINERROR.ERROR_SUCCESS);
452
advapi32.RegCloseKey(handle);