LibreOffice Module cli_ure (master) 1
native_bootstrap.cxx
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 "native_share.h"
21
22#include "rtl/bootstrap.hxx"
23#include "com/sun/star/uno/XComponentContext.hpp"
25#include <memory>
26#include <stdio.h>
27#define WIN32_LEAN_AND_MEAN
28#include <windows.h>
29#include <delayimp.h>
30
31#define INSTALL_PATH L"Software\\LibreOffice\\UNO\\InstallPath"
32#define UNO_PATH L"UNO_PATH"
33
34namespace {
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 nullptr, if no installation was found or
43 if an error occurred
44*/
45WCHAR* getPathFromRegistryKey( HKEY hroot, LPCWSTR subKeyName )
46{
47 // open the specified registry key
48 HKEY hkey;
49 if ( RegOpenKeyExW( hroot, subKeyName, 0, KEY_READ, &hkey ) != ERROR_SUCCESS )
50 return nullptr;
51
52 struct CloseKeyGuard {
53 HKEY m_hkey;
54 ~CloseKeyGuard() { RegCloseKey( m_hkey ); }
55 } aCloseKeyGuard{hkey};
56
57 // find the type and size of the default value
58 DWORD type;
59 DWORD size;
60 if ( RegQueryValueExW( hkey, nullptr, nullptr, &type, nullptr, &size ) != ERROR_SUCCESS )
61 return nullptr;
62
63 // get memory to hold the default value
64 std::unique_ptr<WCHAR[]> data(new WCHAR[size]);
65
66 // read the default value
67 if ( RegQueryValueExW( hkey, nullptr, nullptr, &type, reinterpret_cast<LPBYTE>(data.get()), &size ) != ERROR_SUCCESS )
68 return nullptr;
69
70 return data.release();
71}
72
73/* Returns the path to the program folder of the brand layer,
74 for example C:/Program Files/LibreOffice/program
75 This path is either obtained from the environment variable UNO_PATH
76 or the registry item "Software\\LibreOffice\\UNO\\InstallPath"
77 either in HKEY_CURRENT_USER or HKEY_LOCAL_MACHINE
78 The return value must be freed with delete[]
79*/
80WCHAR* getInstallPath()
81{
82 std::unique_ptr<WCHAR[]> szInstallPath;
83
84 DWORD cChars = GetEnvironmentVariableW(UNO_PATH, nullptr, 0);
85 if (cChars > 0)
86 {
87 szInstallPath.reset(new WCHAR[cChars]);
88 cChars = GetEnvironmentVariableW(UNO_PATH, szInstallPath.get(), cChars);
89 // If PATH is not set then it is no error
90 if (cChars == 0)
91 return nullptr;
92 }
93
94 if (! szInstallPath)
95 {
96 szInstallPath.reset(getPathFromRegistryKey( HKEY_CURRENT_USER, INSTALL_PATH ));
97 if (! szInstallPath)
98 {
99 // read the key's default value from HKEY_LOCAL_MACHINE
100 szInstallPath.reset(getPathFromRegistryKey( HKEY_LOCAL_MACHINE, INSTALL_PATH ));
101 }
102 }
103 return szInstallPath.release();
104}
105
106/* We extend the path to contain the install folder,
107 so that components can use osl_loadModule with arguments, such as
108 "reg3.dll". That is, the arguments are only the library names.
109*/
110void extendPath(LPCWSTR szPath)
111{
112 if (!szPath)
113 return;
114
115 std::unique_ptr<WCHAR[]> sEnvPath;
116 DWORD cChars = GetEnvironmentVariableW(L"PATH", nullptr, 0);
117 if (cChars > 0)
118 {
119 sEnvPath.reset(new WCHAR[cChars]);
120 cChars = GetEnvironmentVariableW(L"PATH", sEnvPath.get(), cChars);
121 // If PATH is not set then it is no error
122 if (cChars == 0 && GetLastError() != ERROR_ENVVAR_NOT_FOUND)
123 return;
124 }
125 // Prepare the new PATH. Add the directory at the front.
126 // Note also adding ';'
127 std::unique_ptr<WCHAR[]> sNewPath(new WCHAR[lstrlenW(sEnvPath.get()) + lstrlenW(szPath) + 2]);
128 lstrcpyW(sNewPath.get(), szPath);
129 if (lstrlenW(sEnvPath.get()))
130 {
131 lstrcatW(sNewPath.get(), L";");
132 lstrcatW(sNewPath.get(), sEnvPath.get());
133 }
134 SetEnvironmentVariableW(L"PATH", sNewPath.get());
135}
136
137HMODULE loadFromPath(LPCSTR sLibName)
138{
139 if (!sLibName)
140 return nullptr;
141
142 // Convert the ansi file name to wchar_t*
143 int size = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sLibName, -1, nullptr, 0);
144 if (size == 0)
145 return nullptr;
146 std::unique_ptr<WCHAR[]> wsLibName(new WCHAR[size]);
147 if (!MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sLibName, -1, wsLibName.get(), size))
148 return nullptr;
149
150 std::unique_ptr<WCHAR[]> szPath(getInstallPath());
151 if (!szPath)
152 return nullptr;
153
154 extendPath(szPath.get());
155
156 std::unique_ptr<WCHAR[]> szFullPath(new WCHAR[lstrlenW(wsLibName.get()) + lstrlenW(szPath.get()) + 2]);
157 lstrcpyW(szFullPath.get(), szPath.get());
158 lstrcatW(szFullPath.get(), L"\\");
159 lstrcatW(szFullPath.get(), wsLibName.get());
160 HMODULE handle = LoadLibraryW(szFullPath.get());
161 return handle;
162}
163
164/* Hook for delayed loading of libraries which this library is linked with.
165 This is a failure hook. That is, it is only called when the loading of
166 a library failed. It will be called when loading of cppuhelper failed.
167 Because we extend the PATH to the install folder while this function is
168 executed (see extendPath), all other libraries are found.
169*/
170extern "C" FARPROC WINAPI delayLoadHook(
171 unsigned int dliNotify,
172 PDelayLoadInfo pdli
173 )
174{
175 if (dliNotify == dliFailLoadLib)
176 {
177 HANDLE h = loadFromPath(pdli->szDll);
178 return reinterpret_cast<FARPROC>(h);
179 }
180 return nullptr;
181}
182}
183
184ExternC
185const PfnDliHook __pfnDliFailureHook2 = delayLoadHook;
186
187using namespace ::com::sun::star;
188using namespace ::com::sun::star::uno;
189
190namespace uno
191{
192namespace util
193{
194
204public ref class Bootstrap sealed
205{
206 inline Bootstrap() {}
207
208public:
209
214 static ::unoidl::com::sun::star::uno::XComponentContext ^
216
227 static ::unoidl::com::sun::star::uno::XComponentContext ^
229 ::System::String ^ ini_file,
230 ::System::Collections::IDictionaryEnumerator ^
231 bootstrap_parameters );
232
237 static ::unoidl::com::sun::star::uno::XComponentContext ^
239};
240
241
242::unoidl::com::sun::star::uno::XComponentContext ^
243Bootstrap::defaultBootstrap_InitialComponentContext(
244 ::System::String ^ ini_file,
245 ::System::Collections::IDictionaryEnumerator ^ bootstrap_parameters )
246{
247 if (nullptr != bootstrap_parameters)
248 {
249 bootstrap_parameters->Reset();
250 while (bootstrap_parameters->MoveNext())
251 {
252 OUString key(
253 String_to_ustring( safe_cast< ::System::String ^ >(
254 bootstrap_parameters->Key ) ) );
255 OUString value(
256 String_to_ustring( safe_cast< ::System::String ^ >(
257 bootstrap_parameters->Value ) ) );
258
259 ::rtl::Bootstrap::set( key, value );
260 }
261 }
262
263 // bootstrap native uno
264 Reference< XComponentContext > xContext;
265 if (nullptr == ini_file)
266 {
267 xContext = ::cppu::defaultBootstrap_InitialComponentContext();
268 }
269 else
270 {
271 xContext = ::cppu::defaultBootstrap_InitialComponentContext(
272 String_to_ustring( safe_cast< ::System::String ^ >( ini_file ) ) );
273 }
274
275 return safe_cast< ::unoidl::com::sun::star::uno::XComponentContext ^ >(
276 to_cli( xContext ) );
277}
278
279
280::unoidl::com::sun::star::uno::XComponentContext ^
281Bootstrap::defaultBootstrap_InitialComponentContext()
282{
283 return defaultBootstrap_InitialComponentContext( nullptr, nullptr );
284}
285
286::unoidl::com::sun::star::uno::XComponentContext ^ Bootstrap::bootstrap()
287{
288 Reference<XComponentContext> xContext = ::cppu::bootstrap();
289 return safe_cast< ::unoidl::com::sun::star::uno::XComponentContext ^ >(
290 to_cli( xContext ) );
291
292}
293
294}
295}
296
297/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
::unoidl::com::sun::star::uno::XComponentContext defaultBootstrap_InitialComponentContext(::System::String ^ ini_file, ::System::Collections::IDictionaryEnumerator ^ bootstrap_parameters)
Bootstraps the initial component context from a native UNO installation.
::unoidl::com::sun::star::uno::XComponentContext bootstrap()
Bootstraps the initial component context from a native UNO installation.
::unoidl::com::sun::star::uno::XComponentContext defaultBootstrap_InitialComponentContext()
Bootstraps the initial component context from a native UNO installation.
Any value
size
CPPUHELPER_DLLPUBLIC css::uno::Reference< css::uno::XComponentContext > SAL_CALL defaultBootstrap_InitialComponentContext()
const rtl::Bootstrap * Bootstrap()
OUString String_to_ustring(::System::String ^ str)
Definition: native_share.h:42
inline ::System::Object to_cli(css::uno::Reference< T > const &x)
Definition: native_share.h:50
sal_Int32 h
ExternC const PfnDliHook __pfnDliFailureHook2
#define UNO_PATH
#define INSTALL_PATH
ResultType type