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