blob: 0d847a842283f68d6d9ebf403bfff6fd35c1a196 [file] [log] [blame]
package npanday.registry.impl;
import npanday.registry.WindowsRegistryAccessException;
import npanday.registry.WindowsRegistryAccessProvider;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.prefs.Preferences;
public class WinRegistry
implements WindowsRegistryAccessProvider
{
public static final int HKEY_CURRENT_USER = 0x80000001;
public static final int HKEY_LOCAL_MACHINE = 0x80000002;
public static final int REG_SUCCESS = 0;
private static final int KEY_ALL_ACCESS = 0xf003f;
private static final int KEY_READ = 0x20019;
private static Preferences userRoot = Preferences.userRoot();
private static Preferences systemRoot = Preferences.systemRoot();
private static Class<? extends Preferences> userClass = userRoot.getClass();
private static Method regOpenKey = null;
private static Method regCloseKey = null;
private static Method regQueryValueEx = null;
private static Method regEnumValue = null;
private static Method regQueryInfoKey = null;
private static Method regEnumKeyEx = null;
private static Method regCreateKeyEx = null;
private static Method regSetValueEx = null;
private static Method regDeleteKey = null;
private static Method regDeleteValue = null;
static
{
try
{
regOpenKey = userClass.getDeclaredMethod(
"WindowsRegOpenKey", new Class[]{ int.class, byte[].class, int.class }
);
regOpenKey.setAccessible( true );
regCloseKey = userClass.getDeclaredMethod( "WindowsRegCloseKey", new Class[]{ int.class } );
regCloseKey.setAccessible( true );
regQueryValueEx = userClass.getDeclaredMethod(
"WindowsRegQueryValueEx", new Class[]{ int.class, byte[].class }
);
regQueryValueEx.setAccessible( true );
regEnumValue = userClass.getDeclaredMethod(
"WindowsRegEnumValue", new Class[]{ int.class, int.class, int.class }
);
regEnumValue.setAccessible( true );
regQueryInfoKey = userClass.getDeclaredMethod( "WindowsRegQueryInfoKey1", new Class[]{ int.class } );
regQueryInfoKey.setAccessible( true );
regEnumKeyEx = userClass.getDeclaredMethod(
"WindowsRegEnumKeyEx", new Class[]{ int.class, int.class, int.class }
);
regEnumKeyEx.setAccessible( true );
regCreateKeyEx = userClass.getDeclaredMethod(
"WindowsRegCreateKeyEx", new Class[]{ int.class, byte[].class }
);
regCreateKeyEx.setAccessible( true );
regSetValueEx = userClass.getDeclaredMethod(
"WindowsRegSetValueEx", new Class[]{ int.class, byte[].class, byte[].class }
);
regSetValueEx.setAccessible( true );
regDeleteValue = userClass.getDeclaredMethod(
"WindowsRegDeleteValue", new Class[]{ int.class, byte[].class }
);
regDeleteValue.setAccessible( true );
regDeleteKey = userClass.getDeclaredMethod(
"WindowsRegDeleteKey", new Class[]{
int.class, byte[].class
}
);
regDeleteKey.setAccessible( true );
}
catch ( Exception e )
{
e.printStackTrace();
}
}
public WinRegistry()
{
}
/**
* Read a value from key and value name
*
* @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
* @param key
* @param valueName
* @return the value
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws java.lang.reflect.InvocationTargetException
*
*/
public static String readString( int hkey, String key, String valueName ) throws
IllegalArgumentException,
IllegalAccessException,
InvocationTargetException
{
if ( hkey == HKEY_LOCAL_MACHINE )
{
return readString( systemRoot, hkey, key, valueName );
}
else if ( hkey == HKEY_CURRENT_USER )
{
return readString( userRoot, hkey, key, valueName );
}
else
{
throw new IllegalArgumentException( "hkey=" + hkey );
}
}
/**
* Read value(s) and value name(s) form given key
*
* @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
* @param key
* @return the value name(s) plus the value(s)
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws java.lang.reflect.InvocationTargetException
*
*/
public static Map<String, String> readStringValues( int hkey, String key ) throws
IllegalArgumentException,
IllegalAccessException,
InvocationTargetException
{
if ( hkey == HKEY_LOCAL_MACHINE )
{
return readStringValues( systemRoot, hkey, key );
}
else if ( hkey == HKEY_CURRENT_USER )
{
return readStringValues( userRoot, hkey, key );
}
else
{
throw new IllegalArgumentException( "hkey=" + hkey );
}
}
/**
* Read the value name(s) from a given key
*
* @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
* @param key
* @return the value name(s)
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws java.lang.reflect.InvocationTargetException
*
*/
public static List<String> readStringSubKeys( int hkey, String key ) throws
IllegalArgumentException,
IllegalAccessException,
InvocationTargetException
{
if ( hkey == HKEY_LOCAL_MACHINE )
{
return readStringSubKeys( systemRoot, hkey, key );
}
else if ( hkey == HKEY_CURRENT_USER )
{
return readStringSubKeys( userRoot, hkey, key );
}
else
{
throw new IllegalArgumentException( "hkey=" + hkey );
}
}
/**
* Create a key
*
* @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
* @param key
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws java.lang.reflect.InvocationTargetException
*
*/
public static void createKey( int hkey, String key ) throws
IllegalArgumentException,
IllegalAccessException,
InvocationTargetException
{
int[] ret;
if ( hkey == HKEY_LOCAL_MACHINE )
{
ret = createKey( systemRoot, hkey, key );
regCloseKey.invoke( systemRoot, new Object[]{ new Integer( ret[0] ) } );
}
else if ( hkey == HKEY_CURRENT_USER )
{
ret = createKey( userRoot, hkey, key );
regCloseKey.invoke( userRoot, new Object[]{ new Integer( ret[0] ) } );
}
else
{
throw new IllegalArgumentException( "hkey=" + hkey );
}
if ( ret[1] != REG_SUCCESS )
{
throw new IllegalArgumentException( "rc=" + ret[1] + " key=" + key );
}
}
/**
* Write a value in a given key/value name
*
* @param hkey
* @param key
* @param valueName
* @param value
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws java.lang.reflect.InvocationTargetException
*
*/
public static void writeStringValue( int hkey, String key, String valueName, String value ) throws
IllegalArgumentException,
IllegalAccessException,
InvocationTargetException
{
if ( hkey == HKEY_LOCAL_MACHINE )
{
writeStringValue( systemRoot, hkey, key, valueName, value );
}
else if ( hkey == HKEY_CURRENT_USER )
{
writeStringValue( userRoot, hkey, key, valueName, value );
}
else
{
throw new IllegalArgumentException( "hkey=" + hkey );
}
}
/**
* Delete a given key
*
* @param hkey
* @param key
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws java.lang.reflect.InvocationTargetException
*
*/
public static void deleteKey( int hkey, String key ) throws
IllegalArgumentException,
IllegalAccessException,
InvocationTargetException
{
int rc = -1;
if ( hkey == HKEY_LOCAL_MACHINE )
{
rc = deleteKey( systemRoot, hkey, key );
}
else if ( hkey == HKEY_CURRENT_USER )
{
rc = deleteKey( userRoot, hkey, key );
}
if ( rc != REG_SUCCESS )
{
throw new IllegalArgumentException( "rc=" + rc + " key=" + key );
}
}
/**
* delete a value from a given key/value name
*
* @param hkey
* @param key
* @param value
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws java.lang.reflect.InvocationTargetException
*
*/
public static void deleteValue( int hkey, String key, String value ) throws
IllegalArgumentException,
IllegalAccessException,
InvocationTargetException
{
int rc = -1;
if ( hkey == HKEY_LOCAL_MACHINE )
{
rc = deleteValue( systemRoot, hkey, key, value );
}
else if ( hkey == HKEY_CURRENT_USER )
{
rc = deleteValue( userRoot, hkey, key, value );
}
if ( rc != REG_SUCCESS )
{
throw new IllegalArgumentException( "rc=" + rc + " key=" + key + " value=" + value );
}
}
// =====================
private static int deleteValue( Preferences root, int hkey, String key, String value ) throws
IllegalArgumentException,
IllegalAccessException,
InvocationTargetException
{
int[] handles = (int[]) regOpenKey.invoke(
root, new Object[]{
new Integer( hkey ), toCstr( key ), new Integer( KEY_ALL_ACCESS )
}
);
if ( handles[1] != REG_SUCCESS )
{
return handles[1]; // can be REG_NOTFOUND, REG_ACCESSDENIED
}
int rc = (
(Integer) regDeleteValue.invoke(
root, new Object[]{
new Integer( handles[0] ), toCstr( value )
}
)
).intValue();
regCloseKey.invoke( root, new Object[]{ new Integer( handles[0] ) } );
return rc;
}
private static int deleteKey( Preferences root, int hkey, String key ) throws
IllegalArgumentException,
IllegalAccessException,
InvocationTargetException
{
int rc = (
(Integer) regDeleteKey.invoke(
root, new Object[]{ new Integer( hkey ), toCstr( key ) }
)
).intValue();
return rc; // can REG_NOTFOUND, REG_ACCESSDENIED, REG_SUCCESS
}
private static String readString( Preferences root, int hkey, String key, String value ) throws
IllegalArgumentException,
IllegalAccessException,
InvocationTargetException
{
int[] handles = (int[]) regOpenKey.invoke(
root, new Object[]{
new Integer( hkey ), toCstr( key ), new Integer( KEY_READ )
}
);
if ( handles[1] != REG_SUCCESS )
{
return null;
}
byte[] valb = (byte[]) regQueryValueEx.invoke(
root, new Object[]{ new Integer( handles[0] ), toCstr( value ) }
);
regCloseKey.invoke( root, new Object[]{ new Integer( handles[0] ) } );
return ( valb != null ? new String( valb ).trim() : null );
}
private static Map<String, String> readStringValues( Preferences root, int hkey, String key ) throws
IllegalArgumentException,
IllegalAccessException,
InvocationTargetException
{
HashMap<String, String> results = new HashMap<String, String>();
int[] handles = (int[]) regOpenKey.invoke(
root, new Object[]{
new Integer( hkey ), toCstr( key ), new Integer( KEY_READ )
}
);
if ( handles[1] != REG_SUCCESS )
{
return null;
}
int[] info = (int[]) regQueryInfoKey.invoke( root, new Object[]{ new Integer( handles[0] ) } );
int count = info[2]; // count
int maxlen = info[3]; // value length max
for ( int index = 0; index < count; index++ )
{
byte[] name = (byte[]) regEnumValue.invoke(
root, new Object[]{
new Integer( handles[0] ), new Integer( index ), new Integer( maxlen + 1 )
}
);
String value = readString( hkey, key, new String( name ) );
results.put( new String( name ).trim(), value );
}
regCloseKey.invoke( root, new Object[]{ new Integer( handles[0] ) } );
return results;
}
private static List<String> readStringSubKeys( Preferences root, int hkey, String key ) throws
IllegalArgumentException,
IllegalAccessException,
InvocationTargetException
{
List<String> results = new ArrayList<String>();
int[] handles = (int[]) regOpenKey.invoke(
root, new Object[]{
new Integer( hkey ), toCstr( key ), new Integer( KEY_READ )
}
);
if ( handles[1] != REG_SUCCESS )
{
return null;
}
int[] info = (int[]) regQueryInfoKey.invoke( root, new Object[]{ new Integer( handles[0] ) } );
int count = info[2]; // count
int maxlen = info[3]; // value length max
for ( int index = 0; index < count; index++ )
{
byte[] name = (byte[]) regEnumKeyEx.invoke(
root, new Object[]{
new Integer( handles[0] ), new Integer( index ), new Integer( maxlen + 1 )
}
);
results.add( new String( name ).trim() );
}
regCloseKey.invoke( root, new Object[]{ new Integer( handles[0] ) } );
return results;
}
private static int[] createKey( Preferences root, int hkey, String key ) throws
IllegalArgumentException,
IllegalAccessException,
InvocationTargetException
{
return (int[]) regCreateKeyEx.invoke( root, new Object[]{ new Integer( hkey ), toCstr( key ) } );
}
private static void writeStringValue(
Preferences root, int hkey, String key, String valueName, String value ) throws
IllegalArgumentException,
IllegalAccessException,
InvocationTargetException
{
int[] handles = (int[]) regOpenKey.invoke(
root, new Object[]{
new Integer( hkey ), toCstr( key ), new Integer( KEY_ALL_ACCESS )
}
);
regSetValueEx.invoke( root, new Object[]{ new Integer( handles[0] ), toCstr( valueName ), toCstr( value ) } );
regCloseKey.invoke( root, new Object[]{ new Integer( handles[0] ) } );
}
// utility
private static byte[] toCstr( String str )
{
byte[] result = new byte[str.length() + 1];
for ( int i = 0; i < str.length(); i++ )
{
result[i] = (byte) str.charAt( i );
}
result[str.length()] = 0;
return result;
}
public String getValue(
RegistryHKey registryHKey, String key, String valueName ) throws WindowsRegistryAccessException
{
try
{
return WinRegistry.readString(
registryHKey.getHKey(), key, valueName
);
}
catch ( InvocationTargetException e )
{
throw new WindowsRegistryAccessException(
"NPANDAY-117-000: Error while retrieving a windows registry value", e
);
}
catch ( IllegalAccessException e )
{
throw new WindowsRegistryAccessException(
"NPANDAY-117-001: Error while retrieving a windows registry value", e
);
}
}
}