xref: /trunk/main/cppuhelper/source/findsofficepath.c (revision 19109cc7d4e1f4b665df04c118b6691809eb39b0)
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 occurred
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 occurred
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_CURRENT_USER, SUBKEYNAME64 );
101     }
102     if ( path == NULL )
103     {
104         /* read the key's default value from HKEY_LOCAL_MACHINE */
105         path = getPathFromRegistryKey( HKEY_LOCAL_MACHINE, SUBKEYNAME );
106     }
107     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 #include <stdio.h>
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 occurred
129  */
130 static char* platformSpecific()
131 {
132     char* path = NULL;
133 
134 #ifdef MACOSX
135     /* On MacOS we have no soffice link under /usr/bin but the default office location is known
136        and we check this only
137      */
138     /* The installation lives in Contents/program (Contents/MacOS holds only the
139        launcher, so that the bundle can be code-signed); soffice is reachable
140        there through a symlink. Before 4.2 everything was in Contents/MacOS, so
141        fall back to that for an older office -- it has to be tried second, as
142        the launcher is in Contents/MacOS in both layouts. */
143     const char* MACDEFAULTOFFICEPATH = "/Applications/OpenOffice.app/Contents/program";
144     const char* MACDEFAULTSOFFICE = "/Applications/OpenOffice.app/Contents/program/soffice";
145     const char* MACLEGACYOFFICEPATH = "/Applications/OpenOffice.app/Contents/MacOS";
146     const char* MACLEGACYSOFFICE = "/Applications/OpenOffice.app/Contents/MacOS/soffice";
147     const char* found = NULL;
148 
149     if ( !access( MACDEFAULTSOFFICE, F_OK ) )
150         found = MACDEFAULTOFFICEPATH;
151     else if ( !access( MACLEGACYSOFFICE, F_OK ) )
152         found = MACLEGACYOFFICEPATH;
153 
154     if ( found )
155     {
156         path = (char*) malloc( strlen(found) + 1 );
157         strcpy( path, found );
158     }
159     return path;
160 #else
161     const int SEPARATOR = '/';
162     const char* PATHSEPARATOR = ":";
163     const char* PATHVARNAME = "PATH";
164     const char* APPENDIX = "/soffice";
165 
166     char* env = NULL;
167     char* str = NULL;
168     char* dir = NULL;
169     char* file = NULL;
170     char* resolved = NULL;
171     char* sep = NULL;
172 
173     char buffer[PATH_MAX];
174     int pos;
175 
176 /* get the value of the PATH environment variable */
177     env = getenv( PATHVARNAME );
178     str = (char*) malloc( strlen( env ) + 1 );
179     strcpy( str, env );
180 
181     /* get the tokens separated by ':' */
182     dir = strtok( str, PATHSEPARATOR );
183 
184     while ( dir )
185     {
186         /* construct soffice file path */
187         file = (char*) malloc( strlen( dir ) + strlen( APPENDIX ) + 1 );
188         strcpy( file, dir );
189         strcat( file, APPENDIX );
190 
191         /* check existence of soffice file */
192         if ( !access( file, F_OK ) )
193         {
194             /* resolve symbolic link */
195             resolved = realpath( file, buffer );
196 
197             if ( resolved != NULL )
198             {
199                 /* get path to program directory */
200                 sep = strrchr( resolved, SEPARATOR );
201 
202                 if ( sep != NULL )
203                 {
204                     pos = sep - resolved;
205                     path = (char*) malloc( pos + 1 );
206                     strncpy( path, resolved, pos );
207                     path[ pos ] = '\0';
208                     free( file );
209                     break;
210                 }
211             }
212         }
213 
214         dir = strtok( NULL, PATHSEPARATOR );
215         free( file );
216     }
217 
218     free( str );
219 
220     return path;
221 #endif
222 }
223 
224 #endif
225 
226 char const* cppuhelper_detail_findSofficePath()
227 {
228     const char* UNOPATHVARNAME = "UNO_PATH";
229 
230     char* path = NULL;
231 
232     /* get the installation path from the UNO_PATH environment variable */
233     path = getenv( UNOPATHVARNAME );
234 
235     if ( path == NULL || strlen( path ) == 0 )
236     {
237         path = platformSpecific();
238     }
239 
240     return path;
241 }
242