/* * File : Registry.java * Project : ClickAgent * Created : Nov 25, 2007 @ 8:40:44 AM by huhlig * * Registry.java is part of the ClickAgent source distribution and * is Copyright (2007) by Hans Uhlig of Click Consulting, Inc. * All Rights Reserved. */ package com.clickconsulting.Win32API; import java.io.IOException; import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.HashMap; import org.jawin.COMError; import org.jawin.COMException; import org.jawin.FuncPtr; import org.jawin.ReturnFlags; import org.jawin.io.LittleEndianInputStream; import org.jawin.io.LittleEndianOutputStream; import org.jawin.io.NakedByteStream; import org.jawin.marshal.StructConverter; /** * TODO: Write Documentation for com.clickconsulting.ccnms.Win32API Registry * * @author Hans W. Uhlig * @since Nov 25, 2007 */ public class Registry { public class RegistryEntry { public final byte[] rawValue; public final String stringValue; public final String pathToKey; public RegistryEntry(String pathToKey, byte[] rawValue, String stringValue) { this.pathToKey = pathToKey; this.rawValue = rawValue; this.stringValue = stringValue; } } public static final HashMap HiveKeys; public static final int HKEY_CLASSES_ROOT =0x80000000; public static final int HKEY_CURRENT_USER =0x80000001; public static final int HKEY_LOCAL_MACHINE =0x80000002; public static final int HKEY_USERS =0x80000003; public static final int HKEY_PERFORMANCE_DATA =0x80000004; public static final int HKEY_CURRENT_CONFIG =0x80000005; public static final int HKEY_DYN_DATA =0x80000006; static private final FuncPtr fpOpenKey; static private final FuncPtr fpQueryValue; static private final FuncPtr fpCloseKey; static private final FuncPtr fpCreateKey; static private final FuncPtr fpDeleteKey; static private final FuncPtr fpEnumKey; static private final FuncPtr fpEnumValue; static { try { // Define our Functions fpOpenKey = new FuncPtr("ADVAPI32.DLL", "RegOpenKeyW"); fpQueryValue = new FuncPtr("ADVAPI32.DLL", "RegQueryValueExW"); fpCloseKey = new FuncPtr("ADVAPI32.DLL", "RegCloseKey"); fpCreateKey = new FuncPtr("ADVAPI32.DLL", "RegCreateKeyW"); fpDeleteKey = new FuncPtr("ADVAPI32.DLL", "RegDeleteKeyW"); fpEnumKey = new FuncPtr("ADVAPI32.DLL", "RegEnumKeyW"); fpEnumValue = new FuncPtr("ADVAPI32.DLL", "RegEnumValueW"); // Load HiveKeys into Map HiveKeys=new HashMap(); HiveKeys.put("HKEY_CLASSES_ROOT", new Integer(0x80000000)); HiveKeys.put("HKEY_CURRENT_USER", new Integer(0x80000001)); HiveKeys.put("HKEY_LOCAL_MACHINE", new Integer(0x80000002)); HiveKeys.put("HKEY_USERS", new Integer(0x80000003)); HiveKeys.put("HKEY_PERFORMANCE_DATA", new Integer(0x80000004)); HiveKeys.put("HKEY_CURRENT_CONFIG", new Integer(0x80000005)); HiveKeys.put("HKEY_DYN_DATA", new Integer(0x80000006)); } catch (COMException e) { throw new COMError("Unable to Initialize Registry."); } } /** * * TODO: Write Documentation for OpenKey * @deprecated * @param hivekey * @param subkey * @return * @throws IOException * @throws COMException */ public static int OpenKey(int hivekey, String subkey) throws IOException, COMException { return fpOpenKey.invoke_OI(hivekey, subkey, ReturnFlags.CHECK_W32); } /** * * TODO: Write Documentation for CreateKey * @deprecated * * @param hivekey * @param subkey * @return * @throws IOException * @throws COMException */ public static int CreateKey(int hivekey, String subkey) throws IOException, COMException { return fpCreateKey.invoke_OI(hivekey, subkey, ReturnFlags.CHECK_W32); } /** * * TODO: Write Documentation for DeleteKey * @deprecated * @param hivekey * @param subkey * @throws IOException * @throws COMException */ public static void DeleteKey(int hivekey, String subkey) throws IOException, COMException { fpDeleteKey.invoke_I(hivekey, subkey, ReturnFlags.CHECK_W32); } /** * * TODO: Write Documentation for CloseKey * @deprecated * * @param key * @throws IOException * @throws COMException */ public static void CloseKey(int key) throws IOException, COMException { fpCloseKey.invoke_I(key, ReturnFlags.CHECK_W32); } /** * * TODO: Write Documentation for QueryKey * @param path * @return */ public static RegistryEntry QueryKey(String path) { byte[] rawValue; String stringValue=""; // Seperate out Path to Key, First entry is Hive, Last Entry is key int hivekeyDelimiter = path.indexOf("\\"); int subkeyDelimiter = path.lastIndexOf("\\"); if(!HiveKeys.containsKey(path.substring(0,hivekeyDelimiter-1))) {throw new COMError("Unknown Hive");} // Neccessary Peices here int hivekey = HiveKeys.get(path.substring(0,hivekeyDelimiter-1)); String subkey = path.substring(subkeyDelimiter); String pathToKey = path.substring(hivekeyDelimiter+1, subkeyDelimiter+1); try { /* * First lets open the Key */ int key = fpOpenKey.invoke_OI(hivekey, pathToKey, ReturnFlags.CHECK_W32); /* * Then we query it */ NakedByteStream nbs = new NakedByteStream(); LittleEndianOutputStream leos = new LittleEndianOutputStream(nbs); LittleEndianInputStream leis; // top level args leos.writeInt(key); leos.writeStringUnicode(subkey); leos.writeInt(0); //reserved leos.writeInt(0); //type (ignore) // Fetch Raw Value byte[] sizeRes = fpQueryValue.invoke("IGIIkA:T7:L20n4", 24, nbs, null, ReturnFlags.CHECK_NONE); // to get the buffer size int size = StructConverter.bytesIntoInt(sizeRes, 0); leos.writeInt(size); rawValue = fpQueryValue.invoke("IGIIM" + size +"P4:T7:L16n" + size, 24, nbs, null, ReturnFlags.CHECK_W32); // Convert Raw Value to String Value leis = new LittleEndianInputStream(new ByteArrayInputStream(rawValue)); stringValue = leis.readUnicodeSz(rawValue.length/2); /* * Then we Close it */ fpCloseKey.invoke_I(key, ReturnFlags.CHECK_W32); } catch (IOException e) { throw new COMError("IOException: "+e.getMessage()); } catch (COMException e) { throw new COMError("COMException: "+e.getMessage()); } return new RegistryEntry(path,rawValue,stringValue); } /** * * TODO: Write Documentation for QueryStringValue * * @deprecated * @param key * @param subkey * @return */ public static String QueryStringValue(int key, String subkey) { byte[] raw; try { raw = QueryRawValue(key, subkey); LittleEndianInputStream leis = new LittleEndianInputStream(new ByteArrayInputStream(raw)); return leis.readUnicodeSz(raw.length/2); } catch (IOException e) { } catch (COMException e) { } return null; } /** * * TODO: Write Documentation for QueryRawValue * * @deprecated * @param key * @param subkey * @return * @throws IOException * @throws COMException */ public static byte[] QueryRawValue(int key, String subkey) throws IOException, COMException { NakedByteStream nbs = new NakedByteStream(); LittleEndianOutputStream leos = new LittleEndianOutputStream(nbs); // top level args leos.writeInt(key); leos.writeStringUnicode(subkey); leos.writeInt(0); //reserved leos.writeInt(0); //type (ignore) byte[] sizeRes = fpQueryValue.invoke("IGIIkA:T7:L20n4", 24, nbs, null, ReturnFlags.CHECK_NONE); // to get the buffer size int size = StructConverter.bytesIntoInt(sizeRes, 0); leos.writeInt(size); byte[] res = fpQueryValue.invoke("IGIIM" + size +"P4:T7:L16n" + size, 24, nbs, null, ReturnFlags.CHECK_W32); return res; } public static String RegEnumKey(int key, int index) throws Exception { NakedByteStream nbs = new NakedByteStream(); LittleEndianOutputStream leos = new LittleEndianOutputStream(nbs); int size = 520; // top level args leos.writeInt(key); leos.writeInt(index); leos.writeInt(size); byte[] result; try { result = fpEnumKey.invoke("IIM" + size + "I:T7:L8n" + size, 16, nbs, null, ReturnFlags.CHECK_W32); } catch (COMException e) { if (e.hresult == 0x80070103) { return null; } throw e; } LittleEndianInputStream leis = new LittleEndianInputStream(new ByteArrayInputStream(result)); return leis.readUnicodeSz(result.length / 2); } public static String RegEnumValue(int key, int index) throws Exception { NakedByteStream nbs = new NakedByteStream(); LittleEndianOutputStream leos = new LittleEndianOutputStream(nbs); int size = 520; // top level args leos.writeInt(key); leos.writeInt(index); leos.writeInt(size); byte[] result; try { result = fpEnumValue.invoke("IIA" + size + "I:T7:L8n" + size, 32, nbs, null, ReturnFlags.CHECK_W32); } catch (COMException e) { if (e.hresult == 0x80070103) { return null; } throw e; } LittleEndianInputStream leis = new LittleEndianInputStream(new ByteArrayInputStream(result)); return leis.readUnicodeSz(result.length / 2); } }