1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_scripting.hxx" 30 #include "basprov.hxx" 31 #include "basscript.hxx" 32 #include "baslibnode.hxx" 33 #include <com/sun/star/frame/XModel.hpp> 34 #include <com/sun/star/script/browse/BrowseNodeTypes.hpp> 35 #include <com/sun/star/script/provider/ScriptFrameworkErrorType.hpp> 36 #include <com/sun/star/document/XEmbeddedScripts.hpp> 37 38 #ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_ 39 #include <cppuhelper/implementationentry.hxx> 40 #endif 41 #include <rtl/uri.hxx> 42 #include <osl/process.h> 43 #include <osl/file.hxx> 44 #include <vos/mutex.hxx> 45 #include <vcl/svapp.hxx> 46 #include <basic/sbx.hxx> 47 #include <basic/basmgr.hxx> 48 #include <basic/basicmanagerrepository.hxx> 49 #include <basic/sbstar.hxx> 50 #include <basic/sbmod.hxx> 51 #include <basic/sbmeth.hxx> 52 #include <sfx2/app.hxx> 53 #include <sfx2/objsh.hxx> 54 55 #include <com/sun/star/util/XMacroExpander.hpp> 56 #include <com/sun/star/script/XLibraryContainer2.hpp> 57 #include <com/sun/star/uri/XUriReference.hpp> 58 #include <com/sun/star/uri/XUriReferenceFactory.hpp> 59 #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp> 60 61 #include <util/util.hxx> 62 #include <util/MiscUtils.hxx> 63 64 65 using namespace ::com::sun::star; 66 using namespace ::com::sun::star::lang; 67 using namespace ::com::sun::star::uno; 68 using namespace ::com::sun::star::script; 69 using namespace ::com::sun::star::document; 70 using namespace ::sf_misc; 71 72 //......................................................................... 73 namespace basprov 74 { 75 //......................................................................... 76 77 // ============================================================================= 78 // component operations 79 // ============================================================================= 80 81 static ::rtl::OUString getImplementationName_BasicProviderImpl() 82 { 83 static ::rtl::OUString* pImplName = 0; 84 if ( !pImplName ) 85 { 86 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 87 if ( !pImplName ) 88 { 89 static ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.scripting.ScriptProviderForBasic" ) ); 90 pImplName = &aImplName; 91 } 92 } 93 return *pImplName; 94 } 95 96 // ----------------------------------------------------------------------------- 97 98 static Sequence< ::rtl::OUString > getSupportedServiceNames_BasicProviderImpl() 99 { 100 static Sequence< ::rtl::OUString >* pNames = 0; 101 if ( !pNames ) 102 { 103 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 104 if ( !pNames ) 105 { 106 static Sequence< ::rtl::OUString > aNames(4); 107 aNames.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.provider.ScriptProviderForBasic" ) ); 108 aNames.getArray()[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.provider.LanguageScriptProvider" ) ); 109 aNames.getArray()[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.provider.ScriptProvider" ) ); 110 aNames.getArray()[3] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.browse.BrowseNode" ) ); 111 pNames = &aNames; 112 } 113 } 114 return *pNames; 115 } 116 117 // ============================================================================= 118 // BasicProviderImpl 119 // ============================================================================= 120 121 BasicProviderImpl::BasicProviderImpl( const Reference< XComponentContext >& xContext ) 122 :m_pAppBasicManager( 0 ) 123 ,m_pDocBasicManager( 0 ) 124 ,m_xLibContainerApp( 0 ) 125 ,m_xLibContainerDoc( 0 ) 126 ,m_xContext( xContext ) 127 ,m_bIsAppScriptCtx( true ) 128 ,m_bIsUserCtx(true) 129 { 130 } 131 132 // ----------------------------------------------------------------------------- 133 134 BasicProviderImpl::~BasicProviderImpl() 135 { 136 } 137 138 // ----------------------------------------------------------------------------- 139 140 bool BasicProviderImpl::isLibraryShared( const Reference< script::XLibraryContainer >& rxLibContainer, const ::rtl::OUString& rLibName ) 141 { 142 bool bIsShared = false; 143 144 Reference< script::XLibraryContainer2 > xLibContainer( rxLibContainer, UNO_QUERY ); 145 if ( xLibContainer.is() && xLibContainer->hasByName( rLibName ) && xLibContainer->isLibraryLink( rLibName ) ) 146 { 147 ::rtl::OUString aFileURL; 148 if ( m_xContext.is() ) 149 { 150 Reference< uri::XUriReferenceFactory > xUriFac; 151 Reference< lang::XMultiComponentFactory > xSMgr( m_xContext->getServiceManager() ); 152 if ( xSMgr.is() ) 153 { 154 xUriFac.set( xSMgr->createInstanceWithContext( ::rtl::OUString::createFromAscii( 155 "com.sun.star.uri.UriReferenceFactory" ), m_xContext ), UNO_QUERY ); 156 } 157 158 if ( xUriFac.is() ) 159 { 160 ::rtl::OUString aLinkURL( xLibContainer->getLibraryLinkURL( rLibName ) ); 161 Reference< uri::XUriReference > xUriRef( xUriFac->parse( aLinkURL ), UNO_QUERY ); 162 163 if ( xUriRef.is() ) 164 { 165 ::rtl::OUString aScheme = xUriRef->getScheme(); 166 if ( aScheme.equalsIgnoreAsciiCaseAscii( "file" ) ) 167 { 168 aFileURL = aLinkURL; 169 } 170 else if ( aScheme.equalsIgnoreAsciiCaseAscii( "vnd.sun.star.pkg" ) ) 171 { 172 ::rtl::OUString aAuthority = xUriRef->getAuthority(); 173 if ( aAuthority.matchIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.expand:" ) ) ) 174 { 175 ::rtl::OUString aDecodedURL( aAuthority.copy( sizeof ( "vnd.sun.star.expand:" ) - 1 ) ); 176 aDecodedURL = ::rtl::Uri::decode( aDecodedURL, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 ); 177 Reference<util::XMacroExpander> xMacroExpander( 178 m_xContext->getValueByName( 179 ::rtl::OUString::createFromAscii( "/singletons/com.sun.star.util.theMacroExpander" ) ), 180 UNO_QUERY ); 181 if ( xMacroExpander.is() ) 182 aFileURL = xMacroExpander->expandMacros( aDecodedURL ); 183 } 184 } 185 } 186 } 187 } 188 189 if ( aFileURL.getLength() ) 190 { 191 osl::DirectoryItem aFileItem; 192 osl::FileStatus aFileStatus( FileStatusMask_FileURL ); 193 OSL_VERIFY( osl::DirectoryItem::get( aFileURL, aFileItem ) == osl::FileBase::E_None ); 194 OSL_VERIFY( aFileItem.getFileStatus( aFileStatus ) == osl::FileBase::E_None ); 195 ::rtl::OUString aCanonicalFileURL( aFileStatus.getFileURL() ); 196 197 ::rtl::OUString aSearchURL1( RTL_CONSTASCII_USTRINGPARAM( "share/basic" ) ); 198 ::rtl::OUString aSearchURL2( RTL_CONSTASCII_USTRINGPARAM( "share/uno_packages" ) ); 199 if( aCanonicalFileURL.indexOf( aSearchURL1 ) != -1 || aCanonicalFileURL.indexOf( aSearchURL2 ) != -1 ) 200 bIsShared = true; 201 } 202 } 203 204 return bIsShared; 205 } 206 207 // ----------------------------------------------------------------------------- 208 // XServiceInfo 209 // ----------------------------------------------------------------------------- 210 211 ::rtl::OUString BasicProviderImpl::getImplementationName( ) throw (RuntimeException) 212 { 213 return getImplementationName_BasicProviderImpl(); 214 } 215 216 // ----------------------------------------------------------------------------- 217 218 sal_Bool BasicProviderImpl::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException) 219 { 220 Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() ); 221 const ::rtl::OUString* pNames = aNames.getConstArray(); 222 const ::rtl::OUString* pEnd = pNames + aNames.getLength(); 223 for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames ) 224 ; 225 226 return pNames != pEnd; 227 } 228 229 // ----------------------------------------------------------------------------- 230 231 Sequence< ::rtl::OUString > BasicProviderImpl::getSupportedServiceNames( ) throw (RuntimeException) 232 { 233 return getSupportedServiceNames_BasicProviderImpl(); 234 } 235 236 // ----------------------------------------------------------------------------- 237 // XInitialization 238 // ----------------------------------------------------------------------------- 239 240 void BasicProviderImpl::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException) 241 { 242 // TODO 243 244 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 245 246 if ( aArguments.getLength() != 1 ) 247 { 248 throw IllegalArgumentException( 249 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BasicProviderImpl::initialize: incorrect argument count." ) ), 250 *this, 251 1 252 ); 253 } 254 255 Reference< frame::XModel > xModel; 256 257 m_xInvocationContext.set( aArguments[0], UNO_QUERY );; 258 if ( m_xInvocationContext.is() ) 259 { 260 xModel.set( m_xInvocationContext->getScriptContainer(), UNO_QUERY ); 261 if ( !xModel.is() ) 262 { 263 throw IllegalArgumentException( 264 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BasicProviderImpl::initialize: unable to determine the document model from the script invocation context." ) ), 265 *this, 266 1 267 ); 268 } 269 } 270 else 271 { 272 if ( !( aArguments[0] >>= m_sScriptingContext ) ) 273 { 274 throw IllegalArgumentException( 275 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BasicProviderImpl::initialize: incorrect argument type " ) ).concat( aArguments[0].getValueTypeName() ), 276 *this, 277 1 278 ); 279 } 280 281 ::rtl::OUString sDoc = OUSTR("vnd.sun.star.tdoc"); 282 if ( m_sScriptingContext.indexOf( sDoc ) == 0 ) 283 { 284 xModel = MiscUtils::tDocUrlToModel( m_sScriptingContext ); 285 // TODO: use ScriptingContantsPool for SCRIPTING_DOC_REF 286 } 287 } 288 289 if ( xModel.is() ) 290 { 291 Reference< XEmbeddedScripts > xDocumentScripts( xModel, UNO_QUERY ); 292 if ( xDocumentScripts.is() ) 293 { 294 m_pDocBasicManager = ::basic::BasicManagerRepository::getDocumentBasicManager( xModel ); 295 m_xLibContainerDoc.set( xDocumentScripts->getBasicLibraries(), UNO_QUERY ); 296 OSL_ENSURE( m_pDocBasicManager && m_xLibContainerDoc.is(), 297 "BasicProviderImpl::initialize: invalid BasicManager, or invalid script container!" ); 298 } 299 m_bIsAppScriptCtx = false; 300 } 301 else 302 { 303 // Provider has been created with application context for user 304 // or share 305 if ( !m_sScriptingContext.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "user" ) ) ) 306 { 307 m_bIsUserCtx = false; 308 } 309 else 310 { 311 /* 312 throw RuntimeException( 313 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BasicProviderImpl::initialize: no scripting context!" ) ), 314 Reference< XInterface >() ); 315 */ 316 } 317 } 318 319 // TODO 320 if ( !m_pAppBasicManager ) 321 m_pAppBasicManager = SFX_APP()->GetBasicManager(); 322 323 if ( !m_xLibContainerApp.is() ) 324 m_xLibContainerApp = Reference< script::XLibraryContainer >( SFX_APP()->GetBasicContainer(), UNO_QUERY ); 325 } 326 327 // ----------------------------------------------------------------------------- 328 329 // XScriptProvider 330 // ----------------------------------------------------------------------------- 331 332 Reference < provider::XScript > BasicProviderImpl::getScript( const ::rtl::OUString& scriptURI ) 333 throw ( provider::ScriptFrameworkErrorException, RuntimeException) 334 { 335 // TODO 336 337 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 338 339 Reference< provider::XScript > xScript; 340 Reference< lang::XMultiComponentFactory > xMcFac ( m_xContext->getServiceManager() ); 341 Reference< uri::XUriReferenceFactory > xFac ( 342 xMcFac->createInstanceWithContext( rtl::OUString::createFromAscii( 343 "com.sun.star.uri.UriReferenceFactory"), m_xContext ) , UNO_QUERY ); 344 345 if ( !xFac.is() ) 346 { 347 throw provider::ScriptFrameworkErrorException( 348 OUSTR( "Failed to instantiate UriReferenceFactory" ), Reference< XInterface >(), 349 scriptURI, OUSTR("Basic"), 350 provider::ScriptFrameworkErrorType::UNKNOWN ); 351 } 352 353 Reference< uri::XUriReference > uriRef( 354 xFac->parse( scriptURI ), UNO_QUERY ); 355 356 Reference < uri::XVndSunStarScriptUrl > sfUri( uriRef, UNO_QUERY ); 357 358 if ( !uriRef.is() || !sfUri.is() ) 359 { 360 ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "BasicProviderImpl::getScript: failed to parse URI: " ); 361 errorMsg = errorMsg.concat( scriptURI ); 362 throw provider::ScriptFrameworkErrorException( 363 errorMsg, Reference< XInterface >(), 364 scriptURI, OUSTR("Basic"), 365 provider::ScriptFrameworkErrorType::MALFORMED_URL ); 366 } 367 368 369 ::rtl::OUString aDescription = sfUri->getName(); 370 ::rtl::OUString aLocation = sfUri->getParameter( 371 ::rtl::OUString::createFromAscii( "location" ) ); 372 373 sal_Int32 nIndex = 0; 374 ::rtl::OUString aLibrary = aDescription.getToken( 0, (sal_Unicode)'.', nIndex ); 375 ::rtl::OUString aModule; 376 if ( nIndex != -1 ) 377 aModule = aDescription.getToken( 0, (sal_Unicode)'.', nIndex ); 378 ::rtl::OUString aMethod; 379 if ( nIndex != -1 ) 380 aMethod = aDescription.getToken( 0, (sal_Unicode)'.', nIndex ); 381 382 if ( aLibrary.getLength() != 0 && aModule.getLength() != 0 && aMethod.getLength() != 0 && aLocation.getLength() != 0 ) 383 { 384 BasicManager* pBasicMgr = NULL; 385 if ( aLocation.equals( ::rtl::OUString::createFromAscii("document") ) ) 386 { 387 pBasicMgr = m_pDocBasicManager; 388 } 389 else if ( aLocation.equals( ::rtl::OUString::createFromAscii("application") ) ) 390 { 391 pBasicMgr = m_pAppBasicManager; 392 } 393 394 if ( pBasicMgr ) 395 { 396 StarBASIC* pBasic = pBasicMgr->GetLib( aLibrary ); 397 if ( !pBasic ) 398 { 399 sal_uInt16 nId = pBasicMgr->GetLibId( aLibrary ); 400 if ( nId != LIB_NOTFOUND ) 401 { 402 pBasicMgr->LoadLib( nId ); 403 pBasic = pBasicMgr->GetLib( aLibrary ); 404 } 405 } 406 if ( pBasic ) 407 { 408 SbModule* pModule = pBasic->FindModule( aModule ); 409 if ( pModule ) 410 { 411 SbxArray* pMethods = pModule->GetMethods(); 412 if ( pMethods ) 413 { 414 SbMethod* pMethod = static_cast< SbMethod* >( pMethods->Find( aMethod, SbxCLASS_METHOD ) ); 415 if ( pMethod && !pMethod->IsHidden() ) 416 { 417 if ( m_pDocBasicManager == pBasicMgr ) 418 xScript = new BasicScriptImpl( aDescription, pMethod, *m_pDocBasicManager, m_xInvocationContext ); 419 else 420 xScript = new BasicScriptImpl( aDescription, pMethod ); 421 } 422 } 423 } 424 } 425 } 426 } 427 428 if ( !xScript.is() ) 429 { 430 ::rtl::OUStringBuffer aMessage; 431 aMessage.appendAscii( "The following Basic script could not be found:\n" ); 432 aMessage.appendAscii( "library: '" ).append( aLibrary ).appendAscii( "'\n" ); 433 aMessage.appendAscii( "module: '" ).append( aModule ).appendAscii( "'\n" ); 434 aMessage.appendAscii( "method: '" ).append( aMethod ).appendAscii( "'\n" ); 435 aMessage.appendAscii( "location: '" ).append( aLocation ).appendAscii( "'\n" ); 436 throw provider::ScriptFrameworkErrorException( 437 aMessage.makeStringAndClear(), 438 Reference< XInterface >(), 439 scriptURI, OUSTR("Basic"), 440 provider::ScriptFrameworkErrorType::NO_SUCH_SCRIPT ); 441 } 442 443 return xScript; 444 } 445 446 // ----------------------------------------------------------------------------- 447 // XBrowseNode 448 // ----------------------------------------------------------------------------- 449 450 ::rtl::OUString BasicProviderImpl::getName( ) throw (RuntimeException) 451 { 452 // TODO 453 454 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 455 456 return ::rtl::OUString::createFromAscii( "Basic" ); 457 } 458 459 // ----------------------------------------------------------------------------- 460 461 Sequence< Reference< browse::XBrowseNode > > BasicProviderImpl::getChildNodes( ) throw (RuntimeException) 462 { 463 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 464 465 Reference< script::XLibraryContainer > xLibContainer; 466 BasicManager* pBasicManager = NULL; 467 468 if ( m_bIsAppScriptCtx ) 469 { 470 xLibContainer = m_xLibContainerApp; 471 pBasicManager = m_pAppBasicManager; 472 } 473 else 474 { 475 xLibContainer = m_xLibContainerDoc; 476 pBasicManager = m_pDocBasicManager; 477 } 478 479 Sequence< Reference< browse::XBrowseNode > > aChildNodes; 480 481 if ( pBasicManager && xLibContainer.is() ) 482 { 483 Sequence< ::rtl::OUString > aLibNames = xLibContainer->getElementNames(); 484 sal_Int32 nLibCount = aLibNames.getLength(); 485 const ::rtl::OUString* pLibNames = aLibNames.getConstArray(); 486 aChildNodes.realloc( nLibCount ); 487 Reference< browse::XBrowseNode >* pChildNodes = aChildNodes.getArray(); 488 sal_Int32 childsFound = 0; 489 490 for ( sal_Int32 i = 0 ; i < nLibCount ; ++i ) 491 { 492 bool bCreate = false; 493 if ( m_bIsAppScriptCtx ) 494 { 495 bool bShared = isLibraryShared( xLibContainer, pLibNames[i] ); 496 if ( ( m_bIsUserCtx && !bShared ) || ( !m_bIsUserCtx && bShared ) ) 497 bCreate = true; 498 } 499 else 500 { 501 bCreate = true; 502 } 503 if ( bCreate ) 504 { 505 pChildNodes[childsFound++] = static_cast< browse::XBrowseNode* >( new BasicLibraryNodeImpl( 506 m_xContext, m_sScriptingContext, pBasicManager, xLibContainer, pLibNames[i], m_bIsAppScriptCtx ) ); 507 } 508 } 509 510 if ( childsFound != nLibCount ) 511 aChildNodes.realloc( childsFound ); 512 } 513 514 return aChildNodes; 515 } 516 517 // ----------------------------------------------------------------------------- 518 519 sal_Bool BasicProviderImpl::hasChildNodes( ) throw (RuntimeException) 520 { 521 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 522 523 sal_Bool bReturn = sal_False; 524 Reference< script::XLibraryContainer > xLibContainer; 525 if ( m_bIsAppScriptCtx ) 526 { 527 xLibContainer = m_xLibContainerApp; 528 } 529 else 530 { 531 xLibContainer = m_xLibContainerDoc; 532 } 533 if ( xLibContainer.is() ) 534 bReturn = xLibContainer->hasElements(); 535 536 return bReturn; 537 } 538 539 // ----------------------------------------------------------------------------- 540 541 sal_Int16 BasicProviderImpl::getType( ) throw (RuntimeException) 542 { 543 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 544 545 return browse::BrowseNodeTypes::CONTAINER; 546 } 547 548 // ============================================================================= 549 // component operations 550 // ============================================================================= 551 552 static Reference< XInterface > SAL_CALL create_BasicProviderImpl( 553 Reference< XComponentContext > const & xContext ) 554 SAL_THROW( () ) 555 { 556 return static_cast< lang::XTypeProvider * >( new BasicProviderImpl( xContext ) ); 557 } 558 559 // ----------------------------------------------------------------------------- 560 561 static struct ::cppu::ImplementationEntry s_component_entries [] = 562 { 563 { 564 create_BasicProviderImpl, getImplementationName_BasicProviderImpl, 565 getSupportedServiceNames_BasicProviderImpl, ::cppu::createSingleComponentFactory, 566 0, 0 567 }, 568 { 0, 0, 0, 0, 0, 0 } 569 }; 570 571 // ----------------------------------------------------------------------------- 572 573 //......................................................................... 574 } // namespace basprov 575 //......................................................................... 576 577 578 // ============================================================================= 579 // component exports 580 // ============================================================================= 581 582 extern "C" 583 { 584 SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment( 585 const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) 586 { 587 (void)ppEnv; 588 589 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; 590 } 591 592 SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory( 593 const sal_Char * pImplName, lang::XMultiServiceFactory * pServiceManager, 594 registry::XRegistryKey * pRegistryKey ) 595 { 596 return ::cppu::component_getFactoryHelper( 597 pImplName, pServiceManager, pRegistryKey, ::basprov::s_component_entries ); 598 } 599 } 600