/*
** Java native interface to the Windows Registry API.
**
** Authored by Timothy Gerard Endres
** <mailto:time@gjt.org> <http://www.trustice.com>
**
** This work has been placed into the public domain.
** You may use this work in any way and for any purpose you wish.
**
** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
** REDISTRIBUTION OF THIS SOFTWARE.
**
*/
package com.newatlanta.jni.registry;
import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
import java.util.Vector;
/**
* The Registry class provides is used to load the native library DLL, as well
* as a placeholder for the top level keys, error codes, and utility methods.
*
* @version 3.1.3
*
*/
public class Registry {
/**
* The following statics are the top level keys. Without these, there is no
* way to get "into" the registry, since the RegOpenSubkey() call requires an
* existing key which contains the subkey.
*/
public static RegistryKey HKEY_CLASSES_ROOT;
public static RegistryKey HKEY_CURRENT_USER;
public static RegistryKey HKEY_LOCAL_MACHINE;
public static RegistryKey HKEY_USERS;
public static RegistryKey HKEY_PERFORMANCE_DATA;
public static RegistryKey HKEY_CURRENT_CONFIG;
public static RegistryKey HKEY_DYN_DATA;
/**
* These are predefined keys ($0-$9) used to make the testing program easier
* to use (less typing).
*/
private static String[] preDefines;
/**
* These are the Registry API error codes, which can be returned via the
* RegistryException.
*/
public static final int ERROR_SUCCESS = 0;
public static final int ERROR_FILE_NOT_FOUND = 2;
public static final int ERROR_ACCESS_DENIED = 5;
public static final int ERROR_INVALID_HANDLE = 6;
public static final int ERROR_INVALID_PARAMETER = 87;
public static final int ERROR_CALL_NOT_IMPLEMENTED = 120;
public static final int ERROR_INSUFFICIENT_BUFFER = 122;
public static final int ERROR_LOCK_FAILED = 167;
public static final int ERROR_TRANSFER_TOO_LONG = 222;
public static final int ERROR_MORE_DATA = 234;
public static final int ERROR_NO_MORE_ITEMS = 259;
public static final int ERROR_BADDB = 1009;
public static final int ERROR_BADKEY = 1010;
public static final int ERROR_CANTOPEN = 1011;
public static final int ERROR_CANTREAD = 1012;
public static final int ERROR_CANTWRITE = 1013;
public static final int ERROR_REGISTRY_RECOVERED = 1014;
public static final int ERROR_REGISTRY_CORRUPT = 1015;
public static final int ERROR_REGISTRY_IO_FAILED = 1016;
public static final int ERROR_NOT_REGISTRY_FILE = 1017;
public static final int ERROR_KEY_DELETED = 1018;
/**
* These are used by dumpHex().
*/
private static final int ROW_BYTES = 16;
private static final int ROW_QTR1 = 3;
private static final int ROW_HALF = 7;
private static final int ROW_QTR2 = 11;
/**
* This is the last key used by the test program ($$).
*/
private static String saveKey = null;
/**
* This is a Hashtable which maps nams to the top level keys.
*/
private static Hashtable topLevelKeys = null;
/**
* If true, debug the fv parameters and computation.
*/
public boolean debugLevel;
/**
* Loads the DLL needed for the native methods, creates the toplevel keys,
* fills the hashtable that maps various names to the toplevel keys.
*/
static {
/*
* ICE_JNIRegistry.dll has been renamed to cfregistry.dll. It is loaded by
* cfREGISTRY.init() so we don't need to load it here.
*
* try { System.loadLibrary( "ICE_JNIRegistry" ); } catch (
* UnsatisfiedLinkError e ) { System.err.println ( "ERROR You have not
* installed the DLL named '" + "ICE_JNIRegistry.DLL'.\n\t" + e.getMessage() ); }
* catch ( SecurityException e ) { System.err.println ( "ERROR You do not
* have permission to load the DLL named '" + "ICE_JNIRegistry.DLL'.\n\t" +
* e.getMessage() ); }
*/
Registry.HKEY_CLASSES_ROOT = new RegistryKey(0x80000000, "HKEY_CLASSES_ROOT");
Registry.HKEY_CURRENT_USER = new RegistryKey(0x80000001, "HKEY_CURRENT_USER");
Registry.HKEY_LOCAL_MACHINE = new RegistryKey(0x80000002, "HKEY_LOCAL_MACHINE");
Registry.HKEY_USERS = new RegistryKey(0x80000003, "HKEY_USERS");
Registry.HKEY_PERFORMANCE_DATA = new RegistryKey(0x80000004, "HKEY_PERFORMANCE_DATA");
Registry.HKEY_CURRENT_CONFIG = new RegistryKey(0x80000005, "HKEY_CURRENT_CONFIG");
Registry.HKEY_DYN_DATA = new RegistryKey(0x80000006, "HKEY_DYN_DATA");
Registry.topLevelKeys = new Hashtable(16);
topLevelKeys.put("HKCR", Registry.HKEY_CLASSES_ROOT);
topLevelKeys.put("HKEY_CLASSES_ROOT", Registry.HKEY_CLASSES_ROOT);
topLevelKeys.put("HKCU", Registry.HKEY_CURRENT_USER);
topLevelKeys.put("HKEY_CURRENT_USER", Registry.HKEY_CURRENT_USER);
topLevelKeys.put("HKLM", Registry.HKEY_LOCAL_MACHINE);
topLevelKeys.put("HKEY_LOCAL_MACHINE", Registry.HKEY_LOCAL_MACHINE);
topLevelKeys.put("HKU", Registry.HKEY_USERS);
topLevelKeys.put("HKUS", Registry.HKEY_USERS);
topLevelKeys.put("HKEY_USERS", Registry.HKEY_USERS);
topLevelKeys.put("HKPD", Registry.HKEY_PERFORMANCE_DATA);
topLevelKeys.put("HKEY_PERFORMANCE_DATA", Registry.HKEY_PERFORMANCE_DATA);
topLevelKeys.put("HKCC", Registry.HKEY_PERFORMANCE_DATA);
topLevelKeys.put("HKEY_CURRENT_CONFIG", Registry.HKEY_PERFORMANCE_DATA);
topLevelKeys.put("HKDD", Registry.HKEY_PERFORMANCE_DATA);
topLevelKeys.put("HKEY_DYN_DATA", Registry.HKEY_PERFORMANCE_DATA);
}
/**
* Get a top level key by name using the top level key Hashtable.
*
* @param keyName
* The name of the top level key.
* @return The top level RegistryKey, or null if unknown keyName.
*
* @see topLevelKeys
*/
public static RegistryKey getTopLevelKey(String keyName) {
return (RegistryKey) Registry.topLevelKeys.get(keyName);
}
/**
* Open a subkey of a given top level key.
*
* @param topKey
* The top level key containing the subkey.
* @param keyName
* The subkey's name.
* @param access
* The access flag for the newly opened key.
* @return The newly opened RegistryKey.
*
* @see RegistryKey
*/
public static RegistryKey openSubkey(RegistryKey topKey, String keyName, int access) {
RegistryKey subKey = null;
try {
subKey = topKey.openSubKey(keyName, access);
} catch (NoSuchKeyException ex) {
subKey = null;
} catch (RegistryException ex) {
subKey = null;
}
return subKey;
}
/**
* Get the description of a Registry error code.
*
* @param errCode
* The error code from a RegistryException
* @return The description of the error code.
*/
public static String getErrorMessage(int errCode) {
switch (errCode) {
case ERROR_SUCCESS:
return "success";
case ERROR_FILE_NOT_FOUND:
return "key or value not found";
case ERROR_ACCESS_DENIED:
return "access denied";
case ERROR_INVALID_HANDLE:
return "invalid handle";
case ERROR_INVALID_PARAMETER:
return "invalid parameter";
case ERROR_CALL_NOT_IMPLEMENTED:
return "call not implemented";
case ERROR_INSUFFICIENT_BUFFER:
return "insufficient buffer";
case ERROR_LOCK_FAILED:
return "lock failed";
case ERROR_TRANSFER_TOO_LONG:
return "transfer was too long";
case ERROR_MORE_DATA:
return "more data buffer needed";
case ERROR_NO_MORE_ITEMS:
return "no more items";
case ERROR_BADDB:
return "bad database";
case ERROR_BADKEY:
return "bad key";
case ERROR_CANTOPEN:
return "can not open";
case ERROR_CANTREAD:
return "can not read";
case ERROR_CANTWRITE:
return "can not write";
case ERROR_REGISTRY_RECOVERED:
return "registry recovered";
case ERROR_REGISTRY_CORRUPT:
return "registry corrupt";
case ERROR_REGISTRY_IO_FAILED:
return "registry IO failed";
case ERROR_NOT_REGISTRY_FILE:
return "not a registry file";
case ERROR_KEY_DELETED:
return "key has been deleted";
}
return "errCode=" + errCode;
}
/**
* Export the textual definition for a registry key to a file. The resulting
* file can be re-loaded via RegEdit.
*
* @param pathName
* The pathname of the file into which to export.
* @param key
* The registry key definition to export.
* @param descend
* If true, descend and export all subkeys.
*
* @exception NoSuchKeyException
* Thrown by openSubKey().
* @exception RegistryException
* Any other registry API error.
*/
public static void exportRegistryKey(String pathName, RegistryKey key, boolean descend) throws java.io.IOException, NoSuchKeyException, RegistryException {
PrintWriter out = new PrintWriter(new FileWriter(pathName));
out.println("REGEDIT4");
out.println("");
key.export(out, descend);
out.flush();
out.close();
}
/**
* The main() method is used to test the Registry package.
*/
public static void main(String argv[]) {
Registry.preDefines = new String[10];
Registry.preDefines[0] = "HKLM\\System\\CurrentControlSet\\control";
Registry.preDefines[1] = "HKLM\\Software";
Registry.preDefines[2] = "HKLM\\Software\\Miscrosoft";
Registry.preDefines[3] = "HKLM\\Software\\Microsoft\\Windows" + "\\CurrentVersion";
Registry.preDefines[4] = "HKLM\\Software\\Microsoft\\Windows" + "\\CurrentVersion\\ProfileList";
Registry.preDefines[5] = "HKCU\\Software";
Registry.preDefines[6] = "HKCU\\Software\\Microsoft";
Registry.preDefines[7] = "HKCU\\AppEvents";
Registry.preDefines[8] = "HKCU\\AppEvents\\Schemes";
Registry.preDefines[9] = "HKCU\\AppEvents\\Schemes";
if (argv.length > 0) {
Registry.subMain(argv);
} else {
String inLine;
String saveLine = null;
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
for (;;) {
System.out.print("command: ");
System.out.flush();
try {
inLine = input.readLine();
} catch (IOException ex) {
inLine = null;
}
if (inLine == null || inLine.length() == 0)
break;
if (inLine.equalsIgnoreCase("help")) {
Registry.usage(null);
continue;
}
String[] subArgs;
if (inLine.equals("!!") && saveLine != null) {
subArgs = Registry.parseArgumentString(saveLine);
} else {
subArgs = Registry.parseArgumentString(inLine);
saveLine = inLine;
}
Registry.subMain(subArgs);
}
}
}
/**
* Print the usage/help information.
*/
public static void usage(String message) {
if (message != null)
System.err.println(message);
System.err.println("keys regKey -- print the key names");
System.err.println("values regKey -- print the value names");
System.err.println("data regKey subKey -- print the key's data");
System.err.println("string regKey subKey -- print REG_SZ key's string");
System.err.println("setbin regKey subKey binaryString -- set REG_BINARY");
System.err.println("setdw regKey subKey int -- set REG_DWORD");
System.err.println("setstr regKey subKey string -- set REG_SZ");
System.err.println("setmulti regKey subKey semiColonString -- set REG_MULTI_SZ");
System.err.println("delkey regKey subKey -- delete key 'subKey' of regKey");
System.err.println("delval regKey subKey -- delete value 'subKey' of regKey");
System.err.println("export regKey fileName -- export registry key to fileName");
System.err.println("expand regKey valueName -- expand string value");
System.err.println("");
System.err.println("!! -- repeats last command");
System.err.println("$$ -- re-uses previous keyname");
System.err.println("Predefined Key Prefixes: (e.g. $0-9)");
for (int idx = 0; idx < Registry.preDefines.length; ++idx)
System.err.println(" $" + idx + "=" + Registry.preDefines[idx]);
}
/**
* The actual main method, which is called for each command.
*/
public static void subMain(String argv[]) {
int index;
RegistryKey topKey = null;
boolean isRemote = false;
String topKeyName = null;
String hostName = null;
if (argv.length < 1 || argv[0].equals("help")) {
Registry.usage(null);
return;
}
if (argv.length < 2) {
Registry.usage(null);
return;
}
String keyName = argv[1];
if (Registry.saveKey != null && keyName.equals("$$")) {
keyName = Registry.saveKey;
} else if (keyName.equals("@@")) {
keyName = "HKCU\\Software\\ICE Engineering\\test";
} else {
char ch1 = keyName.charAt(0);
char ch2 = keyName.charAt(1);
if (ch1 == '$' && ch2 >= '0' && ch2 <= '9') {
int pIdx = (ch2 - '0');
if (Registry.preDefines[pIdx] != null) {
if (keyName.length() < 3)
keyName = Registry.preDefines[pIdx];
else
keyName = Registry.preDefines[pIdx] + keyName.substring(2);
} else {
System.err.println("Predefine '" + keyName + "' not defined.");
return;
}
} else {
Registry.saveKey = argv[1];
}
}
if (keyName.startsWith("\\\\")) {
isRemote = true;
index = keyName.indexOf('\\', 2);
hostName = keyName.substring(2, index);
keyName = keyName.substring(index + 1);
}
index = keyName.indexOf('\\');
if (index < 0) {
//
// "topLevelKeyname"
//
topKeyName = keyName;
keyName = null;
} else if (index < 4) {
//
// INVALID KEYNAME, topLevelName too short
//
System.err.println("Invalid key '" + keyName + "', top level key name too short.");
return;
} else {
//
// "topLevelKeyname\subKey\subKey\..."
//
topKeyName = keyName.substring(0, index);
if ((index + 1) >= keyName.length())
keyName = null;
else
keyName = keyName.substring(index + 1);
}
topKey = Registry.getTopLevelKey(topKeyName);
if (topKey == null) {
System.err.println("ERROR, toplevel key '" + topKeyName + "' not resolved!");
return;
}
if (isRemote) {
System.err.println("REMOTE Key host='" + hostName + "'");
RegistryKey remoteKey = null;
try {
remoteKey = topKey.connectRegistry(hostName);
} catch (NoSuchKeyException ex) {
System.err.println("ERROR No such key connecting to '" + hostName + "', " + ex.getMessage());
return;
} catch (RegistryException ex) {
System.err.println("ERROR errCode=" + ex.getErrorCode() + "' connecting to '" + hostName + "', " + ex.getMessage());
return;
}
if (remoteKey != null) {
topKey = remoteKey;
}
}
//
// P R O C E S S C O M M A N D S
//
if (argv[0].equalsIgnoreCase("create")) {
Registry.createCommand(topKey, keyName);
} else if (argv[0].equalsIgnoreCase("setbin")) {
Registry.setBinaryCommand(topKey, keyName, argv[2], argv[3]);
} else if (argv[0].equalsIgnoreCase("setdw")) {
Registry.setBinaryCommand(topKey, keyName, argv[2], argv[3]);
} else if (argv[0].equalsIgnoreCase("setstr")) {
Registry.setStringCommand(topKey, keyName, argv[2], argv[3]);
} else if (argv[0].equalsIgnoreCase("setmulti")) {
Registry.setMultiStringCommand(topKey, keyName, argv[2], argv[3]);
} else if (argv[0].equalsIgnoreCase("keys")) {
Registry.listKeysCommand(topKey, keyName);
} else if (argv[0].equalsIgnoreCase("values")) {
Registry.listValuesCommand(topKey, keyName);
} else if (argv[0].equalsIgnoreCase("delkey")) {
Registry.deleteKeyCommand(topKey, keyName, argv[2]);
} else if (argv[0].equalsIgnoreCase("delval")) {
Registry.deleteValueCommand(topKey, keyName, argv[2]);
} else if (argv[0].equalsIgnoreCase("data")) {
Registry.getDataCommand(topKey, keyName, argv[2]);
} else if (argv[0].equalsIgnoreCase("string")) {
Registry.getStringCommand(topKey, keyName, argv[2]);
} else if (argv[0].equalsIgnoreCase("export")) {
Registry.exportKeyCommand(topKey, keyName, argv[2]);
} else if (argv[0].equalsIgnoreCase("expand")) {
Registry.expandStringCommand(topKey, keyName, argv[2]);
}
}
private static void exportKeyCommand(RegistryKey topKey, String keyName, String pathName) {
RegistryKey subKey = Registry.openSubKeyVerbose(topKey, keyName, RegistryKey.ACCESS_READ);
if (subKey == null)
return;
try {
Registry.exportRegistryKey(pathName, subKey, true);
} catch (IOException ex) {
System.err.println("IO Exception: '" + ex.getMessage() + "'");
} catch (NoSuchKeyException ex) {
System.err.println("Error, encountered non-existent key during export.");
} catch (RegistryException ex) {
System.err.println("ERROR registry error=" + ex.getErrorCode() + ", " + ex.getMessage());
}
}
private static void getDataCommand(RegistryKey topKey, String keyName, String valueName) {
RegistryKey subKey = Registry.openSubKeyVerbose(topKey, keyName, RegistryKey.ACCESS_READ);
if (subKey == null)
return;
RegistryValue data = null;
try {
data = subKey.getValue(valueName);
} catch (NoSuchValueException ex) {
System.err.println("Value '" + valueName + "' does not exist.");
return;
} catch (RegistryException ex) {
System.err.println("ERROR registry error=" + ex.getErrorCode() + ", " + ex.getMessage());
return;
}
System.err.println("Value '" + valueName + "' is " + data.toString());
if (data instanceof RegStringValue) {
RegStringValue val = (RegStringValue) data;
System.err.println("REG_SZ '" + val.getData() + "'");
} else if (data instanceof RegMultiStringValue) {
RegMultiStringValue val = (RegMultiStringValue) data;
String[] args = val.getData();
for (int idx = 0; idx < args.length; ++idx)
System.err.println("REG_MULTI_SZ[" + idx + "] '" + args[idx] + "'");
} else if (data instanceof RegDWordValue) {
RegDWordValue val = (RegDWordValue) data;
HexNumberFormat xFmt = new HexNumberFormat("XXXXXXXX");
System.err.println("REG_DWORD" + ((RegistryValue.REG_DWORD_BIG_ENDIAN == val.getType()) ? "_BIG_ENDIAN" : "") + " '" + val.getData() + "' [x" + xFmt.format(val.getData()) + "]");
} else {
RegBinaryValue val = (RegBinaryValue) data;
/*
* System.err.println( "BINARY: len=" + val.getLength() );
* System.err.println( "BINARY: [0]=" + val.getData()[0] );
* System.err.println( "BINARY: [1]=" + val.getData()[1] );
* System.err.println( "BINARY: [2]=" + val.getData()[2] );
* System.err.println( "BINARY: [3]=" + val.getData()[3] );
*/
Registry.dumpHexData(System.err, "REG_BINARY '" + val.getName() + "', len=" + val.getLength(), val.getData(), val.getLength());
}
}
private static void getStringCommand(RegistryKey topKey, String keyName, String valueName) {
RegistryKey subKey = Registry.openSubKeyVerbose(topKey, keyName, RegistryKey.ACCESS_READ);
if (subKey == null)
return;
try {
String value = subKey.getStringValue(valueName);
System.err.println("String Value " + valueName + "='" + value + "'");
} catch (RegistryException ex) {
System.err.println("ERROR getting value '" + valueName + "', " + ex.getMessage());
return;
}
}
private static void expandStringCommand(RegistryKey topKey, String keyName, String valueName) {
RegistryKey subKey = Registry.openSubKeyVerbose(topKey, keyName, RegistryKey.ACCESS_READ);
if (subKey == null)
return;
try {
String value = subKey.getStringValue(valueName);
System.err.println("String Value " + valueName + "='" + value + "'");
value = RegistryKey.expandEnvStrings(value);
System.err.println("Expanded Value " + valueName + "='" + value + "'");
} catch (RegistryException ex) {
System.err.println("ERROR getting value '" + valueName + "', " + ex.getMessage());
return;
}
}
private static void deleteKeyCommand(RegistryKey topKey, String keyName, String deleteKeyName) {
RegistryKey subKey = Registry.openSubKeyVerbose(topKey, keyName, RegistryKey.ACCESS_WRITE);
if (subKey == null)
return;
try {
subKey.deleteSubKey(deleteKeyName);
} catch (NoSuchKeyException ex) {
System.err.println("Key '" + keyName + "\\" + deleteKeyName + "' does not exist.");
return;
} catch (RegistryException ex) {
System.err.println("ERROR deleting key '" + keyName + "', " + ex.getMessage());
return;
}
}
private static void deleteValueCommand(RegistryKey topKey, String keyName, String valueName) {
RegistryKey subKey = Registry.openSubKeyVerbose(topKey, keyName, RegistryKey.ACCESS_WRITE);
if (subKey == null)
return;
try {
subKey.deleteValue(valueName);
} catch (NoSuchValueException ex) {
System.err.println("Value '" + valueName + "' does not exist.");
return;
} catch (RegistryException ex) {
System.err.println("ERROR deleting value '" + valueName + "', " + ex.getMessage());
return;
}
}
private static void listKeysCommand(RegistryKey topKey, String keyName) {
RegistryKey subKey = Registry.openSubKeyVerbose(topKey, keyName, RegistryKey.ACCESS_READ);
if (subKey == null)
return;
try {
Enumeration enumer = subKey.keyElements();
for (int kIdx = 0; enumer.hasMoreElements(); ++kIdx) {
String keyStr = (String) enumer.nextElement();
System.err.println("Subkey[" + kIdx + "] = '" + keyStr + "'");
}
} catch (RegistryException ex) {
System.err.println("ERROR getting key enumerator, " + ex.getMessage());
return;
}
}
private static void listValuesCommand(RegistryKey topKey, String keyName) {
RegistryKey subKey = Registry.openSubKeyVerbose(topKey, keyName, RegistryKey.ACCESS_READ);
if (subKey == null)
return;
try {
Enumeration enumer = subKey.valueElements();
for (int kIdx = 0; enumer.hasMoreElements(); ++kIdx) {
String name = (String) enumer.nextElement();
System.err.println("Value Name[" + kIdx + "] = '" + name + "'");
}
} catch (RegistryException ex) {
System.err.println("ERROR getting value enumerator, " + ex.getMessage());
return;
}
}
private static void setMultiStringCommand(RegistryKey topKey, String keyName, String valueName, String data) {
RegistryKey subKey = Registry.openSubKeyVerbose(topKey, keyName, RegistryKey.ACCESS_WRITE);
if (subKey == null)
return;
String[] strArray = Registry.splitString(data, ";");
RegMultiStringValue val = new RegMultiStringValue(subKey, valueName, strArray);
Registry.setValue(subKey, val);
}
private static void setStringCommand(RegistryKey topKey, String keyName, String valueName, String data) {
RegistryKey subKey = Registry.openSubKeyVerbose(topKey, keyName, RegistryKey.ACCESS_WRITE);
if (subKey == null)
return;
RegStringValue val = new RegStringValue(subKey, valueName, data);
Registry.setValue(subKey, val);
}
private static void setBinaryCommand(RegistryKey topKey, String keyName, String valueName, String data) {
RegistryKey subKey = Registry.openSubKeyVerbose(topKey, keyName, RegistryKey.ACCESS_WRITE);
if (subKey == null)
return;
byte[] binData = data.getBytes();
RegBinaryValue val = new RegBinaryValue(subKey, valueName, binData);
Registry.setValue(subKey, val);
}
private static void createCommand(RegistryKey topKey, String keyName) {
RegistryKey subKey;
try {
subKey = topKey.createSubKey(keyName, "", RegistryKey.ACCESS_WRITE);
} catch (RegistryException ex) {
subKey = null;
System.err.println("ERROR creating subKey: " + ex.getMessage());
}
if (subKey != null) {
try {
subKey.flushKey();
subKey.closeKey();
} catch (RegistryException ex) {
subKey = null;
System.err.println("ERROR flushing and closing key: " + ex.getMessage());
}
}
if (subKey != null) {
System.err.println("SUCCEEDED " + (subKey.wasCreated() ? "Creating" : "Opening via create") + " Key '" + keyName + "'");
} else {
System.err.println("FAILED Creating Key '" + keyName + "'");
}
}
private static RegistryKey openSubKeyVerbose(RegistryKey topKey, String keyName, int access) {
RegistryKey subKey = null;
try {
subKey = topKey.openSubKey(keyName, access);
} catch (NoSuchKeyException ex) {
subKey = null;
System.err.println("Key '" + keyName + "' does not exist.");
} catch (RegistryException ex) {
subKey = null;
System.err.println("ERROR registry error=" + ex.getErrorCode() + ", " + ex.getMessage());
}
return subKey;
}
private static void setValue(RegistryKey subKey, RegistryValue value) {
try {
subKey.setValue(value);
subKey.flushKey();
} catch (RegistryException ex) {
System.err.println("ERROR setting MULTI_SZ value '" + value.getName() + "', " + ex.getMessage());
}
}
public static void dumpHexData(PrintStream out, String title, byte[] buf, int numBytes) {
PrintWriter wrtr = new PrintWriter(new OutputStreamWriter(out));
Registry.dumpHexData(wrtr, title, buf, 0, numBytes);
}
public static void dumpHexData(PrintWriter out, String title, byte[] buf, int offset, int numBytes) {
int rows, residue, i, j;
byte[] save_buf = new byte[ROW_BYTES + 2];
char[] hex_buf = new char[4];
char[] idx_buf = new char[8];
char[] hex_chars = new char[20];
hex_chars[0] = '0';
hex_chars[1] = '1';
hex_chars[2] = '2';
hex_chars[3] = '3';
hex_chars[4] = '4';
hex_chars[5] = '5';
hex_chars[6] = '6';
hex_chars[7] = '7';
hex_chars[8] = '8';
hex_chars[9] = '9';
hex_chars[10] = 'A';
hex_chars[11] = 'B';
hex_chars[12] = 'C';
hex_chars[13] = 'D';
hex_chars[14] = 'E';
hex_chars[15] = 'F';
out.println(title + " - " + numBytes + " bytes.");
rows = (numBytes + (ROW_BYTES - 1)) / ROW_BYTES;
residue = (numBytes % ROW_BYTES);
for (i = 0; i < rows; i++) {
int hexVal = (i * ROW_BYTES);
idx_buf[0] = hex_chars[((hexVal >> 12) & 15)];
idx_buf[1] = hex_chars[((hexVal >> 8) & 15)];
idx_buf[2] = hex_chars[((hexVal >> 4) & 15)];
idx_buf[3] = hex_chars[(hexVal & 15)];
String idxStr = new String(idx_buf, 0, 4);
out.print(idxStr + ": ");
for (j = 0; j < ROW_BYTES; j++) {
if (i == (rows - 1) && j >= residue) {
save_buf[j] = ' ';
out.print(" ");
if (j == ROW_QTR1 || j == ROW_HALF || j == ROW_QTR2)
out.print(' ');
} else {
save_buf[j] = buf[offset + (i * ROW_BYTES) + j];
hex_buf[0] = hex_chars[(save_buf[j] >> 4) & 0x0F];
hex_buf[1] = hex_chars[save_buf[j] & 0x0F];
out.print(hex_buf[0]);
out.print(hex_buf[1]);
out.print(' ');
if (j == ROW_QTR1 || j == ROW_HALF || j == ROW_QTR2)
out.print(' ');
if (save_buf[j] < 0x20 || save_buf[j] > 0x7E)
save_buf[j] = (byte) '.';
}
}
String saveStr = new String(save_buf, 0, j);
out.println(" | " + saveStr + " |");
}
out.flush();
}
/**
* Split a string into a string array containing the substrings between the
* delimiters.
*
* NOTE This method WILL <strong>NOT</strong> return an empty token at the
* end of the array that is returned, if the string ends with the delimiter.
* If you wish to have a property string array that ends with the delimiter
* return an empty string at the end of the array, use
* <code>vectorString()</code>.
*/
static public String[] splitString(String splitStr, String delim) {
int i, count;
String[] result;
StringTokenizer toker;
toker = new StringTokenizer(splitStr, delim);
count = toker.countTokens();
result = new String[count];
for (i = 0; i < count; ++i) {
try {
result[i] = toker.nextToken();
} catch (NoSuchElementException ex) {
result = null;
break;
}
}
return result;
}
public static String[] parseArgumentString(String argStr) {
String[] result = null;
Vector vector = Registry.parseArgumentVector(argStr);
if (vector != null && vector.size() > 0) {
result = new String[vector.size()];
vector.copyInto(result);
}
return result;
}
public static Vector parseArgumentVector(String argStr) {
Vector result = new Vector();
StringBuilder argBuf = new StringBuilder();
boolean backSlash = false;
boolean matchSglQuote = false;
boolean matchDblQuote = false;
for (int cIdx = 0; cIdx < argStr.length(); ++cIdx) {
char ch = argStr.charAt(cIdx);
switch (ch) {
//
// W H I T E S P A C E
//
case ' ':
case '\t':
case '\n':
case '\r':
if (backSlash) {
argBuf.append(ch);
backSlash = false;
} else if (matchSglQuote || matchDblQuote) {
argBuf.append(ch);
} else if (argBuf.length() > 0) {
result.addElement(argBuf.toString());
argBuf.setLength(0);
}
break;
case '\\':
if (backSlash) {
argBuf.append("\\");
}
backSlash = !backSlash;
break;
case '\'':
if (backSlash) {
argBuf.append("'");
backSlash = false;
} else if (matchSglQuote) {
result.addElement(argBuf.toString());
argBuf.setLength(0);
matchSglQuote = false;
} else if (!matchDblQuote) {
matchSglQuote = true;
}
break;
case '"':
if (backSlash) {
argBuf.append("\"");
backSlash = false;
} else if (matchDblQuote) {
result.addElement(argBuf.toString());
argBuf.setLength(0);
matchDblQuote = false;
} else if (!matchSglQuote) {
matchDblQuote = true;
}
break;
default:
if (backSlash) {
switch (ch) {
case 'b':
argBuf.append('\b');
break;
case 'f':
argBuf.append('\f');
break;
case 'n':
argBuf.append('\n');
break;
case 'r':
argBuf.append('\r');
break;
case 't':
argBuf.append('\t');
break;
default:
char ch2 = argStr.charAt(cIdx + 1);
char ch3 = argStr.charAt(cIdx + 2);
if ((ch >= '0' && ch <= '7') && (ch2 >= '0' && ch2 <= '7') && (ch3 >= '0' && ch3 <= '7')) {
int octal = (((ch - '0') * 64) + ((ch2 - '0') * 8) + (ch3 - '0'));
argBuf.append((char) octal);
cIdx += 2;
} else if (ch == '0') {
argBuf.append('\0');
} else {
argBuf.append(ch);
}
break;
}
} else {
argBuf.append(ch);
}
backSlash = false;
break;
}
}
if (argBuf.length() > 0) {
result.addElement(argBuf.toString());
}
return result;
}
}