6
|
1 import java.lang.reflect.InvocationTargetException;
|
|
2 import java.lang.reflect.Method;
|
|
3 import java.util.HashMap;
|
|
4 import java.util.Map;
|
|
5 import java.util.ArrayList;
|
|
6 import java.util.List;
|
|
7 import java.util.prefs.Preferences;
|
|
8
|
|
9 public class WindowsRegistry {
|
|
10 public static final int HKEY_CURRENT_USER = 0x80000001;
|
|
11 public static final int HKEY_LOCAL_MACHINE = 0x80000002;
|
|
12 public static final int REG_SUCCESS = 0;
|
|
13 public static final int REG_NOTFOUND = 2;
|
|
14 public static final int REG_ACCESSDENIED = 5;
|
|
15
|
|
16 private static final int KEY_ALL_ACCESS = 0xf003f;
|
|
17 private static final int KEY_READ = 0x20019;
|
|
18 private static Preferences userRoot = Preferences.userRoot();
|
|
19 private static Preferences systemRoot = Preferences.systemRoot();
|
|
20 private static Class<? extends Preferences> userClass = userRoot.getClass();
|
|
21 private static Method regOpenKey = null;
|
|
22 private static Method regCloseKey = null;
|
|
23 private static Method regQueryValueEx = null;
|
|
24 private static Method regEnumValue = null;
|
|
25 private static Method regQueryInfoKey = null;
|
|
26 private static Method regEnumKeyEx = null;
|
|
27 private static Method regCreateKeyEx = null;
|
|
28 private static Method regSetValueEx = null;
|
|
29 private static Method regDeleteKey = null;
|
|
30 private static Method regDeleteValue = null;
|
|
31
|
|
32 static {
|
|
33 try {
|
|
34 regOpenKey = userClass.getDeclaredMethod("WindowsRegOpenKey",
|
|
35 new Class[] { int.class, byte[].class, int.class });
|
|
36 regOpenKey.setAccessible(true);
|
|
37 regCloseKey = userClass.getDeclaredMethod("WindowsRegCloseKey",
|
|
38 new Class[] { int.class });
|
|
39 regCloseKey.setAccessible(true);
|
|
40 regQueryValueEx = userClass.getDeclaredMethod("WindowsRegQueryValueEx",
|
|
41 new Class[] { int.class, byte[].class });
|
|
42 regQueryValueEx.setAccessible(true);
|
|
43 regEnumValue = userClass.getDeclaredMethod("WindowsRegEnumValue",
|
|
44 new Class[] { int.class, int.class, int.class });
|
|
45 regEnumValue.setAccessible(true);
|
|
46 regQueryInfoKey = userClass.getDeclaredMethod("WindowsRegQueryInfoKey1",
|
|
47 new Class[] { int.class });
|
|
48 regQueryInfoKey.setAccessible(true);
|
|
49 regEnumKeyEx = userClass.getDeclaredMethod(
|
|
50 "WindowsRegEnumKeyEx", new Class[] { int.class, int.class,
|
|
51 int.class });
|
|
52 regEnumKeyEx.setAccessible(true);
|
|
53 regCreateKeyEx = userClass.getDeclaredMethod(
|
|
54 "WindowsRegCreateKeyEx", new Class[] { int.class,
|
|
55 byte[].class });
|
|
56 regCreateKeyEx.setAccessible(true);
|
|
57 regSetValueEx = userClass.getDeclaredMethod(
|
|
58 "WindowsRegSetValueEx", new Class[] { int.class,
|
|
59 byte[].class, byte[].class });
|
|
60 regSetValueEx.setAccessible(true);
|
|
61 regDeleteValue = userClass.getDeclaredMethod(
|
|
62 "WindowsRegDeleteValue", new Class[] { int.class,
|
|
63 byte[].class });
|
|
64 regDeleteValue.setAccessible(true);
|
|
65 regDeleteKey = userClass.getDeclaredMethod(
|
|
66 "WindowsRegDeleteKey", new Class[] { int.class,
|
|
67 byte[].class });
|
|
68 regDeleteKey.setAccessible(true);
|
|
69 }
|
|
70 catch (Exception e) {
|
|
71 e.printStackTrace();
|
|
72 }
|
|
73 }
|
|
74
|
|
75 private WindowsRegistry() { }
|
|
76
|
|
77 /**
|
|
78 * Read a value from key and value name
|
|
79 * @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
|
|
80 * @param key
|
|
81 * @param valueName
|
|
82 * @return the value
|
|
83 * @throws IllegalArgumentException
|
|
84 * @throws IllegalAccessException
|
|
85 * @throws InvocationTargetException
|
|
86 */
|
|
87 public static String readString(int hkey, String key, String valueName)
|
|
88 throws IllegalArgumentException, IllegalAccessException,
|
|
89 InvocationTargetException
|
|
90 {
|
|
91 if (hkey == HKEY_LOCAL_MACHINE) {
|
|
92 return readString(systemRoot, hkey, key, valueName);
|
|
93 }
|
|
94 else if (hkey == HKEY_CURRENT_USER) {
|
|
95 return readString(userRoot, hkey, key, valueName);
|
|
96 }
|
|
97 else {
|
|
98 throw new IllegalArgumentException("hkey=" + hkey);
|
|
99 }
|
|
100 }
|
|
101
|
|
102 /**
|
|
103 * Read value(s) and value name(s) form given key
|
|
104 * @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
|
|
105 * @param key
|
|
106 * @return the value name(s) plus the value(s)
|
|
107 * @throws IllegalArgumentException
|
|
108 * @throws IllegalAccessException
|
|
109 * @throws InvocationTargetException
|
|
110 */
|
|
111 public static Map<String, String> readStringValues(int hkey, String key)
|
|
112 throws IllegalArgumentException, IllegalAccessException,
|
|
113 InvocationTargetException
|
|
114 {
|
|
115 if (hkey == HKEY_LOCAL_MACHINE) {
|
|
116 return readStringValues(systemRoot, hkey, key);
|
|
117 }
|
|
118 else if (hkey == HKEY_CURRENT_USER) {
|
|
119 return readStringValues(userRoot, hkey, key);
|
|
120 }
|
|
121 else {
|
|
122 throw new IllegalArgumentException("hkey=" + hkey);
|
|
123 }
|
|
124 }
|
|
125
|
|
126 /**
|
|
127 * Read the value name(s) from a given key
|
|
128 * @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
|
|
129 * @param key
|
|
130 * @return the value name(s)
|
|
131 * @throws IllegalArgumentException
|
|
132 * @throws IllegalAccessException
|
|
133 * @throws InvocationTargetException
|
|
134 */
|
|
135 public static List<String> readStringSubKeys(int hkey, String key)
|
|
136 throws IllegalArgumentException, IllegalAccessException,
|
|
137 InvocationTargetException
|
|
138 {
|
|
139 if (hkey == HKEY_LOCAL_MACHINE) {
|
|
140 return readStringSubKeys(systemRoot, hkey, key);
|
|
141 }
|
|
142 else if (hkey == HKEY_CURRENT_USER) {
|
|
143 return readStringSubKeys(userRoot, hkey, key);
|
|
144 }
|
|
145 else {
|
|
146 throw new IllegalArgumentException("hkey=" + hkey);
|
|
147 }
|
|
148 }
|
|
149
|
|
150 /**
|
|
151 * Create a key
|
|
152 * @param hkey HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
|
|
153 * @param key
|
|
154 * @throws IllegalArgumentException
|
|
155 * @throws IllegalAccessException
|
|
156 * @throws InvocationTargetException
|
|
157 */
|
|
158 public static void createKey(int hkey, String key)
|
|
159 throws IllegalArgumentException, IllegalAccessException,
|
|
160 InvocationTargetException
|
|
161 {
|
|
162 int [] ret;
|
|
163 if (hkey == HKEY_LOCAL_MACHINE) {
|
|
164 ret = createKey(systemRoot, hkey, key);
|
|
165 regCloseKey.invoke(systemRoot, new Object[] { new Integer(ret[0]) });
|
|
166 }
|
|
167 else if (hkey == HKEY_CURRENT_USER) {
|
|
168 ret = createKey(userRoot, hkey, key);
|
|
169 regCloseKey.invoke(userRoot, new Object[] { new Integer(ret[0]) });
|
|
170 }
|
|
171 else {
|
|
172 throw new IllegalArgumentException("hkey=" + hkey);
|
|
173 }
|
|
174 if (ret[1] != REG_SUCCESS) {
|
|
175 throw new IllegalArgumentException("rc=" + ret[1] + " key=" + key);
|
|
176 }
|
|
177 }
|
|
178
|
|
179 /**
|
|
180 * Write a value in a given key/value name
|
|
181 * @param hkey
|
|
182 * @param key
|
|
183 * @param valueName
|
|
184 * @param value
|
|
185 * @throws IllegalArgumentException
|
|
186 * @throws IllegalAccessException
|
|
187 * @throws InvocationTargetException
|
|
188 */
|
|
189 public static void writeStringValue
|
|
190 (int hkey, String key, String valueName, String value)
|
|
191 throws IllegalArgumentException, IllegalAccessException,
|
|
192 InvocationTargetException
|
|
193 {
|
|
194 if (hkey == HKEY_LOCAL_MACHINE) {
|
|
195 writeStringValue(systemRoot, hkey, key, valueName, value);
|
|
196 }
|
|
197 else if (hkey == HKEY_CURRENT_USER) {
|
|
198 writeStringValue(userRoot, hkey, key, valueName, value);
|
|
199 }
|
|
200 else {
|
|
201 throw new IllegalArgumentException("hkey=" + hkey);
|
|
202 }
|
|
203 }
|
|
204
|
|
205 /**
|
|
206 * Delete a given key
|
|
207 * @param hkey
|
|
208 * @param key
|
|
209 * @throws IllegalArgumentException
|
|
210 * @throws IllegalAccessException
|
|
211 * @throws InvocationTargetException
|
|
212 */
|
|
213 public static void deleteKey(int hkey, String key)
|
|
214 throws IllegalArgumentException, IllegalAccessException,
|
|
215 InvocationTargetException
|
|
216 {
|
|
217 int rc = -1;
|
|
218 if (hkey == HKEY_LOCAL_MACHINE) {
|
|
219 rc = deleteKey(systemRoot, hkey, key);
|
|
220 }
|
|
221 else if (hkey == HKEY_CURRENT_USER) {
|
|
222 rc = deleteKey(userRoot, hkey, key);
|
|
223 }
|
|
224 if (rc != REG_SUCCESS) {
|
|
225 throw new IllegalArgumentException("rc=" + rc + " key=" + key);
|
|
226 }
|
|
227 }
|
|
228
|
|
229 /**
|
|
230 * delete a value from a given key/value name
|
|
231 * @param hkey
|
|
232 * @param key
|
|
233 * @param value
|
|
234 * @throws IllegalArgumentException
|
|
235 * @throws IllegalAccessException
|
|
236 * @throws InvocationTargetException
|
|
237 */
|
|
238 public static void deleteValue(int hkey, String key, String value)
|
|
239 throws IllegalArgumentException, IllegalAccessException,
|
|
240 InvocationTargetException
|
|
241 {
|
|
242 int rc = -1;
|
|
243 if (hkey == HKEY_LOCAL_MACHINE) {
|
|
244 rc = deleteValue(systemRoot, hkey, key, value);
|
|
245 }
|
|
246 else if (hkey == HKEY_CURRENT_USER) {
|
|
247 rc = deleteValue(userRoot, hkey, key, value);
|
|
248 }
|
|
249 if (rc != REG_SUCCESS) {
|
|
250 throw new IllegalArgumentException("rc=" + rc + " key=" + key + " value=" + value);
|
|
251 }
|
|
252 }
|
|
253
|
|
254 // =====================
|
|
255
|
|
256 private static int deleteValue
|
|
257 (Preferences root, int hkey, String key, String value)
|
|
258 throws IllegalArgumentException, IllegalAccessException,
|
|
259 InvocationTargetException
|
|
260 {
|
|
261 int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
|
|
262 new Integer(hkey), toCstr(key), new Integer(KEY_ALL_ACCESS) });
|
|
263 if (handles[1] != REG_SUCCESS) {
|
|
264 return handles[1]; // can be REG_NOTFOUND, REG_ACCESSDENIED
|
|
265 }
|
|
266 int rc =((Integer) regDeleteValue.invoke(root,
|
|
267 new Object[] {
|
|
268 new Integer(handles[0]), toCstr(value)
|
|
269 })).intValue();
|
|
270 regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
|
|
271 return rc;
|
|
272 }
|
|
273
|
|
274 private static int deleteKey(Preferences root, int hkey, String key)
|
|
275 throws IllegalArgumentException, IllegalAccessException,
|
|
276 InvocationTargetException
|
|
277 {
|
|
278 int rc =((Integer) regDeleteKey.invoke(root,
|
|
279 new Object[] { new Integer(hkey), toCstr(key) })).intValue();
|
|
280 return rc; // can REG_NOTFOUND, REG_ACCESSDENIED, REG_SUCCESS
|
|
281 }
|
|
282
|
|
283 private static String readString(Preferences root, int hkey, String key, String value)
|
|
284 throws IllegalArgumentException, IllegalAccessException,
|
|
285 InvocationTargetException
|
|
286 {
|
|
287 int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
|
|
288 new Integer(hkey), toCstr(key), new Integer(KEY_READ) });
|
|
289 if (handles[1] != REG_SUCCESS) {
|
|
290 return null;
|
|
291 }
|
|
292 byte[] valb = (byte[]) regQueryValueEx.invoke(root, new Object[] {
|
|
293 new Integer(handles[0]), toCstr(value) });
|
|
294 regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
|
|
295 return (valb != null ? new String(valb).trim() : null);
|
|
296 }
|
|
297
|
|
298 private static Map<String,String> readStringValues
|
|
299 (Preferences root, int hkey, String key)
|
|
300 throws IllegalArgumentException, IllegalAccessException,
|
|
301 InvocationTargetException
|
|
302 {
|
|
303 HashMap<String, String> results = new HashMap<String,String>();
|
|
304 int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
|
|
305 new Integer(hkey), toCstr(key), new Integer(KEY_READ) });
|
|
306 if (handles[1] != REG_SUCCESS) {
|
|
307 return null;
|
|
308 }
|
|
309 int[] info = (int[]) regQueryInfoKey.invoke(root,
|
|
310 new Object[] { new Integer(handles[0]) });
|
|
311
|
|
312 int count = info[2]; // count
|
|
313 int maxlen = info[3]; // value length max
|
|
314 for(int index=0; index<count; index++) {
|
|
315 byte[] name = (byte[]) regEnumValue.invoke(root, new Object[] {
|
|
316 new Integer
|
|
317 (handles[0]), new Integer(index), new Integer(maxlen + 1)});
|
|
318 String value = readString(hkey, key, new String(name));
|
|
319 results.put(new String(name).trim(), value);
|
|
320 }
|
|
321 regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
|
|
322 return results;
|
|
323 }
|
|
324
|
|
325 private static List<String> readStringSubKeys
|
|
326 (Preferences root, int hkey, String key)
|
|
327 throws IllegalArgumentException, IllegalAccessException,
|
|
328 InvocationTargetException
|
|
329 {
|
|
330 List<String> results = new ArrayList<String>();
|
|
331 int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
|
|
332 new Integer(hkey), toCstr(key), new Integer(KEY_READ)
|
|
333 });
|
|
334 if (handles[1] != REG_SUCCESS) {
|
|
335 return null;
|
|
336 }
|
|
337 int[] info = (int[]) regQueryInfoKey.invoke(root,
|
|
338 new Object[] { new Integer(handles[0]) });
|
|
339
|
|
340 int count = info[2]; // count
|
|
341 int maxlen = info[3]; // value length max
|
|
342 for(int index=0; index<count; index++) {
|
|
343 byte[] name = (byte[]) regEnumKeyEx.invoke(root, new Object[] {
|
|
344 new Integer
|
|
345 (handles[0]), new Integer(index), new Integer(maxlen + 1)
|
|
346 });
|
|
347 results.add(new String(name).trim());
|
|
348 }
|
|
349 regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
|
|
350 return results;
|
|
351 }
|
|
352
|
|
353 private static int [] createKey(Preferences root, int hkey, String key)
|
|
354 throws IllegalArgumentException, IllegalAccessException,
|
|
355 InvocationTargetException
|
|
356 {
|
|
357 return (int[]) regCreateKeyEx.invoke(root,
|
|
358 new Object[] { new Integer(hkey), toCstr(key) });
|
|
359 }
|
|
360
|
|
361 private static void writeStringValue
|
|
362 (Preferences root, int hkey, String key, String valueName, String value)
|
|
363 throws IllegalArgumentException, IllegalAccessException,
|
|
364 InvocationTargetException
|
|
365 {
|
|
366 int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
|
|
367 new Integer(hkey), toCstr(key), new Integer(KEY_ALL_ACCESS) });
|
|
368
|
|
369 regSetValueEx.invoke(root,
|
|
370 new Object[] {
|
|
371 new Integer(handles[0]), toCstr(valueName), toCstr(value)
|
|
372 });
|
|
373 regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
|
|
374 }
|
|
375
|
|
376 // utility
|
|
377 private static byte[] toCstr(String str) {
|
|
378 byte[] result = new byte[str.length() + 1];
|
|
379
|
|
380 for (int i = 0; i < str.length(); i++) {
|
|
381 result[i] = (byte) str.charAt(i);
|
|
382 }
|
|
383 result[str.length()] = 0;
|
|
384 return result;
|
|
385 }
|
|
386 }
|
|
387
|