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 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_ucb.hxx" 26 #include <osl/security.hxx> 27 #include <osl/file.hxx> 28 #include <osl/socket.h> 29 #include <cppuhelper/factory.hxx> 30 #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBBUTE_HPP_ 31 #include <com/sun/star/beans/PropertyAttribute.hpp> 32 #endif 33 #include <com/sun/star/ucb/FileSystemNotation.hpp> 34 #include <com/sun/star/beans/PropertyState.hpp> 35 #include "filglob.hxx" 36 #include "filid.hxx" 37 #include "shell.hxx" 38 #include "bc.hxx" 39 #include "prov.hxx" 40 41 42 using namespace fileaccess; 43 using namespace com::sun::star; 44 using namespace com::sun::star::uno; 45 using namespace com::sun::star::lang; 46 using namespace com::sun::star::beans; 47 using namespace com::sun::star::ucb; 48 using namespace com::sun::star::container; 49 50 //========================================================================= 51 extern "C" void SAL_CALL component_getImplementationEnvironment( 52 const sal_Char ** ppEnvTypeName, uno_Environment ** ) 53 { 54 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; 55 } 56 57 //========================================================================= 58 extern "C" void * SAL_CALL component_getFactory( 59 const sal_Char * pImplName, void * pServiceManager, void * ) 60 { 61 void * pRet = 0; 62 63 Reference< XMultiServiceFactory > xSMgr( 64 reinterpret_cast< XMultiServiceFactory * >( pServiceManager ) ); 65 Reference< XSingleServiceFactory > xFactory; 66 67 ////////////////////////////////////////////////////////////////////// 68 // File Content Provider. 69 ////////////////////////////////////////////////////////////////////// 70 71 if ( fileaccess::shell::getImplementationName_static(). 72 compareToAscii( pImplName ) == 0 ) 73 { 74 xFactory = FileProvider::createServiceFactory( xSMgr ); 75 } 76 77 ////////////////////////////////////////////////////////////////////// 78 79 if ( xFactory.is() ) 80 { 81 xFactory->acquire(); 82 pRet = xFactory.get(); 83 } 84 85 return pRet; 86 } 87 88 /****************************************************************************/ 89 /* */ 90 /* */ 91 /* FileProvider */ 92 /* */ 93 /* */ 94 /****************************************************************************/ 95 96 97 98 FileProvider::FileProvider( const Reference< XMultiServiceFactory >& xMultiServiceFactory ) 99 : m_xMultiServiceFactory( xMultiServiceFactory ), 100 m_pMyShell( 0 ) 101 { 102 } 103 104 105 FileProvider::~FileProvider() 106 { 107 if( m_pMyShell ) 108 delete m_pMyShell; 109 } 110 111 112 ////////////////////////////////////////////////////////////////////////// 113 // XInterface 114 ////////////////////////////////////////////////////////////////////////// 115 116 void SAL_CALL 117 FileProvider::acquire( 118 void ) 119 throw() 120 { 121 OWeakObject::acquire(); 122 } 123 124 125 void SAL_CALL 126 FileProvider::release( 127 void ) 128 throw() 129 { 130 OWeakObject::release(); 131 } 132 133 134 Any SAL_CALL 135 FileProvider::queryInterface( 136 const Type& rType ) 137 throw( RuntimeException ) 138 { 139 Any aRet = cppu::queryInterface( 140 rType, 141 SAL_STATIC_CAST( XContentProvider*, this ), 142 SAL_STATIC_CAST( XInitialization*, this ), 143 SAL_STATIC_CAST( XContentIdentifierFactory*, this ), 144 SAL_STATIC_CAST( XServiceInfo*, this ), 145 SAL_STATIC_CAST( XTypeProvider*, this ), 146 SAL_STATIC_CAST( XFileIdentifierConverter*,this ), 147 SAL_STATIC_CAST( XPropertySet*, this ) ); 148 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); 149 } 150 151 /////////////////////////////////////////////////////////////////////////////// 152 // XInitialization 153 154 void SAL_CALL FileProvider::init() 155 { 156 if( ! m_pMyShell ) 157 m_pMyShell = new shell( m_xMultiServiceFactory, this, sal_True ); 158 } 159 160 161 void SAL_CALL 162 FileProvider::initialize( 163 const Sequence< Any >& aArguments ) 164 throw (Exception, RuntimeException) 165 { 166 if( ! m_pMyShell ) { 167 rtl::OUString config; 168 if( aArguments.getLength() > 0 && 169 (aArguments[0] >>= config) && 170 config.compareToAscii("NoConfig") == 0 ) 171 m_pMyShell = new shell( m_xMultiServiceFactory, this, sal_False ); 172 else 173 m_pMyShell = new shell( m_xMultiServiceFactory, this, sal_True ); 174 } 175 } 176 177 178 //////////////////////////////////////////////////////////////////////////////// 179 // 180 // XTypeProvider methods. 181 182 183 XTYPEPROVIDER_IMPL_7( FileProvider, 184 XTypeProvider, 185 XServiceInfo, 186 XInitialization, 187 XContentIdentifierFactory, 188 XPropertySet, 189 XFileIdentifierConverter, 190 XContentProvider ) 191 192 193 //////////////////////////////////////////////////////////////////////////////// 194 // XServiceInfo methods. 195 196 rtl::OUString SAL_CALL 197 FileProvider::getImplementationName() 198 throw( RuntimeException ) 199 { 200 return fileaccess::shell::getImplementationName_static(); 201 } 202 203 204 sal_Bool SAL_CALL 205 FileProvider::supportsService( 206 const rtl::OUString& ServiceName ) 207 throw( RuntimeException ) 208 { 209 return ServiceName == rtl::OUString::createFromAscii( "com.sun.star.ucb.FileContentProvider" ); 210 } 211 212 213 Sequence< rtl::OUString > SAL_CALL 214 FileProvider::getSupportedServiceNames( 215 void ) 216 throw( RuntimeException ) 217 { 218 return fileaccess::shell::getSupportedServiceNames_static(); 219 } 220 221 222 223 Reference< XSingleServiceFactory > SAL_CALL 224 FileProvider::createServiceFactory( 225 const Reference< XMultiServiceFactory >& rxServiceMgr ) 226 { 227 /** 228 * Create a single service factory.<BR> 229 * Note: The function pointer ComponentInstantiation points to a function throws Exception. 230 * 231 * @param rServiceManager the service manager used by the implementation. 232 * @param rImplementationName the implementation name. An empty string is possible. 233 * @param ComponentInstantiation the function pointer to create an object. 234 * @param rServiceNames the service supported by the implementation. 235 * @return a factory that support the interfaces XServiceProvider, XServiceInfo 236 * XSingleServiceFactory and XComponent. 237 * 238 * @see createOneInstanceFactory 239 */ 240 /* 241 * Reference< ::com::sun::star::XSingleServiceFactory > createSingleFactory 242 * ( 243 * const ::com::sun::star::Reference< ::com::sun::star::XMultiServiceFactory > & rServiceManager, 244 * const ::rtl::OUString & rImplementationName, 245 * ComponentInstantiation pCreateFunction, 246 247 * const ::com::sun::star::Sequence< ::rtl::OUString > & rServiceNames 248 * ); 249 */ 250 251 return Reference< XSingleServiceFactory > ( cppu::createSingleFactory( 252 rxServiceMgr, 253 fileaccess::shell::getImplementationName_static(), 254 FileProvider::CreateInstance, 255 fileaccess::shell::getSupportedServiceNames_static() ) ); 256 } 257 258 Reference< XInterface > SAL_CALL 259 FileProvider::CreateInstance( 260 const Reference< XMultiServiceFactory >& xMultiServiceFactory ) 261 { 262 XServiceInfo* xP = (XServiceInfo*) new FileProvider( xMultiServiceFactory ); 263 return Reference< XInterface >::query( xP ); 264 } 265 266 267 268 //////////////////////////////////////////////////////////////////////////////// 269 // XContent 270 //////////////////////////////////////////////////////////////////////////////// 271 272 273 Reference< XContent > SAL_CALL 274 FileProvider::queryContent( 275 const Reference< XContentIdentifier >& xIdentifier ) 276 throw( IllegalIdentifierException, 277 RuntimeException) 278 { 279 init(); 280 rtl::OUString aUnc; 281 sal_Bool err = m_pMyShell->getUnqFromUrl( xIdentifier->getContentIdentifier(), 282 aUnc ); 283 284 if( err ) 285 throw IllegalIdentifierException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 286 287 return Reference< XContent >( new BaseContent( m_pMyShell,xIdentifier,aUnc ) ); 288 } 289 290 291 292 sal_Int32 SAL_CALL 293 FileProvider::compareContentIds( 294 const Reference< XContentIdentifier >& Id1, 295 const Reference< XContentIdentifier >& Id2 ) 296 throw( RuntimeException ) 297 { 298 init(); 299 rtl::OUString aUrl1 = Id1->getContentIdentifier(); 300 rtl::OUString aUrl2 = Id2->getContentIdentifier(); 301 302 sal_Int32 iComp = aUrl1.compareTo( aUrl2 ); 303 304 if ( 0 != iComp ) 305 { 306 rtl::OUString aPath1, aPath2; 307 308 m_pMyShell->getUnqFromUrl( aUrl1, aPath1 ); 309 m_pMyShell->getUnqFromUrl( aUrl2, aPath2 ); 310 311 osl::FileBase::RC error; 312 osl::DirectoryItem aItem1, aItem2; 313 314 error = osl::DirectoryItem::get( aPath1, aItem1 ); 315 if ( error == osl::FileBase::E_None ) 316 error = osl::DirectoryItem::get( aPath2, aItem2 ); 317 318 if ( error != osl::FileBase::E_None ) 319 return iComp; 320 321 osl::FileStatus aStatus1( FileStatusMask_FileURL ); 322 osl::FileStatus aStatus2( FileStatusMask_FileURL ); 323 error = aItem1.getFileStatus( aStatus1 ); 324 if ( error == osl::FileBase::E_None ) 325 error = aItem2.getFileStatus( aStatus2 ); 326 327 if ( error == osl::FileBase::E_None ) 328 { 329 iComp = aStatus1.getFileURL().compareTo( aStatus2.getFileURL() ); 330 331 // Quick hack for Windows to threat all file systems as case insensitive 332 #ifdef WNT 333 if ( 0 != iComp ) 334 { 335 error = osl::FileBase::getSystemPathFromFileURL( aStatus1.getFileURL(), aPath1 ); 336 if ( error == osl::FileBase::E_None ) 337 error = osl::FileBase::getSystemPathFromFileURL( aStatus2.getFileURL(), aPath2 ); 338 339 if ( error == osl::FileBase::E_None ) 340 iComp = rtl_ustr_compareIgnoreAsciiCase( aPath1.getStr(), aPath2.getStr() ); 341 } 342 #endif 343 } 344 } 345 346 return iComp; 347 } 348 349 350 351 Reference< XContentIdentifier > SAL_CALL 352 FileProvider::createContentIdentifier( 353 const rtl::OUString& ContentId ) 354 throw( RuntimeException ) 355 { 356 init(); 357 FileContentIdentifier* p = new FileContentIdentifier( m_pMyShell,ContentId,false ); 358 return Reference< XContentIdentifier >( p ); 359 } 360 361 362 363 //XPropertySetInfoImpl 364 365 class XPropertySetInfoImpl2 366 : public cppu::OWeakObject, 367 public XPropertySetInfo 368 { 369 public: 370 XPropertySetInfoImpl2(); 371 ~XPropertySetInfoImpl2(); 372 373 // XInterface 374 virtual Any SAL_CALL 375 queryInterface( 376 const Type& aType ) 377 throw( RuntimeException); 378 379 virtual void SAL_CALL 380 acquire( 381 void ) 382 throw(); 383 384 virtual void SAL_CALL 385 release( 386 void ) 387 throw(); 388 389 390 virtual Sequence< Property > SAL_CALL 391 getProperties( 392 void ) 393 throw( RuntimeException ); 394 395 virtual Property SAL_CALL 396 getPropertyByName( 397 const rtl::OUString& aName ) 398 throw( UnknownPropertyException, 399 RuntimeException); 400 401 virtual sal_Bool SAL_CALL 402 hasPropertyByName( const rtl::OUString& Name ) 403 throw( RuntimeException ); 404 405 406 private: 407 Sequence< Property > m_seq; 408 }; 409 410 411 XPropertySetInfoImpl2::XPropertySetInfoImpl2() 412 : m_seq( 3 ) 413 { 414 m_seq[0] = Property( rtl::OUString::createFromAscii( "HostName" ), 415 -1, 416 getCppuType( static_cast< rtl::OUString* >( 0 ) ), 417 PropertyAttribute::READONLY ); 418 419 m_seq[1] = Property( rtl::OUString::createFromAscii( "HomeDirectory" ), 420 -1, 421 getCppuType( static_cast< rtl::OUString* >( 0 ) ), 422 PropertyAttribute::READONLY ); 423 424 m_seq[2] = Property( rtl::OUString::createFromAscii( "FileSystemNotation" ), 425 -1, 426 getCppuType( static_cast< sal_Int32* >( 0 ) ), 427 PropertyAttribute::READONLY ); 428 } 429 430 431 XPropertySetInfoImpl2::~XPropertySetInfoImpl2() 432 { 433 // nothing 434 } 435 436 437 void SAL_CALL 438 XPropertySetInfoImpl2::acquire( 439 void ) 440 throw() 441 { 442 OWeakObject::acquire(); 443 } 444 445 446 void SAL_CALL 447 XPropertySetInfoImpl2::release( 448 void ) 449 throw() 450 { 451 OWeakObject::release(); 452 } 453 454 455 Any SAL_CALL 456 XPropertySetInfoImpl2::queryInterface( 457 const Type& rType ) 458 throw( RuntimeException ) 459 { 460 Any aRet = cppu::queryInterface( rType, 461 SAL_STATIC_CAST( XPropertySetInfo*,this) ); 462 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); 463 } 464 465 466 Property SAL_CALL 467 XPropertySetInfoImpl2::getPropertyByName( 468 const rtl::OUString& aName ) 469 throw( UnknownPropertyException, 470 RuntimeException) 471 { 472 for( sal_Int32 i = 0; i < m_seq.getLength(); ++i ) 473 if( m_seq[i].Name == aName ) 474 return m_seq[i]; 475 476 throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 477 } 478 479 480 481 Sequence< Property > SAL_CALL 482 XPropertySetInfoImpl2::getProperties( 483 void ) 484 throw( RuntimeException ) 485 { 486 return m_seq; 487 } 488 489 490 sal_Bool SAL_CALL 491 XPropertySetInfoImpl2::hasPropertyByName( 492 const rtl::OUString& aName ) 493 throw( RuntimeException ) 494 { 495 for( sal_Int32 i = 0; i < m_seq.getLength(); ++i ) 496 if( m_seq[i].Name == aName ) 497 return true; 498 return false; 499 } 500 501 502 503 504 505 void SAL_CALL FileProvider::initProperties( void ) 506 { 507 osl::MutexGuard aGuard( m_aMutex ); 508 if( ! m_xPropertySetInfo.is() ) 509 { 510 osl_getLocalHostname( &m_HostName.pData ); 511 512 #if defined ( UNX ) 513 m_FileSystemNotation = FileSystemNotation::UNIX_NOTATION; 514 #elif defined( WNT ) || defined( OS2 ) 515 m_FileSystemNotation = FileSystemNotation::DOS_NOTATION; 516 #else 517 m_FileSystemNotation = FileSystemNotation::UNKNOWN_NOTATION; 518 #endif 519 osl::Security aSecurity; 520 aSecurity.getHomeDir( m_HomeDirectory ); 521 522 // static const sal_Int32 UNKNOWN_NOTATION = (sal_Int32)0; 523 // static const sal_Int32 UNIX_NOTATION = (sal_Int32)1; 524 // static const sal_Int32 DOS_NOTATION = (sal_Int32)2; 525 // static const sal_Int32 MAC_NOTATION = (sal_Int32)3; 526 527 XPropertySetInfoImpl2* p = new XPropertySetInfoImpl2(); 528 m_xPropertySetInfo = Reference< XPropertySetInfo >( p ); 529 } 530 } 531 532 533 // XPropertySet 534 535 Reference< XPropertySetInfo > SAL_CALL 536 FileProvider::getPropertySetInfo( ) 537 throw( RuntimeException ) 538 { 539 initProperties(); 540 return m_xPropertySetInfo; 541 } 542 543 544 void SAL_CALL 545 FileProvider::setPropertyValue( const rtl::OUString& aPropertyName, 546 const Any& ) 547 throw( UnknownPropertyException, 548 PropertyVetoException, 549 IllegalArgumentException, 550 WrappedTargetException, 551 RuntimeException ) 552 { 553 if( aPropertyName.compareToAscii( "FileSystemNotation" ) == 0 || 554 aPropertyName.compareToAscii( "HomeDirectory" ) == 0 || 555 aPropertyName.compareToAscii( "HostName" ) == 0 ) 556 return; 557 else 558 throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 559 } 560 561 562 563 Any SAL_CALL 564 FileProvider::getPropertyValue( 565 const rtl::OUString& aPropertyName ) 566 throw( UnknownPropertyException, 567 WrappedTargetException, 568 RuntimeException ) 569 { 570 initProperties(); 571 if( aPropertyName.compareToAscii( "FileSystemNotation" ) == 0 ) 572 { 573 Any aAny; 574 aAny <<= m_FileSystemNotation; 575 return aAny; 576 } 577 else if( aPropertyName.compareToAscii( "HomeDirectory" ) == 0 ) 578 { 579 Any aAny; 580 aAny <<= m_HomeDirectory; 581 return aAny; 582 } 583 else if( aPropertyName.compareToAscii( "HostName" ) == 0 ) 584 { 585 Any aAny; 586 aAny <<= m_HostName; 587 return aAny; 588 } 589 else 590 throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 591 } 592 593 594 void SAL_CALL 595 FileProvider::addPropertyChangeListener( 596 const rtl::OUString&, 597 const Reference< XPropertyChangeListener >& ) 598 throw( UnknownPropertyException, 599 WrappedTargetException, 600 RuntimeException) 601 { 602 return; 603 } 604 605 606 void SAL_CALL 607 FileProvider::removePropertyChangeListener( 608 const rtl::OUString&, 609 const Reference< XPropertyChangeListener >& ) 610 throw( UnknownPropertyException, 611 WrappedTargetException, 612 RuntimeException ) 613 { 614 return; 615 } 616 617 void SAL_CALL 618 FileProvider::addVetoableChangeListener( 619 const rtl::OUString&, 620 const Reference< XVetoableChangeListener >& ) 621 throw( UnknownPropertyException, 622 WrappedTargetException, 623 RuntimeException ) 624 { 625 return; 626 } 627 628 629 void SAL_CALL 630 FileProvider::removeVetoableChangeListener( 631 const rtl::OUString&, 632 const Reference< XVetoableChangeListener >& ) 633 throw( UnknownPropertyException, 634 WrappedTargetException, 635 RuntimeException) 636 { 637 return; 638 } 639 640 641 642 // XFileIdentifierConverter 643 644 sal_Int32 SAL_CALL 645 FileProvider::getFileProviderLocality( const rtl::OUString& BaseURL ) 646 throw( RuntimeException ) 647 { 648 // If the base URL is a 'file' URL, return 10 (very 'local'), otherwise 649 // return -1 (missmatch). What is missing is a fast comparison to ASCII, 650 // ignoring case: 651 return BaseURL.getLength() >= 5 652 && (BaseURL[0] == 'F' || BaseURL[0] == 'f') 653 && (BaseURL[1] == 'I' || BaseURL[1] == 'i') 654 && (BaseURL[2] == 'L' || BaseURL[2] == 'l') 655 && (BaseURL[3] == 'E' || BaseURL[3] == 'e') 656 && BaseURL[4] == ':' ? 657 10 : -1; 658 } 659 660 rtl::OUString SAL_CALL FileProvider::getFileURLFromSystemPath( const rtl::OUString&, 661 const rtl::OUString& SystemPath ) 662 throw( RuntimeException ) 663 { 664 rtl::OUString aNormalizedPath; 665 if ( osl::FileBase::getFileURLFromSystemPath( SystemPath,aNormalizedPath ) != osl::FileBase::E_None ) 666 return rtl::OUString(); 667 668 return aNormalizedPath; 669 } 670 671 rtl::OUString SAL_CALL FileProvider::getSystemPathFromFileURL( const rtl::OUString& URL ) 672 throw( RuntimeException ) 673 { 674 rtl::OUString aSystemPath; 675 if (osl::FileBase::getSystemPathFromFileURL( URL,aSystemPath ) != osl::FileBase::E_None ) 676 return rtl::OUString(); 677 678 return aSystemPath; 679 } 680 681