[594] | 1 | package net.oni2.aeinstaller.backend;
|
---|
| 2 |
|
---|
| 3 | import java.lang.reflect.InvocationTargetException;
|
---|
| 4 | import java.lang.reflect.Method;
|
---|
| 5 | import java.util.ArrayList;
|
---|
| 6 | import java.util.HashMap;
|
---|
| 7 | import java.util.List;
|
---|
| 8 | import java.util.Map;
|
---|
| 9 | import java.util.prefs.Preferences;
|
---|
| 10 |
|
---|
| 11 | /**
|
---|
| 12 | * @author Unknown
|
---|
| 13 | */
|
---|
| 14 | public class WinRegistry {
|
---|
| 15 | /**
|
---|
| 16 | * Constant for accessing HKCU
|
---|
| 17 | */
|
---|
| 18 | public static final int HKEY_CURRENT_USER = 0x80000001;
|
---|
| 19 | /**
|
---|
| 20 | * Constant for accessing HKLM
|
---|
| 21 | */
|
---|
| 22 | public static final int HKEY_LOCAL_MACHINE = 0x80000002;
|
---|
| 23 | /**
|
---|
| 24 | * Constant for successful accesses
|
---|
| 25 | */
|
---|
| 26 | public static final int REG_SUCCESS = 0;
|
---|
| 27 | /**
|
---|
| 28 | * Constant for not found
|
---|
| 29 | */
|
---|
| 30 | public static final int REG_NOTFOUND = 2;
|
---|
| 31 | /**
|
---|
| 32 | * Constant for access denied
|
---|
| 33 | */
|
---|
| 34 | public static final int REG_ACCESSDENIED = 5;
|
---|
| 35 |
|
---|
| 36 | /**
|
---|
| 37 | * Access 32bit registry view when running as 64bit application
|
---|
| 38 | */
|
---|
| 39 | public static final int KEY_WOW64_32KEY = 0x0200;
|
---|
| 40 | /**
|
---|
| 41 | * Access 64bit registry view when running as 32bit application
|
---|
| 42 | */
|
---|
| 43 | public static final int KEY_WOW64_64KEY = 0x0100;
|
---|
| 44 |
|
---|
| 45 | private static final int KEY_ALL_ACCESS = 0xf003f;
|
---|
| 46 | private static final int KEY_READ = 0x20019;
|
---|
| 47 | private static Preferences userRoot = Preferences.userRoot();
|
---|
| 48 | private static Preferences systemRoot = Preferences.systemRoot();
|
---|
| 49 | private static Class<? extends Preferences> userClass = userRoot.getClass();
|
---|
| 50 | private static Method regOpenKey = null;
|
---|
| 51 | private static Method regCloseKey = null;
|
---|
| 52 | private static Method regQueryValueEx = null;
|
---|
| 53 | private static Method regEnumValue = null;
|
---|
| 54 | private static Method regQueryInfoKey = null;
|
---|
| 55 | private static Method regEnumKeyEx = null;
|
---|
| 56 | private static Method regCreateKeyEx = null;
|
---|
| 57 | private static Method regSetValueEx = null;
|
---|
| 58 | private static Method regDeleteKey = null;
|
---|
| 59 | private static Method regDeleteValue = null;
|
---|
| 60 |
|
---|
| 61 | private static boolean usable = false;
|
---|
| 62 |
|
---|
| 63 | static {
|
---|
| 64 | try {
|
---|
| 65 | regOpenKey = userClass.getDeclaredMethod("WindowsRegOpenKey",
|
---|
| 66 | new Class[] { int.class, byte[].class, int.class });
|
---|
| 67 | regOpenKey.setAccessible(true);
|
---|
| 68 | regCloseKey = userClass.getDeclaredMethod("WindowsRegCloseKey",
|
---|
| 69 | new Class[] { int.class });
|
---|
| 70 | regCloseKey.setAccessible(true);
|
---|
| 71 | regQueryValueEx = userClass.getDeclaredMethod(
|
---|
| 72 | "WindowsRegQueryValueEx", new Class[] { int.class,
|
---|
| 73 | byte[].class });
|
---|
| 74 | regQueryValueEx.setAccessible(true);
|
---|
| 75 | regEnumValue = userClass.getDeclaredMethod("WindowsRegEnumValue",
|
---|
| 76 | new Class[] { int.class, int.class, int.class });
|
---|
| 77 | regEnumValue.setAccessible(true);
|
---|
| 78 | regQueryInfoKey = userClass.getDeclaredMethod(
|
---|
| 79 | "WindowsRegQueryInfoKey1", new Class[] { int.class });
|
---|
| 80 | regQueryInfoKey.setAccessible(true);
|
---|
| 81 | regEnumKeyEx = userClass.getDeclaredMethod("WindowsRegEnumKeyEx",
|
---|
| 82 | new Class[] { int.class, int.class, int.class });
|
---|
| 83 | regEnumKeyEx.setAccessible(true);
|
---|
| 84 | regCreateKeyEx = userClass.getDeclaredMethod(
|
---|
| 85 | "WindowsRegCreateKeyEx", new Class[] { int.class,
|
---|
| 86 | byte[].class });
|
---|
| 87 | regCreateKeyEx.setAccessible(true);
|
---|
| 88 | regSetValueEx = userClass.getDeclaredMethod("WindowsRegSetValueEx",
|
---|
| 89 | new Class[] { int.class, byte[].class, byte[].class });
|
---|
| 90 | regSetValueEx.setAccessible(true);
|
---|
| 91 | regDeleteValue = userClass.getDeclaredMethod(
|
---|
| 92 | "WindowsRegDeleteValue", new Class[] { int.class,
|
---|
| 93 | byte[].class });
|
---|
| 94 | regDeleteValue.setAccessible(true);
|
---|
| 95 | regDeleteKey = userClass.getDeclaredMethod("WindowsRegDeleteKey",
|
---|
| 96 | new Class[] { int.class, byte[].class });
|
---|
| 97 | regDeleteKey.setAccessible(true);
|
---|
| 98 | usable = true;
|
---|
| 99 | } catch (Exception e) {
|
---|
| 100 | // e.printStackTrace();
|
---|
| 101 | }
|
---|
| 102 | }
|
---|
| 103 |
|
---|
| 104 | private WinRegistry() {
|
---|
| 105 | }
|
---|
| 106 |
|
---|
| 107 | /**
|
---|
| 108 | * Read a value from key and value name
|
---|
| 109 | *
|
---|
| 110 | * @param hkey
|
---|
| 111 | * HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
|
---|
| 112 | * @param key
|
---|
| 113 | * Key to access
|
---|
| 114 | * @param valueName
|
---|
| 115 | * Name of value to read
|
---|
| 116 | * @param wow64
|
---|
| 117 | * 0 for standard registry access (32-bits for 32-bit app,
|
---|
| 118 | * 64-bits for 64-bits app) or KEY_WOW64_32KEY to force access to
|
---|
| 119 | * 32-bit registry view, or KEY_WOW64_64KEY to force access to
|
---|
| 120 | * 64-bit registry view
|
---|
| 121 | * @return the value
|
---|
| 122 | * @throws Exception
|
---|
| 123 | * If registry access impossible
|
---|
| 124 | * @throws IllegalArgumentException
|
---|
| 125 | * On illegal arguments
|
---|
| 126 | * @throws IllegalAccessException
|
---|
| 127 | * On illegal access
|
---|
| 128 | * @throws InvocationTargetException
|
---|
| 129 | * On reflection problems
|
---|
| 130 | */
|
---|
| 131 | public static String readString(int hkey, String key, String valueName,
|
---|
| 132 | int wow64) throws Exception, IllegalArgumentException,
|
---|
| 133 | IllegalAccessException, InvocationTargetException {
|
---|
| 134 | if (!usable)
|
---|
| 135 | throw new Exception(
|
---|
| 136 | "Registry access not supported (not a Windows OS?).");
|
---|
| 137 | if (hkey == HKEY_LOCAL_MACHINE) {
|
---|
| 138 | return readString(systemRoot, hkey, key, valueName, wow64);
|
---|
| 139 | } else if (hkey == HKEY_CURRENT_USER) {
|
---|
| 140 | return readString(userRoot, hkey, key, valueName, wow64);
|
---|
| 141 | } else {
|
---|
| 142 | throw new IllegalArgumentException("hkey=" + hkey);
|
---|
| 143 | }
|
---|
| 144 | }
|
---|
| 145 |
|
---|
| 146 | /**
|
---|
| 147 | * Read value(s) and value name(s) form given key
|
---|
| 148 | *
|
---|
| 149 | * @param hkey
|
---|
| 150 | * HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
|
---|
| 151 | * @param key
|
---|
| 152 | * Key to access
|
---|
| 153 | * @param wow64
|
---|
| 154 | * 0 for standard registry access (32-bits for 32-bit app,
|
---|
| 155 | * 64-bits for 64-bits app) or KEY_WOW64_32KEY to force access to
|
---|
| 156 | * 32-bit registry view, or KEY_WOW64_64KEY to force access to
|
---|
| 157 | * 64-bit registry view
|
---|
| 158 | * @return the value name(s) plus the value(s)
|
---|
| 159 | * @throws Exception
|
---|
| 160 | * If registry access impossible
|
---|
| 161 | * @throws IllegalArgumentException
|
---|
| 162 | * On illegal arguments
|
---|
| 163 | * @throws IllegalAccessException
|
---|
| 164 | * On illegal access
|
---|
| 165 | * @throws InvocationTargetException
|
---|
| 166 | * On reflection problems
|
---|
| 167 | */
|
---|
| 168 | public static Map<String, String> readStringValues(int hkey, String key,
|
---|
| 169 | int wow64) throws Exception, IllegalArgumentException,
|
---|
| 170 | IllegalAccessException, InvocationTargetException {
|
---|
| 171 | if (!usable)
|
---|
| 172 | throw new Exception(
|
---|
| 173 | "Registry access not supported (not a Windows OS?).");
|
---|
| 174 | if (hkey == HKEY_LOCAL_MACHINE) {
|
---|
| 175 | return readStringValues(systemRoot, hkey, key, wow64);
|
---|
| 176 | } else if (hkey == HKEY_CURRENT_USER) {
|
---|
| 177 | return readStringValues(userRoot, hkey, key, wow64);
|
---|
| 178 | } else {
|
---|
| 179 | throw new IllegalArgumentException("hkey=" + hkey);
|
---|
| 180 | }
|
---|
| 181 | }
|
---|
| 182 |
|
---|
| 183 | /**
|
---|
| 184 | * Read the value name(s) from a given key
|
---|
| 185 | *
|
---|
| 186 | * @param hkey
|
---|
| 187 | * HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
|
---|
| 188 | * @param key
|
---|
| 189 | * Key to access
|
---|
| 190 | * @param wow64
|
---|
| 191 | * 0 for standard registry access (32-bits for 32-bit app,
|
---|
| 192 | * 64-bits for 64-bits app) or KEY_WOW64_32KEY to force access to
|
---|
| 193 | * 32-bit registry view, or KEY_WOW64_64KEY to force access to
|
---|
| 194 | * 64-bit registry view
|
---|
| 195 | * @return the value name(s)
|
---|
| 196 | * @throws Exception
|
---|
| 197 | * If registry access impossible
|
---|
| 198 | * @throws IllegalArgumentException
|
---|
| 199 | * On illegal arguments
|
---|
| 200 | * @throws IllegalAccessException
|
---|
| 201 | * On illegal access
|
---|
| 202 | * @throws InvocationTargetException
|
---|
| 203 | * On reflection problems
|
---|
| 204 | */
|
---|
| 205 | public static List<String> readStringSubKeys(int hkey, String key, int wow64)
|
---|
| 206 | throws Exception, IllegalArgumentException, IllegalAccessException,
|
---|
| 207 | InvocationTargetException {
|
---|
| 208 | if (!usable)
|
---|
| 209 | throw new Exception(
|
---|
| 210 | "Registry access not supported (not a Windows OS?).");
|
---|
| 211 | if (hkey == HKEY_LOCAL_MACHINE) {
|
---|
| 212 | return readStringSubKeys(systemRoot, hkey, key, wow64);
|
---|
| 213 | } else if (hkey == HKEY_CURRENT_USER) {
|
---|
| 214 | return readStringSubKeys(userRoot, hkey, key, wow64);
|
---|
| 215 | } else {
|
---|
| 216 | throw new IllegalArgumentException("hkey=" + hkey);
|
---|
| 217 | }
|
---|
| 218 | }
|
---|
| 219 |
|
---|
| 220 | /**
|
---|
| 221 | * Create a key
|
---|
| 222 | *
|
---|
| 223 | * @param hkey
|
---|
| 224 | * HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
|
---|
| 225 | * @param key
|
---|
| 226 | * Key to access
|
---|
| 227 | * @throws Exception
|
---|
| 228 | * If registry access impossible
|
---|
| 229 | * @throws IllegalArgumentException
|
---|
| 230 | * On illegal arguments
|
---|
| 231 | * @throws IllegalAccessException
|
---|
| 232 | * On illegal access
|
---|
| 233 | * @throws InvocationTargetException
|
---|
| 234 | * On reflection problems
|
---|
| 235 | */
|
---|
| 236 | public static void createKey(int hkey, String key) throws Exception,
|
---|
| 237 | IllegalArgumentException, IllegalAccessException,
|
---|
| 238 | InvocationTargetException {
|
---|
| 239 | int[] ret;
|
---|
| 240 | if (!usable)
|
---|
| 241 | throw new Exception(
|
---|
| 242 | "Registry access not supported (not a Windows OS?).");
|
---|
| 243 | if (hkey == HKEY_LOCAL_MACHINE) {
|
---|
| 244 | ret = createKey(systemRoot, hkey, key);
|
---|
| 245 | regCloseKey
|
---|
| 246 | .invoke(systemRoot, new Object[] { new Integer(ret[0]) });
|
---|
| 247 | } else if (hkey == HKEY_CURRENT_USER) {
|
---|
| 248 | ret = createKey(userRoot, hkey, key);
|
---|
| 249 | regCloseKey.invoke(userRoot, new Object[] { new Integer(ret[0]) });
|
---|
| 250 | } else {
|
---|
| 251 | throw new IllegalArgumentException("hkey=" + hkey);
|
---|
| 252 | }
|
---|
| 253 | if (ret[1] != REG_SUCCESS) {
|
---|
| 254 | throw new IllegalArgumentException("rc=" + ret[1] + " key=" + key);
|
---|
| 255 | }
|
---|
| 256 | }
|
---|
| 257 |
|
---|
| 258 | /**
|
---|
| 259 | * Write a value in a given key/value name
|
---|
| 260 | *
|
---|
| 261 | * @param hkey
|
---|
| 262 | * HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
|
---|
| 263 | * @param key
|
---|
| 264 | * Key to access
|
---|
| 265 | * @param valueName
|
---|
| 266 | * Name of value to write to
|
---|
| 267 | * @param value
|
---|
| 268 | * String to write
|
---|
| 269 | * @param wow64
|
---|
| 270 | * 0 for standard registry access (32-bits for 32-bit app,
|
---|
| 271 | * 64-bits for 64-bits app) or KEY_WOW64_32KEY to force access to
|
---|
| 272 | * 32-bit registry view, or KEY_WOW64_64KEY to force access to
|
---|
| 273 | * 64-bit registry view
|
---|
| 274 | * @throws Exception
|
---|
| 275 | * If registry access impossible
|
---|
| 276 | * @throws IllegalArgumentException
|
---|
| 277 | * On illegal arguments
|
---|
| 278 | * @throws IllegalAccessException
|
---|
| 279 | * On illegal access
|
---|
| 280 | * @throws InvocationTargetException
|
---|
| 281 | * On reflection problems
|
---|
| 282 | */
|
---|
| 283 | public static void writeStringValue(int hkey, String key, String valueName,
|
---|
| 284 | String value, int wow64) throws Exception,
|
---|
| 285 | IllegalArgumentException, IllegalAccessException,
|
---|
| 286 | InvocationTargetException {
|
---|
| 287 | if (!usable)
|
---|
| 288 | throw new Exception(
|
---|
| 289 | "Registry access not supported (not a Windows OS?).");
|
---|
| 290 | if (hkey == HKEY_LOCAL_MACHINE) {
|
---|
| 291 | writeStringValue(systemRoot, hkey, key, valueName, value, wow64);
|
---|
| 292 | } else if (hkey == HKEY_CURRENT_USER) {
|
---|
| 293 | writeStringValue(userRoot, hkey, key, valueName, value, wow64);
|
---|
| 294 | } else {
|
---|
| 295 | throw new IllegalArgumentException("hkey=" + hkey);
|
---|
| 296 | }
|
---|
| 297 | }
|
---|
| 298 |
|
---|
| 299 | /**
|
---|
| 300 | * Delete a given key
|
---|
| 301 | *
|
---|
| 302 | * @param hkey
|
---|
| 303 | * HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
|
---|
| 304 | * @param key
|
---|
| 305 | * Key to delete
|
---|
| 306 | * @throws Exception
|
---|
| 307 | * If registry access impossible
|
---|
| 308 | * @throws IllegalArgumentException
|
---|
| 309 | * On illegal arguments
|
---|
| 310 | * @throws IllegalAccessException
|
---|
| 311 | * On illegal access
|
---|
| 312 | * @throws InvocationTargetException
|
---|
| 313 | * On reflection problems
|
---|
| 314 | */
|
---|
| 315 | public static void deleteKey(int hkey, String key) throws Exception,
|
---|
| 316 | IllegalArgumentException, IllegalAccessException,
|
---|
| 317 | InvocationTargetException {
|
---|
| 318 | int rc = -1;
|
---|
| 319 | if (!usable)
|
---|
| 320 | throw new Exception(
|
---|
| 321 | "Registry access not supported (not a Windows OS?).");
|
---|
| 322 | if (hkey == HKEY_LOCAL_MACHINE) {
|
---|
| 323 | rc = deleteKey(systemRoot, hkey, key);
|
---|
| 324 | } else if (hkey == HKEY_CURRENT_USER) {
|
---|
| 325 | rc = deleteKey(userRoot, hkey, key);
|
---|
| 326 | }
|
---|
| 327 | if (rc != REG_SUCCESS) {
|
---|
| 328 | throw new IllegalArgumentException("rc=" + rc + " key=" + key);
|
---|
| 329 | }
|
---|
| 330 | }
|
---|
| 331 |
|
---|
| 332 | /**
|
---|
| 333 | * delete a value from a given key/value name
|
---|
| 334 | *
|
---|
| 335 | * @param hkey
|
---|
| 336 | * HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
|
---|
| 337 | * @param key
|
---|
| 338 | * Key to access
|
---|
| 339 | * @param value
|
---|
| 340 | * Name of value to delete
|
---|
| 341 | * @param wow64
|
---|
| 342 | * 0 for standard registry access (32-bits for 32-bit app,
|
---|
| 343 | * 64-bits for 64-bits app) or KEY_WOW64_32KEY to force access to
|
---|
| 344 | * 32-bit registry view, or KEY_WOW64_64KEY to force access to
|
---|
| 345 | * 64-bit registry view
|
---|
| 346 | * @throws Exception
|
---|
| 347 | * If registry access impossible
|
---|
| 348 | * @throws IllegalArgumentException
|
---|
| 349 | * On illegal arguments
|
---|
| 350 | * @throws IllegalAccessException
|
---|
| 351 | * On illegal access
|
---|
| 352 | * @throws InvocationTargetException
|
---|
| 353 | * On reflection problems
|
---|
| 354 | */
|
---|
| 355 | public static void deleteValue(int hkey, String key, String value, int wow64)
|
---|
| 356 | throws Exception, IllegalArgumentException, IllegalAccessException,
|
---|
| 357 | InvocationTargetException {
|
---|
| 358 | if (!usable)
|
---|
| 359 | throw new Exception(
|
---|
| 360 | "Registry access not supported (not a Windows OS?).");
|
---|
| 361 | int rc = -1;
|
---|
| 362 | if (hkey == HKEY_LOCAL_MACHINE) {
|
---|
| 363 | rc = deleteValue(systemRoot, hkey, key, value, wow64);
|
---|
| 364 | } else if (hkey == HKEY_CURRENT_USER) {
|
---|
| 365 | rc = deleteValue(userRoot, hkey, key, value, wow64);
|
---|
| 366 | }
|
---|
| 367 | if (rc != REG_SUCCESS) {
|
---|
| 368 | throw new IllegalArgumentException("rc=" + rc + " key=" + key
|
---|
| 369 | + " value=" + value);
|
---|
| 370 | }
|
---|
| 371 | }
|
---|
| 372 |
|
---|
| 373 | // ========================================================================
|
---|
| 374 | private static int deleteValue(Preferences root, int hkey, String key,
|
---|
| 375 | String value, int wow64) throws IllegalArgumentException,
|
---|
| 376 | IllegalAccessException, InvocationTargetException {
|
---|
| 377 | int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
|
---|
| 378 | new Integer(hkey), toCstr(key),
|
---|
| 379 | new Integer(KEY_ALL_ACCESS | wow64) });
|
---|
| 380 | if (handles[1] != REG_SUCCESS) {
|
---|
| 381 | return handles[1]; // can be REG_NOTFOUND, REG_ACCESSDENIED
|
---|
| 382 | }
|
---|
| 383 | int rc = ((Integer) regDeleteValue.invoke(root, new Object[] {
|
---|
| 384 | new Integer(handles[0]), toCstr(value) })).intValue();
|
---|
| 385 | regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
|
---|
| 386 | return rc;
|
---|
| 387 | }
|
---|
| 388 |
|
---|
| 389 | // ========================================================================
|
---|
| 390 | private static int deleteKey(Preferences root, int hkey, String key)
|
---|
| 391 | throws IllegalArgumentException, IllegalAccessException,
|
---|
| 392 | InvocationTargetException {
|
---|
| 393 | int rc = ((Integer) regDeleteKey.invoke(root, new Object[] {
|
---|
| 394 | new Integer(hkey), toCstr(key) })).intValue();
|
---|
| 395 | return rc; // can REG_NOTFOUND, REG_ACCESSDENIED, REG_SUCCESS
|
---|
| 396 | }
|
---|
| 397 |
|
---|
| 398 | // ========================================================================
|
---|
| 399 | private static String readString(Preferences root, int hkey, String key,
|
---|
| 400 | String value, int wow64) throws IllegalArgumentException,
|
---|
| 401 | IllegalAccessException, InvocationTargetException {
|
---|
| 402 | int[] handles = (int[]) regOpenKey
|
---|
| 403 | .invoke(root, new Object[] { new Integer(hkey), toCstr(key),
|
---|
| 404 | new Integer(KEY_READ | wow64) });
|
---|
| 405 | if (handles[1] != REG_SUCCESS) {
|
---|
| 406 | return null;
|
---|
| 407 | }
|
---|
| 408 | byte[] valb = (byte[]) regQueryValueEx.invoke(root, new Object[] {
|
---|
| 409 | new Integer(handles[0]), toCstr(value) });
|
---|
| 410 | regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
|
---|
| 411 | return (valb != null ? new String(valb).trim() : null);
|
---|
| 412 | }
|
---|
| 413 |
|
---|
| 414 | // ========================================================================
|
---|
| 415 | private static Map<String, String> readStringValues(Preferences root,
|
---|
| 416 | int hkey, String key, int wow64) throws Exception,
|
---|
| 417 | IllegalArgumentException, IllegalAccessException,
|
---|
| 418 | InvocationTargetException {
|
---|
| 419 | HashMap<String, String> results = new HashMap<String, String>();
|
---|
| 420 | int[] handles = (int[]) regOpenKey
|
---|
| 421 | .invoke(root, new Object[] { new Integer(hkey), toCstr(key),
|
---|
| 422 | new Integer(KEY_READ | wow64) });
|
---|
| 423 | if (handles[1] != REG_SUCCESS) {
|
---|
| 424 | return null;
|
---|
| 425 | }
|
---|
| 426 | int[] info = (int[]) regQueryInfoKey.invoke(root,
|
---|
| 427 | new Object[] { new Integer(handles[0]) });
|
---|
| 428 |
|
---|
| 429 | int count = info[2]; // count
|
---|
| 430 | int maxlen = info[4]; // value length max
|
---|
| 431 | for (int index = 0; index < count; index++) {
|
---|
| 432 | byte[] name = (byte[]) regEnumValue.invoke(root, new Object[] {
|
---|
| 433 | new Integer(handles[0]), new Integer(index),
|
---|
| 434 | new Integer(maxlen + 1) });
|
---|
| 435 | String value = readString(hkey, key, new String(name), wow64);
|
---|
| 436 | results.put(new String(name).trim(), value);
|
---|
| 437 | }
|
---|
| 438 | regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
|
---|
| 439 | return results;
|
---|
| 440 | }
|
---|
| 441 |
|
---|
| 442 | // ========================================================================
|
---|
| 443 | private static List<String> readStringSubKeys(Preferences root, int hkey,
|
---|
| 444 | String key, int wow64) throws IllegalArgumentException,
|
---|
| 445 | IllegalAccessException, InvocationTargetException {
|
---|
| 446 | List<String> results = new ArrayList<String>();
|
---|
| 447 | int[] handles = (int[]) regOpenKey
|
---|
| 448 | .invoke(root, new Object[] { new Integer(hkey), toCstr(key),
|
---|
| 449 | new Integer(KEY_READ | wow64) });
|
---|
| 450 | if (handles[1] != REG_SUCCESS) {
|
---|
| 451 | return null;
|
---|
| 452 | }
|
---|
| 453 | int[] info = (int[]) regQueryInfoKey.invoke(root,
|
---|
| 454 | new Object[] { new Integer(handles[0]) });
|
---|
| 455 |
|
---|
| 456 | int count = info[0]; // Fix: info[2] was being used here with wrong
|
---|
| 457 | // results. Suggested by davenpcj, confirmed by
|
---|
| 458 | // Petrucio
|
---|
| 459 | int maxlen = info[3]; // value length max
|
---|
| 460 | for (int index = 0; index < count; index++) {
|
---|
| 461 | byte[] name = (byte[]) regEnumKeyEx.invoke(root, new Object[] {
|
---|
| 462 | new Integer(handles[0]), new Integer(index),
|
---|
| 463 | new Integer(maxlen + 1) });
|
---|
| 464 | results.add(new String(name).trim());
|
---|
| 465 | }
|
---|
| 466 | regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
|
---|
| 467 | return results;
|
---|
| 468 | }
|
---|
| 469 |
|
---|
| 470 | // ========================================================================
|
---|
| 471 | private static int[] createKey(Preferences root, int hkey, String key)
|
---|
| 472 | throws IllegalArgumentException, IllegalAccessException,
|
---|
| 473 | InvocationTargetException {
|
---|
| 474 | return (int[]) regCreateKeyEx.invoke(root, new Object[] {
|
---|
| 475 | new Integer(hkey), toCstr(key) });
|
---|
| 476 | }
|
---|
| 477 |
|
---|
| 478 | // ========================================================================
|
---|
| 479 | private static void writeStringValue(Preferences root, int hkey,
|
---|
| 480 | String key, String valueName, String value, int wow64)
|
---|
| 481 | throws IllegalArgumentException, IllegalAccessException,
|
---|
| 482 | InvocationTargetException {
|
---|
| 483 | int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
|
---|
| 484 | new Integer(hkey), toCstr(key),
|
---|
| 485 | new Integer(KEY_ALL_ACCESS | wow64) });
|
---|
| 486 | regSetValueEx.invoke(root, new Object[] { new Integer(handles[0]),
|
---|
| 487 | toCstr(valueName), toCstr(value) });
|
---|
| 488 | regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
|
---|
| 489 | }
|
---|
| 490 |
|
---|
| 491 | // ========================================================================
|
---|
| 492 | // utility
|
---|
| 493 | private static byte[] toCstr(String str) {
|
---|
| 494 | byte[] result = new byte[str.length() + 1];
|
---|
| 495 |
|
---|
| 496 | for (int i = 0; i < str.length(); i++) {
|
---|
| 497 | result[i] = (byte) str.charAt(i);
|
---|
| 498 | }
|
---|
| 499 | result[str.length()] = 0;
|
---|
| 500 | return result;
|
---|
| 501 | }
|
---|
| 502 | }
|
---|