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