Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / cli_ure / source / native / native_bootstrap.cxx
blob145d6c08536b738a0322f97f929670bc293f23a7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 // Use UNICODE Windows and C API.
30 #define _UNICODE
31 #define UNICODE
33 #ifdef _MSC_VER
34 #pragma warning(push, 1)
35 #endif
36 #include <windows.h>
37 #include "uno/environment.hxx"
38 #ifdef _MSC_VER
39 #pragma warning(pop)
40 #endif
42 #include <tchar.h>
44 #include "native_share.h"
46 #include "rtl/bootstrap.hxx"
47 #include "com/sun/star/uno/XComponentContext.hpp"
48 #include "cppuhelper/bootstrap.hxx"
49 #include <delayimp.h>
50 #include <stdio.h>
52 using namespace ::rtl;
53 using namespace ::com::sun::star;
54 using namespace ::com::sun::star::uno;
56 namespace cli_ure {
57 WCHAR * resolveLink(WCHAR * path);
60 #define INSTALL_PATH L"Software\\LibreOffice\\UNO\\InstallPath"
61 #define URE_LINK L"\\ure-link"
62 #define URE_BIN L"\\bin"
63 #define UNO_PATH L"UNO_PATH"
65 namespace
69 * Gets the installation path from the Windows Registry for the specified
70 * registry key.
72 * @param hroot open handle to predefined root registry key
73 * @param subKeyName name of the subkey to open
75 * @return the installation path or NULL, if no installation was found or
76 * if an error occurred
78 WCHAR* getPathFromRegistryKey( HKEY hroot, LPCWSTR subKeyName )
80 HKEY hkey;
81 DWORD type;
82 TCHAR* data = NULL;
83 DWORD size;
85 /* open the specified registry key */
86 if ( RegOpenKeyEx( hroot, subKeyName, 0, KEY_READ, &hkey ) != ERROR_SUCCESS )
88 return NULL;
91 /* find the type and size of the default value */
92 if ( RegQueryValueEx( hkey, NULL, NULL, &type, NULL, &size) != ERROR_SUCCESS )
94 RegCloseKey( hkey );
95 return NULL;
98 /* get memory to hold the default value */
99 data = new WCHAR[size];
101 /* read the default value */
102 if ( RegQueryValueEx( hkey, NULL, NULL, &type, (LPBYTE) data, &size ) != ERROR_SUCCESS )
104 RegCloseKey( hkey );
105 return NULL;
108 /* release registry key handle */
109 RegCloseKey( hkey );
111 return data;
114 /* If the path does not end with '\' the las segment will be removed.
115 path: C:\a\b
116 -> C:\a
117 @param io_path
118 in/out parameter. The string is not reallocated. Simply a '\0'
119 will be inserted to shorten the string.
121 void oneDirUp(LPTSTR io_path)
123 WCHAR * pEnd = io_path + lstrlen(io_path) - 1;
124 while (pEnd > io_path //prevent crashing if provided string does not contain a backslash
125 && *pEnd != L'\\')
126 pEnd --;
127 *pEnd = L'\0';
131 /* Returns the path to the program folder of the brand layer,
132 for example c:/LibreOffice 3/program
133 This path is either obtained from the environment variable UNO_PATH
134 or the registry item
135 "Software\\LibreOffice\\UNO\\InstallPath"
136 either in HKEY_CURRENT_USER or HKEY_LOCAL_MACHINE
137 The return value must be freed with delete[]
139 WCHAR * getInstallPath()
141 WCHAR * szInstallPath = NULL;
143 DWORD cChars = GetEnvironmentVariable(UNO_PATH, NULL, 0);
144 if (cChars > 0)
146 szInstallPath = new WCHAR[cChars];
147 cChars = GetEnvironmentVariable(UNO_PATH, szInstallPath, cChars);
148 //If PATH is not set then it is no error
149 if (cChars == 0)
151 delete[] szInstallPath;
152 return NULL;
156 if (! szInstallPath)
158 szInstallPath = getPathFromRegistryKey( HKEY_CURRENT_USER, INSTALL_PATH );
159 if ( szInstallPath == NULL )
161 /* read the key's default value from HKEY_LOCAL_MACHINE */
162 szInstallPath = getPathFromRegistryKey( HKEY_LOCAL_MACHINE, INSTALL_PATH );
165 return szInstallPath;
168 /* Returns the path to the URE/bin path, where cppuhelper lib resides.
169 The returned string must be freed with delete[]
171 WCHAR* getUnoPath()
173 WCHAR * szLinkPath = NULL;
174 WCHAR * szUrePath = NULL;
175 WCHAR * szUreBin = NULL; //the return value
177 WCHAR * szInstallPath = getInstallPath();
178 if (szInstallPath)
180 oneDirUp(szInstallPath);
182 //build the path to the ure-link file
183 szUrePath = new WCHAR[MAX_PATH];
184 szUrePath[0] = L'\0';
185 lstrcat(szUrePath, szInstallPath);
186 lstrcat(szUrePath, URE_LINK);
188 //get the path to the actual Ure folder
189 if (cli_ure::resolveLink(szUrePath))
191 //build the path to the URE/bin directory
192 szUreBin = new WCHAR[lstrlen(szUrePath) + lstrlen(URE_BIN) + 1];
193 szUreBin[0] = L'\0';
194 lstrcat(szUreBin, szUrePath);
195 lstrcat(szUreBin, URE_BIN);
198 #if OSL_DEBUG_LEVEL >=2
199 if (szUreBin)
201 fwprintf(stdout,L"[cli_cppuhelper]: Path to URE libraries:\n %s \n", szUreBin);
203 else
205 fwprintf(stdout,L"[cli_cppuhelper]: Failed to determine location of URE.\n");
207 #endif
208 delete[] szInstallPath;
209 delete[] szLinkPath;
210 delete[] szUrePath;
211 return szUreBin;
215 /*We extend the path to contain the Ure/bin folder,
216 so that components can use osl_loadModule with arguments, such as
217 "reg3.dll". That is, the arguments are only the library names.
219 void extendPath(LPCWSTR szUreBinPath)
221 if (!szUreBinPath)
222 return;
224 WCHAR * sEnvPath = NULL;
225 DWORD cChars = GetEnvironmentVariable(L"PATH", sEnvPath, 0);
226 if (cChars > 0)
228 sEnvPath = new WCHAR[cChars];
229 cChars = GetEnvironmentVariable(L"PATH", sEnvPath, cChars);
230 //If PATH is not set then it is no error
231 if (cChars == 0 && GetLastError() != ERROR_ENVVAR_NOT_FOUND)
233 delete[] sEnvPath;
234 return;
237 //prepare the new PATH. Add the Ure/bin directory at the front.
238 //note also adding ';'
239 WCHAR * sNewPath = new WCHAR[lstrlen(sEnvPath) + lstrlen(szUreBinPath) + 2];
240 sNewPath[0] = L'\0';
241 lstrcat(sNewPath, szUreBinPath);
242 if (lstrlen(sEnvPath))
244 lstrcat(sNewPath, L";");
245 lstrcat(sNewPath, sEnvPath);
247 BOOL bSet = SetEnvironmentVariable(L"PATH", sNewPath);
249 delete[] sEnvPath;
250 delete[] sNewPath;
254 HMODULE loadFromPath(LPCWSTR sLibName)
256 if (sLibName == NULL)
257 return NULL;
259 WCHAR * szUreBinPath = getUnoPath();
260 if (!szUreBinPath)
261 return NULL;
263 extendPath(szUreBinPath);
265 WCHAR* szFullPath = new WCHAR[lstrlen(sLibName) + lstrlen(szUreBinPath) + 2];
266 szFullPath[0] = L'\0';
267 lstrcat(szFullPath, szUreBinPath);
268 lstrcat(szFullPath, L"\\");
269 lstrcat(szFullPath, sLibName);
270 HMODULE handle = LoadLibraryEx(szFullPath, NULL,
271 LOAD_WITH_ALTERED_SEARCH_PATH);
273 delete[] szFullPath;
274 delete[] szUreBinPath;
275 return handle;
278 /*Hook for delayed loading of libraries which this library is linked with.
279 This is a failure hook. That is, it is only called when the loading of
280 a library failed. It will be called when loading of cppuhelper failed.
281 Because we extend the PATH to the URE/bin folder while this function is
282 executed (see extendPath), all other libraries are found.
284 extern "C" FARPROC WINAPI delayLoadHook(
285 unsigned dliNotify,
286 PDelayLoadInfo pdli
289 if (dliNotify == dliFailLoadLib)
291 LPWSTR szLibName = NULL;
292 //Convert the ansi file name to wchar_t*
293 int size = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pdli->szDll, -1, NULL, 0);
294 if (size > 0)
296 szLibName = new WCHAR[size];
297 if (! MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pdli->szDll, -1, szLibName, size))
299 return 0;
302 HANDLE h = loadFromPath(szLibName);
303 delete[] szLibName;
304 return (FARPROC) h;
306 return 0;
310 ExternC
311 PfnDliHook __pfnDliFailureHook2 = delayLoadHook;
313 namespace uno
315 namespace util
318 /** Bootstrapping native UNO.
320 Bootstrapping requires the existence of many libraries which are contained
321 in an URE installation. To find and load these libraries the Windows
322 registry keys HKEY_CURRENT_USER\Software\LibreOffice\Layer\URE\1
323 and HKEY_LOCAL_MACHINE\Software\LibreOffice\Layer\URE\1 are examined.
324 These contain a named value UREINSTALLLOCATION which holds a path to the URE
325 installation folder.
327 public __sealed __gc class Bootstrap
329 inline Bootstrap() {}
331 public:
333 /** Bootstraps the initial component context from a native UNO installation.
335 @see cppuhelper/bootstrap.hxx:defaultBootstrap_InitialComponentContext()
337 static ::unoidl::com::sun::star::uno::XComponentContext *
338 defaultBootstrap_InitialComponentContext();
340 /** Bootstraps the initial component context from a native UNO installation.
342 @param ini_file
343 a file URL of an ini file, e.g. uno.ini/unorc. (The ini file must
344 reside next to the cppuhelper library)
345 @param bootstrap_parameters
346 bootstrap parameters (maybe null)
348 @see cppuhelper/bootstrap.hxx:defaultBootstrap_InitialComponentContext()
350 static ::unoidl::com::sun::star::uno::XComponentContext *
351 defaultBootstrap_InitialComponentContext(
352 ::System::String * ini_file,
353 ::System::Collections::IDictionaryEnumerator *
354 bootstrap_parameters );
356 /** Bootstraps the initial component context from a native UNO installation.
358 @see cppuhelper/bootstrap.hxx:bootstrap()
360 static ::unoidl::com::sun::star::uno::XComponentContext *
361 bootstrap();
364 //______________________________________________________________________________
365 ::unoidl::com::sun::star::uno::XComponentContext *
366 Bootstrap::defaultBootstrap_InitialComponentContext(
367 ::System::String * ini_file,
368 ::System::Collections::IDictionaryEnumerator * bootstrap_parameters )
370 if (0 != bootstrap_parameters)
372 bootstrap_parameters->Reset();
373 while (bootstrap_parameters->MoveNext())
375 OUString key(
376 String_to_ustring( __try_cast< ::System::String * >(
377 bootstrap_parameters->get_Key() ) ) );
378 OUString value(
379 String_to_ustring( __try_cast< ::System::String * >(
380 bootstrap_parameters->get_Value() ) ) );
382 ::rtl::Bootstrap::set( key, value );
386 // bootstrap native uno
387 Reference< XComponentContext > xContext;
388 if (0 == ini_file)
390 xContext = ::cppu::defaultBootstrap_InitialComponentContext();
392 else
394 xContext = ::cppu::defaultBootstrap_InitialComponentContext(
395 String_to_ustring( __try_cast< ::System::String * >( ini_file ) ) );
398 return __try_cast< ::unoidl::com::sun::star::uno::XComponentContext * >(
399 to_cli( xContext ) );
402 //______________________________________________________________________________
403 ::unoidl::com::sun::star::uno::XComponentContext *
404 Bootstrap::defaultBootstrap_InitialComponentContext()
406 return defaultBootstrap_InitialComponentContext( 0, 0 );
409 ::unoidl::com::sun::star::uno::XComponentContext * Bootstrap::bootstrap()
411 Reference<XComponentContext> xContext = ::cppu::bootstrap();
412 return __try_cast< ::unoidl::com::sun::star::uno::XComponentContext * >(
413 to_cli( xContext ) );
420 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */