1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // Use UNICODE Windows and C API. 25 #define _UNICODE 26 #define UNICODE 27 28 #ifdef _MSC_VER 29 #pragma warning(push, 1) 30 #endif 31 #include <windows.h> 32 #include "uno/environment.hxx" 33 #ifdef _MSC_VER 34 #pragma warning(pop) 35 #endif 36 37 #include <tchar.h> 38 39 #include "native_share.h" 40 41 #include "rtl/bootstrap.hxx" 42 #include "com/sun/star/uno/XComponentContext.hpp" 43 #include "cppuhelper/bootstrap.hxx" 44 #include <delayimp.h> 45 #include <stdio.h> 46 47 using namespace ::rtl; 48 using namespace ::com::sun::star; 49 using namespace ::com::sun::star::uno; 50 51 namespace cli_ure { 52 WCHAR * resolveLink(WCHAR * path); 53 } 54 55 // INSTALL_PATH value needs to correspond to the Windows registry subkey 56 // in main\scp2\source\ooo\registryitem_ooo.scp 57 #define INSTALL_PATH L"Software\\OpenOffice\\UNO\\InstallPath" 58 #define INSTALL_PATH_64 L"Software\\Wow6432Node\\OpenOffice\\UNO\\InstallPath" 59 #define UNO_PATH L"UNO_PATH" 60 61 namespace 62 { 63 64 /* 65 * Gets the installation path from the Windows Registry for the specified 66 * registry key. 67 * 68 * @param hroot open handle to predefined root registry key 69 * @param subKeyName name of the subkey to open 70 * 71 * @return the installation path or NULL, if no installation was found or 72 * if an error occurred 73 */ 74 WCHAR* getPathFromRegistryKey( HKEY hroot, LPCWSTR subKeyName ) 75 { 76 HKEY hkey; 77 DWORD type; 78 TCHAR* data = NULL; 79 DWORD size; 80 81 /* open the specified registry key */ 82 if ( RegOpenKeyEx( hroot, subKeyName, 0, KEY_READ, &hkey ) != ERROR_SUCCESS ) 83 { 84 return NULL; 85 } 86 87 /* find the type and size of the default value */ 88 if ( RegQueryValueEx( hkey, NULL, NULL, &type, NULL, &size) != ERROR_SUCCESS ) 89 { 90 RegCloseKey( hkey ); 91 return NULL; 92 } 93 94 /* get memory to hold the default value */ 95 data = new WCHAR[size]; 96 97 /* read the default value */ 98 if ( RegQueryValueEx( hkey, NULL, NULL, &type, (LPBYTE) data, &size ) != ERROR_SUCCESS ) 99 { 100 RegCloseKey( hkey ); 101 return NULL; 102 } 103 104 /* release registry key handle */ 105 RegCloseKey( hkey ); 106 107 return data; 108 } 109 110 /* Returns the path to the program folder of the brand layer, 111 for example c:/openoffice.org 3/program 112 This path is either obtained from the environment variable UNO_PATH 113 or the registry item 114 "Software\\OpenOffice\\UNO\\InstallPath" 115 either in HKEY_CURRENT_USER or HKEY_LOCAL_MACHINE 116 The return value must be freed with delete[] 117 */ 118 WCHAR * getInstallPath() 119 { 120 WCHAR * szInstallPath = NULL; 121 122 DWORD cChars = GetEnvironmentVariable(UNO_PATH, NULL, 0); 123 if (cChars > 0) 124 { 125 szInstallPath = new WCHAR[cChars+1]; 126 cChars = GetEnvironmentVariable(UNO_PATH, szInstallPath, cChars+1); 127 //If PATH is not set then it is no error 128 if (cChars == 0) 129 { 130 delete[] szInstallPath; 131 return NULL; 132 } 133 } 134 135 if (! szInstallPath) 136 { 137 szInstallPath = getPathFromRegistryKey( HKEY_CURRENT_USER, INSTALL_PATH ); 138 if ( szInstallPath == NULL ) 139 { 140 /* read the key's default value from HKEY_LOCAL_USER */ 141 szInstallPath = getPathFromRegistryKey( HKEY_CURRENT_USER, INSTALL_PATH_64 ); 142 } 143 if ( szInstallPath == NULL ) 144 { 145 /* read the key's default value from HKEY_LOCAL_MACHINE */ 146 szInstallPath = getPathFromRegistryKey( HKEY_LOCAL_MACHINE, INSTALL_PATH ); 147 } 148 if ( szInstallPath == NULL ) 149 { 150 /* read the key's default value from HKEY_LOCAL_MACHINE */ 151 szInstallPath = getPathFromRegistryKey( HKEY_LOCAL_MACHINE, INSTALL_PATH_64 ); 152 } 153 } 154 return szInstallPath; 155 } 156 157 158 /*We extend the path to contain the Ure/bin folder, 159 so that components can use osl_loadModule with arguments, such as 160 "reg3.dll". That is, the arguments are only the library names. 161 */ 162 void extendPath(LPCWSTR szUreBinPath) 163 { 164 if (!szUreBinPath) 165 return; 166 167 WCHAR * sEnvPath = NULL; 168 DWORD cChars = GetEnvironmentVariable(L"PATH", sEnvPath, 0); 169 if (cChars > 0) 170 { 171 sEnvPath = new WCHAR[cChars]; 172 cChars = GetEnvironmentVariable(L"PATH", sEnvPath, cChars); 173 //If PATH is not set then it is no error 174 if (cChars == 0 && GetLastError() != ERROR_ENVVAR_NOT_FOUND) 175 { 176 delete[] sEnvPath; 177 return; 178 } 179 } 180 //prepare the new PATH. Add the Ure/bin directory at the front. 181 //note also adding ';' 182 WCHAR * sNewPath = new WCHAR[lstrlen(sEnvPath) + lstrlen(szUreBinPath) + 2]; 183 sNewPath[0] = L'\0'; 184 lstrcat(sNewPath, szUreBinPath); 185 if (lstrlen(sEnvPath)) 186 { 187 lstrcat(sNewPath, L";"); 188 lstrcat(sNewPath, sEnvPath); 189 } 190 BOOL bSet = SetEnvironmentVariable(L"PATH", sNewPath); 191 192 delete[] sEnvPath; 193 delete[] sNewPath; 194 } 195 196 197 HMODULE loadFromPath(LPCWSTR sLibName) 198 { 199 if (sLibName == NULL) 200 return NULL; 201 202 WCHAR * szUreBinPath = getInstallPath(); 203 if (!szUreBinPath) 204 return NULL; 205 206 extendPath(szUreBinPath); 207 208 WCHAR* szFullPath = new WCHAR[lstrlen(sLibName) + lstrlen(szUreBinPath) + 2]; 209 szFullPath[0] = L'\0'; 210 lstrcat(szFullPath, szUreBinPath); 211 lstrcat(szFullPath, L"\\"); 212 lstrcat(szFullPath, sLibName); 213 HMODULE handle = LoadLibraryEx(szFullPath, NULL, 214 LOAD_WITH_ALTERED_SEARCH_PATH); 215 216 delete[] szFullPath; 217 delete[] szUreBinPath; 218 return handle; 219 } 220 221 /*Hook for delayed loading of libraries which this library is linked with. 222 This is a failure hook. That is, it is only called when the loading of 223 a library failed. It will be called when loading of cppuhelper failed. 224 Because we extend the PATH to the URE/bin folder while this function is 225 executed (see extendPath), all other libraries are found. 226 */ 227 extern "C" FARPROC WINAPI delayLoadHook( 228 unsigned dliNotify, 229 PDelayLoadInfo pdli 230 ) 231 { 232 if (dliNotify == dliFailLoadLib) 233 { 234 LPWSTR szLibName = NULL; 235 //Convert the ansi file name to wchar_t* 236 int size = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pdli->szDll, -1, NULL, 0); 237 if (size > 0) 238 { 239 szLibName = new WCHAR[size]; 240 if (! MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pdli->szDll, -1, szLibName, size)) 241 { 242 return 0; 243 } 244 } 245 HANDLE h = loadFromPath(szLibName); 246 delete[] szLibName; 247 return (FARPROC) h; 248 } 249 return 0; 250 } 251 } 252 253 ExternC 254 PfnDliHook __pfnDliFailureHook2 = delayLoadHook; 255 256 namespace uno 257 { 258 namespace util 259 { 260 261 /** Bootstrapping native UNO. 262 263 Bootstrapping requires the existence of many libraries which are contained 264 in an URE installation. To find and load these libraries the Windows 265 registry keys HKEY_CURRENT_USER\Software\OpenOffice\UNO\InstallPath 266 and HKEY_LOCAL_MACHINE\Software\OpenOffice\UNO\InstallPath are examined. 267 The default value contain the path to the office prgoram dir. No seaparate URE 268 anymore. 269 */ 270 public __sealed __gc class Bootstrap 271 { 272 inline Bootstrap() {} 273 274 public: 275 276 /** Bootstraps the initial component context from a native UNO installation. 277 278 @see cppuhelper/bootstrap.hxx:defaultBootstrap_InitialComponentContext() 279 */ 280 static ::unoidl::com::sun::star::uno::XComponentContext * 281 defaultBootstrap_InitialComponentContext(); 282 283 /** Bootstraps the initial component context from a native UNO installation. 284 285 @param ini_file 286 a file URL of an ini file, e.g. uno.ini/unorc. (The ini file must 287 reside next to the cppuhelper library) 288 @param bootstrap_parameters 289 bootstrap parameters (maybe null) 290 291 @see cppuhelper/bootstrap.hxx:defaultBootstrap_InitialComponentContext() 292 */ 293 static ::unoidl::com::sun::star::uno::XComponentContext * 294 defaultBootstrap_InitialComponentContext( 295 ::System::String * ini_file, 296 ::System::Collections::IDictionaryEnumerator * 297 bootstrap_parameters ); 298 299 /** Bootstraps the initial component context from a native UNO installation. 300 301 @see cppuhelper/bootstrap.hxx:bootstrap() 302 */ 303 static ::unoidl::com::sun::star::uno::XComponentContext * 304 bootstrap(); 305 }; 306 307 //______________________________________________________________________________ 308 ::unoidl::com::sun::star::uno::XComponentContext * 309 Bootstrap::defaultBootstrap_InitialComponentContext( 310 ::System::String * ini_file, 311 ::System::Collections::IDictionaryEnumerator * bootstrap_parameters ) 312 { 313 if (0 != bootstrap_parameters) 314 { 315 bootstrap_parameters->Reset(); 316 while (bootstrap_parameters->MoveNext()) 317 { 318 OUString key( 319 String_to_ustring( __try_cast< ::System::String * >( 320 bootstrap_parameters->get_Key() ) ) ); 321 OUString value( 322 String_to_ustring( __try_cast< ::System::String * >( 323 bootstrap_parameters->get_Value() ) ) ); 324 325 ::rtl::Bootstrap::set( key, value ); 326 } 327 } 328 329 // bootstrap native uno 330 Reference< XComponentContext > xContext; 331 if (0 == ini_file) 332 { 333 xContext = ::cppu::defaultBootstrap_InitialComponentContext(); 334 } 335 else 336 { 337 xContext = ::cppu::defaultBootstrap_InitialComponentContext( 338 String_to_ustring( __try_cast< ::System::String * >( ini_file ) ) ); 339 } 340 341 return __try_cast< ::unoidl::com::sun::star::uno::XComponentContext * >( 342 to_cli( xContext ) ); 343 } 344 345 //______________________________________________________________________________ 346 ::unoidl::com::sun::star::uno::XComponentContext * 347 Bootstrap::defaultBootstrap_InitialComponentContext() 348 { 349 return defaultBootstrap_InitialComponentContext( 0, 0 ); 350 } 351 352 ::unoidl::com::sun::star::uno::XComponentContext * Bootstrap::bootstrap() 353 { 354 Reference<XComponentContext> xContext = ::cppu::bootstrap(); 355 return __try_cast< ::unoidl::com::sun::star::uno::XComponentContext * >( 356 to_cli( xContext ) ); 357 358 } 359 360 } 361 } 362