1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_desktop.hxx" 30 31 32 #include "userinstall.hxx" 33 #include "langselect.hxx" 34 35 #include <stdio.h> 36 #include <rtl/ustring.hxx> 37 #include <rtl/ustrbuf.hxx> 38 #include <osl/file.hxx> 39 #include <osl/mutex.hxx> 40 #include <osl/process.h> 41 #include <osl/diagnose.h> 42 #include <vos/security.hxx> 43 #include <vos/ref.hxx> 44 #include <vos/process.hxx> 45 46 #ifndef _TOOLS_RESMGR_HXX_ 47 #include <tools/resmgr.hxx> 48 #endif 49 #include <unotools/bootstrap.hxx> 50 #include <svl/languageoptions.hxx> 51 #ifndef _SVTOOLS_SYSLOCALEOPTIONSOPTIONS_HXX 52 #include <unotools/syslocaleoptions.hxx> 53 #endif 54 #include <comphelper/processfactory.hxx> 55 #include <com/sun/star/container/XNameAccess.hpp> 56 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 57 #include <com/sun/star/beans/XPropertySet.hpp> 58 #include <i18npool/mslangid.hxx> 59 #include <com/sun/star/uno/Any.hxx> 60 #include <com/sun/star/util/XChangesBatch.hpp> 61 #include <com/sun/star/beans/XHierarchicalPropertySet.hpp> 62 #include <com/sun/star/beans/NamedValue.hpp> 63 #include <com/sun/star/container/XHierarchicalNameAccess.hpp> 64 #include <com/sun/star/lang/XComponent.hpp> 65 #include <com/sun/star/lang/XLocalizable.hpp> 66 #include <com/sun/star/lang/Locale.hpp> 67 68 #include "app.hxx" 69 70 using namespace rtl; 71 using namespace osl; 72 using namespace utl; 73 using namespace com::sun::star::container; 74 using namespace com::sun::star::uno; 75 using namespace com::sun::star::lang; 76 using namespace com::sun::star::beans; 77 using namespace com::sun::star::util; 78 79 80 namespace desktop { 81 82 static UserInstall::UserInstallError create_user_install(OUString&); 83 84 static bool is_user_install() 85 { 86 try 87 { 88 OUString sConfigSrvc( 89 RTL_CONSTASCII_USTRINGPARAM( 90 "com.sun.star.configuration.ConfigurationProvider" ) ); 91 OUString sAccessSrvc( 92 RTL_CONSTASCII_USTRINGPARAM( 93 "com.sun.star.configuration.ConfigurationAccess" ) ); 94 95 // get configuration provider 96 Reference< XMultiServiceFactory > theMSF 97 = comphelper::getProcessServiceFactory(); 98 Reference< XMultiServiceFactory > theConfigProvider 99 = Reference< XMultiServiceFactory >( 100 theMSF->createInstance(sConfigSrvc), UNO_QUERY_THROW); 101 102 // localize the provider to user selection 103 // Reference< XLocalizable > localizable(theConfigProvider, UNO_QUERY_THROW); 104 // LanguageType aUserLanguageType = LanguageSelection::getLanguageType(); 105 // Locale aLocale( MsLangId::convertLanguageToIsoString(aUserLanguageType)); 106 // localizable->setLocale(aLocale); 107 108 Reference< XLocalizable > localizable(theConfigProvider, UNO_QUERY_THROW); 109 OUString aUserLanguage = LanguageSelection::getLanguageString(); 110 Locale aLocale = LanguageSelection::IsoStringToLocale(aUserLanguage); 111 localizable->setLocale(aLocale); 112 113 Sequence< Any > theArgs(1); 114 NamedValue v; 115 v.Name = OUString::createFromAscii("NodePath"); 116 v.Value = makeAny(OUString::createFromAscii("org.openoffice.Setup")); 117 theArgs[0] <<= v; 118 Reference< XHierarchicalNameAccess> hnacc( 119 theConfigProvider->createInstanceWithArguments( 120 sAccessSrvc, theArgs), UNO_QUERY_THROW); 121 122 try 123 { 124 sal_Bool bValue = sal_False; 125 hnacc->getByHierarchicalName( 126 OUString( RTL_CONSTASCII_USTRINGPARAM( 127 "Office/ooSetupInstCompleted" ) ) ) >>= bValue; 128 129 return bValue ? true : false; 130 } 131 catch ( NoSuchElementException const & ) 132 { 133 // just return false in this case. 134 } 135 } 136 catch (Exception const & e) 137 { 138 OString msg(OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US)); 139 OSL_ENSURE(sal_False, msg.getStr()); 140 } 141 142 return false; 143 } 144 145 UserInstall::UserInstallError UserInstall::finalize() 146 { 147 OUString aUserInstallPath; 148 utl::Bootstrap::PathStatus aLocateResult = 149 utl::Bootstrap::locateUserInstallation(aUserInstallPath); 150 151 switch (aLocateResult) { 152 153 case utl::Bootstrap::DATA_INVALID: 154 case utl::Bootstrap::DATA_MISSING: 155 case utl::Bootstrap::DATA_UNKNOWN: 156 // cannot find a valid path or path is missing 157 return E_Unknown; 158 159 case utl::Bootstrap::PATH_EXISTS: 160 { 161 // path exists, check if an installation lives there 162 if ( is_user_install() ) 163 { 164 return E_None; 165 } 166 // Note: fall-thru intended. 167 } 168 case utl::Bootstrap::PATH_VALID: 169 // found a path but need to create user install 170 return create_user_install(aUserInstallPath); 171 default: 172 return E_Unknown; 173 } 174 } 175 176 static osl::FileBase::RC copy_recursive( const rtl::OUString& srcUnqPath, const rtl::OUString& dstUnqPath) 177 { 178 179 FileBase::RC err; 180 DirectoryItem aDirItem; 181 DirectoryItem::get(srcUnqPath, aDirItem); 182 FileStatus aFileStatus(FileStatusMask_All); 183 aDirItem.getFileStatus(aFileStatus); 184 185 if( aFileStatus.getFileType() == FileStatus::Directory) 186 { 187 // create directory if not already there 188 err = Directory::create( dstUnqPath ); 189 if (err == osl::FileBase::E_EXIST) 190 err = osl::FileBase::E_None; 191 192 FileBase::RC next = err; 193 if (err == osl::FileBase::E_None) 194 { 195 // iterate through directory contents 196 Directory aDir( srcUnqPath ); 197 aDir.open(); 198 while (err == osl::FileBase::E_None && 199 (next = aDir.getNextItem( aDirItem )) == osl::FileBase::E_None) 200 { 201 aDirItem.getFileStatus(aFileStatus); 202 // generate new src/dst pair and make recursive call 203 rtl::OUString newSrcUnqPath = aFileStatus.getFileURL(); 204 rtl::OUString newDstUnqPath = dstUnqPath; 205 rtl::OUString itemname = aFileStatus.getFileName(); 206 // append trailing '/' if needed 207 if (newDstUnqPath.lastIndexOf(sal_Unicode('/')) != newDstUnqPath.getLength()-1) 208 newDstUnqPath += rtl::OUString::createFromAscii("/"); 209 newDstUnqPath += itemname; 210 // recursion 211 err = copy_recursive(newSrcUnqPath, newDstUnqPath); 212 } 213 aDir.close(); 214 215 if ( err != osl::FileBase::E_None ) 216 return err; 217 if( next != FileBase::E_NOENT ) 218 err = FileBase::E_INVAL; 219 } 220 } 221 else 222 { 223 // copy single file - foldback 224 err = File::copy( srcUnqPath,dstUnqPath ); 225 } 226 return err; 227 } 228 229 static const char *pszSrcList[] = { 230 "/presets", 231 NULL 232 }; 233 static const char *pszDstList[] = { 234 "/user", 235 NULL 236 }; 237 238 239 static UserInstall::UserInstallError create_user_install(OUString& aUserPath) 240 { 241 OUString aBasePath; 242 if (utl::Bootstrap::locateBaseInstallation(aBasePath) != utl::Bootstrap::PATH_EXISTS) 243 return UserInstall::E_InvalidBaseinstall; 244 245 // create the user directory 246 FileBase::RC rc = Directory::createPath(aUserPath); 247 if ((rc != FileBase::E_None) && (rc != FileBase::E_EXIST)) return UserInstall::E_Creation; 248 249 // copy data from shared data directory of base installation 250 for (sal_Int32 i=0; pszSrcList[i]!=NULL && pszDstList[i]!=NULL; i++) 251 { 252 rc = copy_recursive( 253 aBasePath + OUString::createFromAscii(pszSrcList[i]), 254 aUserPath + OUString::createFromAscii(pszDstList[i])); 255 if ((rc != FileBase::E_None) && (rc != FileBase::E_EXIST)) 256 { 257 if ( rc == FileBase::E_NOSPC ) 258 return UserInstall::E_NoDiskSpace; 259 else if ( rc == FileBase::E_ACCES ) 260 return UserInstall::E_NoWriteAccess; 261 else 262 return UserInstall::E_Creation; 263 } 264 } 265 try 266 { 267 OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider"); 268 OUString sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationUpdateAccess"); 269 270 // get configuration provider 271 Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory(); 272 Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory >( 273 theMSF->createInstance(sConfigSrvc), UNO_QUERY_THROW); 274 Sequence< Any > theArgs(1); 275 NamedValue v(OUString::createFromAscii("NodePath"), makeAny(OUString::createFromAscii("org.openoffice.Setup"))); 276 //v.Name = OUString::createFromAscii("NodePath"); 277 //v.Value = makeAny(OUString::createFromAscii("org.openoffice.Setup")); 278 theArgs[0] <<= v; 279 Reference< XHierarchicalPropertySet> hpset( 280 theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs), UNO_QUERY_THROW); 281 hpset->setHierarchicalPropertyValue(OUString::createFromAscii("Office/ooSetupInstCompleted"), makeAny(sal_True)); 282 Reference< XChangesBatch >(hpset, UNO_QUERY_THROW)->commitChanges(); 283 } 284 catch ( PropertyVetoException& ) 285 { 286 // we are not allowed to change this 287 } 288 catch (Exception& e) 289 { 290 OString aMsg("create_user_install(): "); 291 aMsg += OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US); 292 OSL_ENSURE(sal_False, aMsg.getStr()); 293 return UserInstall::E_Creation; 294 } 295 296 return UserInstall::E_None; 297 298 } 299 } 300 301 302