├── .classpath ├── .gitignore ├── .project ├── .travis.yml ├── LICENSE.txt ├── README.md ├── pom.xml └── src ├── example └── java │ └── com │ └── sarxos │ └── win32 │ └── regutil │ ├── GetKeyValue.java │ ├── ListKeys.java │ └── ListValues.java └── main └── java └── com └── github └── sarxos └── winreg ├── HKey.java ├── RegistryException.java ├── WindowsRegistry.java └── internal ├── HKeyAccess.java ├── RC.java ├── ReflectedMethods.java └── WindowsPreferencesBuilder.java /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .settings 3 | 4 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | win-registry 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.m2e.core.maven2Nature 21 | org.eclipse.jdt.core.javanature 22 | 23 | 24 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (C) 2011 - 2014 Bartosz Firyn and contributors 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | windows-registry-util 2 | ============ 3 | 4 | 100% pure Java, simple Windows registry utility. 5 | 6 | [![Build Status](https://secure.travis-ci.org/sarxos/win-registry.png?branch=master)](http://travis-ci.org/sarxos/win-registry) 7 | 8 | ## Maven Integration 9 | 10 | Add dependency to your project: 11 | 12 | ```xml 13 | 14 | com.github.sarxos 15 | windows-registry-util 16 | 0.3 17 | 18 | ``` 19 | 20 | ## Features 21 | 22 | * createKey(HKey, String) 23 | * deleteKey(HKey, String) 24 | * deleteValue(HKey, String, String) 25 | * readString(HKey, String, String) 26 | * readString(HKey, String, String, String) 27 | * readStringSubKeys(HKey, String) 28 | * readStringSubKeys(HKey, String, String) 29 | * readStringValues(HKey, String) 30 | * readStringValues(HKey, String, String) 31 | * writeStringValue(HKey, String, String, String) 32 | 33 | ## Limits 34 | 35 | 1. It can read values of ```REG_SZ``` and ```REG_EXPAND_SZ``` only. 36 | 2. It can read only these entries which user has permission to access. 37 | 38 | ## Example 39 | 40 | Read Windows distribution name: 41 | 42 | ```java 43 | WindowsRegistry reg = WindowsRegistry.getInstance(); 44 | String tree = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"; 45 | String value = reg.readString(HKey.HKLM, tree, "ProductName"); 46 | System.out.println("Windows Distribution = " + value); 47 | ``` 48 | 49 | List keys under ```SOFTWARE\Microsoft\Windows NT\CurrentVersion\Network```: 50 | 51 | ```java 52 | WindowsRegistry reg = WindowsRegistry.getInstance(); 53 | String branch = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Network"; 54 | List keys = reg.readStringSubKeys(HKey.HKLM, branch); 55 | for (String key : keys) { 56 | System.out.println(key); 57 | } 58 | ``` 59 | 60 | ## Credits 61 | 62 | Great kudos and appreciation goes to: 63 | 64 | * Konstantin Kladko, who wrote WindowsPreferences class, 65 | * Tarun Elankath ([lenkite](https://github.com/lenkite)), who [described](http://lenkite.blogspot.fr/2008/05/access-windows-registry-using-java.html) method to hack the above class, 66 | * Yunqi Ouyang ([oyyq99999](https://github.com/oyyq99999)), who managed to [hack it](https://github.com/sarxos/win-registry/pull/1) to gain access to HKCR, HKU and HKCC. 67 | 68 | 69 | 70 | ## License 71 | 72 | Copyright (C) 2011 - 2014 Bartosz Firyn and contributors 73 | 74 | Permission is hereby granted, free of charge, to any person obtaining 75 | a copy of this software and associated documentation files (the 76 | "Software"), to deal in the Software without restriction, including 77 | without limitation the rights to use, copy, modify, merge, publish, 78 | distribute, sublicense, and/or sell copies of the Software, and to 79 | permit persons to whom the Software is furnished to do so, subject to 80 | the following conditions: 81 | 82 | The above copyright notice and this permission notice shall be 83 | included in all copies or substantial portions of the Software. 84 | 85 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 88 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 89 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 90 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 91 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 92 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | org.sonatype.oss 7 | oss-parent 8 | 7 9 | 10 | 11 | 12 | UTF-8 13 | 14 | 15 | com.github.sarxos 16 | windows-registry-util 17 | 0.4-SNAPSHOT 18 | bundle 19 | 20 | Windows Registry Utility 21 | 100% pure Java, simple Windows registry utility 22 | https://github.com/sarxos/win-registry 23 | 2011 24 | 25 | 26 | Bartosz Firyn (sarxos) 27 | https://github.com/sarxos 28 | 29 | 30 | 31 | 32 | MIT License 33 | https://raw.github.com/sarxos/win-registry/master/LICENSE.txt 34 | repo,manual 35 | 36 | 37 | 38 | 39 | 40 | ${repo-id} 41 | ${repo-url} 42 | 43 | 44 | 45 | 46 | scm:git:git@github.com:sarxos/win-registry.git 47 | scm:git:git@github.com:sarxos/win-registry.git 48 | git@github.com:sarxos/win-registry.git 49 | 50 | 51 | 52 | GitHub Issues Manager 53 | https://github.com/sarxos/win-registry/issues 54 | 55 | 56 | 57 | 58 | sarxos 59 | Bartosz Firyn 60 | bartoszfiryn@gmail.com 61 | 62 | Developer 63 | 64 | https://github.com/sarxos 65 | +1 66 | 67 | 68 | oyyq99999 69 | Yunqi Ouyang 70 | 71 | Developer 72 | 73 | https://github.com/oyyq99999 74 | +8 75 | 76 | 77 | ToBeKedge 78 | Cyril MICOUD 79 | 80 | Developer 81 | 82 | https://github.com/ToBeKedge 83 | +1 84 | 85 | 86 | 87 | 88 | 89 | snapshot 90 | 91 | true 92 | 93 | 94 | sonatype-nexus-staging 95 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 96 | 97 | 98 | 99 | release 100 | 101 | 102 | performRelease 103 | true 104 | 105 | 106 | 107 | sonatype-nexus-staging 108 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 109 | 110 | 111 | 112 | 113 | org.apache.maven.plugins 114 | maven-source-plugin 115 | 2.1.2 116 | 117 | 118 | attach-sources 119 | 120 | jar 121 | 122 | 123 | 124 | 125 | 126 | org.apache.maven.plugins 127 | maven-javadoc-plugin 128 | 2.8.1 129 | 130 | 131 | attach-javadocs 132 | 133 | jar 134 | 135 | 136 | 137 | 138 | 139 | org.apache.maven.plugins 140 | maven-gpg-plugin 141 | 1.1 142 | 143 | 144 | sign-artifacts 145 | verify 146 | 147 | sign 148 | 149 | 150 | 151 | 152 | 153 | org.apache.maven.plugins 154 | maven-release-plugin 155 | 2.2.2 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | org.eclipse.m2e 168 | lifecycle-mapping 169 | 1.0.0 170 | 171 | 172 | 173 | 174 | 175 | com.github.danielflower.mavenplugins 176 | maven-gitlog-plugin 177 | [1.4.11,) 178 | 179 | generate 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | org.apache.maven.plugins 196 | maven-compiler-plugin 197 | 2.3.2 198 | 199 | 1.6 200 | 1.6 201 | 202 | 203 | 204 | org.apache.felix 205 | maven-bundle-plugin 206 | 2.3.7 207 | true 208 | 209 | 210 | ${project.name} 211 | ${project.groupId}-${project.artifactId}-${project.version} 212 | * 213 | 214 | com.github.sarxos.winreg.internal, 215 | 216 | 217 | com.github.sarxos.winreg, 218 | 219 | 220 | 221 | 222 | 223 | org.apache.maven.plugins 224 | maven-enforcer-plugin 225 | 1.0 226 | 227 | 228 | enforce-maven-version 229 | 230 | enforce 231 | 232 | 233 | 234 | 235 | [3.0,) 236 | you-must-run-maven-3.0-or-above 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | com.github.danielflower.mavenplugins 245 | maven-gitlog-plugin 246 | 1.4.11 247 | 248 | 249 | 250 | generate 251 | 252 | process-resources 253 | 254 | 255 | 256 | 257 | org.apache.maven.plugins 258 | maven-site-plugin 259 | 3.0 260 | 261 | 262 | org.apache.maven.plugins 263 | maven-source-plugin 264 | 2.1.2 265 | 266 | 267 | attach-sources 268 | 269 | jar 270 | 271 | 272 | 273 | 274 | 275 | org.apache.maven.plugins 276 | maven-javadoc-plugin 277 | 2.8.1 278 | 279 | 280 | attach-javadocs 281 | 282 | jar 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | org.apache.maven.wagon 292 | wagon-ftp 293 | 1.0-beta-7 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | org.apache.maven.plugins 302 | maven-javadoc-plugin 303 | 2.8.1 304 | 305 | public 306 | windows,java,registry,utility 307 | 308 | public 309 | http://java.sun.com/javase/1.6.0/docs/api 310 | 311 | true 312 | true 313 | ${project.name} ${project.version} API - ${maven.build.timestamp} 314 | ${project.name} ${project.version} API - ${maven.build.timestamp} 315 |
${project.organization.name}]]>
316 |
${project.organization.name}]]>
317 | ${project.organization.name}. All Rights Reserved.]]> 318 |
319 |
320 | 321 | org.apache.maven.plugins 322 | maven-jxr-plugin 323 | 2.1 324 | 325 | true 326 | true 327 | 328 | 329 | 330 | org.codehaus.mojo 331 | taglist-maven-plugin 332 | 2.4 333 | 334 | 335 | 336 | 337 | Things to be done 338 | 339 | 340 | TODO 341 | exact 342 | 343 | 344 | FIXME 345 | exact 346 | 347 | 348 | XXX 349 | exact 350 | 351 | 352 | 353 | 354 | 355 | true 356 | 357 | 358 | 359 | org.apache.maven.plugins 360 | maven-project-info-reports-plugin 361 | 2.4 362 | 363 | 364 | 365 | cim 366 | dependencies 367 | dependency-convergence 368 | dependency-management 369 | distribution-management 370 | help 371 | index 372 | issue-tracking 373 | license 374 | mailing-list 375 | modules 376 | plugin-management 377 | plugins 378 | project-team 379 | scm 380 | summary 381 | 382 | 383 | 384 | 385 | 386 | com.googlecode.maven-overview-plugin 387 | maven-overview-plugin 388 | 1.6 389 | 390 | 700 391 | 700 392 | 393 | 394 | 395 | org.codehaus.mojo 396 | cobertura-maven-plugin 397 | 2.5.1 398 | 399 | 400 | org.apache.maven.plugins 401 | maven-surefire-report-plugin 402 | 2.12 403 | 404 | 405 | org.apache.maven.plugins 406 | maven-pmd-plugin 407 | 2.4 408 | 409 | true 410 | utf-8 411 | 100 412 | 1.6 413 | true 414 | 415 | 416 |
417 |
418 | 419 |
-------------------------------------------------------------------------------- /src/example/java/com/sarxos/win32/regutil/GetKeyValue.java: -------------------------------------------------------------------------------- 1 | package com.sarxos.win32.regutil; 2 | 3 | import com.github.sarxos.winreg.HKey; 4 | import com.github.sarxos.winreg.RegistryException; 5 | import com.github.sarxos.winreg.WindowsRegistry; 6 | 7 | 8 | 9 | /** 10 | * @author Bartosz Firyn (SarXos) 11 | */ 12 | public class GetKeyValue { 13 | 14 | public static void main(String[] args) throws RegistryException { 15 | WindowsRegistry reg = WindowsRegistry.getInstance(); 16 | String tree = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"; 17 | String value = reg.readString(HKey.HKLM, tree, "ProductName"); 18 | System.out.println("Windows Distribution = " + value); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/example/java/com/sarxos/win32/regutil/ListKeys.java: -------------------------------------------------------------------------------- 1 | package com.sarxos.win32.regutil; 2 | 3 | import java.util.List; 4 | 5 | import com.github.sarxos.winreg.HKey; 6 | import com.github.sarxos.winreg.RegistryException; 7 | import com.github.sarxos.winreg.WindowsRegistry; 8 | 9 | 10 | 11 | /** 12 | * @author Bartosz Firyn (SarXos) 13 | */ 14 | public class ListKeys { 15 | 16 | public static void main(String[] args) throws RegistryException { 17 | WindowsRegistry reg = WindowsRegistry.getInstance(); 18 | String branch = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Network"; 19 | List keys = reg.readStringSubKeys(HKey.HKLM, branch); 20 | for (String key : keys) { 21 | System.out.println(key); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/example/java/com/sarxos/win32/regutil/ListValues.java: -------------------------------------------------------------------------------- 1 | package com.sarxos.win32.regutil; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.github.sarxos.winreg.HKey; 7 | import com.github.sarxos.winreg.RegistryException; 8 | import com.github.sarxos.winreg.WindowsRegistry; 9 | 10 | 11 | 12 | /** 13 | * @author Cyril MICOUD (ToBeKedge) 14 | */ 15 | public class ListValues { 16 | 17 | public static void main(String[] args) throws RegistryException { 18 | WindowsRegistry reg = WindowsRegistry.getInstance(); 19 | String branch = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Devices"; 20 | Map values = reg.readStringValues(HKey.HKCU, branch); 21 | for (Map.Entry value : values.entrySet()) { 22 | System.out.println(value.getKey() + ": " + value.getValue()); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/github/sarxos/winreg/HKey.java: -------------------------------------------------------------------------------- 1 | package com.github.sarxos.winreg; 2 | 3 | import static com.github.sarxos.winreg.internal.WindowsPreferencesBuilder.HKCC_VALUE; 4 | import static com.github.sarxos.winreg.internal.WindowsPreferencesBuilder.HKCR_VALUE; 5 | import static com.github.sarxos.winreg.internal.WindowsPreferencesBuilder.HKCU_VALUE; 6 | import static com.github.sarxos.winreg.internal.WindowsPreferencesBuilder.HKLM_VALUE; 7 | import static com.github.sarxos.winreg.internal.WindowsPreferencesBuilder.HKU_VALUE; 8 | 9 | import java.util.prefs.Preferences; 10 | 11 | import com.github.sarxos.winreg.internal.WindowsPreferencesBuilder; 12 | 13 | 14 | /** 15 | * HKEY enumeration. 16 | * 17 | * @author Bartosz Firyn (sarxos) 18 | * @author Yunqi Ouyang (oyyq99999) 19 | */ 20 | public enum HKey { 21 | 22 | /** 23 | * HKEY_CLASSES_ROOT 24 | */ 25 | HKCR(HKCR_VALUE, WindowsPreferencesBuilder.getHKCR()), 26 | 27 | /** 28 | * HKEY_CURRENT_USER 29 | */ 30 | HKCU(HKCU_VALUE, Preferences.userRoot()), 31 | 32 | /** 33 | * HKEY_LOCAL_MACHINE 34 | */ 35 | HKLM(HKLM_VALUE, Preferences.systemRoot()), 36 | 37 | /** 38 | * HKEY_USERS 39 | */ 40 | HKU(HKU_VALUE, WindowsPreferencesBuilder.getHKU()), 41 | 42 | /** 43 | * HKEY_CURRENT_CONFIG 44 | */ 45 | HKCC(HKCC_VALUE, WindowsPreferencesBuilder.getHKCC()); 46 | 47 | private int hex = 0; 48 | 49 | private Preferences root = null; 50 | 51 | private HKey(final int hex, final Preferences root) { 52 | this.hex = hex; 53 | this.root = root; 54 | } 55 | 56 | public int hex() { 57 | return hex; 58 | } 59 | 60 | public Preferences root() { 61 | return root; 62 | } 63 | 64 | public static HKey fromHex(int hex) { 65 | HKey[] hks = HKey.values(); 66 | for (HKey hk : hks) { 67 | if (hk.hex() == hex) { 68 | return hk; 69 | } 70 | } 71 | return null; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/com/github/sarxos/winreg/RegistryException.java: -------------------------------------------------------------------------------- 1 | package com.github.sarxos.winreg; 2 | 3 | @SuppressWarnings("serial") 4 | public class RegistryException extends Exception { 5 | 6 | public RegistryException() { 7 | super(); 8 | } 9 | 10 | public RegistryException(String arg0, Throwable arg1) { 11 | super(arg0, arg1); 12 | } 13 | 14 | public RegistryException(String arg0) { 15 | super(arg0); 16 | } 17 | 18 | public RegistryException(Throwable arg0) { 19 | super(arg0); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/github/sarxos/winreg/WindowsRegistry.java: -------------------------------------------------------------------------------- 1 | package com.github.sarxos.winreg; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.github.sarxos.winreg.internal.RC; 7 | import com.github.sarxos.winreg.internal.ReflectedMethods; 8 | 9 | 10 | /** 11 | * Simple windows registry utility. 12 | * 13 | * @author Bartosz Firyn (sarxos) 14 | * @author Yunqi Ouyang (oyyq99999) 15 | */ 16 | public class WindowsRegistry { 17 | 18 | /** 19 | * Static instance. 20 | */ 21 | private static WindowsRegistry instance = new WindowsRegistry(); 22 | 23 | /** 24 | * I'm singleton class. 25 | */ 26 | private WindowsRegistry() { 27 | } 28 | 29 | /** 30 | * @return Static instance 31 | */ 32 | public static WindowsRegistry getInstance() { 33 | return instance; 34 | } 35 | 36 | /** 37 | * Read a value from key and value name 38 | * 39 | * @param hk the HKEY 40 | * @param key the key 41 | * @param valueName the value name 42 | * @return String value 43 | * @throws RegistryException when something is not right 44 | */ 45 | public String readString(HKey hk, String key, String valueName) throws RegistryException { 46 | return readString(hk, key, valueName, null); 47 | } 48 | 49 | /** 50 | * Read a value from key and value name 51 | * 52 | * @param hk the HKEY 53 | * @param key the key 54 | * @param valueName the value name 55 | * @param charsetName which charset to use 56 | * @return String value 57 | * @throws RegistryException when something is not right 58 | */ 59 | public String readString(HKey hk, String key, String valueName, String charsetName) throws RegistryException { 60 | try { 61 | return ReflectedMethods.readString(hk.root(), hk.hex(), key, valueName, charsetName); 62 | } catch (Exception e) { 63 | throw new RegistryException("Cannot read " + valueName + " value from key " + key, e); 64 | } 65 | } 66 | 67 | /** 68 | * Read value(s) and value name(s) form given key 69 | * 70 | * @param hk the HKEY 71 | * @param key the key 72 | * @return the value name(s) plus the value(s) 73 | * @throws RegistryException when something is not right 74 | */ 75 | public Map readStringValues(HKey hk, String key) throws RegistryException { 76 | return readStringValues(hk, key, null); 77 | } 78 | 79 | /** 80 | * Read value(s) and value name(s) form given key 81 | * 82 | * @param hk the HKEY 83 | * @param key the key 84 | * @param charsetName which charset to use 85 | * @return the value name(s) plus the value(s) 86 | * @throws RegistryException when something is not right 87 | */ 88 | public Map readStringValues(HKey hk, String key, String charsetName) throws RegistryException { 89 | try { 90 | return ReflectedMethods.readStringValues(hk.root(), hk.hex(), key, charsetName); 91 | } catch (Exception e) { 92 | throw new RegistryException("Cannot read values from key " + key, e); 93 | } 94 | } 95 | 96 | /** 97 | * Read the value name(s) from a given key 98 | * 99 | * @param hk the HKEY 100 | * @param key the key 101 | * @return the value name(s) 102 | * @throws RegistryException when something is not right 103 | */ 104 | public List readStringSubKeys(HKey hk, String key) throws RegistryException { 105 | return readStringSubKeys(hk, key, null); 106 | } 107 | 108 | /** 109 | * Read the value name(s) from a given key 110 | * 111 | * @param hk the HKEY 112 | * @param key the key 113 | * @param charsetName which charset to use 114 | * @return the value name(s) 115 | * @throws RegistryException when something is not right 116 | */ 117 | public List readStringSubKeys(HKey hk, String key, String charsetName) throws RegistryException { 118 | try { 119 | return ReflectedMethods.readStringSubKeys(hk.root(), hk.hex(), key, charsetName); 120 | } catch (Exception e) { 121 | throw new RegistryException("Cannot read sub keys from key " + key, e); 122 | } 123 | } 124 | 125 | /** 126 | * Create key in registry. 127 | * 128 | * @param hk the HKEY 129 | * @param key the key 130 | * @throws RegistryException when something is not right 131 | */ 132 | public void createKey(HKey hk, String key) throws RegistryException { 133 | int[] ret; 134 | try { 135 | ret = ReflectedMethods.createKey(hk.root(), hk.hex(), key); 136 | } catch (Exception e) { 137 | throw new RegistryException("Cannot create key " + key, e); 138 | } 139 | if (ret.length == 0) { 140 | throw new RegistryException("Cannot create key " + key + ". Zero return length"); 141 | } 142 | if (ret[1] != RC.SUCCESS) { 143 | throw new RegistryException("Cannot create key " + key + ". Return code is " + ret[1]); 144 | } 145 | } 146 | 147 | /** 148 | * Write a value in a given key/value name 149 | * 150 | * @param hk the HKEY to be used 151 | * @param key the key to be written 152 | * @param valueName the value name 153 | * @param value the value 154 | * @throws RegistryException when something is not right 155 | */ 156 | public void writeStringValue(HKey hk, String key, String valueName, String value) throws RegistryException { 157 | try { 158 | ReflectedMethods.writeStringValue(hk.root(), hk.hex(), key, valueName, value); 159 | } catch (Exception e) { 160 | throw new RegistryException("Cannot write " + valueName + " value " + value + " in key " + key, e); 161 | } 162 | } 163 | 164 | /** 165 | * Delete given key from registry. 166 | * 167 | * @param hk the HKEY 168 | * @param key the key to be deleted 169 | * @throws RegistryException when something is not right 170 | */ 171 | public void deleteKey(HKey hk, String key) throws RegistryException { 172 | int rc = -1; 173 | try { 174 | rc = ReflectedMethods.deleteKey(hk.root(), hk.hex(), key); 175 | } catch (Exception e) { 176 | throw new RegistryException("Cannot delete key " + key, e); 177 | } 178 | if (rc != RC.SUCCESS) { 179 | throw new RegistryException("Cannot delete key " + key + ". Return code is " + rc); 180 | } 181 | } 182 | 183 | /** 184 | * Delete value from given key/value name. 185 | * 186 | * @param hk the HKEY 187 | * @param key the key 188 | * @param value the value 189 | * @throws RegistryException when something is not right 190 | */ 191 | public void deleteValue(HKey hk, String key, String value) throws RegistryException { 192 | int rc = -1; 193 | try { 194 | rc = ReflectedMethods.deleteValue(hk.root(), hk.hex(), key, value); 195 | } catch (Exception e) { 196 | throw new RegistryException("Cannot delete value " + value + " from key " + key, e); 197 | } 198 | if (rc != RC.SUCCESS) { 199 | throw new RegistryException("Cannot delete value " + value + " from key " + key + ". Return code is " + rc); 200 | } 201 | } 202 | 203 | } 204 | -------------------------------------------------------------------------------- /src/main/java/com/github/sarxos/winreg/internal/HKeyAccess.java: -------------------------------------------------------------------------------- 1 | package com.github.sarxos.winreg.internal; 2 | 3 | /** 4 | * Windows security masks. 5 | * 6 | * @author Bartosz Firyn (sarxos) 7 | */ 8 | public class HKeyAccess { 9 | 10 | public static final int ALL = 0xf003f; 11 | public static final int READ = 0x20019; 12 | public static final int DELETE = 0x10000; 13 | public static final int QUERY_VALUE = 1; 14 | public static final int SET_VALUE = 2; 15 | public static final int CREATE_SUB_KEY = 4; 16 | public static final int ENUMERATE_SUB_KEYS = 8; 17 | public static final int WRITE = 0x20006; 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/github/sarxos/winreg/internal/RC.java: -------------------------------------------------------------------------------- 1 | package com.github.sarxos.winreg.internal; 2 | 3 | public class RC { 4 | 5 | public static final int SUCCESS = 0; 6 | public static final int NOTFOUND = 2; 7 | public static final int ACCESSDENIED = 5; 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/github/sarxos/winreg/internal/ReflectedMethods.java: -------------------------------------------------------------------------------- 1 | package com.github.sarxos.winreg.internal; 2 | 3 | import java.lang.reflect.Method; 4 | import java.util.ArrayList; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | import java.util.logging.Logger; 9 | import java.util.prefs.Preferences; 10 | 11 | import com.github.sarxos.winreg.HKey; 12 | 13 | 14 | /** 15 | * A set of methods used to operate on Windows registry. Those methods comes 16 | * from private Sun API from WindowsPreferences written by 17 | * Konstantin Kladko. Access method used here has been initially found by Tarun 18 | * Elankath 19 | * (http://lenkite.blogspot.fr/2008/05/access-windows-registry-using-java.html). 20 | * 21 | * @author Bartosz Firyn (sarxos) 22 | * @author Yunqi Ouyang (oyyq99999) 23 | * @author Cyril MICOUD (ToBeKedge) 24 | */ 25 | public final class ReflectedMethods { 26 | 27 | private static final Logger LOG = Logger.getLogger(ReflectedMethods.class.getName()); 28 | 29 | private static final Class IC = int.class; 30 | private static final Class BAC = byte[].class; 31 | 32 | private static final Method OPEN_KEY = setupMethod("WindowsRegOpenKey", new Class[] { IC, BAC, IC }); 33 | private static final Method CLOSE_KEY = setupMethod("WindowsRegCloseKey", new Class[] { IC }); 34 | private static final Method QUERY_VALUE_EX = setupMethod("WindowsRegQueryValueEx", new Class[] { IC, BAC }); 35 | private static final Method ENUM_VALUE = setupMethod("WindowsRegEnumValue", new Class[] { IC, IC, IC }); 36 | private static final Method QUERY_INFO_KEY = setupMethod("WindowsRegQueryInfoKey1", new Class[] { IC }); 37 | private static final Method ENUM_KEY_EX = setupMethod("WindowsRegEnumKeyEx", new Class[] { IC, IC, IC }); 38 | private static final Method CREATE_KEY_EX = setupMethod("WindowsRegCreateKeyEx", new Class[] { IC, BAC }); 39 | private static final Method SET_VALUE_EX = setupMethod("WindowsRegSetValueEx", new Class[] { IC, BAC, BAC }); 40 | private static final Method DELETE_VALUE = setupMethod("WindowsRegDeleteValue", new Class[] { IC, BAC }); 41 | private static final Method DELETE_KEY = setupMethod("WindowsRegDeleteKey", new Class[] { IC, BAC }); 42 | 43 | private static final String NATIVE_ENCODING = System.getProperty("sun.jnu.encoding", null); 44 | 45 | private static Method setupMethod(String name, Class[] args) { 46 | Method method = null; 47 | try { 48 | method = HKey.HKCU.root().getClass().getDeclaredMethod(name, args); 49 | } catch (Exception e) { 50 | throw new RuntimeException(e); 51 | } 52 | method.setAccessible(true); 53 | return method; 54 | } 55 | 56 | public static int deleteValue(Preferences root, int hkey, String key, String value) throws Exception { 57 | int[] handles = keyOpen(root, hkey, key, HKeyAccess.ALL); 58 | int rc = (Integer) invoke(DELETE_VALUE, root, handles[0], value); 59 | keyClose(root, handles); 60 | return rc; 61 | } 62 | 63 | public static int deleteKey(Preferences root, int hkey, String key) throws Exception { 64 | return (Integer) invoke(DELETE_KEY, root, hkey, key); 65 | } 66 | 67 | public static String readString(Preferences root, int hkey, String key, String value, String charsetName) throws Exception { 68 | int[] handles = keyOpen(root, hkey, key, HKeyAccess.READ); 69 | byte[] valb = (byte[]) invoke(QUERY_VALUE_EX, root, handles[0], value); 70 | keyClose(root, handles); 71 | return strFromNativeBytes(valb, charsetName); 72 | } 73 | 74 | public static Map readStringValues(Preferences root, int hkey, String key, String charsetName) throws Exception { 75 | 76 | int[] handles = keyOpen(root, hkey, key, HKeyAccess.READ); 77 | int[] info = (int[]) invoke(QUERY_INFO_KEY, root, handles[0]); 78 | 79 | // info[0] = number of keys which can be read 80 | // info[1] = ?? 81 | // info[2] = number of all value entries in given key 82 | // info[3] = maximum string length from all the key names 83 | // info[4] = maximum string length from all the values 84 | 85 | int count = info[2]; 86 | int maxlen = info[4]; 87 | 88 | HashMap results = new HashMap(); 89 | for (int index = 0; index < count; index++) { 90 | byte[] name = (byte[]) invoke(ENUM_VALUE, root, handles[0], index, maxlen + 1); 91 | String strName = strFromNativeBytes(name, charsetName); 92 | String value = readString(root, hkey, key, strName, charsetName); 93 | results.put(strName.trim(), value); 94 | } 95 | keyClose(root, handles); 96 | return results; 97 | } 98 | 99 | public static List readStringSubKeys(Preferences root, int hkey, String key, String charsetName) throws Exception { 100 | 101 | int[] handles = keyOpen(root, hkey, key, HKeyAccess.READ); 102 | int[] info = (int[]) invoke(QUERY_INFO_KEY, root, handles[0]); 103 | 104 | // info[0] = number of keys which can be read 105 | // info[1] = ?? 106 | // info[2] = number of all value entries in given key 107 | // info[3] = maximum string length from all the key names 108 | // info[4] = maximum string length from all the values 109 | 110 | int count = info[0]; 111 | int maxlen = info[3]; 112 | 113 | List results = new ArrayList(); 114 | for (int index = 0; index < count; index++) { 115 | byte[] name = (byte[]) invoke(ENUM_KEY_EX, root, handles[0], index, maxlen + 1); 116 | results.add(strFromNativeBytes(name, charsetName)); 117 | } 118 | keyClose(root, handles); 119 | return results; 120 | } 121 | 122 | public static int[] createKey(Preferences root, int hkey, String key) throws Exception { 123 | int[] handles = (int[]) invoke(CREATE_KEY_EX, root, hkey, key); 124 | keyClose(root, handles); 125 | return handles; 126 | } 127 | 128 | public static void writeStringValue(Preferences root, int hkey, String key, String valueName, String value) throws Exception { 129 | int[] handles = keyOpen(root, hkey, key, HKeyAccess.ALL); 130 | invoke(SET_VALUE_EX, root, handles[0], valueName, value); 131 | keyClose(root, handles); 132 | } 133 | 134 | private static Object invoke(Method method, Preferences root, Object... args) throws Exception { 135 | Object[] arguments = new Object[args.length]; 136 | for (int i = 0; i < args.length; i++) { 137 | Object arg = args[i]; 138 | if (arg instanceof Integer) { 139 | arguments[i] = arg; 140 | } else if (arg instanceof String) { 141 | arguments[i] = strToNativeBytes(arg.toString()); 142 | } 143 | } 144 | return method.invoke(root, arguments); 145 | } 146 | 147 | private static int[] keyOpen(Preferences root, int hkey, String key, int access) throws Exception { 148 | int[] handles = (int[]) invoke(OPEN_KEY, root, hkey, key, access); 149 | if (handles[1] != RC.SUCCESS) { 150 | throw new IllegalAccessException("Cannot open " + HKey.fromHex(hkey) + "\\" + key); 151 | } 152 | return handles; 153 | } 154 | 155 | private static void keyClose(Preferences root, int[] handles) throws Exception { 156 | invoke(CLOSE_KEY, root, handles[0]); 157 | } 158 | 159 | private static byte[] strToNativeBytes(String str) { 160 | byte[] bytes = null; 161 | try { 162 | bytes = str.getBytes(NATIVE_ENCODING); 163 | } catch (Exception e) { 164 | bytes = str.getBytes(); 165 | } 166 | byte[] result = new byte[bytes.length + 1]; 167 | System.arraycopy(bytes, 0, result, 0, bytes.length); 168 | result[bytes.length] = 0; 169 | return result; 170 | } 171 | 172 | private static String strFromNativeBytes(byte[] bytes, String charsetName) { 173 | if (bytes == null) { 174 | return null; 175 | } 176 | if (charsetName == null) { 177 | charsetName = NATIVE_ENCODING; 178 | } 179 | String result; 180 | try { 181 | result = new String(bytes, charsetName); 182 | } catch (Exception e) { 183 | result = new String(bytes); 184 | } 185 | return result == null ? null : result.trim(); 186 | } 187 | 188 | private ReflectedMethods() { 189 | } 190 | 191 | } 192 | -------------------------------------------------------------------------------- /src/main/java/com/github/sarxos/winreg/internal/WindowsPreferencesBuilder.java: -------------------------------------------------------------------------------- 1 | package com.github.sarxos.winreg.internal; 2 | 3 | import java.lang.reflect.Constructor; 4 | import java.util.logging.Level; 5 | import java.util.logging.Logger; 6 | import java.util.prefs.Preferences; 7 | 8 | 9 | /** 10 | * Preferences builder to hack {@link Preferences} constructor and gain access 11 | * to HKCR, HKU and HKCC. 12 | * 13 | * @author Yunqi Ouyang (oyyq99999) 14 | */ 15 | public class WindowsPreferencesBuilder { 16 | 17 | private static final Logger LOG = Logger.getLogger(WindowsPreferencesBuilder.class.getName()); 18 | 19 | private static final byte[] WINDOWS_ROOT_PATH = stringToByteArray(""); 20 | public static final int HKCR_VALUE = 0x80000000; 21 | public static final int HKCU_VALUE = 0x80000001; 22 | public static final int HKLM_VALUE = 0x80000002; 23 | public static final int HKU_VALUE = 0x80000003; 24 | public static final int HKCC_VALUE = 0x80000005; 25 | private static Preferences hkcr = null; 26 | private static Preferences hkcu = Preferences.userRoot(); 27 | private static Preferences hklm = Preferences.systemRoot(); 28 | private static Preferences hku = null; 29 | private static Preferences hkcc = null; 30 | 31 | static { 32 | Class clazz = Preferences.userRoot().getClass(); 33 | Constructor constructor; 34 | try { 35 | constructor = clazz.getDeclaredConstructor(int.class, byte[].class); 36 | constructor.setAccessible(true); 37 | hkcr = constructor.newInstance(HKCR_VALUE, WINDOWS_ROOT_PATH); 38 | hku = constructor.newInstance(HKU_VALUE, WINDOWS_ROOT_PATH); 39 | hkcc = constructor.newInstance(HKCC_VALUE, WINDOWS_ROOT_PATH); 40 | } catch (Exception e) { 41 | LOG.log(Level.SEVERE, "Cannot instantiate preferences", e); 42 | } 43 | } 44 | 45 | public static Preferences getHKCR() { 46 | return hkcr; 47 | } 48 | 49 | public static Preferences getHKCU() { 50 | return hkcu; 51 | } 52 | 53 | public static Preferences getHKLM() { 54 | return hklm; 55 | } 56 | 57 | public static Preferences getHKU() { 58 | return hku; 59 | } 60 | 61 | public static Preferences getHKCC() { 62 | return hkcc; 63 | } 64 | 65 | /** 66 | * Returns this java string as a null-terminated byte array 67 | */ 68 | private static byte[] stringToByteArray(String str) { 69 | byte[] result = new byte[str.length() + 1]; 70 | for (int i = 0; i < str.length(); i++) { 71 | result[i] = (byte) str.charAt(i); 72 | } 73 | result[str.length()] = 0; 74 | return result; 75 | } 76 | } --------------------------------------------------------------------------------