1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 package com.sun.star.lib.loader; 25 26 import java.io.BufferedInputStream; 27 import java.io.BufferedOutputStream; 28 import java.io.File; 29 import java.io.FileOutputStream; 30 import java.io.InputStream; 31 32 33 /** 34 * This class provides functionality for reading string values from the 35 * Windows Registry. It requires the native library unowinreg.dll. 36 */ 37 final class WinRegKey { 38 39 private String m_rootKeyName; 40 private String m_subKeyName; 41 42 // native methods to access the windows registry winreg_RegOpenClassesRoot( long[] hkresult )43 private static native boolean winreg_RegOpenClassesRoot( long[] hkresult ); winreg_RegOpenCurrentConfig( long[] hkresult )44 private static native boolean winreg_RegOpenCurrentConfig( 45 long[] hkresult ); winreg_RegOpenCurrentUser( long[] hkresult )46 private static native boolean winreg_RegOpenCurrentUser( long[] hkresult ); winreg_RegOpenLocalMachine( long[] hkresult )47 private static native boolean winreg_RegOpenLocalMachine( long[] hkresult ); winreg_RegOpenUsers( long[] hkresult )48 private static native boolean winreg_RegOpenUsers( long[] hkresult ); winreg_RegOpenKeyEx( long parent, String name, long[] hkresult )49 private static native boolean winreg_RegOpenKeyEx( long parent, String name, 50 long[] hkresult ); winreg_RegCloseKey( long hkey )51 private static native boolean winreg_RegCloseKey( long hkey ); winreg_RegQueryValueEx( long hkey, String value, long[] type, byte[] data, long[] size )52 private static native boolean winreg_RegQueryValueEx( 53 long hkey, String value, long[] type, 54 byte[] data, long[] size ); winreg_RegQueryInfoKey( long hkey, long[] subkeys, long[] maxSubkeyLen, long[] values, long[] maxValueNameLen, long[] maxValueLen, long[] secDescriptor )55 private static native boolean winreg_RegQueryInfoKey( 56 long hkey, long[] subkeys, long[] maxSubkeyLen, 57 long[] values, long[] maxValueNameLen, 58 long[] maxValueLen, long[] secDescriptor ); 59 60 // load the native library unowinreg.dll 61 static { 62 try { 63 ClassLoader cl = WinRegKey.class.getClassLoader(); 64 InputStream is = cl.getResourceAsStream( "win/unowinreg.dll" ); 65 if ( is != null ) { 66 // generate a temporary name for lib file and write to temp 67 // location 68 BufferedInputStream istream = new BufferedInputStream( is ); 69 File libfile = File.createTempFile( "unowinreg", ".dll" ); libfile.deleteOnExit()70 libfile.deleteOnExit(); // ensure deletion 71 BufferedOutputStream ostream = new BufferedOutputStream( 72 new FileOutputStream( libfile ) ); 73 int bsize = 2048; int n = 0; 74 byte[] buffer = new byte[bsize]; 75 while ( ( n = istream.read( buffer, 0, bsize ) ) != -1 ) { ostream.write( buffer, 0, n )76 ostream.write( buffer, 0, n ); 77 } istream.close()78 istream.close(); ostream.close()79 ostream.close(); 80 // load library libfile.getPath()81 System.load( libfile.getPath() ); 82 } else { 83 // If the library cannot be found as a class loader resource, 84 // try the global System.loadLibrary(). The JVM will look for 85 // it in the java.library.path. 86 System.loadLibrary( "unowinreg" ); 87 } 88 } catch ( java.lang.Exception e ) { 89 System.err.println( "com.sun.star.lib.loader.WinRegKey: " + 90 "loading of native library failed!" + e ); 91 } 92 } 93 94 /** 95 * Constructs a <code>WinRegKey</code>. 96 */ WinRegKey( String rootKeyName, String subKeyName )97 public WinRegKey( String rootKeyName, String subKeyName ) { 98 m_rootKeyName = rootKeyName; 99 m_subKeyName = subKeyName; 100 } 101 102 /** 103 * Reads a string value for the specified value name. 104 */ getStringValue( String valueName )105 public String getStringValue( String valueName ) throws WinRegKeyException { 106 byte[] data = getValue( valueName ); 107 // remove terminating null character 108 return new String( data, 0, data.length - 1 ); 109 } 110 111 /** 112 * Reads a value for the specified value name. 113 */ getValue( String valueName )114 private byte[] getValue( String valueName ) throws WinRegKeyException { 115 116 byte[] result = null; 117 long[] hkey = {0}; 118 119 // open the specified registry key 120 boolean bRet = false; 121 long[] hroot = {0}; 122 if ( m_rootKeyName.equals( "HKEY_CLASSES_ROOT" ) ) { 123 bRet = winreg_RegOpenClassesRoot( hroot ); 124 } else if ( m_rootKeyName.equals( "HKEY_CURRENT_CONFIG" ) ) { 125 bRet = winreg_RegOpenCurrentConfig( hroot ); 126 } else if ( m_rootKeyName.equals( "HKEY_CURRENT_USER" ) ) { 127 bRet = winreg_RegOpenCurrentUser( hroot ); 128 } else if ( m_rootKeyName.equals( "HKEY_LOCAL_MACHINE" ) ) { 129 bRet = winreg_RegOpenLocalMachine( hroot ); 130 } else if ( m_rootKeyName.equals( "HKEY_USERS" ) ) { 131 bRet = winreg_RegOpenUsers( hroot ); 132 } else { 133 throw new WinRegKeyException( "unknown root registry key!"); 134 } 135 if ( !bRet ) { 136 throw new WinRegKeyException( "opening root registry key " + 137 "failed!" ); 138 } 139 if ( !winreg_RegOpenKeyEx( hroot[0], m_subKeyName, hkey ) ) { 140 if ( !winreg_RegCloseKey( hroot[0] ) ) { 141 throw new WinRegKeyException( "opening registry key and " + 142 "releasing root registry key handle failed!" ); 143 } 144 throw new WinRegKeyException( "opening registry key failed!" ); 145 } 146 147 // get the size of the longest data component among the key's values 148 long[] subkeys = {0}; 149 long[] maxSubkeyLen = {0}; 150 long[] values = {0}; 151 long[] maxValueNameLen = {0}; 152 long[] maxValueLen = {0}; 153 long[] secDescriptor = {0}; 154 if ( !winreg_RegQueryInfoKey( hkey[0], subkeys, maxSubkeyLen, 155 values, maxValueNameLen, maxValueLen, secDescriptor ) ) { 156 if ( !winreg_RegCloseKey( hkey[0] ) || 157 !winreg_RegCloseKey( hroot[0] ) ) { 158 throw new WinRegKeyException( "retrieving information about " + 159 "the registry key and releasing registry key handles " + 160 "failed!" ); 161 } 162 throw new WinRegKeyException( "retrieving information about " + 163 "the registry key failed!" ); 164 } 165 166 // get the data for the specified value name 167 byte[] buffer = new byte[ (int) maxValueLen[0] ]; 168 long[] size = new long[1]; 169 size[0] = buffer.length; 170 long[] type = new long[1]; 171 type[0] = 0; 172 if ( !winreg_RegQueryValueEx( hkey[0], valueName, type, buffer, 173 size ) ) { 174 if ( !winreg_RegCloseKey( hkey[0] ) || 175 !winreg_RegCloseKey( hroot[0] ) ) { 176 throw new WinRegKeyException( "retrieving data for the " + 177 "specified value name and releasing registry key handles " + 178 "failed!" ); 179 } 180 throw new WinRegKeyException( "retrieving data for the " + 181 "specified value name failed!" ); 182 } 183 184 // release registry key handles 185 if ( !winreg_RegCloseKey( hkey[0] ) || 186 !winreg_RegCloseKey( hroot[0] ) ) { 187 throw new WinRegKeyException( "releasing registry key handles " + 188 "failed!" ); 189 } 190 191 result = new byte[ (int) size[0] ]; 192 System.arraycopy( buffer, 0, result, 0, (int)size[0] ); 193 194 return result; 195 } 196 } 197