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 #include "precompiled_cppuhelper.hxx"
25 #include "sal/config.h"
26 
27 #include <stdlib.h>
28 #include <string.h>
29 
30 #if defined WNT
31 
32 #define WIN32_LEAN_AND_MEAN
33 #include <windows.h>
34 
35 /*
36  * Gets the installation path from the Windows Registry for the specified
37  * registry key.
38  *
39  * @param hroot       open handle to predefined root registry key
40  * @param subKeyName  name of the subkey to open
41  *
42  * @return the installation path or NULL, if no installation was found or
43  *         if an error occured
44  */
45 static char* getPathFromRegistryKey( HKEY hroot, const char* subKeyName )
46 {
47     HKEY hkey;
48     DWORD type;
49     char* data = NULL;
50     DWORD size;
51 
52     /* open the specified registry key */
53     if ( RegOpenKeyEx( hroot, subKeyName, 0, KEY_READ, &hkey ) != ERROR_SUCCESS )
54     {
55         return NULL;
56     }
57 
58     /* find the type and size of the default value */
59     if ( RegQueryValueEx( hkey, NULL, NULL, &type, NULL, &size) != ERROR_SUCCESS )
60     {
61         RegCloseKey( hkey );
62         return NULL;
63     }
64 
65     /* get memory to hold the default value */
66     data = (char*) malloc( size );
67 
68     /* read the default value */
69     if ( RegQueryValueEx( hkey, NULL, NULL, &type, (LPBYTE) data, &size ) != ERROR_SUCCESS )
70     {
71         RegCloseKey( hkey );
72         return NULL;
73     }
74 
75     /* release registry key handle */
76     RegCloseKey( hkey );
77 
78     return data;
79 }
80 
81 /*
82  * Gets the installation path from the Windows Registry.
83  *
84  * @return the installation path or NULL, if no installation was found or
85  *         if an error occured
86  */
87 static char* platformSpecific()
88 {
89     const char* SUBKEYNAME = "Software\\OpenOffice\\UNO\\InstallPath";
90     const char* SUBKEYNAME64 = "Software\\Wow6432Node\\OpenOffice\\UNO\\InstallPath";
91 
92     char* path = NULL;
93 
94     /* read the key's default value from HKEY_CURRENT_USER */
95     path = getPathFromRegistryKey( HKEY_CURRENT_USER, SUBKEYNAME );
96 
97     if ( path == NULL )
98     {
99         /* read the key's default value from HKEY_LOCAL_USER 64 */
100         path = getPathFromRegistryKey( HKEY_LOCAL_MACHINE, SUBKEYNAME64 );
101     }
102     else if ( path == NULL )
103     {
104         /* read the key's default value from HKEY_LOCAL_MACHINE */
105         path = getPathFromRegistryKey( HKEY_LOCAL_MACHINE, SUBKEYNAME );
106     }
107     else if ( path == NULL )
108     {
109         /* read the key's default value from HKEY_LOCAL_MACHINE 64*/
110         path = getPathFromRegistryKey( HKEY_LOCAL_MACHINE, SUBKEYNAME64 );
111     }
112 
113     return path;
114 }
115 
116 #else
117 
118 #include <unistd.h>
119 #include <limits.h>
120 
121 /*
122  * Gets the installation path from the PATH environment variable.
123  *
124  * <p>An installation is found, if the executable 'soffice' or a symbolic link
125  * is in one of the directories listed in the PATH environment variable.</p>
126  *
127  * @return the installation path or NULL, if no installation was found or
128  *         if an error occured
129  */
130 static char* platformSpecific()
131 {
132     const int SEPARATOR = '/';
133     const char* PATHSEPARATOR = ":";
134     const char* PATHVARNAME = "PATH";
135     const char* APPENDIX = "/soffice";
136 
137     char* path = NULL;
138     char* env = NULL;
139     char* str = NULL;
140     char* dir = NULL;
141     char* file = NULL;
142     char* resolved = NULL;
143 	char* sep = NULL;
144 
145     char buffer[PATH_MAX];
146     int pos;
147 
148     /* get the value of the PATH environment variable */
149     env = getenv( PATHVARNAME );
150 	str = (char*) malloc( strlen( env ) + 1 );
151 	strcpy( str, env );
152 
153     /* get the tokens separated by ':' */
154     dir = strtok( str, PATHSEPARATOR );
155 
156 	while ( dir )
157 	{
158         /* construct soffice file path */
159         file = (char*) malloc( strlen( dir ) + strlen( APPENDIX ) + 1 );
160 		strcpy( file, dir );
161 		strcat( file, APPENDIX );
162 
163 		/* check existence of soffice file */
164 		if ( !access( file, F_OK ) )
165 		{
166             /* resolve symbolic link */
167 			resolved = realpath( file, buffer );
168 
169             if ( resolved != NULL )
170 			{
171                 /* get path to program directory */
172 				sep = strrchr( resolved, SEPARATOR );
173 
174 				if ( sep != NULL )
175 				{
176                     pos = sep - resolved;
177                     path = (char*) malloc( pos + 1 );
178                     strncpy( path, resolved, pos );
179                     path[ pos ] = '\0';
180                     free( file );
181                     break;
182 				}
183 			}
184 		}
185 
186 		dir = strtok( NULL, PATHSEPARATOR );
187         free( file );
188 	}
189 
190 	free( str );
191 
192     return path;
193 }
194 
195 #endif
196 
197 char const* cppuhelper_detail_findSofficePath()
198 {
199     const char* UNOPATHVARNAME = "UNO_PATH";
200 
201     char* path = NULL;
202 
203     /* get the installation path from the UNO_PATH environment variable */
204     path = getenv( UNOPATHVARNAME );
205 
206     if ( path == NULL || strlen( path ) == 0 )
207     {
208 		path = platformSpecific();
209     }
210 
211     return path;
212 }
213