source: java/PlatformTools/src/net/oni2/platformtools/WinRegistry.java@ 736

Last change on this file since 736 was 724, checked in by alloc, 12 years ago

Platform tools library (information about platform, program execution)

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