diff options
Diffstat (limited to 'cli_ure/source/native')
-rw-r--r-- | cli_ure/source/native/assembly.cxx | 26 | ||||
-rw-r--r-- | cli_ure/source/native/cli_cppuhelper_config | 11 | ||||
-rw-r--r-- | cli_ure/source/native/native_bootstrap.cxx | 297 | ||||
-rw-r--r-- | cli_ure/source/native/native_share.h | 112 | ||||
-rw-r--r-- | cli_ure/source/native/path.cxx | 48 |
5 files changed, 494 insertions, 0 deletions
diff --git a/cli_ure/source/native/assembly.cxx b/cli_ure/source/native/assembly.cxx new file mode 100644 index 000000000..521f5a484 --- /dev/null +++ b/cli_ure/source/native/assembly.cxx @@ -0,0 +1,26 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +[assembly:System::Reflection::AssemblyProduct( "CLI-UNO Language Binding" )]; +[assembly:System::Reflection::AssemblyDescription( "CLI-UNO Helper Library" )]; +[assembly:System::Reflection::AssemblyDelaySign(true)]; +[assembly:System::Reflection::AssemblyCompany( "OpenOffice.org" )]; +[assembly:System::Reflection::AssemblyVersion( "@CLI_CPPUHELPER_NEW_VERSION@" )]; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/cli_ure/source/native/cli_cppuhelper_config b/cli_ure/source/native/cli_cppuhelper_config new file mode 100644 index 000000000..627a3a564 --- /dev/null +++ b/cli_ure/source/native/cli_cppuhelper_config @@ -0,0 +1,11 @@ +<?xml version="1.0"?> +<configuration> + <runtime> + <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> + <dependentAssembly> + <assemblyIdentity name="cli_cppuhelper" publicKeyToken="ce2cb7e279207b9e"/> + <bindingRedirect oldVersion="CLI_CPPUHELPER_OLD_VERSION" newVersion="CLI_CPPUHELPER_NEW_VERSION" /> + </dependentAssembly> + </assemblyBinding> + </runtime> +</configuration>
\ No newline at end of file diff --git a/cli_ure/source/native/native_bootstrap.cxx b/cli_ure/source/native/native_bootstrap.cxx new file mode 100644 index 000000000..f26a634c2 --- /dev/null +++ b/cli_ure/source/native/native_bootstrap.cxx @@ -0,0 +1,297 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "native_share.h" + +#include "rtl/bootstrap.hxx" +#include "com/sun/star/uno/XComponentContext.hpp" +#include "cppuhelper/bootstrap.hxx" +#include <memory> +#include <stdio.h> +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <delayimp.h> + +#define INSTALL_PATH L"Software\\LibreOffice\\UNO\\InstallPath" +#define UNO_PATH L"UNO_PATH" + +namespace { + +/* Gets the installation path from the Windows Registry for the specified + registry key. + + @param hroot open handle to predefined root registry key + @param subKeyName name of the subkey to open + + @return the installation path or nullptr, if no installation was found or + if an error occurred +*/ +WCHAR* getPathFromRegistryKey( HKEY hroot, LPCWSTR subKeyName ) +{ + // open the specified registry key + HKEY hkey; + if ( RegOpenKeyExW( hroot, subKeyName, 0, KEY_READ, &hkey ) != ERROR_SUCCESS ) + return nullptr; + + struct CloseKeyGuard { + HKEY m_hkey; + ~CloseKeyGuard() { RegCloseKey( m_hkey ); } + } aCloseKeyGuard{hkey}; + + // find the type and size of the default value + DWORD type; + DWORD size; + if ( RegQueryValueExW( hkey, nullptr, nullptr, &type, nullptr, &size ) != ERROR_SUCCESS ) + return nullptr; + + // get memory to hold the default value + std::unique_ptr<WCHAR[]> data(new WCHAR[size]); + + // read the default value + if ( RegQueryValueExW( hkey, nullptr, nullptr, &type, reinterpret_cast<LPBYTE>(data.get()), &size ) != ERROR_SUCCESS ) + return nullptr; + + return data.release(); +} + +/* Returns the path to the program folder of the brand layer, + for example C:/Program Files/LibreOffice/program + This path is either obtained from the environment variable UNO_PATH + or the registry item "Software\\LibreOffice\\UNO\\InstallPath" + either in HKEY_CURRENT_USER or HKEY_LOCAL_MACHINE + The return value must be freed with delete[] +*/ +WCHAR* getInstallPath() +{ + std::unique_ptr<WCHAR[]> szInstallPath; + + DWORD cChars = GetEnvironmentVariableW(UNO_PATH, nullptr, 0); + if (cChars > 0) + { + szInstallPath.reset(new WCHAR[cChars]); + cChars = GetEnvironmentVariableW(UNO_PATH, szInstallPath.get(), cChars); + // If PATH is not set then it is no error + if (cChars == 0) + return nullptr; + } + + if (! szInstallPath) + { + szInstallPath.reset(getPathFromRegistryKey( HKEY_CURRENT_USER, INSTALL_PATH )); + if (! szInstallPath) + { + // read the key's default value from HKEY_LOCAL_MACHINE + szInstallPath.reset(getPathFromRegistryKey( HKEY_LOCAL_MACHINE, INSTALL_PATH )); + } + } + return szInstallPath.release(); +} + +/* We extend the path to contain the install folder, + so that components can use osl_loadModule with arguments, such as + "reg3.dll". That is, the arguments are only the library names. +*/ +void extendPath(LPCWSTR szPath) +{ + if (!szPath) + return; + + std::unique_ptr<WCHAR[]> sEnvPath; + DWORD cChars = GetEnvironmentVariableW(L"PATH", nullptr, 0); + if (cChars > 0) + { + sEnvPath.reset(new WCHAR[cChars]); + cChars = GetEnvironmentVariableW(L"PATH", sEnvPath.get(), cChars); + // If PATH is not set then it is no error + if (cChars == 0 && GetLastError() != ERROR_ENVVAR_NOT_FOUND) + return; + } + // Prepare the new PATH. Add the directory at the front. + // Note also adding ';' + std::unique_ptr<WCHAR[]> sNewPath(new WCHAR[lstrlenW(sEnvPath.get()) + lstrlenW(szPath) + 2]); + lstrcpyW(sNewPath.get(), szPath); + if (lstrlenW(sEnvPath.get())) + { + lstrcatW(sNewPath.get(), L";"); + lstrcatW(sNewPath.get(), sEnvPath.get()); + } + SetEnvironmentVariableW(L"PATH", sNewPath.get()); +} + +HMODULE loadFromPath(LPCSTR sLibName) +{ + if (!sLibName) + return nullptr; + + // Convert the ansi file name to wchar_t* + int size = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sLibName, -1, nullptr, 0); + if (size == 0) + return nullptr; + std::unique_ptr<WCHAR[]> wsLibName(new WCHAR[size]); + if (!MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sLibName, -1, wsLibName.get(), size)) + return nullptr; + + std::unique_ptr<WCHAR[]> szPath(getInstallPath()); + if (!szPath) + return nullptr; + + extendPath(szPath.get()); + + std::unique_ptr<WCHAR[]> szFullPath(new WCHAR[lstrlenW(wsLibName.get()) + lstrlenW(szPath.get()) + 2]); + lstrcpyW(szFullPath.get(), szPath.get()); + lstrcatW(szFullPath.get(), L"\\"); + lstrcatW(szFullPath.get(), wsLibName.get()); + HMODULE handle = LoadLibraryW(szFullPath.get()); + return handle; +} + +/* Hook for delayed loading of libraries which this library is linked with. + This is a failure hook. That is, it is only called when the loading of + a library failed. It will be called when loading of cppuhelper failed. + Because we extend the PATH to the install folder while this function is + executed (see extendPath), all other libraries are found. +*/ +extern "C" FARPROC WINAPI delayLoadHook( + unsigned int dliNotify, + PDelayLoadInfo pdli + ) +{ + if (dliNotify == dliFailLoadLib) + { + HANDLE h = loadFromPath(pdli->szDll); + return reinterpret_cast<FARPROC>(h); + } + return nullptr; +} +} + +ExternC +const PfnDliHook __pfnDliFailureHook2 = delayLoadHook; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +namespace uno +{ +namespace util +{ + +/** Bootstrapping native UNO. + + Bootstrapping requires the existence of many libraries which are contained + in an URE installation. To find and load these libraries the Windows + registry keys HKEY_CURRENT_USER\Software\LibreOffice\Layer\URE\1 + and HKEY_LOCAL_MACHINE\Software\LibreOffice\Layer\URE\1 are examined. + These contain a named value UREINSTALLLOCATION which holds a path to the URE + installation folder. +*/ +public ref class Bootstrap sealed +{ + inline Bootstrap() {} + +public: + + /** Bootstraps the initial component context from a native UNO installation. + + @see cppuhelper/bootstrap.hxx:defaultBootstrap_InitialComponentContext() + */ + static ::unoidl::com::sun::star::uno::XComponentContext ^ + defaultBootstrap_InitialComponentContext(); + + /** Bootstraps the initial component context from a native UNO installation. + + @param ini_file + a file URL of an ini file, e.g. uno.ini/unorc. (The ini file must + reside next to the cppuhelper library) + @param bootstrap_parameters + bootstrap parameters (maybe null) + + @see cppuhelper/bootstrap.hxx:defaultBootstrap_InitialComponentContext() + */ + static ::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. + + @see cppuhelper/bootstrap.hxx:bootstrap() + */ + static ::unoidl::com::sun::star::uno::XComponentContext ^ + bootstrap(); +}; + + +::unoidl::com::sun::star::uno::XComponentContext ^ +Bootstrap::defaultBootstrap_InitialComponentContext( + ::System::String ^ ini_file, + ::System::Collections::IDictionaryEnumerator ^ bootstrap_parameters ) +{ + if (nullptr != bootstrap_parameters) + { + bootstrap_parameters->Reset(); + while (bootstrap_parameters->MoveNext()) + { + OUString key( + String_to_ustring( safe_cast< ::System::String ^ >( + bootstrap_parameters->Key ) ) ); + OUString value( + String_to_ustring( safe_cast< ::System::String ^ >( + bootstrap_parameters->Value ) ) ); + + ::rtl::Bootstrap::set( key, value ); + } + } + + // bootstrap native uno + Reference< XComponentContext > xContext; + if (nullptr == ini_file) + { + xContext = ::cppu::defaultBootstrap_InitialComponentContext(); + } + else + { + xContext = ::cppu::defaultBootstrap_InitialComponentContext( + String_to_ustring( safe_cast< ::System::String ^ >( ini_file ) ) ); + } + + return safe_cast< ::unoidl::com::sun::star::uno::XComponentContext ^ >( + to_cli( xContext ) ); +} + + +::unoidl::com::sun::star::uno::XComponentContext ^ +Bootstrap::defaultBootstrap_InitialComponentContext() +{ + return defaultBootstrap_InitialComponentContext( nullptr, nullptr ); +} + +::unoidl::com::sun::star::uno::XComponentContext ^ Bootstrap::bootstrap() +{ + Reference<XComponentContext> xContext = ::cppu::bootstrap(); + return safe_cast< ::unoidl::com::sun::star::uno::XComponentContext ^ >( + to_cli( xContext ) ); + +} + +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/cli_ure/source/native/native_share.h b/cli_ure/source/native/native_share.h new file mode 100644 index 000000000..f733d2558 --- /dev/null +++ b/cli_ure/source/native/native_share.h @@ -0,0 +1,112 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#using "cli_ure.dll" +#using "cli_uretypes.dll" + +#include "rtl/ustring.hxx" +#include <uno/lbnames.h> +#include "uno/mapping.hxx" + +#include <vcclr.h> + + +namespace uno +{ +namespace util +{ + + +inline ::System::String ^ ustring_to_String( OUString const & ustr ) +{ + return gcnew ::System::String( + reinterpret_cast<wchar_t const *>(ustr.getStr()), 0, ustr.getLength()); +} + +inline OUString String_to_ustring( ::System::String ^ str ) +{ + OSL_ASSERT( sizeof (wchar_t) == sizeof (sal_Unicode) ); + pin_ptr<wchar_t const> chars = PtrToStringChars( str ); + return OUString(reinterpret_cast<sal_Unicode const *>(chars), str->Length); +} + +template< typename T > +inline ::System::Object ^ to_cli( + css::uno::Reference< T > const & x ) +{ + css::uno::Mapping mapping( + CPPU_CURRENT_LANGUAGE_BINDING_NAME, UNO_LB_CLI ); + OSL_ASSERT( mapping.is() ); + if (! mapping.is()) + { + throw css::uno::RuntimeException( + "cannot get mapping from C++ to CLI!", + css::uno::Reference< + css::uno::XInterface >() ); + } + + intptr_t intptr = + reinterpret_cast< intptr_t >( + mapping.mapInterface( x.get(), cppu::UnoType<decltype(x)>::get() ) ); + ::System::Runtime::InteropServices::GCHandle ^ handle = ::System::Runtime::InteropServices::GCHandle::FromIntPtr(::System::IntPtr(intptr)); + ::System::Object ^ ret = handle->Target; + handle->Free(); + return ret; +} + +template< typename T > +inline void to_uno( + css::uno::Reference< T > * pRet, ::System::Object ^ x ) +{ + css::uno::Mapping mapping( + UNO_LB_CLI, CPPU_CURRENT_LANGUAGE_BINDING_NAME ); + OSL_ASSERT( mapping.is() ); + if (! mapping.is()) + { + throw css::uno::RuntimeException( + "cannot get mapping from CLI to C++!", + css::uno::Reference< + css::uno::XInterface >() ); + } + + ::System::Runtime::InteropServices::GCHandle handle( + ::System::Runtime::InteropServices::GCHandle::Alloc( x ) ); + T * ret = 0; + mapping.mapInterface( + reinterpret_cast< void ** >( &ret ), + reinterpret_cast< void * >( + ::System::Runtime::InteropServices::GCHandle::op_Explicit( handle ) +#if defined _WIN64 + .ToInt64() +#elif defined _WIN32 + .ToInt32() +#else +#error ERROR: either _WIN64 or _WIN32 must be defined + ERROR: either _WIN64 or _WIN32 must be defined +#endif + ), + cppu::UnoType<T>::get() ); + handle.Free(); + pRet->set( ret, SAL_NO_ACQUIRE /* takeover ownership */ ); +} + +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/cli_ure/source/native/path.cxx b/cli_ure/source/native/path.cxx new file mode 100644 index 000000000..6fae51314 --- /dev/null +++ b/cli_ure/source/native/path.cxx @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "sal/config.h" + +#if defined(_WIN32) + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + +#include "sal/types.h" + +namespace cli_ure { + +SAL_DLLPUBLIC_EXPORT WCHAR * filename(WCHAR * path) { + WCHAR * f = path; + for (WCHAR * p = path;;) { + switch (*p++) { + case L'\0': + return f; + case L'\\': + f = p; + break; + } + } +} + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |