1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "native_share.h"
22 #include "rtl/bootstrap.hxx"
23 #include "com/sun/star/uno/XComponentContext.hpp"
24 #include "cppuhelper/bootstrap.hxx"
27 #define WIN32_LEAN_AND_MEAN
31 #define INSTALL_PATH L"Software\\LibreOffice\\UNO\\InstallPath"
32 #define UNO_PATH L"UNO_PATH"
36 /* Gets the installation path from the Windows Registry for the specified
39 @param hroot open handle to predefined root registry key
40 @param subKeyName name of the subkey to open
42 @return the installation path or nullptr, if no installation was found or
45 WCHAR
* getPathFromRegistryKey( HKEY hroot
, LPCWSTR subKeyName
)
47 // open the specified registry key
49 if ( RegOpenKeyExW( hroot
, subKeyName
, 0, KEY_READ
, &hkey
) != ERROR_SUCCESS
)
52 struct CloseKeyGuard
{
54 ~CloseKeyGuard() { RegCloseKey( m_hkey
); }
55 } aCloseKeyGuard
{hkey
};
57 // find the type and size of the default value
60 if ( RegQueryValueExW( hkey
, nullptr, nullptr, &type
, nullptr, &size
) != ERROR_SUCCESS
)
63 // get memory to hold the default value
64 std::unique_ptr
<WCHAR
[]> data(new WCHAR
[size
]);
66 // read the default value
67 if ( RegQueryValueExW( hkey
, nullptr, nullptr, &type
, reinterpret_cast<LPBYTE
>(data
.get()), &size
) != ERROR_SUCCESS
)
70 return data
.release();
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[]
80 WCHAR
* getInstallPath()
82 std::unique_ptr
<WCHAR
[]> szInstallPath
;
84 DWORD cChars
= GetEnvironmentVariableW(UNO_PATH
, nullptr, 0);
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
96 szInstallPath
.reset(getPathFromRegistryKey( HKEY_CURRENT_USER
, INSTALL_PATH
));
99 // read the key's default value from HKEY_LOCAL_MACHINE
100 szInstallPath
.reset(getPathFromRegistryKey( HKEY_LOCAL_MACHINE
, INSTALL_PATH
));
103 return szInstallPath
.release();
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.
110 void extendPath(LPCWSTR szPath
)
115 std::unique_ptr
<WCHAR
[]> sEnvPath
;
116 DWORD cChars
= GetEnvironmentVariableW(L
"PATH", nullptr, 0);
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
)
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()))
131 lstrcatW(sNewPath
.get(), L
";");
132 lstrcatW(sNewPath
.get(), sEnvPath
.get());
134 SetEnvironmentVariableW(L
"PATH", sNewPath
.get());
137 HMODULE
loadFromPath(LPCSTR sLibName
)
142 // Convert the ansi file name to wchar_t*
143 int size
= MultiByteToWideChar(CP_ACP
, MB_PRECOMPOSED
, sLibName
, -1, nullptr, 0);
146 std::unique_ptr
<WCHAR
[]> wsLibName(new WCHAR
[size
]);
147 if (!MultiByteToWideChar(CP_ACP
, MB_PRECOMPOSED
, sLibName
, -1, wsLibName
.get(), size
))
150 std::unique_ptr
<WCHAR
[]> szPath(getInstallPath());
154 extendPath(szPath
.get());
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());
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.
170 extern "C" FARPROC WINAPI
delayLoadHook(
171 unsigned int dliNotify
,
175 if (dliNotify
== dliFailLoadLib
)
177 HANDLE h
= loadFromPath(pdli
->szDll
);
178 return reinterpret_cast<FARPROC
>(h
);
185 const PfnDliHook __pfnDliFailureHook2
= delayLoadHook
;
187 using namespace ::com::sun::star
;
188 using namespace ::com::sun::star::uno
;
195 /** Bootstrapping native UNO.
197 Bootstrapping requires the existence of many libraries which are contained
198 in an URE installation. To find and load these libraries the Windows
199 registry keys HKEY_CURRENT_USER\Software\LibreOffice\Layer\URE\1
200 and HKEY_LOCAL_MACHINE\Software\LibreOffice\Layer\URE\1 are examined.
201 These contain a named value UREINSTALLLOCATION which holds a path to the URE
204 public ref
class Bootstrap sealed
206 inline Bootstrap() {}
210 /** Bootstraps the initial component context from a native UNO installation.
212 @see cppuhelper/bootstrap.hxx:defaultBootstrap_InitialComponentContext()
214 static ::unoidl::com::sun::star::uno::XComponentContext
^
215 defaultBootstrap_InitialComponentContext();
217 /** Bootstraps the initial component context from a native UNO installation.
220 a file URL of an ini file, e.g. uno.ini/unorc. (The ini file must
221 reside next to the cppuhelper library)
222 @param bootstrap_parameters
223 bootstrap parameters (maybe null)
225 @see cppuhelper/bootstrap.hxx:defaultBootstrap_InitialComponentContext()
227 static ::unoidl::com::sun::star::uno::XComponentContext
^
228 defaultBootstrap_InitialComponentContext(
229 ::System::String
^ ini_file
,
230 ::System::Collections::IDictionaryEnumerator
^
231 bootstrap_parameters
);
233 /** Bootstraps the initial component context from a native UNO installation.
235 @see cppuhelper/bootstrap.hxx:bootstrap()
237 static ::unoidl::com::sun::star::uno::XComponentContext
^
242 ::unoidl::com::sun::star::uno::XComponentContext
^
243 Bootstrap::defaultBootstrap_InitialComponentContext(
244 ::System::String
^ ini_file
,
245 ::System::Collections::IDictionaryEnumerator
^ bootstrap_parameters
)
247 if (nullptr != bootstrap_parameters
)
249 bootstrap_parameters
->Reset();
250 while (bootstrap_parameters
->MoveNext())
253 String_to_ustring( safe_cast
< ::System::String
^ >(
254 bootstrap_parameters
->Key
) ) );
256 String_to_ustring( safe_cast
< ::System::String
^ >(
257 bootstrap_parameters
->Value
) ) );
259 ::rtl::Bootstrap::set( key
, value
);
263 // bootstrap native uno
264 Reference
< XComponentContext
> xContext
;
265 if (nullptr == ini_file
)
267 xContext
= ::cppu::defaultBootstrap_InitialComponentContext();
271 xContext
= ::cppu::defaultBootstrap_InitialComponentContext(
272 String_to_ustring( safe_cast
< ::System::String
^ >( ini_file
) ) );
275 return safe_cast
< ::unoidl::com::sun::star::uno::XComponentContext
^ >(
276 to_cli( xContext
) );
280 ::unoidl::com::sun::star::uno::XComponentContext
^
281 Bootstrap::defaultBootstrap_InitialComponentContext()
283 return defaultBootstrap_InitialComponentContext( nullptr, nullptr );
286 ::unoidl::com::sun::star::uno::XComponentContext
^ Bootstrap::bootstrap()
288 Reference
<XComponentContext
> xContext
= ::cppu::bootstrap();
289 return safe_cast
< ::unoidl::com::sun::star::uno::XComponentContext
^ >(
290 to_cli( xContext
) );
297 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */