xref: /aoo41x/main/desktop/source/app/userinstall.cxx (revision cdf0e10c)
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