LibreOffice Module cppuhelper (master)  1
findsofficepath.c
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <sal/config.h>
21 
22 #include <stdlib.h>
23 #include <string.h>
24 
26 
27 #if defined(_WIN32)
28 
29 #define WIN32_LEAN_AND_MEAN
30 #include <windows.h>
31 
32 /*
33  * Gets the installation path from the Windows Registry for the specified
34  * registry key.
35  *
36  * @param hroot open handle to predefined root registry key
37  * @param subKeyName name of the subkey to open
38  *
39  * @return the installation path or NULL, if no installation was found or
40  * if an error occurred
41  */
42 static wchar_t* getPathFromRegistryKey( HKEY hroot, const wchar_t* subKeyName )
43 {
44  HKEY hkey;
45  DWORD type;
46  wchar_t* data = NULL;
47  DWORD size;
48 
49  /* open the specified registry key */
50  if ( RegOpenKeyExW( hroot, subKeyName, 0, KEY_READ, &hkey ) != ERROR_SUCCESS )
51  {
52  return NULL;
53  }
54 
55  /* find the type and size of the default value */
56  if ( RegQueryValueExW( hkey, NULL, NULL, &type, NULL, &size) != ERROR_SUCCESS )
57  {
58  RegCloseKey( hkey );
59  return NULL;
60  }
61 
62  /* get memory to hold the default value */
63  data = (wchar_t*) malloc( size + sizeof(wchar_t) );
64 
65  /* read the default value */
66  if ( RegQueryValueExW( hkey, NULL, NULL, &type, (LPBYTE) data, &size ) != ERROR_SUCCESS )
67  {
68  RegCloseKey( hkey );
69  free( data );
70  return NULL;
71  }
72 
73  // According to https://msdn.microsoft.com/en-us/ms724911, If the data has the REG_SZ,
74  // REG_MULTI_SZ or REG_EXPAND_SZ type, the string may not have been stored with the
75  // proper terminating null characters
76  data[size / sizeof(wchar_t)] = 0;
77 
78  /* release registry key handle */
79  RegCloseKey( hkey );
80 
81  return data;
82 }
83 
84 /*
85  * Gets the installation path from the Windows Registry.
86  *
87  * @return the installation path or NULL, if no installation was found or
88  * if an error occurred
89  */
90 static wchar_t* platformSpecific()
91 {
92  const wchar_t* UNOPATHVARNAME = L"UNO_PATH";
93 
94  /* get the installation path from the UNO_PATH environment variable */
95  wchar_t* env = _wgetenv(UNOPATHVARNAME);
96 
97  if (env && env[0])
98  {
99  return wcsdup(env);
100  }
101 
102  const wchar_t* SUBKEYNAME = L"Software\\LibreOffice\\UNO\\InstallPath";
103 
104  /* read the key's default value from HKEY_CURRENT_USER */
105  wchar_t* path = getPathFromRegistryKey( HKEY_CURRENT_USER, SUBKEYNAME );
106 
107  if ( path == NULL )
108  {
109  /* read the key's default value from HKEY_LOCAL_MACHINE */
110  path = getPathFromRegistryKey( HKEY_LOCAL_MACHINE, SUBKEYNAME );
111  }
112 
113  return path;
114 }
115 
116 #else
117 
118 #include <limits.h>
119 
120 /*
121  * Gets the installation path from the PATH environment variable.
122  *
123  * <p>An installation is found, if the executable 'soffice' or a symbolic link
124  * is in one of the directories listed in the PATH environment variable.</p>
125  *
126  * @return the installation path or NULL, if no installation was found or
127  * if an error occurred
128  */
129 static char* platformSpecific(void)
130 {
131  const char* UNOPATHVARNAME = "UNO_PATH";
132 
133  /* get the installation path from the UNO_PATH environment variable */
134  char* env = getenv(UNOPATHVARNAME);
135 
136  const int SEPARATOR = '/';
137  const char* PATHSEPARATOR = ":";
138  const char* PATHVARNAME = "PATH";
139  const char* APPENDIX = "/libreoffice";
140 
141  char* path = NULL;
142  char* str = NULL;
143  char* dir = NULL;
144  char* sep = NULL;
145 
146  char buffer[PATH_MAX];
147  int pos;
148 
149  if (env && env[0])
150  {
151  return strdup(env);
152  }
153 
154  /* get the value of the PATH environment variable */
155  env = getenv( PATHVARNAME );
156  if (env == NULL)
157  return NULL;
158 
159  str = strdup( env );
160  if (str == NULL)
161  return NULL;
162 
163  /* get the tokens separated by ':' */
164  dir = strtok( str, PATHSEPARATOR );
165 
166  while ( dir )
167  {
168  /* construct soffice file path */
169  char* resolved = NULL;
170  char* file = (char*) malloc( strlen( dir ) + strlen( APPENDIX ) + 1 );
171  if (file == NULL)
172  {
173  free(str);
174  return NULL;
175  }
176 
177  strcpy( file, dir );
178  strcat( file, APPENDIX );
179 
180  /* resolve symbolic link */
181  resolved = realpath( file, buffer );
182  if ( resolved != NULL )
183  {
184  /* get path to program directory */
185  sep = strrchr( resolved, SEPARATOR );
186 
187  if ( sep != NULL )
188  {
189  pos = sep - resolved;
190  path = (char*) malloc( pos + 1 );
191  strncpy( path, resolved, pos );
192  path[ pos ] = '\0';
193  free( file );
194  break;
195  }
196  }
197 
198  dir = strtok( NULL, PATHSEPARATOR );
199  free( file );
200  }
201 
202  free( str );
203 
204  return path;
205 }
206 
207 #endif
208 
209 #if defined(_WIN32)
210 wchar_t*
211 #else
212 char*
213 #endif
215 {
216  return platformSpecific();
217 }
218 
219 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define SEPARATOR
return NULL
size_t pos
static char * platformSpecific(void)
size
exports com.sun.star.chart2. data
char * cppuhelper_detail_findSofficePath()
ResultType type
#define PATHSEPARATOR