update dev300-m58
[ooovba.git] / cli_ure / source / native / native_bootstrap.cxx
blob4cb020b0e17e5640c818948d544c5a7c362892ca
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: native_bootstrap.cxx,v $
10 * $Revision: 1.14.12.5 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // Use UNICODE Windows and C API.
32 #define _UNICODE
33 #define UNICODE
35 #ifdef _MSC_VER
36 #pragma warning(push, 1)
37 #endif
38 #include <windows.h>
39 #include "uno/environment.hxx"
40 #ifdef _MSC_VER
41 #pragma warning(pop)
42 #endif
44 #include <tchar.h>
46 #include "native_share.h"
48 #include "rtl/bootstrap.hxx"
49 #include "com/sun/star/uno/XComponentContext.hpp"
50 #include "cppuhelper/bootstrap.hxx"
51 #include <delayimp.h>
52 #include <stdio.h>
54 using namespace ::rtl;
55 using namespace ::com::sun::star;
56 using namespace ::com::sun::star::uno;
58 namespace cli_ure {
59 WCHAR * resolveLink(WCHAR * path);
62 #define INSTALL_PATH L"Software\\OpenOffice.org\\UNO\\InstallPath"
63 #define BASIS_LINK L"\\basis-link"
64 #define URE_LINK L"\\ure-link"
65 #define URE_BIN L"\\bin"
66 #define UNO_PATH L"UNO_PATH"
68 namespace
72 * Gets the installation path from the Windows Registry for the specified
73 * registry key.
75 * @param hroot open handle to predefined root registry key
76 * @param subKeyName name of the subkey to open
78 * @return the installation path or NULL, if no installation was found or
79 * if an error occured
81 WCHAR* getPathFromRegistryKey( HKEY hroot, LPCWSTR subKeyName )
83 HKEY hkey;
84 DWORD type;
85 TCHAR* data = NULL;
86 DWORD size;
88 /* open the specified registry key */
89 if ( RegOpenKeyEx( hroot, subKeyName, 0, KEY_READ, &hkey ) != ERROR_SUCCESS )
91 return NULL;
94 /* find the type and size of the default value */
95 if ( RegQueryValueEx( hkey, NULL, NULL, &type, NULL, &size) != ERROR_SUCCESS )
97 RegCloseKey( hkey );
98 return NULL;
101 /* get memory to hold the default value */
102 data = new WCHAR[size];
104 /* read the default value */
105 if ( RegQueryValueEx( hkey, NULL, NULL, &type, (LPBYTE) data, &size ) != ERROR_SUCCESS )
107 RegCloseKey( hkey );
108 return NULL;
111 /* release registry key handle */
112 RegCloseKey( hkey );
114 return data;
117 /* If the path does not end with '\' the las segment will be removed.
118 path: C:\a\b
119 -> C:\a
120 @param io_path
121 in/out parameter. The string is not reallocated. Simply a '\0'
122 will be inserted to shorten the string.
124 void oneDirUp(LPTSTR io_path)
126 WCHAR * pEnd = io_path + lstrlen(io_path) - 1;
127 while (pEnd > io_path //prevent crashing if provided string does not contain a backslash
128 && *pEnd != L'\\')
129 pEnd --;
130 *pEnd = L'\0';
134 /* Returns the path to the program folder of the brand layer,
135 for example c:/openoffice.org 3/program
136 This path is either obtained from the environment variable UNO_PATH
137 or the registry item
138 "Software\\OpenOffice.org\\UNO\\InstallPath"
139 either in HKEY_CURRENT_USER or HKEY_LOCAL_MACHINE
140 The return value must be freed with delete[]
142 WCHAR * getInstallPath()
144 WCHAR * szInstallPath = NULL;
146 DWORD cChars = GetEnvironmentVariable(UNO_PATH, NULL, 0);
147 if (cChars > 0)
149 szInstallPath = new WCHAR[cChars];
150 cChars = GetEnvironmentVariable(UNO_PATH, szInstallPath, cChars);
151 //If PATH is not set then it is no error
152 if (cChars == 0)
154 delete[] szInstallPath;
155 return NULL;
159 if (! szInstallPath)
161 szInstallPath = getPathFromRegistryKey( HKEY_CURRENT_USER, INSTALL_PATH );
162 if ( szInstallPath == NULL )
164 /* read the key's default value from HKEY_LOCAL_MACHINE */
165 szInstallPath = getPathFromRegistryKey( HKEY_LOCAL_MACHINE, INSTALL_PATH );
168 return szInstallPath;
171 /* Returns the path to the URE/bin path, where cppuhelper lib resides.
172 The returned string must be freed with delete[]
174 WCHAR* getUnoPath()
176 WCHAR * szLinkPath = NULL;
177 WCHAR * szUrePath = NULL;
178 WCHAR * szUreBin = NULL; //the return value
180 WCHAR * szInstallPath = getInstallPath();
181 if (szInstallPath)
183 //build the path tho the basis-link file
184 oneDirUp(szInstallPath);
185 int sizeLinkPath = lstrlen(szInstallPath) + lstrlen(INSTALL_PATH) + 1;
186 if (sizeLinkPath < MAX_PATH)
187 sizeLinkPath = MAX_PATH;
188 szLinkPath = new WCHAR[sizeLinkPath];
189 szLinkPath[0] = L'\0';
190 lstrcat(szLinkPath, szInstallPath);
191 lstrcat(szLinkPath, BASIS_LINK);
193 //get the path to the actual Basis folder
194 if (cli_ure::resolveLink(szLinkPath))
196 //build the path to the ure-link file
197 int sizeUrePath = lstrlen(szLinkPath) + lstrlen(URE_LINK) + 1;
198 if (sizeUrePath < MAX_PATH)
199 sizeUrePath = MAX_PATH;
200 szUrePath = new WCHAR[sizeUrePath];
201 szUrePath[0] = L'\0';
202 lstrcat(szUrePath, szLinkPath);
203 lstrcat(szUrePath, URE_LINK);
205 //get the path to the actual Ure folder
206 if (cli_ure::resolveLink(szUrePath))
208 //build the path to the URE/bin directory
209 szUreBin = new WCHAR[lstrlen(szUrePath) + lstrlen(URE_BIN) + 1];
210 szUreBin[0] = L'\0';
211 lstrcat(szUreBin, szUrePath);
212 lstrcat(szUreBin, URE_BIN);
216 #if OSL_DEBUG_LEVEL >=2
217 if (szUreBin)
219 fwprintf(stdout,L"[cli_cppuhelper]: Path to URE libraries:\n %s \n", szUreBin);
221 else
223 fwprintf(stdout,L"[cli_cppuhelper]: Failed to determine location of URE.\n");
225 #endif
226 delete[] szInstallPath;
227 delete[] szLinkPath;
228 delete[] szUrePath;
229 return szUreBin;
233 /*We extend the path to contain the Ure/bin folder,
234 so that components can use osl_loadModule with arguments, such as
235 "reg3.dll". That is, the arguments are only the library names.
237 void extendPath(LPCWSTR szUreBinPath)
239 if (!szUreBinPath)
240 return;
242 WCHAR * sEnvPath = NULL;
243 DWORD cChars = GetEnvironmentVariable(L"PATH", sEnvPath, 0);
244 if (cChars > 0)
246 sEnvPath = new WCHAR[cChars];
247 cChars = GetEnvironmentVariable(L"PATH", sEnvPath, cChars);
248 //If PATH is not set then it is no error
249 if (cChars == 0 && GetLastError() != ERROR_ENVVAR_NOT_FOUND)
251 delete[] sEnvPath;
252 return;
255 //prepare the new PATH. Add the Ure/bin directory at the front.
256 //note also adding ';'
257 WCHAR * sNewPath = new WCHAR[lstrlen(sEnvPath) + lstrlen(szUreBinPath) + 2];
258 sNewPath[0] = L'\0';
259 lstrcat(sNewPath, szUreBinPath);
260 if (lstrlen(sEnvPath))
262 lstrcat(sNewPath, L";");
263 lstrcat(sNewPath, sEnvPath);
265 BOOL bSet = SetEnvironmentVariable(L"PATH", sNewPath);
267 delete[] sEnvPath;
268 delete[] sNewPath;
272 HMODULE loadFromPath(LPCWSTR sLibName)
274 if (sLibName == NULL)
275 return NULL;
277 WCHAR * szUreBinPath = getUnoPath();
278 if (!szUreBinPath)
279 return NULL;
281 extendPath(szUreBinPath);
283 WCHAR* szFullPath = new WCHAR[lstrlen(sLibName) + lstrlen(szUreBinPath) + 2];
284 szFullPath[0] = L'\0';
285 lstrcat(szFullPath, szUreBinPath);
286 lstrcat(szFullPath, L"\\");
287 lstrcat(szFullPath, sLibName);
288 HMODULE handle = LoadLibraryEx(szFullPath, NULL,
289 LOAD_WITH_ALTERED_SEARCH_PATH);
291 delete[] szFullPath;
292 delete[] szUreBinPath;
293 return handle;
296 /*Hook for delayed loading of libraries which this library is linked with.
297 This is a failure hook. That is, it is only called when the loading of
298 a library failed. It will be called when loading of cppuhelper failed.
299 Because we extend the PATH to the URE/bin folder while this function is
300 executed (see extendPath), all other libraries are found.
302 extern "C" FARPROC WINAPI delayLoadHook(
303 unsigned dliNotify,
304 PDelayLoadInfo pdli
307 if (dliNotify == dliFailLoadLib)
309 LPWSTR szLibName = NULL;
310 //Convert the ansi file name to wchar_t*
311 int size = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pdli->szDll, -1, NULL, 0);
312 if (size > 0)
314 szLibName = new WCHAR[size];
315 if (! MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pdli->szDll, -1, szLibName, size))
317 return 0;
320 HANDLE h = loadFromPath(szLibName);
321 delete[] szLibName;
322 return (FARPROC) h;
324 return 0;
328 ExternC
329 PfnDliHook __pfnDliFailureHook2 = delayLoadHook;
331 namespace uno
333 namespace util
336 /** Bootstrapping native UNO.
338 Bootstrapping requires the existence of many libraries which are contained
339 in an URE installation. To find and load these libraries the Windows
340 registry keys HKEY_CURRENT_USER\Software\OpenOffice.org\Layer\URE\1
341 and HKEY_LOCAL_MACHINE\Software\OpenOffice.org\Layer\URE\1 are examined.
342 These contain a named value UREINSTALLLOCATION which holds a path to the URE
343 installation folder.
345 public __sealed __gc class Bootstrap
347 inline Bootstrap() {}
349 public:
351 /** Bootstraps the initial component context from a native UNO installation.
353 @see cppuhelper/bootstrap.hxx:defaultBootstrap_InitialComponentContext()
355 static ::unoidl::com::sun::star::uno::XComponentContext *
356 defaultBootstrap_InitialComponentContext();
358 /** Bootstraps the initial component context from a native UNO installation.
360 @param ini_file
361 a file URL of an ini file, e.g. uno.ini/unorc. (The ini file must
362 reside next to the cppuhelper library)
363 @param bootstrap_parameters
364 bootstrap parameters (maybe null)
366 @see cppuhelper/bootstrap.hxx:defaultBootstrap_InitialComponentContext()
368 static ::unoidl::com::sun::star::uno::XComponentContext *
369 defaultBootstrap_InitialComponentContext(
370 ::System::String * ini_file,
371 ::System::Collections::IDictionaryEnumerator *
372 bootstrap_parameters );
374 /** Bootstraps the initial component context from a native UNO installation.
376 @see cppuhelper/bootstrap.hxx:bootstrap()
378 static ::unoidl::com::sun::star::uno::XComponentContext *
379 bootstrap();
382 //______________________________________________________________________________
383 ::unoidl::com::sun::star::uno::XComponentContext *
384 Bootstrap::defaultBootstrap_InitialComponentContext(
385 ::System::String * ini_file,
386 ::System::Collections::IDictionaryEnumerator * bootstrap_parameters )
388 if (0 != bootstrap_parameters)
390 bootstrap_parameters->Reset();
391 while (bootstrap_parameters->MoveNext())
393 OUString key(
394 String_to_ustring( __try_cast< ::System::String * >(
395 bootstrap_parameters->get_Key() ) ) );
396 OUString value(
397 String_to_ustring( __try_cast< ::System::String * >(
398 bootstrap_parameters->get_Value() ) ) );
400 ::rtl::Bootstrap::set( key, value );
404 // bootstrap native uno
405 Reference< XComponentContext > xContext;
406 if (0 == ini_file)
408 xContext = ::cppu::defaultBootstrap_InitialComponentContext();
410 else
412 xContext = ::cppu::defaultBootstrap_InitialComponentContext(
413 String_to_ustring( __try_cast< ::System::String * >( ini_file ) ) );
416 return __try_cast< ::unoidl::com::sun::star::uno::XComponentContext * >(
417 to_cli( xContext ) );
420 //______________________________________________________________________________
421 ::unoidl::com::sun::star::uno::XComponentContext *
422 Bootstrap::defaultBootstrap_InitialComponentContext()
424 return defaultBootstrap_InitialComponentContext( 0, 0 );
427 ::unoidl::com::sun::star::uno::XComponentContext * Bootstrap::bootstrap()
429 Reference<XComponentContext> xContext = ::cppu::bootstrap();
430 return __try_cast< ::unoidl::com::sun::star::uno::XComponentContext * >(
431 to_cli( xContext ) );