blob: 6d2140f568cd0fce7a1e0d8c63545886ad330ae7 [file] [log] [blame]
/**************************************************************
*
* 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;
}
}