1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 package com.sun.star.lib.loader; 29 30 import java.io.BufferedInputStream; 31 import java.io.BufferedOutputStream; 32 import java.io.File; 33 import java.io.FileOutputStream; 34 import java.io.InputStream; 35 36 37 /** 38 * This class provides functionality for reading string values from the 39 * Windows Registry. It requires the native library unowinreg.dll. 40 */ 41 final class WinRegKey { 42 43 private String m_rootKeyName; 44 private String m_subKeyName; 45 46 // native methods to access the windows registry 47 private static native boolean winreg_RegOpenClassesRoot( long[] hkresult ); 48 private static native boolean winreg_RegOpenCurrentConfig( 49 long[] hkresult ); 50 private static native boolean winreg_RegOpenCurrentUser( long[] hkresult ); 51 private static native boolean winreg_RegOpenLocalMachine( long[] hkresult ); 52 private static native boolean winreg_RegOpenUsers( long[] hkresult ); 53 private static native boolean winreg_RegOpenKeyEx( long parent, String name, 54 long[] hkresult ); 55 private static native boolean winreg_RegCloseKey( long hkey ); 56 private static native boolean winreg_RegQueryValueEx( 57 long hkey, String value, long[] type, 58 byte[] data, long[] size ); 59 private static native boolean winreg_RegQueryInfoKey( 60 long hkey, long[] subkeys, long[] maxSubkeyLen, 61 long[] values, long[] maxValueNameLen, 62 long[] maxValueLen, long[] secDescriptor ); 63 64 // load the native library unowinreg.dll 65 static { 66 try { 67 ClassLoader cl = WinRegKey.class.getClassLoader(); 68 InputStream is = cl.getResourceAsStream( "win/unowinreg.dll" ); 69 if ( is != null ) { 70 // generate a temporary name for lib file and write to temp 71 // location 72 BufferedInputStream istream = new BufferedInputStream( is ); 73 File libfile = File.createTempFile( "unowinreg", ".dll" ); 74 libfile.deleteOnExit(); // ensure deletion 75 BufferedOutputStream ostream = new BufferedOutputStream( 76 new FileOutputStream( libfile ) ); 77 int bsize = 2048; int n = 0; 78 byte[] buffer = new byte[bsize]; 79 while ( ( n = istream.read( buffer, 0, bsize ) ) != -1 ) { 80 ostream.write( buffer, 0, n ); 81 } 82 istream.close(); 83 ostream.close(); 84 // load library 85 System.load( libfile.getPath() ); 86 } else { 87 // If the library cannot be found as a class loader resource, 88 // try the global System.loadLibrary(). The JVM will look for 89 // it in the java.library.path. 90 System.loadLibrary( "unowinreg" ); 91 } 92 } catch ( java.lang.Exception e ) { 93 System.err.println( "com.sun.star.lib.loader.WinRegKey: " + 94 "loading of native library failed!" + e ); 95 } 96 } 97 98 /** 99 * Constructs a <code>WinRegKey</code>. 100 */ 101 public WinRegKey( String rootKeyName, String subKeyName ) { 102 m_rootKeyName = rootKeyName; 103 m_subKeyName = subKeyName; 104 } 105 106 /** 107 * Reads a string value for the specified value name. 108 */ 109 public String getStringValue( String valueName ) throws WinRegKeyException { 110 byte[] data = getValue( valueName ); 111 // remove terminating null character 112 return new String( data, 0, data.length - 1 ); 113 } 114 115 /** 116 * Reads a value for the specified value name. 117 */ 118 private byte[] getValue( String valueName ) throws WinRegKeyException { 119 120 byte[] result = null; 121 long[] hkey = {0}; 122 123 // open the specified registry key 124 boolean bRet = false; 125 long[] hroot = {0}; 126 if ( m_rootKeyName.equals( "HKEY_CLASSES_ROOT" ) ) { 127 bRet = winreg_RegOpenClassesRoot( hroot ); 128 } else if ( m_rootKeyName.equals( "HKEY_CURRENT_CONFIG" ) ) { 129 bRet = winreg_RegOpenCurrentConfig( hroot ); 130 } else if ( m_rootKeyName.equals( "HKEY_CURRENT_USER" ) ) { 131 bRet = winreg_RegOpenCurrentUser( hroot ); 132 } else if ( m_rootKeyName.equals( "HKEY_LOCAL_MACHINE" ) ) { 133 bRet = winreg_RegOpenLocalMachine( hroot ); 134 } else if ( m_rootKeyName.equals( "HKEY_USERS" ) ) { 135 bRet = winreg_RegOpenUsers( hroot ); 136 } else { 137 throw new WinRegKeyException( "unknown root registry key!"); 138 } 139 if ( !bRet ) { 140 throw new WinRegKeyException( "opening root registry key " + 141 "failed!" ); 142 } 143 if ( !winreg_RegOpenKeyEx( hroot[0], m_subKeyName, hkey ) ) { 144 if ( !winreg_RegCloseKey( hroot[0] ) ) { 145 throw new WinRegKeyException( "opening registry key and " + 146 "releasing root registry key handle failed!" ); 147 } 148 throw new WinRegKeyException( "opening registry key failed!" ); 149 } 150 151 // get the size of the longest data component among the key's values 152 long[] subkeys = {0}; 153 long[] maxSubkeyLen = {0}; 154 long[] values = {0}; 155 long[] maxValueNameLen = {0}; 156 long[] maxValueLen = {0}; 157 long[] secDescriptor = {0}; 158 if ( !winreg_RegQueryInfoKey( hkey[0], subkeys, maxSubkeyLen, 159 values, maxValueNameLen, maxValueLen, secDescriptor ) ) { 160 if ( !winreg_RegCloseKey( hkey[0] ) || 161 !winreg_RegCloseKey( hroot[0] ) ) { 162 throw new WinRegKeyException( "retrieving information about " + 163 "the registry key and releasing registry key handles " + 164 "failed!" ); 165 } 166 throw new WinRegKeyException( "retrieving information about " + 167 "the registry key failed!" ); 168 } 169 170 // get the data for the specified value name 171 byte[] buffer = new byte[ (int) maxValueLen[0] ]; 172 long[] size = new long[1]; 173 size[0] = buffer.length; 174 long[] type = new long[1]; 175 type[0] = 0; 176 if ( !winreg_RegQueryValueEx( hkey[0], valueName, type, buffer, 177 size ) ) { 178 if ( !winreg_RegCloseKey( hkey[0] ) || 179 !winreg_RegCloseKey( hroot[0] ) ) { 180 throw new WinRegKeyException( "retrieving data for the " + 181 "specified value name and releasing registry key handles " + 182 "failed!" ); 183 } 184 throw new WinRegKeyException( "retrieving data for the " + 185 "specified value name failed!" ); 186 } 187 188 // release registry key handles 189 if ( !winreg_RegCloseKey( hkey[0] ) || 190 !winreg_RegCloseKey( hroot[0] ) ) { 191 throw new WinRegKeyException( "releasing registry key handles " + 192 "failed!" ); 193 } 194 195 result = new byte[ (int) size[0] ]; 196 System.arraycopy( buffer, 0, result, 0, (int)size[0] ); 197 198 return result; 199 } 200 } 201