Avoid potential negative array index access to cached text.
[LibreOffice.git] / cli_ure / source / native / native_bootstrap.cxx
blobf26a634c2aa14c89639ebfbc97bb8d7151f3e276
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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"
25 #include <memory>
26 #include <stdio.h>
27 #define WIN32_LEAN_AND_MEAN
28 #include <windows.h>
29 #include <delayimp.h>
31 #define INSTALL_PATH L"Software\\LibreOffice\\UNO\\InstallPath"
32 #define UNO_PATH L"UNO_PATH"
34 namespace {
36 /* Gets the installation path from the Windows Registry for the specified
37 registry key.
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
43 if an error occurred
45 WCHAR* getPathFromRegistryKey( HKEY hroot, LPCWSTR subKeyName )
47 // open the specified registry key
48 HKEY hkey;
49 if ( RegOpenKeyExW( hroot, subKeyName, 0, KEY_READ, &hkey ) != ERROR_SUCCESS )
50 return nullptr;
52 struct CloseKeyGuard {
53 HKEY m_hkey;
54 ~CloseKeyGuard() { RegCloseKey( m_hkey ); }
55 } aCloseKeyGuard{hkey};
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;
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 )
68 return nullptr;
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);
85 if (cChars > 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
90 if (cChars == 0)
91 return nullptr;
94 if (! szInstallPath)
96 szInstallPath.reset(getPathFromRegistryKey( HKEY_CURRENT_USER, INSTALL_PATH ));
97 if (! szInstallPath)
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)
112 if (!szPath)
113 return;
115 std::unique_ptr<WCHAR[]> sEnvPath;
116 DWORD cChars = GetEnvironmentVariableW(L"PATH", nullptr, 0);
117 if (cChars > 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)
123 return;
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)
139 if (!sLibName)
140 return nullptr;
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;
150 std::unique_ptr<WCHAR[]> szPath(getInstallPath());
151 if (!szPath)
152 return nullptr;
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());
161 return handle;
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,
172 PDelayLoadInfo pdli
175 if (dliNotify == dliFailLoadLib)
177 HANDLE h = loadFromPath(pdli->szDll);
178 return reinterpret_cast<FARPROC>(h);
180 return nullptr;
184 ExternC
185 const PfnDliHook __pfnDliFailureHook2 = delayLoadHook;
187 using namespace ::com::sun::star;
188 using namespace ::com::sun::star::uno;
190 namespace uno
192 namespace util
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
202 installation folder.
204 public ref class Bootstrap sealed
206 inline Bootstrap() {}
208 public:
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.
219 @param ini_file
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 ^
238 bootstrap();
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())
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 ) ) );
259 ::rtl::Bootstrap::set( key, value );
263 // bootstrap native uno
264 Reference< XComponentContext > xContext;
265 if (nullptr == ini_file)
267 xContext = ::cppu::defaultBootstrap_InitialComponentContext();
269 else
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: */