/*
* Registry.java
*
* Created on 17. August 2007, 15:07
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package jnacontrib.win32;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.TreeMap;
import java.util.TreeSet;
import jnacontrib.jna.Advapi32;
import jnacontrib.jna.WINBASE;
import jnacontrib.jna.WINERROR;
import jnacontrib.jna.WINNT;
import jnacontrib.jna.WINREG;
import com.sun.jna.ptr.IntByReference;
/**
* Methods for accessing the Windows Registry. Only String and DWORD values
* supported at the moment.
*/
public class Registry
{
public static enum REGISTRY_ROOT_KEY
{
CLASSES_ROOT, CURRENT_USER, LOCAL_MACHINE, USERS
};
private final static HashMap<REGISTRY_ROOT_KEY, Integer> rootKeyMap = new HashMap<REGISTRY_ROOT_KEY, Integer>();
static
{
rootKeyMap.put(REGISTRY_ROOT_KEY.CLASSES_ROOT, WINREG.HKEY_CLASSES_ROOT);
rootKeyMap.put(REGISTRY_ROOT_KEY.CURRENT_USER, WINREG.HKEY_CURRENT_USER);
rootKeyMap.put(REGISTRY_ROOT_KEY.LOCAL_MACHINE, WINREG.HKEY_LOCAL_MACHINE);
rootKeyMap.put(REGISTRY_ROOT_KEY.USERS, WINREG.HKEY_USERS);
}
/**
* Testing.
*
* @param args
* arguments
* @throws java.lang.Exception
* on error
*/
public static void main(String[] args) throws Exception
{
}
/**
* Gets one of the root keys.
*
* @param key
* key type
* @return root key
*/
private static int getRegistryRootKey(REGISTRY_ROOT_KEY key)
{
Advapi32 advapi32;
IntByReference pHandle;
int handle = 0;
advapi32 = Advapi32.INSTANCE;
pHandle = new IntByReference();
if (advapi32.RegOpenKeyEx(rootKeyMap.get(key), null, 0, 0, pHandle) == WINERROR.ERROR_SUCCESS)
{
handle = pHandle.getValue();
}
return (handle);
}
/**
* Opens a key.
*
* @param rootKey
* root key
* @param subKeyName
* name of the key
* @param access
* access mode
* @return handle to the key or 0
*/
private static int openKey(REGISTRY_ROOT_KEY rootKey, String subKeyName, int access)
{
Advapi32 advapi32;
IntByReference pHandle;
int rootKeyHandle;
advapi32 = Advapi32.INSTANCE;
rootKeyHandle = getRegistryRootKey(rootKey);
pHandle = new IntByReference();
if (advapi32.RegOpenKeyEx(rootKeyHandle, subKeyName, 0, access, pHandle) == WINERROR.ERROR_SUCCESS)
{
return (pHandle.getValue());
}
else
{
return (0);
}
}
/**
* Converts a Windows buffer to a Java String.
*
* @param buf
* buffer
* @throws java.io.UnsupportedEncodingException
* on error
* @return String
*/
private static String convertBufferToString(byte[] buf) throws UnsupportedEncodingException
{
return (new String(buf, 0, buf.length - 2, "UTF-16LE"));
}
/**
* Converts a Windows buffer to an int.
*
* @param buf
* buffer
* @return int
*/
private static int convertBufferToInt(byte[] buf)
{
return (((int) (buf[0] & 0xff)) + (((int) (buf[1] & 0xff)) << 8) + (((int) (buf[2] & 0xff)) << 16) + (((int) (buf[3] & 0xff)) << 24));
}
/**
* Read a String value.
*
* @param rootKey
* root key
* @param subKeyName
* key name
* @param name
* value name
* @throws java.io.UnsupportedEncodingException
* on error
* @return String or null
*/
public static String getStringValue(REGISTRY_ROOT_KEY rootKey, String subKeyName, String name) throws UnsupportedEncodingException
{
Advapi32 advapi32;
IntByReference pType, lpcbData;
byte[] lpData = new byte[1];
int handle = 0;
String ret = null;
advapi32 = Advapi32.INSTANCE;
pType = new IntByReference();
lpcbData = new IntByReference();
handle = openKey(rootKey, subKeyName, WINNT.KEY_READ);
if (handle != 0)
{
if (advapi32.RegQueryValueEx(handle, name, null, pType, lpData, lpcbData) == WINERROR.ERROR_MORE_DATA)
{
lpData = new byte[lpcbData.getValue()];
if (advapi32.RegQueryValueEx(handle, name, null, pType, lpData, lpcbData) == WINERROR.ERROR_SUCCESS)
{
ret = convertBufferToString(lpData);
}
}
advapi32.RegCloseKey(handle);
}
return (ret);
}
/**
* Read an int value.
*
*
* @return int or 0
* @param rootKey
* root key
* @param subKeyName
* key name
* @param name
* value name
*/
public static int getIntValue(REGISTRY_ROOT_KEY rootKey, String subKeyName, String name)
{
Advapi32 advapi32;
IntByReference pType, lpcbData;
byte[] lpData = new byte[1];
int handle = 0;
int ret = 0;
advapi32 = Advapi32.INSTANCE;
pType = new IntByReference();
lpcbData = new IntByReference();
handle = openKey(rootKey, subKeyName, WINNT.KEY_READ);
if (handle != 0)
{
if (advapi32.RegQueryValueEx(handle, name, null, pType, lpData, lpcbData) == WINERROR.ERROR_MORE_DATA)
{
lpData = new byte[lpcbData.getValue()];
if (advapi32.RegQueryValueEx(handle, name, null, pType, lpData, lpcbData) == WINERROR.ERROR_SUCCESS)
{
ret = convertBufferToInt(lpData);
}
}
advapi32.RegCloseKey(handle);
}
return (ret);
}
/**
* Delete a value.
*
* @param rootKey
* root key
* @param subKeyName
* key name
* @param name
* value name
* @return true on success
*/
public static boolean deleteValue(REGISTRY_ROOT_KEY rootKey, String subKeyName, String name)
{
Advapi32 advapi32;
int handle;
boolean ret = true;
advapi32 = Advapi32.INSTANCE;
handle = openKey(rootKey, subKeyName, WINNT.KEY_READ | WINNT.KEY_WRITE);
if (handle != 0)
{
if (advapi32.RegDeleteValue(handle, name) == WINERROR.ERROR_SUCCESS)
{
ret = true;
}
advapi32.RegCloseKey(handle);
}
return (ret);
}
/**
* Writes a String value.
*
* @param rootKey
* root key
* @param subKeyName
* key name
* @param name
* value name
* @param value
* value
* @throws java.io.UnsupportedEncodingException
* on error
* @return true on success
*/
public static boolean setStringValue(REGISTRY_ROOT_KEY rootKey, String subKeyName, String name, String value) throws UnsupportedEncodingException
{
Advapi32 advapi32;
int handle;
byte[] data;
boolean ret = false;
data = Arrays.copyOf(value.getBytes("UTF-16LE"), value.length() * 2 + 2);
advapi32 = Advapi32.INSTANCE;
handle = openKey(rootKey, subKeyName, WINNT.KEY_READ | WINNT.KEY_WRITE);
if (handle != 0)
{
if (advapi32.RegSetValueEx(handle, name, 0, WINNT.REG_SZ, data, data.length) == WINERROR.ERROR_SUCCESS)
{
ret = true;
}
advapi32.RegCloseKey(handle);
}
return (ret);
}
/**
* Writes an int value.
*
*
* @return true on success
* @param rootKey
* root key
* @param subKeyName
* key name
* @param name
* value name
* @param value
* value
*/
public static boolean setIntValue(REGISTRY_ROOT_KEY rootKey, String subKeyName, String name, int value)
{
Advapi32 advapi32;
int handle;
byte[] data;
boolean ret = false;
data = new byte[4];
data[0] = (byte) (value & 0xff);
data[1] = (byte) ((value >> 8) & 0xff);
data[2] = (byte) ((value >> 16) & 0xff);
data[3] = (byte) ((value >> 24) & 0xff);
advapi32 = Advapi32.INSTANCE;
handle = openKey(rootKey, subKeyName, WINNT.KEY_READ | WINNT.KEY_WRITE);
if (handle != 0)
{
if (advapi32.RegSetValueEx(handle, name, 0, WINNT.REG_DWORD, data, data.length) == WINERROR.ERROR_SUCCESS)
{
ret = true;
}
advapi32.RegCloseKey(handle);
}
return (ret);
}
/**
* Check for existence of a value.
*
* @param rootKey
* root key
* @param subKeyName
* key name
* @param name
* value name
* @return true if exists
*/
public static boolean valueExists(REGISTRY_ROOT_KEY rootKey, String subKeyName, String name)
{
Advapi32 advapi32;
IntByReference pType, lpcbData;
byte[] lpData = new byte[1];
int handle = 0;
boolean ret = false;
advapi32 = Advapi32.INSTANCE;
pType = new IntByReference();
lpcbData = new IntByReference();
handle = openKey(rootKey, subKeyName, WINNT.KEY_READ);
if (handle != 0)
{
if (advapi32.RegQueryValueEx(handle, name, null, pType, lpData, lpcbData) != WINERROR.ERROR_FILE_NOT_FOUND)
{
ret = true;
}
else
{
ret = false;
}
advapi32.RegCloseKey(handle);
}
return (ret);
}
/**
* Create a new key.
*
* @param rootKey
* root key
* @param parent
* name of parent key
* @param name
* key name
* @return true on success
*/
public static boolean createKey(REGISTRY_ROOT_KEY rootKey, String parent, String name)
{
Advapi32 advapi32;
IntByReference hkResult, dwDisposition;
int handle = 0;
boolean ret = false;
advapi32 = Advapi32.INSTANCE;
hkResult = new IntByReference();
dwDisposition = new IntByReference();
handle = openKey(rootKey, parent, WINNT.KEY_READ);
if (handle != 0)
{
if (advapi32.RegCreateKeyEx(handle, name, 0, null, WINNT.REG_OPTION_NON_VOLATILE, WINNT.KEY_READ, null, hkResult, dwDisposition) == WINERROR.ERROR_SUCCESS)
{
ret = true;
advapi32.RegCloseKey(hkResult.getValue());
}
else
{
ret = false;
}
advapi32.RegCloseKey(handle);
}
return (ret);
}
/**
* Delete a key.
*
* @param rootKey
* root key
* @param parent
* name of parent key
* @param name
* key name
* @return true on success
*/
public static boolean deleteKey(REGISTRY_ROOT_KEY rootKey, String parent, String name)
{
Advapi32 advapi32;
int handle = 0;
boolean ret = false;
advapi32 = Advapi32.INSTANCE;
handle = openKey(rootKey, parent, WINNT.KEY_READ);
if (handle != 0)
{
if (advapi32.RegDeleteKey(handle, name) == WINERROR.ERROR_SUCCESS)
{
ret = true;
}
else
{
ret = false;
}
advapi32.RegCloseKey(handle);
}
return (ret);
}
/**
* Get all sub keys of a key.
*
* @param rootKey
* root key
* @param parent
* key name
* @return array with all sub key names
*/
public static String[] getSubKeys(REGISTRY_ROOT_KEY rootKey, String parent)
{
Advapi32 advapi32;
int handle = 0, dwIndex;
char[] lpName;
IntByReference lpcName;
WINBASE.FILETIME lpftLastWriteTime;
TreeSet<String> subKeys = new TreeSet<String>();
advapi32 = Advapi32.INSTANCE;
handle = openKey(rootKey, parent, WINNT.KEY_READ);
lpName = new char[256];
lpcName = new IntByReference(256);
lpftLastWriteTime = new WINBASE.FILETIME();
if (handle != 0)
{
dwIndex = 0;
while (advapi32.RegEnumKeyEx(handle, dwIndex, lpName, lpcName, null, null, null, lpftLastWriteTime) == WINERROR.ERROR_SUCCESS)
{
subKeys.add(new String(lpName, 0, lpcName.getValue()));
lpcName.setValue(256);
dwIndex++;
}
advapi32.RegCloseKey(handle);
}
return (subKeys.toArray(new String[]
{}));
}
/**
* Get all values under a key.
*
* @param rootKey
* root key
* @param key
* jey name
* @throws java.io.UnsupportedEncodingException
* on error
* @return TreeMap with name and value pairs
*/
public static TreeMap<String, Object> getValues(REGISTRY_ROOT_KEY rootKey, String key) throws UnsupportedEncodingException
{
Advapi32 advapi32;
int handle = 0, dwIndex, result = 0;
char[] lpValueName;
byte[] lpData;
IntByReference lpcchValueName, lpType, lpcbData;
String name;
TreeMap<String, Object> values = new TreeMap<String, Object>(String.CASE_INSENSITIVE_ORDER);
advapi32 = Advapi32.INSTANCE;
handle = openKey(rootKey, key, WINNT.KEY_READ);
lpValueName = new char[16384];
lpcchValueName = new IntByReference(16384);
lpType = new IntByReference();
lpData = new byte[1];
lpcbData = new IntByReference();
if (handle != 0)
{
dwIndex = 0;
do
{
lpcbData.setValue(0);
result = advapi32.RegEnumValue(handle, dwIndex, lpValueName, lpcchValueName, null, lpType, lpData, lpcbData);
if (result == WINERROR.ERROR_MORE_DATA)
{
lpData = new byte[lpcbData.getValue()];
lpcchValueName = new IntByReference(16384);
result = advapi32.RegEnumValue(handle, dwIndex, lpValueName, lpcchValueName, null, lpType, lpData, lpcbData);
if (result == WINERROR.ERROR_SUCCESS)
{
name = new String(lpValueName, 0, lpcchValueName.getValue());
switch (lpType.getValue())
{
case WINNT.REG_SZ:
values.put(name, convertBufferToString(lpData));
break;
case WINNT.REG_DWORD:
values.put(name, convertBufferToInt(lpData));
break;
default:
break;
}
}
}
dwIndex++;
}
while (result == WINERROR.ERROR_SUCCESS);
advapi32.RegCloseKey(handle);
}
return (values);
}
}