1*9d7e27acSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*9d7e27acSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*9d7e27acSAndrew Rist * or more contributor license agreements. See the NOTICE file 5*9d7e27acSAndrew Rist * distributed with this work for additional information 6*9d7e27acSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*9d7e27acSAndrew Rist * to you under the Apache License, Version 2.0 (the 8*9d7e27acSAndrew Rist * "License"); you may not use this file except in compliance 9*9d7e27acSAndrew Rist * with the License. You may obtain a copy of the License at 10*9d7e27acSAndrew Rist * 11*9d7e27acSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*9d7e27acSAndrew Rist * 13*9d7e27acSAndrew Rist * Unless required by applicable law or agreed to in writing, 14*9d7e27acSAndrew Rist * software distributed under the License is distributed on an 15*9d7e27acSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*9d7e27acSAndrew Rist * KIND, either express or implied. See the License for the 17*9d7e27acSAndrew Rist * specific language governing permissions and limitations 18*9d7e27acSAndrew Rist * under the License. 19*9d7e27acSAndrew Rist * 20*9d7e27acSAndrew Rist *************************************************************/ 21*9d7e27acSAndrew Rist 22*9d7e27acSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_cppuhelper.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <string.h> 28cdf0e10cSrcweir #include <vector> 29cdf0e10cSrcweir 30cdf0e10cSrcweir #include "rtl/process.h" 31cdf0e10cSrcweir #include "rtl/bootstrap.hxx" 32cdf0e10cSrcweir #include "rtl/random.h" 33cdf0e10cSrcweir #include "rtl/string.hxx" 34cdf0e10cSrcweir #include "rtl/ustrbuf.hxx" 35cdf0e10cSrcweir #include "rtl/uri.hxx" 36cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0 37cdf0e10cSrcweir #include "rtl/strbuf.hxx" 38cdf0e10cSrcweir #endif 39cdf0e10cSrcweir #include "osl/diagnose.h" 40cdf0e10cSrcweir #include "osl/file.hxx" 41cdf0e10cSrcweir #include "osl/module.hxx" 42cdf0e10cSrcweir #include "osl/security.hxx" 43cdf0e10cSrcweir #include "osl/thread.hxx" 44cdf0e10cSrcweir 45cdf0e10cSrcweir #include "cppuhelper/shlib.hxx" 46cdf0e10cSrcweir #include "cppuhelper/bootstrap.hxx" 47cdf0e10cSrcweir #include "cppuhelper/component_context.hxx" 48cdf0e10cSrcweir #include "cppuhelper/access_control.hxx" 49cdf0e10cSrcweir #include "cppuhelper/findsofficepath.h" 50cdf0e10cSrcweir 51cdf0e10cSrcweir #include "com/sun/star/uno/XComponentContext.hpp" 52cdf0e10cSrcweir #include "com/sun/star/uno/XCurrentContext.hpp" 53cdf0e10cSrcweir 54cdf0e10cSrcweir #include "com/sun/star/lang/XSingleServiceFactory.hpp" 55cdf0e10cSrcweir #include "com/sun/star/lang/XSingleComponentFactory.hpp" 56cdf0e10cSrcweir #include "com/sun/star/lang/XInitialization.hpp" 57cdf0e10cSrcweir #include "com/sun/star/lang/XServiceInfo.hpp" 58cdf0e10cSrcweir #include "com/sun/star/registry/XSimpleRegistry.hpp" 59cdf0e10cSrcweir #include "com/sun/star/container/XSet.hpp" 60cdf0e10cSrcweir #include "com/sun/star/beans/PropertyValue.hpp" 61cdf0e10cSrcweir #include "com/sun/star/io/IOException.hpp" 62cdf0e10cSrcweir #include "com/sun/star/bridge/UnoUrlResolver.hpp" 63cdf0e10cSrcweir #include "com/sun/star/bridge/XUnoUrlResolver.hpp" 64cdf0e10cSrcweir 65cdf0e10cSrcweir #include "macro_expander.hxx" 66cdf0e10cSrcweir 67cdf0e10cSrcweir #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) 68cdf0e10cSrcweir #define ARLEN(x) sizeof (x) / sizeof *(x) 69cdf0e10cSrcweir 70cdf0e10cSrcweir 71cdf0e10cSrcweir using namespace ::rtl; 72cdf0e10cSrcweir using namespace ::osl; 73cdf0e10cSrcweir using namespace ::com::sun::star; 74cdf0e10cSrcweir using namespace ::com::sun::star::uno; 75cdf0e10cSrcweir 76cdf0e10cSrcweir namespace cppu 77cdf0e10cSrcweir { 78cdf0e10cSrcweir 79cdf0e10cSrcweir OUString const & get_this_libpath() 80cdf0e10cSrcweir { 81cdf0e10cSrcweir static OUString s_path; 82cdf0e10cSrcweir if (0 == s_path.getLength()) 83cdf0e10cSrcweir { 84cdf0e10cSrcweir OUString path; 85cdf0e10cSrcweir Module::getUrlFromAddress( reinterpret_cast<oslGenericFunction>(get_this_libpath), path ); 86cdf0e10cSrcweir path = path.copy( 0, path.lastIndexOf( '/' ) ); 87cdf0e10cSrcweir MutexGuard guard( Mutex::getGlobalMutex() ); 88cdf0e10cSrcweir if (0 == s_path.getLength()) 89cdf0e10cSrcweir s_path = path; 90cdf0e10cSrcweir } 91cdf0e10cSrcweir return s_path; 92cdf0e10cSrcweir } 93cdf0e10cSrcweir 94cdf0e10cSrcweir Bootstrap const & get_unorc() SAL_THROW( () ) 95cdf0e10cSrcweir { 96cdf0e10cSrcweir static rtlBootstrapHandle s_bstrap = 0; 97cdf0e10cSrcweir if (! s_bstrap) 98cdf0e10cSrcweir { 99cdf0e10cSrcweir OUString iniName( 100cdf0e10cSrcweir get_this_libpath() + OUSTR("/" SAL_CONFIGFILE("uno")) ); 101cdf0e10cSrcweir rtlBootstrapHandle bstrap = rtl_bootstrap_args_open( iniName.pData ); 102cdf0e10cSrcweir 103cdf0e10cSrcweir ClearableMutexGuard guard( Mutex::getGlobalMutex() ); 104cdf0e10cSrcweir if (s_bstrap) 105cdf0e10cSrcweir { 106cdf0e10cSrcweir guard.clear(); 107cdf0e10cSrcweir rtl_bootstrap_args_close( bstrap ); 108cdf0e10cSrcweir } 109cdf0e10cSrcweir else 110cdf0e10cSrcweir { 111cdf0e10cSrcweir s_bstrap = bstrap; 112cdf0e10cSrcweir } 113cdf0e10cSrcweir } 114cdf0e10cSrcweir return *(Bootstrap const *)&s_bstrap; 115cdf0e10cSrcweir } 116cdf0e10cSrcweir 117cdf0e10cSrcweir 118cdf0e10cSrcweir void addFactories( 119cdf0e10cSrcweir char const * const * ppNames /* lib, implname, ..., 0 */, 120cdf0e10cSrcweir OUString const & bootstrapPath, 121cdf0e10cSrcweir Reference< lang::XMultiComponentFactory > const & xMgr, 122cdf0e10cSrcweir Reference< registry::XRegistryKey > const & xKey ) 123cdf0e10cSrcweir SAL_THROW( (Exception) ) 124cdf0e10cSrcweir { 125cdf0e10cSrcweir Reference< container::XSet > xSet( xMgr, UNO_QUERY ); 126cdf0e10cSrcweir OSL_ASSERT( xSet.is() ); 127cdf0e10cSrcweir Reference< lang::XMultiServiceFactory > xSF( xMgr, UNO_QUERY ); 128cdf0e10cSrcweir 129cdf0e10cSrcweir while (*ppNames) 130cdf0e10cSrcweir { 131cdf0e10cSrcweir OUString lib( OUString::createFromAscii( *ppNames++ ) ); 132cdf0e10cSrcweir OUString implName( OUString::createFromAscii( *ppNames++ ) ); 133cdf0e10cSrcweir 134cdf0e10cSrcweir Any aFac( makeAny( loadSharedLibComponentFactory( 135cdf0e10cSrcweir lib, bootstrapPath, implName, xSF, xKey ) ) ); 136cdf0e10cSrcweir xSet->insert( aFac ); 137cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 138cdf0e10cSrcweir if (xSet->has( aFac )) 139cdf0e10cSrcweir { 140cdf0e10cSrcweir Reference< lang::XServiceInfo > xInfo; 141cdf0e10cSrcweir if (aFac >>= xInfo) 142cdf0e10cSrcweir { 143cdf0e10cSrcweir ::fprintf( 144cdf0e10cSrcweir stderr, "> implementation %s supports: ", ppNames[ -1 ] ); 145cdf0e10cSrcweir Sequence< OUString > supported( 146cdf0e10cSrcweir xInfo->getSupportedServiceNames() ); 147cdf0e10cSrcweir for ( sal_Int32 nPos = supported.getLength(); nPos--; ) 148cdf0e10cSrcweir { 149cdf0e10cSrcweir OString str( OUStringToOString( 150cdf0e10cSrcweir supported[ nPos ], RTL_TEXTENCODING_ASCII_US ) ); 151cdf0e10cSrcweir ::fprintf( stderr, nPos ? "%s, " : "%s\n", str.getStr() ); 152cdf0e10cSrcweir } 153cdf0e10cSrcweir } 154cdf0e10cSrcweir else 155cdf0e10cSrcweir { 156cdf0e10cSrcweir ::fprintf( 157cdf0e10cSrcweir stderr, 158cdf0e10cSrcweir "> implementation %s provides NO lang::XServiceInfo!!!\n", 159cdf0e10cSrcweir ppNames[ -1 ] ); 160cdf0e10cSrcweir } 161cdf0e10cSrcweir } 162cdf0e10cSrcweir #endif 163cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0 164cdf0e10cSrcweir if (! xSet->has( aFac )) 165cdf0e10cSrcweir { 166cdf0e10cSrcweir OStringBuffer buf( 64 ); 167cdf0e10cSrcweir buf.append( "### failed inserting shared lib \"" ); 168cdf0e10cSrcweir buf.append( ppNames[ -2 ] ); 169cdf0e10cSrcweir buf.append( "\"!!!" ); 170cdf0e10cSrcweir OString str( buf.makeStringAndClear() ); 171cdf0e10cSrcweir OSL_ENSURE( 0, str.getStr() ); 172cdf0e10cSrcweir } 173cdf0e10cSrcweir #endif 174cdf0e10cSrcweir } 175cdf0e10cSrcweir } 176cdf0e10cSrcweir 177cdf0e10cSrcweir // private forward decl 178cdf0e10cSrcweir Reference< lang::XMultiComponentFactory > bootstrapInitialSF( 179cdf0e10cSrcweir OUString const & rBootstrapPath ) 180cdf0e10cSrcweir SAL_THROW( (Exception) ); 181cdf0e10cSrcweir 182cdf0e10cSrcweir Reference< XComponentContext > bootstrapInitialContext( 183cdf0e10cSrcweir Reference< lang::XMultiComponentFactory > const & xSF, 184cdf0e10cSrcweir Reference< registry::XSimpleRegistry > const & types_xRegistry, 185cdf0e10cSrcweir Reference< registry::XSimpleRegistry > const & services_xRegistry, 186cdf0e10cSrcweir OUString const & rBootstrapPath, Bootstrap const & bootstrap ) 187cdf0e10cSrcweir SAL_THROW( (Exception) ); 188cdf0e10cSrcweir 189cdf0e10cSrcweir Reference< XComponentContext > SAL_CALL createInitialCfgComponentContext( 190cdf0e10cSrcweir ContextEntry_Init const * pEntries, sal_Int32 nEntries, 191cdf0e10cSrcweir Reference< XComponentContext > const & xDelegate ) 192cdf0e10cSrcweir SAL_THROW( () ); 193cdf0e10cSrcweir 194cdf0e10cSrcweir Reference< registry::XSimpleRegistry > SAL_CALL createRegistryWrapper( 195cdf0e10cSrcweir const Reference< XComponentContext >& xContext ); 196cdf0e10cSrcweir 197cdf0e10cSrcweir namespace { 198cdf0e10cSrcweir 199cdf0e10cSrcweir template< class T > 200cdf0e10cSrcweir inline beans::PropertyValue createPropertyValue( 201cdf0e10cSrcweir OUString const & name, T const & value ) 202cdf0e10cSrcweir SAL_THROW( () ) 203cdf0e10cSrcweir { 204cdf0e10cSrcweir return beans::PropertyValue( 205cdf0e10cSrcweir name, -1, makeAny( value ), beans::PropertyState_DIRECT_VALUE ); 206cdf0e10cSrcweir } 207cdf0e10cSrcweir 208cdf0e10cSrcweir OUString findBoostrapArgument( 209cdf0e10cSrcweir const Bootstrap & bootstrap, 210cdf0e10cSrcweir const OUString & arg_name, 211cdf0e10cSrcweir sal_Bool * pFallenBack ) 212cdf0e10cSrcweir SAL_THROW(()) 213cdf0e10cSrcweir { 214cdf0e10cSrcweir OUString result; 215cdf0e10cSrcweir 216cdf0e10cSrcweir OUString prefixed_arg_name = OUSTR("UNO_"); 217cdf0e10cSrcweir prefixed_arg_name += arg_name.toAsciiUpperCase(); 218cdf0e10cSrcweir 219cdf0e10cSrcweir // environment not set -> try relative to executable 220cdf0e10cSrcweir if(!bootstrap.getFrom(prefixed_arg_name, result)) 221cdf0e10cSrcweir { 222cdf0e10cSrcweir if(pFallenBack) 223cdf0e10cSrcweir *pFallenBack = sal_True; 224cdf0e10cSrcweir 225cdf0e10cSrcweir OUString fileName; 226cdf0e10cSrcweir bootstrap.getIniName(fileName); 227cdf0e10cSrcweir 228cdf0e10cSrcweir // cut the rc extension 229cdf0e10cSrcweir OUStringBuffer result_buf( 64 ); 230cdf0e10cSrcweir result_buf.append( 231cdf0e10cSrcweir fileName.copy( 232cdf0e10cSrcweir 0, fileName.getLength() - strlen(SAL_CONFIGFILE(""))) ); 233cdf0e10cSrcweir result_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("_") ); 234cdf0e10cSrcweir result_buf.append( arg_name.toAsciiLowerCase() ); 235cdf0e10cSrcweir result_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(".rdb") ); 236cdf0e10cSrcweir result = result_buf.makeStringAndClear(); 237cdf0e10cSrcweir 238cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 239cdf0e10cSrcweir OString result_dbg = 240cdf0e10cSrcweir OUStringToOString(result, RTL_TEXTENCODING_ASCII_US); 241cdf0e10cSrcweir OString arg_name_dbg = 242cdf0e10cSrcweir OUStringToOString(arg_name, RTL_TEXTENCODING_ASCII_US); 243cdf0e10cSrcweir OSL_TRACE( 244cdf0e10cSrcweir "cppuhelper::findBoostrapArgument - " 245cdf0e10cSrcweir "setting %s relative to executable: %s\n", 246cdf0e10cSrcweir arg_name_dbg.getStr(), 247cdf0e10cSrcweir result_dbg.getStr() ); 248cdf0e10cSrcweir #endif 249cdf0e10cSrcweir } 250cdf0e10cSrcweir else 251cdf0e10cSrcweir { 252cdf0e10cSrcweir if(pFallenBack) 253cdf0e10cSrcweir *pFallenBack = sal_False; 254cdf0e10cSrcweir 255cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 256cdf0e10cSrcweir OString prefixed_arg_name_dbg = OUStringToOString( 257cdf0e10cSrcweir prefixed_arg_name, RTL_TEXTENCODING_ASCII_US ); 258cdf0e10cSrcweir OString result_dbg = OUStringToOString( 259cdf0e10cSrcweir result, RTL_TEXTENCODING_ASCII_US ); 260cdf0e10cSrcweir OSL_TRACE( 261cdf0e10cSrcweir "cppuhelper::findBoostrapArgument - found %s in env: %s", 262cdf0e10cSrcweir prefixed_arg_name_dbg.getStr(), 263cdf0e10cSrcweir result_dbg.getStr() ); 264cdf0e10cSrcweir #endif 265cdf0e10cSrcweir } 266cdf0e10cSrcweir 267cdf0e10cSrcweir return result; 268cdf0e10cSrcweir } 269cdf0e10cSrcweir 270cdf0e10cSrcweir Reference< registry::XSimpleRegistry > nestRegistries( 271cdf0e10cSrcweir const OUString baseDir, 272cdf0e10cSrcweir const Reference< lang::XSingleServiceFactory > & xSimRegFac, 273cdf0e10cSrcweir const Reference< lang::XSingleServiceFactory > & xNesRegFac, 274cdf0e10cSrcweir OUString csl_rdbs, 275cdf0e10cSrcweir const OUString & write_rdb, 276cdf0e10cSrcweir sal_Bool forceWrite_rdb, 277cdf0e10cSrcweir sal_Bool bFallenBack ) 278cdf0e10cSrcweir SAL_THROW((Exception)) 279cdf0e10cSrcweir { 280cdf0e10cSrcweir sal_Int32 index; 281cdf0e10cSrcweir Reference< registry::XSimpleRegistry > lastRegistry; 282cdf0e10cSrcweir 283cdf0e10cSrcweir if(write_rdb.getLength()) // is there a write registry given? 284cdf0e10cSrcweir { 285cdf0e10cSrcweir lastRegistry.set(xSimRegFac->createInstance(), UNO_QUERY); 286cdf0e10cSrcweir 287cdf0e10cSrcweir try 288cdf0e10cSrcweir { 289cdf0e10cSrcweir lastRegistry->open(write_rdb, sal_False, forceWrite_rdb); 290cdf0e10cSrcweir } 291cdf0e10cSrcweir catch (registry::InvalidRegistryException & invalidRegistryException) 292cdf0e10cSrcweir { 293cdf0e10cSrcweir (void) invalidRegistryException; 294cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 295cdf0e10cSrcweir OString rdb_name_tmp = OUStringToOString( 296cdf0e10cSrcweir write_rdb, RTL_TEXTENCODING_ASCII_US); 297cdf0e10cSrcweir OString message_dbg = OUStringToOString( 298cdf0e10cSrcweir invalidRegistryException.Message, RTL_TEXTENCODING_ASCII_US); 299cdf0e10cSrcweir OSL_TRACE( 300cdf0e10cSrcweir "warning: couldn't open %s cause of %s", 301cdf0e10cSrcweir rdb_name_tmp.getStr(), message_dbg.getStr() ); 302cdf0e10cSrcweir #endif 303cdf0e10cSrcweir } 304cdf0e10cSrcweir 305cdf0e10cSrcweir if(!lastRegistry->isValid()) 306cdf0e10cSrcweir lastRegistry.clear(); 307cdf0e10cSrcweir } 308cdf0e10cSrcweir 309cdf0e10cSrcweir do 310cdf0e10cSrcweir { 311cdf0e10cSrcweir index = csl_rdbs.indexOf((sal_Unicode)' '); 312cdf0e10cSrcweir OUString rdb_name = (index == -1) ? csl_rdbs : csl_rdbs.copy(0, index); 313cdf0e10cSrcweir csl_rdbs = (index == -1) ? OUString() : csl_rdbs.copy(index + 1); 314cdf0e10cSrcweir 315cdf0e10cSrcweir if (! rdb_name.getLength()) 316cdf0e10cSrcweir continue; 317cdf0e10cSrcweir 318cdf0e10cSrcweir bool optional = ('?' == rdb_name[ 0 ]); 319cdf0e10cSrcweir if (optional) 320cdf0e10cSrcweir rdb_name = rdb_name.copy( 1 ); 321cdf0e10cSrcweir 322cdf0e10cSrcweir try 323cdf0e10cSrcweir { 324cdf0e10cSrcweir Reference<registry::XSimpleRegistry> simpleRegistry( 325cdf0e10cSrcweir xSimRegFac->createInstance(), UNO_QUERY_THROW ); 326cdf0e10cSrcweir 327cdf0e10cSrcweir osl::FileBase::getAbsoluteFileURL(baseDir, rdb_name, rdb_name); 328cdf0e10cSrcweir simpleRegistry->open(rdb_name, sal_True, sal_False); 329cdf0e10cSrcweir 330cdf0e10cSrcweir if(lastRegistry.is()) 331cdf0e10cSrcweir { 332cdf0e10cSrcweir Reference< registry::XSimpleRegistry > nestedRegistry( 333cdf0e10cSrcweir xNesRegFac->createInstance(), UNO_QUERY ); 334cdf0e10cSrcweir Reference< lang::XInitialization > nestedRegistry_xInit( 335cdf0e10cSrcweir nestedRegistry, UNO_QUERY ); 336cdf0e10cSrcweir 337cdf0e10cSrcweir Sequence<Any> aArgs(2); 338cdf0e10cSrcweir aArgs[0] <<= lastRegistry; 339cdf0e10cSrcweir aArgs[1] <<= simpleRegistry; 340cdf0e10cSrcweir 341cdf0e10cSrcweir nestedRegistry_xInit->initialize(aArgs); 342cdf0e10cSrcweir 343cdf0e10cSrcweir lastRegistry = nestedRegistry; 344cdf0e10cSrcweir } 345cdf0e10cSrcweir else 346cdf0e10cSrcweir lastRegistry = simpleRegistry; 347cdf0e10cSrcweir } 348cdf0e10cSrcweir catch(registry::InvalidRegistryException & invalidRegistryException) 349cdf0e10cSrcweir { 350cdf0e10cSrcweir if (! optional) 351cdf0e10cSrcweir { 352cdf0e10cSrcweir // if a registry was explicitly given, the exception shall fly 353cdf0e10cSrcweir if( ! bFallenBack ) 354cdf0e10cSrcweir throw; 355cdf0e10cSrcweir } 356cdf0e10cSrcweir 357cdf0e10cSrcweir (void) invalidRegistryException; 358cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 359cdf0e10cSrcweir OString rdb_name_tmp = OUStringToOString( 360cdf0e10cSrcweir rdb_name, RTL_TEXTENCODING_ASCII_US ); 361cdf0e10cSrcweir OString message_dbg = OUStringToOString( 362cdf0e10cSrcweir invalidRegistryException.Message, RTL_TEXTENCODING_ASCII_US ); 363cdf0e10cSrcweir OSL_TRACE( 364cdf0e10cSrcweir "warning: couldn't open %s cause of %s", 365cdf0e10cSrcweir rdb_name_tmp.getStr(), message_dbg.getStr() ); 366cdf0e10cSrcweir #endif 367cdf0e10cSrcweir } 368cdf0e10cSrcweir } 369cdf0e10cSrcweir while(index != -1 && csl_rdbs.getLength()); // are there more rdbs in list? 370cdf0e10cSrcweir 371cdf0e10cSrcweir return lastRegistry; 372cdf0e10cSrcweir } 373cdf0e10cSrcweir 374cdf0e10cSrcweir Reference< XComponentContext > 375cdf0e10cSrcweir SAL_CALL defaultBootstrap_InitialComponentContext( 376cdf0e10cSrcweir Bootstrap const & bootstrap ) 377cdf0e10cSrcweir SAL_THROW( (Exception) ) 378cdf0e10cSrcweir { 379cdf0e10cSrcweir OUString bootstrapPath; 380cdf0e10cSrcweir if (!bootstrap.getFrom( 381cdf0e10cSrcweir rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("URE_INTERNAL_LIB_DIR")), 382cdf0e10cSrcweir bootstrapPath)) 383cdf0e10cSrcweir { 384cdf0e10cSrcweir bootstrapPath = get_this_libpath(); 385cdf0e10cSrcweir } 386cdf0e10cSrcweir 387cdf0e10cSrcweir OUString iniDir; 388cdf0e10cSrcweir osl_getProcessWorkingDir(&iniDir.pData); 389cdf0e10cSrcweir 390cdf0e10cSrcweir Reference<lang::XMultiComponentFactory> smgr_XMultiComponentFactory( 391cdf0e10cSrcweir bootstrapInitialSF(bootstrapPath) ); 392cdf0e10cSrcweir Reference<lang::XMultiServiceFactory> smgr_XMultiServiceFactory( 393cdf0e10cSrcweir smgr_XMultiComponentFactory, UNO_QUERY ); 394cdf0e10cSrcweir 395cdf0e10cSrcweir Reference<registry::XRegistryKey> xEmptyKey; 396cdf0e10cSrcweir Reference<lang::XSingleServiceFactory> xSimRegFac( 397cdf0e10cSrcweir loadSharedLibComponentFactory( 398cdf0e10cSrcweir OUSTR("bootstrap.uno" SAL_DLLEXTENSION), bootstrapPath, 399cdf0e10cSrcweir OUSTR("com.sun.star.comp.stoc.SimpleRegistry"), 400cdf0e10cSrcweir smgr_XMultiServiceFactory, 401cdf0e10cSrcweir xEmptyKey), 402cdf0e10cSrcweir UNO_QUERY); 403cdf0e10cSrcweir 404cdf0e10cSrcweir Reference<lang::XSingleServiceFactory> xNesRegFac( 405cdf0e10cSrcweir loadSharedLibComponentFactory( 406cdf0e10cSrcweir OUSTR("bootstrap.uno" SAL_DLLEXTENSION), bootstrapPath, 407cdf0e10cSrcweir OUSTR("com.sun.star.comp.stoc.NestedRegistry"), 408cdf0e10cSrcweir smgr_XMultiServiceFactory, 409cdf0e10cSrcweir xEmptyKey), 410cdf0e10cSrcweir UNO_QUERY); 411cdf0e10cSrcweir 412cdf0e10cSrcweir sal_Bool bFallenback_types; 413cdf0e10cSrcweir OUString cls_uno_types = 414cdf0e10cSrcweir findBoostrapArgument( bootstrap, OUSTR("TYPES"), &bFallenback_types ); 415cdf0e10cSrcweir 416cdf0e10cSrcweir Reference<registry::XSimpleRegistry> types_xRegistry = 417cdf0e10cSrcweir nestRegistries( 418cdf0e10cSrcweir iniDir, xSimRegFac, xNesRegFac, cls_uno_types, 419cdf0e10cSrcweir OUString(), sal_False, bFallenback_types ); 420cdf0e10cSrcweir 421cdf0e10cSrcweir // ==== bootstrap from services registry ==== 422cdf0e10cSrcweir 423cdf0e10cSrcweir sal_Bool bFallenback_services; 424cdf0e10cSrcweir OUString cls_uno_services = findBoostrapArgument( 425cdf0e10cSrcweir bootstrap, OUSTR("SERVICES"), &bFallenback_services ); 426cdf0e10cSrcweir 427cdf0e10cSrcweir sal_Bool fallenBackWriteRegistry; 428cdf0e10cSrcweir OUString write_rdb = findBoostrapArgument( 429cdf0e10cSrcweir bootstrap, OUSTR("WRITERDB"), &fallenBackWriteRegistry ); 430cdf0e10cSrcweir if (fallenBackWriteRegistry) 431cdf0e10cSrcweir { 432cdf0e10cSrcweir // no standard write rdb anymore 433cdf0e10cSrcweir write_rdb = OUString(); 434cdf0e10cSrcweir } 435cdf0e10cSrcweir 436cdf0e10cSrcweir Reference<registry::XSimpleRegistry> services_xRegistry = nestRegistries( 437cdf0e10cSrcweir iniDir, xSimRegFac, xNesRegFac, cls_uno_services, write_rdb, 438cdf0e10cSrcweir !fallenBackWriteRegistry, bFallenback_services ); 439cdf0e10cSrcweir 440cdf0e10cSrcweir Reference< XComponentContext > xContext( 441cdf0e10cSrcweir bootstrapInitialContext( 442cdf0e10cSrcweir smgr_XMultiComponentFactory, types_xRegistry, services_xRegistry, 443cdf0e10cSrcweir bootstrapPath, bootstrap ) ); 444cdf0e10cSrcweir 445cdf0e10cSrcweir // initialize sf 446cdf0e10cSrcweir Reference< lang::XInitialization > xInit( 447cdf0e10cSrcweir smgr_XMultiComponentFactory, UNO_QUERY ); 448cdf0e10cSrcweir OSL_ASSERT( xInit.is() ); 449cdf0e10cSrcweir Sequence< Any > aSFInit( 1 ); 450cdf0e10cSrcweir aSFInit[ 0 ] <<= services_xRegistry; 451cdf0e10cSrcweir xInit->initialize( aSFInit ); 452cdf0e10cSrcweir 453cdf0e10cSrcweir return xContext; 454cdf0e10cSrcweir } 455cdf0e10cSrcweir 456cdf0e10cSrcweir } 457cdf0e10cSrcweir 458cdf0e10cSrcweir Reference< XComponentContext > 459cdf0e10cSrcweir SAL_CALL defaultBootstrap_InitialComponentContext( 460cdf0e10cSrcweir OUString const & iniFile ) 461cdf0e10cSrcweir SAL_THROW( (Exception) ) 462cdf0e10cSrcweir { 463cdf0e10cSrcweir Bootstrap bootstrap( iniFile ); 464cdf0e10cSrcweir if (bootstrap.getHandle() == 0) 465cdf0e10cSrcweir throw io::IOException(OUSTR("Cannot open for reading: ") + iniFile, 0); 466cdf0e10cSrcweir return defaultBootstrap_InitialComponentContext( bootstrap ); 467cdf0e10cSrcweir } 468cdf0e10cSrcweir 469cdf0e10cSrcweir Reference< XComponentContext > 470cdf0e10cSrcweir SAL_CALL defaultBootstrap_InitialComponentContext() 471cdf0e10cSrcweir SAL_THROW( (Exception) ) 472cdf0e10cSrcweir { 473cdf0e10cSrcweir return defaultBootstrap_InitialComponentContext( get_unorc() ); 474cdf0e10cSrcweir } 475cdf0e10cSrcweir 476cdf0e10cSrcweir BootstrapException::BootstrapException() 477cdf0e10cSrcweir { 478cdf0e10cSrcweir } 479cdf0e10cSrcweir 480cdf0e10cSrcweir BootstrapException::BootstrapException( const ::rtl::OUString & rMessage ) 481cdf0e10cSrcweir :m_aMessage( rMessage ) 482cdf0e10cSrcweir { 483cdf0e10cSrcweir } 484cdf0e10cSrcweir 485cdf0e10cSrcweir BootstrapException::BootstrapException( const BootstrapException & e ) 486cdf0e10cSrcweir { 487cdf0e10cSrcweir m_aMessage = e.m_aMessage; 488cdf0e10cSrcweir } 489cdf0e10cSrcweir 490cdf0e10cSrcweir BootstrapException::~BootstrapException() 491cdf0e10cSrcweir { 492cdf0e10cSrcweir } 493cdf0e10cSrcweir 494cdf0e10cSrcweir BootstrapException & BootstrapException::operator=( const BootstrapException & e ) 495cdf0e10cSrcweir { 496cdf0e10cSrcweir m_aMessage = e.m_aMessage; 497cdf0e10cSrcweir return *this; 498cdf0e10cSrcweir } 499cdf0e10cSrcweir 500cdf0e10cSrcweir const ::rtl::OUString & BootstrapException::getMessage() const 501cdf0e10cSrcweir { 502cdf0e10cSrcweir return m_aMessage; 503cdf0e10cSrcweir } 504cdf0e10cSrcweir 505cdf0e10cSrcweir Reference< XComponentContext > SAL_CALL bootstrap() 506cdf0e10cSrcweir { 507cdf0e10cSrcweir Reference< XComponentContext > xRemoteContext; 508cdf0e10cSrcweir 509cdf0e10cSrcweir try 510cdf0e10cSrcweir { 511cdf0e10cSrcweir char const * p1 = cppuhelper_detail_findSofficePath(); 512cdf0e10cSrcweir if (p1 == NULL) { 513cdf0e10cSrcweir throw BootstrapException( 514cdf0e10cSrcweir OUSTR("no soffice installation found!")); 515cdf0e10cSrcweir } 516cdf0e10cSrcweir rtl::OUString p2; 517cdf0e10cSrcweir if (!rtl_convertStringToUString( 518cdf0e10cSrcweir &p2.pData, p1, strlen(p1), osl_getThreadTextEncoding(), 519cdf0e10cSrcweir (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR | 520cdf0e10cSrcweir RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR | 521cdf0e10cSrcweir RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR))) 522cdf0e10cSrcweir { 523cdf0e10cSrcweir throw BootstrapException( 524cdf0e10cSrcweir OUSTR("bad characters in soffice installation path!")); 525cdf0e10cSrcweir } 526cdf0e10cSrcweir OUString path; 527cdf0e10cSrcweir if (osl::FileBase::getFileURLFromSystemPath(p2, path) != 528cdf0e10cSrcweir osl::FileBase::E_None) 529cdf0e10cSrcweir { 530cdf0e10cSrcweir throw BootstrapException( 531cdf0e10cSrcweir OUSTR("cannot convert soffice installation path to URL!")); 532cdf0e10cSrcweir } 533cdf0e10cSrcweir if (path.getLength() > 0 && path[path.getLength() - 1] != '/') { 534cdf0e10cSrcweir path += OUSTR("/"); 535cdf0e10cSrcweir } 536cdf0e10cSrcweir 537cdf0e10cSrcweir OUString uri; 538cdf0e10cSrcweir if (!Bootstrap::get(OUSTR("URE_BOOTSTRAP"), uri)) { 539cdf0e10cSrcweir Bootstrap::set( 540cdf0e10cSrcweir OUSTR("URE_BOOTSTRAP"), 541cdf0e10cSrcweir Bootstrap::encode(path + OUSTR(SAL_CONFIGFILE("fundamental")))); 542cdf0e10cSrcweir } 543cdf0e10cSrcweir 544cdf0e10cSrcweir // create default local component context 545cdf0e10cSrcweir Reference< XComponentContext > xLocalContext( 546cdf0e10cSrcweir defaultBootstrap_InitialComponentContext() ); 547cdf0e10cSrcweir if ( !xLocalContext.is() ) 548cdf0e10cSrcweir throw BootstrapException( OUSTR( "no local component context!" ) ); 549cdf0e10cSrcweir 550cdf0e10cSrcweir // create a random pipe name 551cdf0e10cSrcweir rtlRandomPool hPool = rtl_random_createPool(); 552cdf0e10cSrcweir if ( hPool == 0 ) 553cdf0e10cSrcweir throw BootstrapException( OUSTR( "cannot create random pool!" ) ); 554cdf0e10cSrcweir sal_uInt8 bytes[ 16 ]; 555cdf0e10cSrcweir if ( rtl_random_getBytes( hPool, bytes, ARLEN( bytes ) ) 556cdf0e10cSrcweir != rtl_Random_E_None ) 557cdf0e10cSrcweir throw BootstrapException( OUSTR( "random pool error!" ) ); 558cdf0e10cSrcweir rtl_random_destroyPool( hPool ); 559cdf0e10cSrcweir ::rtl::OUStringBuffer buf; 560cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "uno" ) ); 561cdf0e10cSrcweir for ( sal_uInt32 i = 0; i < ARLEN( bytes ); ++i ) 562cdf0e10cSrcweir buf.append( static_cast< sal_Int32 >( bytes[ i ] ) ); 563cdf0e10cSrcweir OUString sPipeName( buf.makeStringAndClear() ); 564cdf0e10cSrcweir 565cdf0e10cSrcweir // accept string 566cdf0e10cSrcweir OSL_ASSERT( buf.getLength() == 0 ); 567cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "-accept=pipe,name=" ) ); 568cdf0e10cSrcweir buf.append( sPipeName ); 569cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ";urp;" ) ); 570cdf0e10cSrcweir 571cdf0e10cSrcweir // arguments 572cdf0e10cSrcweir OUString args [] = { 573cdf0e10cSrcweir OUSTR( "-nologo" ), 574cdf0e10cSrcweir OUSTR( "-nodefault" ), 575cdf0e10cSrcweir OUSTR( "-norestore" ), 576cdf0e10cSrcweir OUSTR( "-nocrashreport" ), 577cdf0e10cSrcweir OUSTR( "-nolockcheck" ), 578cdf0e10cSrcweir buf.makeStringAndClear() 579cdf0e10cSrcweir }; 580cdf0e10cSrcweir rtl_uString * ar_args [] = { 581cdf0e10cSrcweir args[ 0 ].pData, 582cdf0e10cSrcweir args[ 1 ].pData, 583cdf0e10cSrcweir args[ 2 ].pData, 584cdf0e10cSrcweir args[ 3 ].pData, 585cdf0e10cSrcweir args[ 4 ].pData, 586cdf0e10cSrcweir args[ 5 ].pData 587cdf0e10cSrcweir }; 588cdf0e10cSrcweir ::osl::Security sec; 589cdf0e10cSrcweir 590cdf0e10cSrcweir // start office process 591cdf0e10cSrcweir oslProcess hProcess = 0; 592cdf0e10cSrcweir oslProcessError rc = osl_executeProcess( 593cdf0e10cSrcweir (path + OUSTR("soffice")).pData, ar_args, ARLEN( ar_args ), 594cdf0e10cSrcweir osl_Process_DETACHED, 595cdf0e10cSrcweir sec.getHandle(), 596cdf0e10cSrcweir 0, // => current working dir 597cdf0e10cSrcweir 0, 0, // => no env vars 598cdf0e10cSrcweir &hProcess ); 599cdf0e10cSrcweir switch ( rc ) 600cdf0e10cSrcweir { 601cdf0e10cSrcweir case osl_Process_E_None: 602cdf0e10cSrcweir osl_freeProcessHandle( hProcess ); 603cdf0e10cSrcweir break; 604cdf0e10cSrcweir case osl_Process_E_NotFound: 605cdf0e10cSrcweir throw BootstrapException( OUSTR( "image not found!" ) ); 606cdf0e10cSrcweir case osl_Process_E_TimedOut: 607cdf0e10cSrcweir throw BootstrapException( OUSTR( "timout occured!" ) ); 608cdf0e10cSrcweir case osl_Process_E_NoPermission: 609cdf0e10cSrcweir throw BootstrapException( OUSTR( "permission denied!" ) ); 610cdf0e10cSrcweir case osl_Process_E_Unknown: 611cdf0e10cSrcweir throw BootstrapException( OUSTR( "unknown error!" ) ); 612cdf0e10cSrcweir case osl_Process_E_InvalidError: 613cdf0e10cSrcweir default: 614cdf0e10cSrcweir throw BootstrapException( OUSTR( "unmapped error!" ) ); 615cdf0e10cSrcweir } 616cdf0e10cSrcweir 617cdf0e10cSrcweir // create a URL resolver 618cdf0e10cSrcweir Reference< bridge::XUnoUrlResolver > xUrlResolver( 619cdf0e10cSrcweir bridge::UnoUrlResolver::create( xLocalContext ) ); 620cdf0e10cSrcweir 621cdf0e10cSrcweir // connection string 622cdf0e10cSrcweir OSL_ASSERT( buf.getLength() == 0 ); 623cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "uno:pipe,name=" ) ); 624cdf0e10cSrcweir buf.append( sPipeName ); 625cdf0e10cSrcweir buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( 626cdf0e10cSrcweir ";urp;StarOffice.ComponentContext" ) ); 627cdf0e10cSrcweir OUString sConnectString( buf.makeStringAndClear() ); 628cdf0e10cSrcweir 629cdf0e10cSrcweir // wait until office is started 630cdf0e10cSrcweir for ( ; ; ) 631cdf0e10cSrcweir { 632cdf0e10cSrcweir try 633cdf0e10cSrcweir { 634cdf0e10cSrcweir // try to connect to office 635cdf0e10cSrcweir xRemoteContext.set( 636cdf0e10cSrcweir xUrlResolver->resolve( sConnectString ), UNO_QUERY_THROW ); 637cdf0e10cSrcweir break; 638cdf0e10cSrcweir } 639cdf0e10cSrcweir catch ( connection::NoConnectException & ) 640cdf0e10cSrcweir { 641cdf0e10cSrcweir // wait 500 ms, then try to connect again 642cdf0e10cSrcweir TimeValue tv = { 0 /* secs */, 500000000 /* nanosecs */ }; 643cdf0e10cSrcweir ::osl::Thread::wait( tv ); 644cdf0e10cSrcweir } 645cdf0e10cSrcweir } 646cdf0e10cSrcweir } 647cdf0e10cSrcweir catch ( Exception & e ) 648cdf0e10cSrcweir { 649cdf0e10cSrcweir throw BootstrapException( 650cdf0e10cSrcweir OUSTR( "unexpected UNO exception caught: " ) + e.Message ); 651cdf0e10cSrcweir } 652cdf0e10cSrcweir 653cdf0e10cSrcweir return xRemoteContext; 654cdf0e10cSrcweir } 655cdf0e10cSrcweir 656cdf0e10cSrcweir OUString bootstrap_expandUri(OUString const & uri) { 657cdf0e10cSrcweir static char const PREFIX[] = "vnd.sun.star.expand:"; 658cdf0e10cSrcweir return uri.matchAsciiL(RTL_CONSTASCII_STRINGPARAM(PREFIX)) 659cdf0e10cSrcweir ? cppuhelper::detail::expandMacros( 660cdf0e10cSrcweir rtl::Uri::decode( 661cdf0e10cSrcweir uri.copy(RTL_CONSTASCII_LENGTH(PREFIX)), 662cdf0e10cSrcweir rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8)) 663cdf0e10cSrcweir : uri; 664cdf0e10cSrcweir } 665cdf0e10cSrcweir 666cdf0e10cSrcweir } // namespace cppu 667