1*2722ceddSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*2722ceddSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*2722ceddSAndrew Rist * or more contributor license agreements. See the NOTICE file 5*2722ceddSAndrew Rist * distributed with this work for additional information 6*2722ceddSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*2722ceddSAndrew Rist * to you under the Apache License, Version 2.0 (the 8*2722ceddSAndrew Rist * "License"); you may not use this file except in compliance 9*2722ceddSAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*2722ceddSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*2722ceddSAndrew Rist * Unless required by applicable law or agreed to in writing, 14*2722ceddSAndrew Rist * software distributed under the License is distributed on an 15*2722ceddSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*2722ceddSAndrew Rist * KIND, either express or implied. See the License for the 17*2722ceddSAndrew Rist * specific language governing permissions and limitations 18*2722ceddSAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*2722ceddSAndrew Rist *************************************************************/ 21*2722ceddSAndrew Rist 22*2722ceddSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_desktop.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include "dp_misc.h" 28cdf0e10cSrcweir #include "dp_backend.h" 29cdf0e10cSrcweir #include "dp_ucb.h" 30cdf0e10cSrcweir #include "dp_interact.h" 31cdf0e10cSrcweir #include "rtl/string.hxx" 32cdf0e10cSrcweir #include "osl/file.hxx" 33cdf0e10cSrcweir #include "ucbhelper/content.hxx" 34cdf0e10cSrcweir #include "comphelper/servicedecl.hxx" 35cdf0e10cSrcweir #include "svl/inettype.hxx" 36cdf0e10cSrcweir #include "cppuhelper/implbase1.hxx" 37cdf0e10cSrcweir #include "dp_executablebackenddb.hxx" 38cdf0e10cSrcweir 39cdf0e10cSrcweir using namespace ::com::sun::star; 40cdf0e10cSrcweir using namespace ::com::sun::star::uno; 41cdf0e10cSrcweir using namespace ::com::sun::star::ucb; 42cdf0e10cSrcweir using namespace dp_misc; 43cdf0e10cSrcweir using ::rtl::OUString; 44cdf0e10cSrcweir 45cdf0e10cSrcweir namespace dp_registry { 46cdf0e10cSrcweir namespace backend { 47cdf0e10cSrcweir namespace executable { 48cdf0e10cSrcweir namespace { 49cdf0e10cSrcweir 50cdf0e10cSrcweir class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend 51cdf0e10cSrcweir { 52cdf0e10cSrcweir class ExecutablePackageImpl : public ::dp_registry::backend::Package 53cdf0e10cSrcweir { 54cdf0e10cSrcweir BackendImpl * getMyBackend() const; 55cdf0e10cSrcweir 56cdf0e10cSrcweir // Package 57cdf0e10cSrcweir virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_( 58cdf0e10cSrcweir ::osl::ResettableMutexGuard & guard, 59cdf0e10cSrcweir ::rtl::Reference<dp_misc::AbortChannel> const & abortChannel, 60cdf0e10cSrcweir Reference<XCommandEnvironment> const & xCmdEnv ); 61cdf0e10cSrcweir virtual void processPackage_( 62cdf0e10cSrcweir ::osl::ResettableMutexGuard & guard, 63cdf0e10cSrcweir bool registerPackage, 64cdf0e10cSrcweir bool startup, 65cdf0e10cSrcweir ::rtl::Reference<dp_misc::AbortChannel> const & abortChannel, 66cdf0e10cSrcweir Reference<XCommandEnvironment> const & xCmdEnv ); 67cdf0e10cSrcweir 68cdf0e10cSrcweir bool getFileAttributes(sal_uInt64& out_Attributes); 69cdf0e10cSrcweir bool isUrlTargetInExtension(); 70cdf0e10cSrcweir 71cdf0e10cSrcweir public: 72cdf0e10cSrcweir inline ExecutablePackageImpl( 73cdf0e10cSrcweir ::rtl::Reference<PackageRegistryBackend> const & myBackend, 74cdf0e10cSrcweir OUString const & url, OUString const & name, 75cdf0e10cSrcweir Reference<deployment::XPackageTypeInfo> const & xPackageType, 76cdf0e10cSrcweir bool bRemoved, OUString const & identifier) 77cdf0e10cSrcweir : Package( myBackend, url, name, name /* display-name */, 78cdf0e10cSrcweir xPackageType, bRemoved, identifier) 79cdf0e10cSrcweir {} 80cdf0e10cSrcweir }; 81cdf0e10cSrcweir friend class ExecutablePackageImpl; 82cdf0e10cSrcweir 83cdf0e10cSrcweir typedef ::std::hash_map< OUString, Reference<XInterface>, 84cdf0e10cSrcweir ::rtl::OUStringHash > t_string2object; 85cdf0e10cSrcweir 86cdf0e10cSrcweir // PackageRegistryBackend 87cdf0e10cSrcweir virtual Reference<deployment::XPackage> bindPackage_( 88cdf0e10cSrcweir OUString const & url, OUString const & mediaType, sal_Bool bRemoved, 89cdf0e10cSrcweir OUString const & identifier, Reference<XCommandEnvironment> const & xCmdEnv ); 90cdf0e10cSrcweir 91cdf0e10cSrcweir void addDataToDb(OUString const & url); 92cdf0e10cSrcweir bool hasActiveEntry(OUString const & url); 93cdf0e10cSrcweir void revokeEntryFromDb(OUString const & url); 94cdf0e10cSrcweir 95cdf0e10cSrcweir Reference<deployment::XPackageTypeInfo> m_xExecutableTypeInfo; 96cdf0e10cSrcweir std::auto_ptr<ExecutableBackendDb> m_backendDb; 97cdf0e10cSrcweir public: 98cdf0e10cSrcweir BackendImpl( Sequence<Any> const & args, 99cdf0e10cSrcweir Reference<XComponentContext> const & xComponentContext ); 100cdf0e10cSrcweir 101cdf0e10cSrcweir // XPackageRegistry 102cdf0e10cSrcweir virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL 103cdf0e10cSrcweir getSupportedPackageTypes() throw (RuntimeException); 104cdf0e10cSrcweir virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType) 105cdf0e10cSrcweir throw (deployment::DeploymentException, 106cdf0e10cSrcweir uno::RuntimeException); 107cdf0e10cSrcweir 108cdf0e10cSrcweir using PackageRegistryBackend::disposing; 109cdf0e10cSrcweir }; 110cdf0e10cSrcweir 111cdf0e10cSrcweir 112cdf0e10cSrcweir BackendImpl::BackendImpl( 113cdf0e10cSrcweir Sequence<Any> const & args, 114cdf0e10cSrcweir Reference<XComponentContext> const & xComponentContext ) 115cdf0e10cSrcweir : PackageRegistryBackend( args, xComponentContext ), 116cdf0e10cSrcweir m_xExecutableTypeInfo(new Package::TypeInfo( 117cdf0e10cSrcweir OUSTR("application/vnd.sun.star.executable"), 118cdf0e10cSrcweir OUSTR(""), 119cdf0e10cSrcweir OUSTR("Executable"), 120cdf0e10cSrcweir RID_IMG_COMPONENT, 121cdf0e10cSrcweir RID_IMG_COMPONENT_HC ) ) 122cdf0e10cSrcweir { 123cdf0e10cSrcweir if (!transientMode()) 124cdf0e10cSrcweir { 125cdf0e10cSrcweir OUString dbFile = makeURL(getCachePath(), OUSTR("backenddb.xml")); 126cdf0e10cSrcweir m_backendDb.reset( 127cdf0e10cSrcweir new ExecutableBackendDb(getComponentContext(), dbFile)); 128cdf0e10cSrcweir } 129cdf0e10cSrcweir } 130cdf0e10cSrcweir 131cdf0e10cSrcweir void BackendImpl::addDataToDb(OUString const & url) 132cdf0e10cSrcweir { 133cdf0e10cSrcweir if (m_backendDb.get()) 134cdf0e10cSrcweir m_backendDb->addEntry(url); 135cdf0e10cSrcweir } 136cdf0e10cSrcweir 137cdf0e10cSrcweir void BackendImpl::revokeEntryFromDb(OUString const & url) 138cdf0e10cSrcweir { 139cdf0e10cSrcweir if (m_backendDb.get()) 140cdf0e10cSrcweir m_backendDb->revokeEntry(url); 141cdf0e10cSrcweir } 142cdf0e10cSrcweir 143cdf0e10cSrcweir bool BackendImpl::hasActiveEntry(OUString const & url) 144cdf0e10cSrcweir { 145cdf0e10cSrcweir if (m_backendDb.get()) 146cdf0e10cSrcweir return m_backendDb->hasActiveEntry(url); 147cdf0e10cSrcweir return false; 148cdf0e10cSrcweir } 149cdf0e10cSrcweir 150cdf0e10cSrcweir 151cdf0e10cSrcweir // XPackageRegistry 152cdf0e10cSrcweir Sequence< Reference<deployment::XPackageTypeInfo> > 153cdf0e10cSrcweir BackendImpl::getSupportedPackageTypes() throw (RuntimeException) 154cdf0e10cSrcweir { 155cdf0e10cSrcweir return Sequence<Reference<deployment::XPackageTypeInfo> >( 156cdf0e10cSrcweir & m_xExecutableTypeInfo, 1); 157cdf0e10cSrcweir } 158cdf0e10cSrcweir 159cdf0e10cSrcweir void BackendImpl::packageRemoved(OUString const & url, OUString const & /*mediaType*/) 160cdf0e10cSrcweir throw (deployment::DeploymentException, 161cdf0e10cSrcweir uno::RuntimeException) 162cdf0e10cSrcweir { 163cdf0e10cSrcweir if (m_backendDb.get()) 164cdf0e10cSrcweir m_backendDb->removeEntry(url); 165cdf0e10cSrcweir } 166cdf0e10cSrcweir 167cdf0e10cSrcweir // PackageRegistryBackend 168cdf0e10cSrcweir Reference<deployment::XPackage> BackendImpl::bindPackage_( 169cdf0e10cSrcweir OUString const & url, OUString const & mediaType, sal_Bool bRemoved, 170cdf0e10cSrcweir OUString const & identifier, Reference<XCommandEnvironment> const & xCmdEnv ) 171cdf0e10cSrcweir { 172cdf0e10cSrcweir if (mediaType.getLength() == 0) 173cdf0e10cSrcweir { 174cdf0e10cSrcweir throw lang::IllegalArgumentException( 175cdf0e10cSrcweir StrCannotDetectMediaType::get() + url, 176cdf0e10cSrcweir static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) ); 177cdf0e10cSrcweir } 178cdf0e10cSrcweir 179cdf0e10cSrcweir String type, subType; 180cdf0e10cSrcweir INetContentTypeParameterList params; 181cdf0e10cSrcweir if (INetContentTypes::parse( mediaType, type, subType, ¶ms )) 182cdf0e10cSrcweir { 183cdf0e10cSrcweir if (type.EqualsIgnoreCaseAscii("application")) 184cdf0e10cSrcweir { 185cdf0e10cSrcweir OUString name; 186cdf0e10cSrcweir if (!bRemoved) 187cdf0e10cSrcweir { 188cdf0e10cSrcweir ::ucbhelper::Content ucbContent( url, xCmdEnv ); 189cdf0e10cSrcweir name = ucbContent.getPropertyValue( 190cdf0e10cSrcweir dp_misc::StrTitle::get() ).get<OUString>(); 191cdf0e10cSrcweir } 192cdf0e10cSrcweir if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.executable")) 193cdf0e10cSrcweir { 194cdf0e10cSrcweir return new BackendImpl::ExecutablePackageImpl( 195cdf0e10cSrcweir this, url, name, m_xExecutableTypeInfo, bRemoved, 196cdf0e10cSrcweir identifier); 197cdf0e10cSrcweir } 198cdf0e10cSrcweir } 199cdf0e10cSrcweir } 200cdf0e10cSrcweir return Reference<deployment::XPackage>(); 201cdf0e10cSrcweir } 202cdf0e10cSrcweir 203cdf0e10cSrcweir //############################################################################## 204cdf0e10cSrcweir 205cdf0e10cSrcweir 206cdf0e10cSrcweir // Package 207cdf0e10cSrcweir BackendImpl * BackendImpl::ExecutablePackageImpl::getMyBackend() const 208cdf0e10cSrcweir { 209cdf0e10cSrcweir BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get()); 210cdf0e10cSrcweir if (NULL == pBackend) 211cdf0e10cSrcweir { 212cdf0e10cSrcweir //May throw a DisposedException 213cdf0e10cSrcweir check(); 214cdf0e10cSrcweir //We should never get here... 215cdf0e10cSrcweir throw RuntimeException( 216cdf0e10cSrcweir OUSTR("Failed to get the BackendImpl"), 217cdf0e10cSrcweir static_cast<OWeakObject*>(const_cast<ExecutablePackageImpl *>(this))); 218cdf0e10cSrcweir } 219cdf0e10cSrcweir return pBackend; 220cdf0e10cSrcweir } 221cdf0e10cSrcweir 222cdf0e10cSrcweir beans::Optional< beans::Ambiguous<sal_Bool> > 223cdf0e10cSrcweir BackendImpl::ExecutablePackageImpl::isRegistered_( 224cdf0e10cSrcweir ::osl::ResettableMutexGuard &, 225cdf0e10cSrcweir ::rtl::Reference<dp_misc::AbortChannel> const &, 226cdf0e10cSrcweir Reference<XCommandEnvironment> const & ) 227cdf0e10cSrcweir { 228cdf0e10cSrcweir bool registered = getMyBackend()->hasActiveEntry(getURL()); 229cdf0e10cSrcweir return beans::Optional< beans::Ambiguous<sal_Bool> >( 230cdf0e10cSrcweir sal_True /* IsPresent */, 231cdf0e10cSrcweir beans::Ambiguous<sal_Bool>( 232cdf0e10cSrcweir registered, sal_False /* IsAmbiguous */ ) ); 233cdf0e10cSrcweir } 234cdf0e10cSrcweir 235cdf0e10cSrcweir void BackendImpl::ExecutablePackageImpl::processPackage_( 236cdf0e10cSrcweir ::osl::ResettableMutexGuard &, 237cdf0e10cSrcweir bool doRegisterPackage, 238cdf0e10cSrcweir bool /*startup*/, 239cdf0e10cSrcweir ::rtl::Reference<dp_misc::AbortChannel> const & abortChannel, 240cdf0e10cSrcweir Reference<XCommandEnvironment> const & /*xCmdEnv*/ ) 241cdf0e10cSrcweir { 242cdf0e10cSrcweir checkAborted(abortChannel); 243cdf0e10cSrcweir if (doRegisterPackage) 244cdf0e10cSrcweir { 245cdf0e10cSrcweir if (!isUrlTargetInExtension()) 246cdf0e10cSrcweir { 247cdf0e10cSrcweir OSL_ASSERT(0); 248cdf0e10cSrcweir return; 249cdf0e10cSrcweir } 250cdf0e10cSrcweir sal_uInt64 attributes = 0; 251cdf0e10cSrcweir //Setting the executable attribut does not affect executables on Windows 252cdf0e10cSrcweir if (getFileAttributes(attributes)) 253cdf0e10cSrcweir { 254cdf0e10cSrcweir if(getMyBackend()->m_context.equals(OUSTR("user"))) 255cdf0e10cSrcweir attributes |= osl_File_Attribute_OwnExe; 256cdf0e10cSrcweir else if (getMyBackend()->m_context.equals(OUSTR("shared"))) 257cdf0e10cSrcweir attributes |= (osl_File_Attribute_OwnExe | osl_File_Attribute_GrpExe 258cdf0e10cSrcweir | osl_File_Attribute_OthExe); 259cdf0e10cSrcweir else if (!getMyBackend()->m_context.equals(OUSTR("bundled")) 260cdf0e10cSrcweir && !getMyBackend()->m_context.equals(OUSTR("bundled_prereg"))) 261cdf0e10cSrcweir //Bundled extension are required to be in the properly 262cdf0e10cSrcweir //installed. That is an executable must have the right flags 263cdf0e10cSrcweir OSL_ASSERT(0); 264cdf0e10cSrcweir 265cdf0e10cSrcweir //This won't have affect on Windows 266cdf0e10cSrcweir osl::File::setAttributes( 267cdf0e10cSrcweir dp_misc::expandUnoRcUrl(m_url), attributes); 268cdf0e10cSrcweir } 269cdf0e10cSrcweir getMyBackend()->addDataToDb(getURL()); 270cdf0e10cSrcweir } 271cdf0e10cSrcweir else 272cdf0e10cSrcweir { 273cdf0e10cSrcweir getMyBackend()->revokeEntryFromDb(getURL()); 274cdf0e10cSrcweir } 275cdf0e10cSrcweir } 276cdf0e10cSrcweir 277cdf0e10cSrcweir //We currently cannot check if this XPackage represents a content of a particular extension 278cdf0e10cSrcweir //But we can check if we are within $UNO_USER_PACKAGES_CACHE etc. 279cdf0e10cSrcweir //Done for security reasons. For example an extension manifest could contain a path to 280cdf0e10cSrcweir //an executable outside the extension. 281cdf0e10cSrcweir bool BackendImpl::ExecutablePackageImpl::isUrlTargetInExtension() 282cdf0e10cSrcweir { 283cdf0e10cSrcweir bool bSuccess = false; 284cdf0e10cSrcweir OUString sExtensionDir; 285cdf0e10cSrcweir if(getMyBackend()->m_context.equals(OUSTR("user"))) 286cdf0e10cSrcweir sExtensionDir = dp_misc::expandUnoRcTerm(OUSTR("$UNO_USER_PACKAGES_CACHE")); 287cdf0e10cSrcweir else if (getMyBackend()->m_context.equals(OUSTR("shared"))) 288cdf0e10cSrcweir sExtensionDir = dp_misc::expandUnoRcTerm(OUSTR("$UNO_SHARED_PACKAGES_CACHE")); 289cdf0e10cSrcweir else if (getMyBackend()->m_context.equals(OUSTR("bundled")) 290cdf0e10cSrcweir || getMyBackend()->m_context.equals(OUSTR("bundled_prereg"))) 291cdf0e10cSrcweir sExtensionDir = dp_misc::expandUnoRcTerm(OUSTR("$BUNDLED_EXTENSIONS")); 292cdf0e10cSrcweir else 293cdf0e10cSrcweir OSL_ASSERT(0); 294cdf0e10cSrcweir //remove file ellipses 295cdf0e10cSrcweir if (osl::File::E_None == osl::File::getAbsoluteFileURL(OUString(), sExtensionDir, sExtensionDir)) 296cdf0e10cSrcweir { 297cdf0e10cSrcweir OUString sFile; 298cdf0e10cSrcweir if (osl::File::E_None == osl::File::getAbsoluteFileURL( 299cdf0e10cSrcweir OUString(), dp_misc::expandUnoRcUrl(m_url), sFile)) 300cdf0e10cSrcweir { 301cdf0e10cSrcweir if (sal_True == sFile.match(sExtensionDir, 0)) 302cdf0e10cSrcweir bSuccess = true; 303cdf0e10cSrcweir } 304cdf0e10cSrcweir } 305cdf0e10cSrcweir return bSuccess; 306cdf0e10cSrcweir } 307cdf0e10cSrcweir 308cdf0e10cSrcweir bool BackendImpl::ExecutablePackageImpl::getFileAttributes(sal_uInt64& out_Attributes) 309cdf0e10cSrcweir { 310cdf0e10cSrcweir bool bSuccess = false; 311cdf0e10cSrcweir const OUString url(dp_misc::expandUnoRcUrl(m_url)); 312cdf0e10cSrcweir osl::DirectoryItem item; 313cdf0e10cSrcweir if (osl::FileBase::E_None == osl::DirectoryItem::get(url, item)) 314cdf0e10cSrcweir { 315cdf0e10cSrcweir osl::FileStatus aStatus(osl_FileStatus_Mask_Attributes); 316cdf0e10cSrcweir if( osl::FileBase::E_None == item.getFileStatus(aStatus)) 317cdf0e10cSrcweir { 318cdf0e10cSrcweir out_Attributes = aStatus.getAttributes(); 319cdf0e10cSrcweir bSuccess = true; 320cdf0e10cSrcweir } 321cdf0e10cSrcweir } 322cdf0e10cSrcweir return bSuccess; 323cdf0e10cSrcweir } 324cdf0e10cSrcweir 325cdf0e10cSrcweir //############################################################################## 326cdf0e10cSrcweir 327cdf0e10cSrcweir 328cdf0e10cSrcweir } // anon namespace 329cdf0e10cSrcweir 330cdf0e10cSrcweir namespace sdecl = comphelper::service_decl; 331cdf0e10cSrcweir sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI; 332cdf0e10cSrcweir extern sdecl::ServiceDecl const serviceDecl( 333cdf0e10cSrcweir serviceBI, 334cdf0e10cSrcweir "com.sun.star.comp.deployment.executable.PackageRegistryBackend", 335cdf0e10cSrcweir BACKEND_SERVICE_NAME ); 336cdf0e10cSrcweir 337cdf0e10cSrcweir } // namespace component 338cdf0e10cSrcweir } // namespace backend 339cdf0e10cSrcweir } // namespace dp_registry 340cdf0e10cSrcweir 341cdf0e10cSrcweir 342