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_file.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" SAL_DLLPUBLIC_EXPORT 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" SAL_DLLPUBLIC_EXPORT 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 { 138 Any aRet = cppu::queryInterface( 139 rType, 140 SAL_STATIC_CAST( XContentProvider*, this ), 141 SAL_STATIC_CAST( XInitialization*, this ), 142 SAL_STATIC_CAST( XContentIdentifierFactory*, this ), 143 SAL_STATIC_CAST( XServiceInfo*, this ), 144 SAL_STATIC_CAST( XTypeProvider*, this ), 145 SAL_STATIC_CAST( XFileIdentifierConverter*,this ), 146 SAL_STATIC_CAST( XPropertySet*, this ) ); 147 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); 148 } 149 150 /////////////////////////////////////////////////////////////////////////////// 151 // XInitialization 152 153 void SAL_CALL FileProvider::init() 154 { 155 if( ! m_pMyShell ) 156 m_pMyShell = new shell( m_xMultiServiceFactory, this, sal_True ); 157 } 158 159 160 void SAL_CALL 161 FileProvider::initialize( 162 const Sequence< Any >& aArguments ) 163 { 164 if( ! m_pMyShell ) { 165 rtl::OUString config; 166 if( aArguments.getLength() > 0 && 167 (aArguments[0] >>= config) && 168 config.compareToAscii("NoConfig") == 0 ) 169 m_pMyShell = new shell( m_xMultiServiceFactory, this, sal_False ); 170 else 171 m_pMyShell = new shell( m_xMultiServiceFactory, this, sal_True ); 172 } 173 } 174 175 176 //////////////////////////////////////////////////////////////////////////////// 177 // 178 // XTypeProvider methods. 179 180 181 XTYPEPROVIDER_IMPL_7( FileProvider, 182 XTypeProvider, 183 XServiceInfo, 184 XInitialization, 185 XContentIdentifierFactory, 186 XPropertySet, 187 XFileIdentifierConverter, 188 XContentProvider ) 189 190 191 //////////////////////////////////////////////////////////////////////////////// 192 // XServiceInfo methods. 193 194 rtl::OUString SAL_CALL 195 FileProvider::getImplementationName() 196 { 197 return fileaccess::shell::getImplementationName_static(); 198 } 199 200 201 sal_Bool SAL_CALL 202 FileProvider::supportsService( 203 const rtl::OUString& ServiceName ) 204 { 205 return ServiceName == rtl::OUString::createFromAscii( "com.sun.star.ucb.FileContentProvider" ); 206 } 207 208 209 Sequence< rtl::OUString > SAL_CALL 210 FileProvider::getSupportedServiceNames( 211 void ) 212 { 213 return fileaccess::shell::getSupportedServiceNames_static(); 214 } 215 216 217 218 Reference< XSingleServiceFactory > SAL_CALL 219 FileProvider::createServiceFactory( 220 const Reference< XMultiServiceFactory >& rxServiceMgr ) 221 { 222 /** 223 * Create a single service factory.<BR> 224 * Note: The function pointer ComponentInstantiation points to a function throws Exception. 225 * 226 * @param rServiceManager the service manager used by the implementation. 227 * @param rImplementationName the implementation name. An empty string is possible. 228 * @param ComponentInstantiation the function pointer to create an object. 229 * @param rServiceNames the service supported by the implementation. 230 * @return a factory that support the interfaces XServiceProvider, XServiceInfo 231 * XSingleServiceFactory and XComponent. 232 * 233 * @see createOneInstanceFactory 234 */ 235 /* 236 * Reference< ::com::sun::star::XSingleServiceFactory > createSingleFactory 237 * ( 238 * const ::com::sun::star::Reference< ::com::sun::star::XMultiServiceFactory > & rServiceManager, 239 * const ::rtl::OUString & rImplementationName, 240 * ComponentInstantiation pCreateFunction, 241 242 * const ::com::sun::star::Sequence< ::rtl::OUString > & rServiceNames 243 * ); 244 */ 245 246 return Reference< XSingleServiceFactory > ( cppu::createSingleFactory( 247 rxServiceMgr, 248 fileaccess::shell::getImplementationName_static(), 249 FileProvider::CreateInstance, 250 fileaccess::shell::getSupportedServiceNames_static() ) ); 251 } 252 253 Reference< XInterface > SAL_CALL 254 FileProvider::CreateInstance( 255 const Reference< XMultiServiceFactory >& xMultiServiceFactory ) 256 { 257 XServiceInfo* xP = (XServiceInfo*) new FileProvider( xMultiServiceFactory ); 258 return Reference< XInterface >::query( xP ); 259 } 260 261 262 263 //////////////////////////////////////////////////////////////////////////////// 264 // XContent 265 //////////////////////////////////////////////////////////////////////////////// 266 267 268 Reference< XContent > SAL_CALL 269 FileProvider::queryContent( 270 const Reference< XContentIdentifier >& xIdentifier ) 271 { 272 init(); 273 rtl::OUString aUnc; 274 sal_Bool err = m_pMyShell->getUnqFromUrl( xIdentifier->getContentIdentifier(), 275 aUnc ); 276 277 if( err ) 278 throw IllegalIdentifierException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 279 280 return Reference< XContent >( new BaseContent( m_pMyShell,xIdentifier,aUnc ) ); 281 } 282 283 284 285 sal_Int32 SAL_CALL 286 FileProvider::compareContentIds( 287 const Reference< XContentIdentifier >& Id1, 288 const Reference< XContentIdentifier >& Id2 ) 289 { 290 init(); 291 rtl::OUString aUrl1 = Id1->getContentIdentifier(); 292 rtl::OUString aUrl2 = Id2->getContentIdentifier(); 293 294 sal_Int32 iComp = aUrl1.compareTo( aUrl2 ); 295 296 if ( 0 != iComp ) 297 { 298 rtl::OUString aPath1, aPath2; 299 300 m_pMyShell->getUnqFromUrl( aUrl1, aPath1 ); 301 m_pMyShell->getUnqFromUrl( aUrl2, aPath2 ); 302 303 osl::FileBase::RC error; 304 osl::DirectoryItem aItem1, aItem2; 305 306 error = osl::DirectoryItem::get( aPath1, aItem1 ); 307 if ( error == osl::FileBase::E_None ) 308 error = osl::DirectoryItem::get( aPath2, aItem2 ); 309 310 if ( error != osl::FileBase::E_None ) 311 return iComp; 312 313 osl::FileStatus aStatus1( FileStatusMask_FileURL ); 314 osl::FileStatus aStatus2( FileStatusMask_FileURL ); 315 error = aItem1.getFileStatus( aStatus1 ); 316 if ( error == osl::FileBase::E_None ) 317 error = aItem2.getFileStatus( aStatus2 ); 318 319 if ( error == osl::FileBase::E_None ) 320 { 321 iComp = aStatus1.getFileURL().compareTo( aStatus2.getFileURL() ); 322 323 // Quick hack for Windows to treat all file systems as case insensitive 324 #ifdef WNT 325 if ( 0 != iComp ) 326 { 327 error = osl::FileBase::getSystemPathFromFileURL( aStatus1.getFileURL(), aPath1 ); 328 if ( error == osl::FileBase::E_None ) 329 error = osl::FileBase::getSystemPathFromFileURL( aStatus2.getFileURL(), aPath2 ); 330 331 if ( error == osl::FileBase::E_None ) 332 iComp = rtl_ustr_compareIgnoreAsciiCase( aPath1.getStr(), aPath2.getStr() ); 333 } 334 #endif 335 } 336 } 337 338 return iComp; 339 } 340 341 342 343 Reference< XContentIdentifier > SAL_CALL 344 FileProvider::createContentIdentifier( 345 const rtl::OUString& ContentId ) 346 { 347 init(); 348 FileContentIdentifier* p = new FileContentIdentifier( m_pMyShell,ContentId,false ); 349 return Reference< XContentIdentifier >( p ); 350 } 351 352 353 354 //XPropertySetInfoImpl 355 356 class XPropertySetInfoImpl2 357 : public cppu::OWeakObject, 358 public XPropertySetInfo 359 { 360 public: 361 XPropertySetInfoImpl2(); 362 ~XPropertySetInfoImpl2(); 363 364 // XInterface 365 virtual Any SAL_CALL 366 queryInterface( 367 const Type& aType ); 368 369 virtual void SAL_CALL 370 acquire( 371 void ) 372 throw(); 373 374 virtual void SAL_CALL 375 release( 376 void ) 377 throw(); 378 379 380 virtual Sequence< Property > SAL_CALL 381 getProperties( 382 void ); 383 384 virtual Property SAL_CALL 385 getPropertyByName( 386 const rtl::OUString& aName ); 387 388 virtual sal_Bool SAL_CALL 389 hasPropertyByName( const rtl::OUString& Name ); 390 391 392 private: 393 Sequence< Property > m_seq; 394 }; 395 396 397 XPropertySetInfoImpl2::XPropertySetInfoImpl2() 398 : m_seq( 3 ) 399 { 400 m_seq[0] = Property( rtl::OUString::createFromAscii( "HostName" ), 401 -1, 402 getCppuType( static_cast< rtl::OUString* >( 0 ) ), 403 PropertyAttribute::READONLY ); 404 405 m_seq[1] = Property( rtl::OUString::createFromAscii( "HomeDirectory" ), 406 -1, 407 getCppuType( static_cast< rtl::OUString* >( 0 ) ), 408 PropertyAttribute::READONLY ); 409 410 m_seq[2] = Property( rtl::OUString::createFromAscii( "FileSystemNotation" ), 411 -1, 412 getCppuType( static_cast< sal_Int32* >( 0 ) ), 413 PropertyAttribute::READONLY ); 414 } 415 416 417 XPropertySetInfoImpl2::~XPropertySetInfoImpl2() 418 { 419 // nothing 420 } 421 422 423 void SAL_CALL 424 XPropertySetInfoImpl2::acquire( 425 void ) 426 throw() 427 { 428 OWeakObject::acquire(); 429 } 430 431 432 void SAL_CALL 433 XPropertySetInfoImpl2::release( 434 void ) 435 throw() 436 { 437 OWeakObject::release(); 438 } 439 440 441 Any SAL_CALL 442 XPropertySetInfoImpl2::queryInterface( 443 const Type& rType ) 444 { 445 Any aRet = cppu::queryInterface( rType, 446 SAL_STATIC_CAST( XPropertySetInfo*,this) ); 447 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); 448 } 449 450 451 Property SAL_CALL 452 XPropertySetInfoImpl2::getPropertyByName( 453 const rtl::OUString& aName ) 454 { 455 for( sal_Int32 i = 0; i < m_seq.getLength(); ++i ) 456 if( m_seq[i].Name == aName ) 457 return m_seq[i]; 458 459 throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 460 } 461 462 463 464 Sequence< Property > SAL_CALL 465 XPropertySetInfoImpl2::getProperties( 466 void ) 467 { 468 return m_seq; 469 } 470 471 472 sal_Bool SAL_CALL 473 XPropertySetInfoImpl2::hasPropertyByName( 474 const rtl::OUString& aName ) 475 { 476 for( sal_Int32 i = 0; i < m_seq.getLength(); ++i ) 477 if( m_seq[i].Name == aName ) 478 return true; 479 return false; 480 } 481 482 483 484 485 486 void SAL_CALL FileProvider::initProperties( void ) 487 { 488 osl::MutexGuard aGuard( m_aMutex ); 489 if( ! m_xPropertySetInfo.is() ) 490 { 491 osl_getLocalHostname( &m_HostName.pData ); 492 493 #if defined ( UNX ) 494 m_FileSystemNotation = FileSystemNotation::UNIX_NOTATION; 495 #elif defined( WNT ) || defined( OS2 ) 496 m_FileSystemNotation = FileSystemNotation::DOS_NOTATION; 497 #else 498 m_FileSystemNotation = FileSystemNotation::UNKNOWN_NOTATION; 499 #endif 500 osl::Security aSecurity; 501 aSecurity.getHomeDir( m_HomeDirectory ); 502 503 // static const sal_Int32 UNKNOWN_NOTATION = (sal_Int32)0; 504 // static const sal_Int32 UNIX_NOTATION = (sal_Int32)1; 505 // static const sal_Int32 DOS_NOTATION = (sal_Int32)2; 506 // static const sal_Int32 MAC_NOTATION = (sal_Int32)3; 507 508 XPropertySetInfoImpl2* p = new XPropertySetInfoImpl2(); 509 m_xPropertySetInfo = Reference< XPropertySetInfo >( p ); 510 } 511 } 512 513 514 // XPropertySet 515 516 Reference< XPropertySetInfo > SAL_CALL 517 FileProvider::getPropertySetInfo( ) 518 { 519 initProperties(); 520 return m_xPropertySetInfo; 521 } 522 523 524 void SAL_CALL 525 FileProvider::setPropertyValue( const rtl::OUString& aPropertyName, 526 const Any& ) 527 { 528 if( aPropertyName.compareToAscii( "FileSystemNotation" ) == 0 || 529 aPropertyName.compareToAscii( "HomeDirectory" ) == 0 || 530 aPropertyName.compareToAscii( "HostName" ) == 0 ) 531 return; 532 else 533 throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 534 } 535 536 537 538 Any SAL_CALL 539 FileProvider::getPropertyValue( 540 const rtl::OUString& aPropertyName ) 541 { 542 initProperties(); 543 if( aPropertyName.compareToAscii( "FileSystemNotation" ) == 0 ) 544 { 545 Any aAny; 546 aAny <<= m_FileSystemNotation; 547 return aAny; 548 } 549 else if( aPropertyName.compareToAscii( "HomeDirectory" ) == 0 ) 550 { 551 Any aAny; 552 aAny <<= m_HomeDirectory; 553 return aAny; 554 } 555 else if( aPropertyName.compareToAscii( "HostName" ) == 0 ) 556 { 557 Any aAny; 558 aAny <<= m_HostName; 559 return aAny; 560 } 561 else 562 throw UnknownPropertyException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ), uno::Reference< uno::XInterface >() ); 563 } 564 565 566 void SAL_CALL 567 FileProvider::addPropertyChangeListener( 568 const rtl::OUString&, 569 const Reference< XPropertyChangeListener >& ) 570 { 571 return; 572 } 573 574 575 void SAL_CALL 576 FileProvider::removePropertyChangeListener( 577 const rtl::OUString&, 578 const Reference< XPropertyChangeListener >& ) 579 { 580 return; 581 } 582 583 void SAL_CALL 584 FileProvider::addVetoableChangeListener( 585 const rtl::OUString&, 586 const Reference< XVetoableChangeListener >& ) 587 { 588 return; 589 } 590 591 592 void SAL_CALL 593 FileProvider::removeVetoableChangeListener( 594 const rtl::OUString&, 595 const Reference< XVetoableChangeListener >& ) 596 { 597 return; 598 } 599 600 601 602 // XFileIdentifierConverter 603 604 sal_Int32 SAL_CALL 605 FileProvider::getFileProviderLocality( const rtl::OUString& BaseURL ) 606 { 607 // If the base URL is a 'file' URL, return 10 (very 'local'), otherwise 608 // return -1 (mismatch). What is missing is a fast comparison to ASCII, 609 // ignoring case: 610 return BaseURL.getLength() >= 5 611 && (BaseURL[0] == 'F' || BaseURL[0] == 'f') 612 && (BaseURL[1] == 'I' || BaseURL[1] == 'i') 613 && (BaseURL[2] == 'L' || BaseURL[2] == 'l') 614 && (BaseURL[3] == 'E' || BaseURL[3] == 'e') 615 && BaseURL[4] == ':' ? 616 10 : -1; 617 } 618 619 rtl::OUString SAL_CALL FileProvider::getFileURLFromSystemPath( const rtl::OUString&, 620 const rtl::OUString& SystemPath ) 621 { 622 rtl::OUString aNormalizedPath; 623 if ( osl::FileBase::getFileURLFromSystemPath( SystemPath,aNormalizedPath ) != osl::FileBase::E_None ) 624 return rtl::OUString(); 625 626 return aNormalizedPath; 627 } 628 629 rtl::OUString SAL_CALL FileProvider::getSystemPathFromFileURL( const rtl::OUString& URL ) 630 { 631 rtl::OUString aSystemPath; 632 if (osl::FileBase::getSystemPathFromFileURL( URL,aSystemPath ) != osl::FileBase::E_None ) 633 return rtl::OUString(); 634 635 return aSystemPath; 636 } 637