| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_desktop.hxx" |
| |
| |
| #include "userinstall.hxx" |
| #include "langselect.hxx" |
| |
| #include <stdio.h> |
| #include <rtl/ustring.hxx> |
| #include <rtl/ustrbuf.hxx> |
| #include <osl/file.hxx> |
| #include <osl/mutex.hxx> |
| #include <osl/process.h> |
| #include <osl/diagnose.h> |
| #include <vos/security.hxx> |
| #include <vos/ref.hxx> |
| #include <vos/process.hxx> |
| |
| #ifndef _TOOLS_RESMGR_HXX_ |
| #include <tools/resmgr.hxx> |
| #endif |
| #include <unotools/bootstrap.hxx> |
| #include <svl/languageoptions.hxx> |
| #ifndef _SVTOOLS_SYSLOCALEOPTIONSOPTIONS_HXX |
| #include <unotools/syslocaleoptions.hxx> |
| #endif |
| #include <comphelper/processfactory.hxx> |
| #include <com/sun/star/container/XNameAccess.hpp> |
| #include <com/sun/star/lang/XMultiServiceFactory.hpp> |
| #include <com/sun/star/beans/XPropertySet.hpp> |
| #include <i18npool/mslangid.hxx> |
| #include <com/sun/star/uno/Any.hxx> |
| #include <com/sun/star/util/XChangesBatch.hpp> |
| #include <com/sun/star/beans/XHierarchicalPropertySet.hpp> |
| #include <com/sun/star/beans/NamedValue.hpp> |
| #include <com/sun/star/container/XHierarchicalNameAccess.hpp> |
| #include <com/sun/star/lang/XComponent.hpp> |
| #include <com/sun/star/lang/XLocalizable.hpp> |
| #include <com/sun/star/lang/Locale.hpp> |
| |
| #include "app.hxx" |
| |
| using namespace rtl; |
| using namespace osl; |
| using namespace utl; |
| using namespace com::sun::star::container; |
| using namespace com::sun::star::uno; |
| using namespace com::sun::star::lang; |
| using namespace com::sun::star::beans; |
| using namespace com::sun::star::util; |
| |
| |
| namespace desktop { |
| |
| static UserInstall::UserInstallError create_user_install(OUString&); |
| |
| static bool is_user_install() |
| { |
| try |
| { |
| OUString sConfigSrvc( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.configuration.ConfigurationProvider" ) ); |
| OUString sAccessSrvc( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.configuration.ConfigurationAccess" ) ); |
| |
| // get configuration provider |
| Reference< XMultiServiceFactory > theMSF |
| = comphelper::getProcessServiceFactory(); |
| Reference< XMultiServiceFactory > theConfigProvider |
| = Reference< XMultiServiceFactory >( |
| theMSF->createInstance(sConfigSrvc), UNO_QUERY_THROW); |
| |
| // localize the provider to user selection |
| // Reference< XLocalizable > localizable(theConfigProvider, UNO_QUERY_THROW); |
| // LanguageType aUserLanguageType = LanguageSelection::getLanguageType(); |
| // Locale aLocale( MsLangId::convertLanguageToIsoString(aUserLanguageType)); |
| // localizable->setLocale(aLocale); |
| |
| Reference< XLocalizable > localizable(theConfigProvider, UNO_QUERY_THROW); |
| OUString aUserLanguage = LanguageSelection::getLanguageString(); |
| Locale aLocale = LanguageSelection::IsoStringToLocale(aUserLanguage); |
| localizable->setLocale(aLocale); |
| |
| Sequence< Any > theArgs(1); |
| NamedValue v; |
| v.Name = OUString::createFromAscii("NodePath"); |
| v.Value = makeAny(OUString::createFromAscii("org.openoffice.Setup")); |
| theArgs[0] <<= v; |
| Reference< XHierarchicalNameAccess> hnacc( |
| theConfigProvider->createInstanceWithArguments( |
| sAccessSrvc, theArgs), UNO_QUERY_THROW); |
| |
| try |
| { |
| sal_Bool bValue = sal_False; |
| hnacc->getByHierarchicalName( |
| OUString( RTL_CONSTASCII_USTRINGPARAM( |
| "Office/ooSetupInstCompleted" ) ) ) >>= bValue; |
| |
| return bValue ? true : false; |
| } |
| catch ( NoSuchElementException const & ) |
| { |
| // just return false in this case. |
| } |
| } |
| catch (Exception const & e) |
| { |
| OString msg(OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US)); |
| OSL_ENSURE(sal_False, msg.getStr()); |
| } |
| |
| return false; |
| } |
| |
| UserInstall::UserInstallError UserInstall::finalize() |
| { |
| OUString aUserInstallPath; |
| utl::Bootstrap::PathStatus aLocateResult = |
| utl::Bootstrap::locateUserInstallation(aUserInstallPath); |
| |
| switch (aLocateResult) { |
| |
| case utl::Bootstrap::DATA_INVALID: |
| case utl::Bootstrap::DATA_MISSING: |
| case utl::Bootstrap::DATA_UNKNOWN: |
| // cannot find a valid path or path is missing |
| return E_Unknown; |
| |
| case utl::Bootstrap::PATH_EXISTS: |
| { |
| // path exists, check if an installation lives there |
| if ( is_user_install() ) |
| { |
| return E_None; |
| } |
| // Note: fall-thru intended. |
| } |
| case utl::Bootstrap::PATH_VALID: |
| // found a path but need to create user install |
| return create_user_install(aUserInstallPath); |
| default: |
| return E_Unknown; |
| } |
| } |
| |
| static osl::FileBase::RC copy_recursive( const rtl::OUString& srcUnqPath, const rtl::OUString& dstUnqPath) |
| { |
| |
| FileBase::RC err; |
| DirectoryItem aDirItem; |
| DirectoryItem::get(srcUnqPath, aDirItem); |
| FileStatus aFileStatus(FileStatusMask_All); |
| aDirItem.getFileStatus(aFileStatus); |
| |
| if( aFileStatus.getFileType() == FileStatus::Directory) |
| { |
| // create directory if not already there |
| err = Directory::create( dstUnqPath ); |
| if (err == osl::FileBase::E_EXIST) |
| err = osl::FileBase::E_None; |
| |
| FileBase::RC next = err; |
| if (err == osl::FileBase::E_None) |
| { |
| // iterate through directory contents |
| Directory aDir( srcUnqPath ); |
| aDir.open(); |
| while (err == osl::FileBase::E_None && |
| (next = aDir.getNextItem( aDirItem )) == osl::FileBase::E_None) |
| { |
| aDirItem.getFileStatus(aFileStatus); |
| // generate new src/dst pair and make recursive call |
| rtl::OUString newSrcUnqPath = aFileStatus.getFileURL(); |
| rtl::OUString newDstUnqPath = dstUnqPath; |
| rtl::OUString itemname = aFileStatus.getFileName(); |
| // append trailing '/' if needed |
| if (newDstUnqPath.lastIndexOf(sal_Unicode('/')) != newDstUnqPath.getLength()-1) |
| newDstUnqPath += rtl::OUString::createFromAscii("/"); |
| newDstUnqPath += itemname; |
| // recursion |
| err = copy_recursive(newSrcUnqPath, newDstUnqPath); |
| } |
| aDir.close(); |
| |
| if ( err != osl::FileBase::E_None ) |
| return err; |
| if( next != FileBase::E_NOENT ) |
| err = FileBase::E_INVAL; |
| } |
| } |
| else |
| { |
| // copy single file - foldback |
| err = File::copy( srcUnqPath,dstUnqPath ); |
| } |
| return err; |
| } |
| |
| static const char *pszSrcList[] = { |
| "/presets", |
| NULL |
| }; |
| static const char *pszDstList[] = { |
| "/user", |
| NULL |
| }; |
| |
| |
| static UserInstall::UserInstallError create_user_install(OUString& aUserPath) |
| { |
| OUString aBasePath; |
| if (utl::Bootstrap::locateBaseInstallation(aBasePath) != utl::Bootstrap::PATH_EXISTS) |
| return UserInstall::E_InvalidBaseinstall; |
| |
| // create the user directory |
| FileBase::RC rc = Directory::createPath(aUserPath); |
| if ((rc != FileBase::E_None) && (rc != FileBase::E_EXIST)) return UserInstall::E_Creation; |
| |
| // copy data from shared data directory of base installation |
| for (sal_Int32 i=0; pszSrcList[i]!=NULL && pszDstList[i]!=NULL; i++) |
| { |
| rc = copy_recursive( |
| aBasePath + OUString::createFromAscii(pszSrcList[i]), |
| aUserPath + OUString::createFromAscii(pszDstList[i])); |
| if ((rc != FileBase::E_None) && (rc != FileBase::E_EXIST)) |
| { |
| if ( rc == FileBase::E_NOSPC ) |
| return UserInstall::E_NoDiskSpace; |
| else if ( rc == FileBase::E_ACCES ) |
| return UserInstall::E_NoWriteAccess; |
| else |
| return UserInstall::E_Creation; |
| } |
| } |
| try |
| { |
| OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider"); |
| OUString sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationUpdateAccess"); |
| |
| // get configuration provider |
| Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory(); |
| Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >( |
| theMSF->createInstance(sConfigSrvc), UNO_QUERY_THROW); |
| Sequence< Any > theArgs(1); |
| NamedValue v(OUString::createFromAscii("NodePath"), makeAny(OUString::createFromAscii("org.openoffice.Setup"))); |
| //v.Name = OUString::createFromAscii("NodePath"); |
| //v.Value = makeAny(OUString::createFromAscii("org.openoffice.Setup")); |
| theArgs[0] <<= v; |
| Reference< XHierarchicalPropertySet> hpset( |
| theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs), UNO_QUERY_THROW); |
| hpset->setHierarchicalPropertyValue(OUString::createFromAscii("Office/ooSetupInstCompleted"), makeAny(sal_True)); |
| Reference< XChangesBatch >(hpset, UNO_QUERY_THROW)->commitChanges(); |
| } |
| catch ( PropertyVetoException& ) |
| { |
| // we are not allowed to change this |
| } |
| catch (Exception& e) |
| { |
| OString aMsg("create_user_install(): "); |
| aMsg += OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US); |
| OSL_ENSURE(sal_False, aMsg.getStr()); |
| return UserInstall::E_Creation; |
| } |
| |
| return UserInstall::E_None; |
| |
| } |
| } |
| |
| |