xref: /aoo42x/main/desktop/source/app/app.cxx (revision aa94018d)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_desktop.hxx"
26 
27 #include <cstdlib>
28 #include <vector>
29 
30 #include <memory>
31 #include <unistd.h>
32 #include "app.hxx"
33 #include "desktop.hrc"
34 #include "appinit.hxx"
35 #include "officeipcthread.hxx"
36 #include "cmdlineargs.hxx"
37 #include "desktopresid.hxx"
38 #include "dispatchwatcher.hxx"
39 #include "configinit.hxx"
40 #include "lockfile.hxx"
41 #include "checkinstall.hxx"
42 #include "cmdlinehelp.hxx"
43 #include "userinstall.hxx"
44 #include "desktopcontext.hxx"
45 #include "exithelper.hxx"
46 #include "../migration/pages.hxx"
47 
48 #include <svtools/javacontext.hxx>
49 #include <com/sun/star/frame/XSessionManagerListener.hpp>
50 #include <com/sun/star/frame/XSynchronousDispatch.hpp>
51 #include <com/sun/star/document/CorruptedFilterConfigurationException.hpp>
52 #include <com/sun/star/configuration/CorruptedConfigurationException.hpp>
53 #include <com/sun/star/frame/XStorable.hpp>
54 #include <com/sun/star/util/XModifiable.hpp>
55 #include <com/sun/star/util/XFlushable.hpp>
56 #include <com/sun/star/system/XSystemShellExecute.hpp>
57 #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
58 #include <com/sun/star/beans/XPropertySet.hpp>
59 #include <com/sun/star/lang/XComponent.hpp>
60 #include <com/sun/star/uno/RuntimeException.hpp>
61 #include <com/sun/star/io/IOException.hpp>
62 #include <com/sun/star/lang/IllegalArgumentException.hpp>
63 #include <com/sun/star/lang/WrappedTargetException.hpp>
64 #include <com/sun/star/frame/XDesktop.hpp>
65 #include <com/sun/star/frame/XComponentLoader.hpp>
66 #include <com/sun/star/view/XPrintable.hpp>
67 #include <com/sun/star/lang/XInitialization.hpp>
68 #include <com/sun/star/frame/XFramesSupplier.hpp>
69 #include <com/sun/star/awt/XTopWindow.hpp>
70 #include <com/sun/star/util/XURLTransformer.hpp>
71 #include <com/sun/star/util/URL.hpp>
72 #include <com/sun/star/util/XCloseable.hpp>
73 #include <com/sun/star/frame/XDispatch.hpp>
74 #include <com/sun/star/frame/XDispatchProvider.hpp>
75 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
76 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
77 #include <com/sun/star/configuration/MissingBootstrapFileException.hpp>
78 #include <com/sun/star/configuration/InvalidBootstrapFileException.hpp>
79 #include <com/sun/star/configuration/InstallationIncompleteException.hpp>
80 #include <com/sun/star/configuration/backend/BackendSetupException.hpp>
81 #include <com/sun/star/configuration/backend/BackendAccessException.hpp>
82 #include <com/sun/star/container/XEnumeration.hpp>
83 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
84 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
85 #include <com/sun/star/task/XJobExecutor.hpp>
86 #include <com/sun/star/task/XRestartManager.hpp>
87 #ifndef _COM_SUN_STAR_TASK_XJOBEXECUTOR_HPP_
88 #include <com/sun/star/task/XJob.hpp>
89 #endif
90 #include <com/sun/star/beans/XPropertySet.hpp>
91 #include <com/sun/star/beans/NamedValue.hpp>
92 #include <com/sun/star/task/XJob.hpp>
93 #include <com/sun/star/document/XEventListener.hpp>
94 #include <com/sun/star/ui/XUIElementFactoryRegistration.hpp>
95 #include <com/sun/star/frame/XUIControllerRegistration.hpp>
96 
97 #include <com/sun/star/java/XJavaVM.hpp>
98 #include <tools/testtoolloader.hxx>
99 #include <tools/solar.h>
100 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
101 #include <toolkit/unohlp.hxx>
102 #endif
103 #include <vos/security.hxx>
104 #include <vos/ref.hxx>
105 #include <comphelper/processfactory.hxx>
106 #include <comphelper/componentcontext.hxx>
107 #include <comphelper/configurationhelper.hxx>
108 #ifndef _UTL__HXX_
109 #include <unotools/configmgr.hxx>
110 #endif
111 #include <unotools/configitem.hxx>
112 #include <unotools/confignode.hxx>
113 #include <unotools/ucbhelper.hxx>
114 #include <tools/tempfile.hxx>
115 #include <tools/urlobj.hxx>
116 #include <unotools/moduleoptions.hxx>
117 #include <osl/module.h>
118 #include <osl/file.hxx>
119 #include <osl/signal.h>
120 #include <osl/thread.hxx>
121 #include <rtl/uuid.h>
122 #include <rtl/uri.hxx>
123 #include <unotools/pathoptions.hxx>
124 #include <svl/languageoptions.hxx>
125 #include <unotools/internaloptions.hxx>
126 #include <svtools/miscopt.hxx>
127 #include <svtools/menuoptions.hxx>
128 #include <unotools/syslocaleoptions.hxx>
129 #include <unotools/syslocale.hxx>
130 #include <svl/folderrestriction.hxx>
131 #include <svl/eitem.hxx>
132 #include <svl/itemset.hxx>
133 #include <unotools/tempfile.hxx>
134 #include <rtl/logfile.hxx>
135 #include <rtl/ustrbuf.hxx>
136 #include <rtl/strbuf.hxx>
137 #include <rtl/bootstrap.hxx>
138 #include <rtl/instance.hxx>
139 #include <unotools/configmgr.hxx>
140 #include <vcl/help.hxx>
141 #include <vcl/msgbox.hxx>
142 #include <vcl/bitmap.hxx>
143 #include <vcl/stdtext.hxx>
144 #include <vcl/msgbox.hxx>
145 #include <sfx2/sfx.hrc>
146 #include <sfx2/app.hxx>
147 #include <ucbhelper/contentbroker.hxx>
148 #include <unotools/bootstrap.hxx>
149 #include <cppuhelper/bootstrap.hxx>
150 
151 #include "vos/process.hxx"
152 
153 #include <svtools/fontsubstconfig.hxx>
154 #include <svtools/accessibilityoptions.hxx>
155 #include <svtools/apearcfg.hxx>
156 #include <unotools/misccfg.hxx>
157 #include <svtools/filter.hxx>
158 
159 #include "langselect.hxx"
160 
161 #include "com/sun/star/deployment/ExtensionManager.hpp"
162 #include "com/sun/star/deployment/XExtensionManager.hpp"
163 #include "com/sun/star/task/XInteractionApprove.hpp"
164 #include "cppuhelper/compbase3.hxx"
165 #include <hash_set>
166 
167 #if defined MACOSX
168 #include <errno.h>
169 #include <sys/wait.h>
170 #endif
171 
172 #define DEFINE_CONST_UNICODE(CONSTASCII)        UniString(RTL_CONSTASCII_USTRINGPARAM(CONSTASCII))
173 #define OUSTR(x)                                ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(x))
174 #define U2S(STRING)                             ::rtl::OUStringToOString(STRING, RTL_TEXTENCODING_UTF8)
175 
176 using namespace vos;
177 using namespace rtl;
178 
179 using namespace ::com::sun::star::uno;
180 using namespace ::com::sun::star::util;
181 using namespace ::com::sun::star::lang;
182 using namespace ::com::sun::star::beans;
183 //using namespace ::com::sun::star::bridge;
184 using namespace ::com::sun::star::frame;
185 using namespace ::com::sun::star::document;
186 using namespace ::com::sun::star::view;
187 using namespace ::com::sun::star::task;
188 using namespace ::com::sun::star::system;
189 using namespace ::com::sun::star::ui::dialogs;
190 using namespace ::com::sun::star::container;
191 
192 namespace css = ::com::sun::star;
193 
194 ResMgr*                 desktop::Desktop::pResMgr = 0;
195 
196 namespace {
197 
198 /** Write a marker file that is basically empty (just a single
199     character to prevent it from being deleted.)  Its time of last
200     modification is its only important feature.
201 
202     This is a simplified version of the function in
203     dp_extensionmanager.cxx.  It uses direct file access instead of
204     the UCB.  May prove to be too simple, but then again, it may not.
205 */
206 bool writeLastModified (::rtl::OUString& rsURL)
207 {
208     try
209     {
210         // Remove the file if it already exists.
211         ::osl::File::remove(rsURL);
212 
213         ::osl::File aFile (rsURL);
214         if (aFile.open(OpenFlag_Create | OpenFlag_Write) != ::osl::File::E_None)
215             return false;
216 
217         const char aBuffer[] = "1";
218         sal_uInt64 nBytesWritten (0);
219         if (aFile.write(aBuffer, strlen(aBuffer), nBytesWritten) != ::osl::File::E_None)
220             return false;
221 
222         if (aFile.close() != ::osl::File::E_None)
223             return false;
224 
225         return true;
226     }
227     catch(...)
228     {
229     }
230     return false;
231 }
232 
233 } // end of anonymous namespace
234 
235 
236 
237 namespace desktop
238 {
239 
240 static SalMainPipeExchangeSignalHandler* pSignalHandler = 0;
241 static sal_Bool _bCrashReporterEnabled = sal_True;
242 
243 static const ::rtl::OUString CFG_PACKAGE_COMMON_HELP   ( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.Office.Common/Help"));
244 
245 static ::rtl::OUString getBrandSharePreregBundledPathURL();
246 // #i119950# Add a option that not to display the "Fatal Error" on dialog title
247 void FatalError(const ::rtl::OUString& sMessage, const sal_Bool isDisplayErrorString = sal_True);
248 // ----------------------------------------------------------------------------
249 
250 ResMgr* Desktop::GetDesktopResManager()
251 {
252     if ( !Desktop::pResMgr )
253     {
254         String aMgrName = String::CreateFromAscii( "dkt" );
255 
256         // Create desktop resource manager and bootstrap process
257         // was successful. Use default way to get language specific message.
258         if ( Application::IsInExecute() )
259             Desktop::pResMgr = ResMgr::CreateResMgr( U2S( aMgrName ));
260 
261         if ( !Desktop::pResMgr )
262         {
263             // Use VCL to get the correct language specific message as we
264             // are in the bootstrap process and not able to get the installed
265             // language!!
266 /*
267             LanguageType aLanguageType = LANGUAGE_DONTKNOW;
268 
269             Desktop::pResMgr = ResMgr::SearchCreateResMgr( U2S( aMgrName ), aLanguageType );
270             AllSettings as = GetSettings();
271             as.SetUILanguage(aLanguageType);
272             SetSettings(as);
273 */
274             // LanguageSelection langselect;
275             OUString aUILocaleString = LanguageSelection::getLanguageString();
276             sal_Int32 nIndex = 0;
277             OUString aLanguage = aUILocaleString.getToken( 0, '-', nIndex);
278             OUString aCountry = aUILocaleString.getToken( 0, '-', nIndex);
279             OUString aVariant = aUILocaleString.getToken( 0, '-', nIndex);
280 
281             ::com::sun::star::lang::Locale aLocale( aLanguage, aCountry, aVariant );
282 
283             Desktop::pResMgr = ResMgr::SearchCreateResMgr( U2S( aMgrName ), aLocale);
284             AllSettings as = GetSettings();
285             as.SetUILocale(aLocale);
286             SetSettings(as);
287         }
288     }
289 
290     return Desktop::pResMgr;
291 }
292 
293 // ----------------------------------------------------------------------------
294 // Get a message string securely. There is a fallback string if the resource
295 // is not available.
296 
297 OUString Desktop::GetMsgString( sal_uInt16 nId, const OUString& aFaultBackMsg )
298 {
299     ResMgr* resMgr = GetDesktopResManager();
300     if ( !resMgr )
301         return aFaultBackMsg;
302     else
303         return OUString( String( ResId( nId, *resMgr )));
304 }
305 
306 OUString MakeStartupErrorMessage(OUString const & aErrorMessage)
307 {
308     OUStringBuffer    aDiagnosticMessage( 100 );
309 
310     ResMgr* pResMgr = Desktop::GetDesktopResManager();
311     if ( pResMgr )
312         aDiagnosticMessage.append( OUString(String(ResId(STR_BOOTSTRAP_ERR_CANNOT_START, *pResMgr))) );
313     else
314         aDiagnosticMessage.appendAscii( "The program cannot be started." );
315 
316     aDiagnosticMessage.appendAscii( "\n" );
317 
318     aDiagnosticMessage.append( aErrorMessage );
319 
320     return aDiagnosticMessage.makeStringAndClear();
321 }
322 
323 OUString MakeStartupConfigAccessErrorMessage( OUString const & aInternalErrMsg )
324 {
325     OUStringBuffer aDiagnosticMessage( 200 );
326 
327     ResMgr* pResMgr = Desktop::GetDesktopResManager();
328     if ( pResMgr )
329         aDiagnosticMessage.append( OUString(String(ResId(STR_BOOTSTRAP_ERR_CFG_DATAACCESS, *pResMgr ))) );
330     else
331         aDiagnosticMessage.appendAscii( "The program cannot be started." );
332 
333     if ( aInternalErrMsg.getLength() > 0 )
334     {
335         aDiagnosticMessage.appendAscii( "\n\n" );
336         if ( pResMgr )
337             aDiagnosticMessage.append( OUString(String(ResId(STR_INTERNAL_ERRMSG, *pResMgr ))) );
338         else
339             aDiagnosticMessage.appendAscii( "The following internal error has occured:\n\n" );
340         aDiagnosticMessage.append( aInternalErrMsg );
341     }
342 
343     return aDiagnosticMessage.makeStringAndClear();
344 }
345 
346 //=============================================================================
347 // shows a simple error box with the given message ... but exits from these process !
348 //
349 // Fatal errors cant be solved by the process ... nor any recovery can help.
350 // Mostly the installation was damaged and must be repaired manually .. or by calling
351 // setup again.
352 //
353 // On the other side we must make sure that no further actions will be possible within
354 // the current office process ! No pipe requests, no menu/toolbar/shortuct actions
355 // are allowed. Otherwise we will force a "crash inside a crash".
356 //
357 // Thats why we have to use a special native message box here which does not use yield :-)
358 //=============================================================================
359 void FatalError(const ::rtl::OUString& sMessage, const sal_Bool isDisplayErrorString)
360 {
361     ::rtl::OUString sProductKey = ::utl::Bootstrap::getProductKey();
362     if ( ! sProductKey.getLength())
363     {
364         ::vos::OStartupInfo aInfo;
365         aInfo.getExecutableFile( sProductKey );
366 
367         ::sal_uInt32 nLastIndex = sProductKey.lastIndexOf('/');
368         if ( nLastIndex > 0 )
369             sProductKey = sProductKey.copy( nLastIndex+1 );
370     }
371 
372     ::rtl::OUStringBuffer sTitle (128);
373     sTitle.append      (sProductKey     );
374 	if (isDisplayErrorString) {
375 		sTitle.appendAscii (" - Fatal Error");
376 	}
377     Application::ShowNativeErrorBox (sTitle.makeStringAndClear (), sMessage);
378     _exit(ExitHelper::E_FATAL_ERROR);
379 }
380 
381 static bool ShouldSuppressUI(CommandLineArgs* pCmdLine)
382 {
383     return  pCmdLine->IsInvisible() ||
384             pCmdLine->IsHeadless() ||
385             pCmdLine->IsQuickstart();
386 }
387 
388 CommandLineArgs* Desktop::GetCommandLineArgs()
389 {
390     static CommandLineArgs* pArgs = 0;
391     if ( !pArgs )
392     {
393         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
394         if ( !pArgs )
395             pArgs = new CommandLineArgs;
396     }
397 
398     return pArgs;
399 }
400 
401 sal_Bool InitConfiguration()
402 {
403     RTL_LOGFILE_CONTEXT( aLog, "desktop (jb99855) ::InitConfiguration" );
404 
405     Reference< XMultiServiceFactory > xProvider( CreateApplicationConfigurationProvider( ) );
406     return xProvider.is();
407 }
408 
409 namespace
410 {
411     struct BrandName
412         : public rtl::Static< String, BrandName > {};
413     struct Version
414         : public rtl::Static< String, Version > {};
415     struct AboutBoxVersion
416         : public rtl::Static< String, AboutBoxVersion > {};
417     struct OOOVendor
418         : public rtl::Static< String, OOOVendor > {};
419     struct Extension
420         : public rtl::Static< String, Extension > {};
421     struct XMLFileFormatName
422         : public rtl::Static< String, XMLFileFormatName > {};
423     struct XMLFileFormatVersion
424         : public rtl::Static< String, XMLFileFormatVersion > {};
425     struct WriterCompatibilityVersionOOo11
426         : public rtl::Static< String, WriterCompatibilityVersionOOo11 > {};
427 }
428 
429 void ReplaceStringHookProc( UniString& rStr )
430 {
431     static int nAll = 0, nPro = 0;
432 
433     nAll++;
434     if ( rStr.SearchAscii( "%PRODUCT" ) != STRING_NOTFOUND )
435     {
436         String &rBrandName = BrandName::get();
437         String &rVersion = Version::get();
438         String &rAboutBoxVersion = AboutBoxVersion::get();
439         String &rExtension = Extension::get();
440         String &rXMLFileFormatName = XMLFileFormatName::get();
441         String &rXMLFileFormatVersion = XMLFileFormatVersion::get();
442 
443         if ( !rBrandName.Len() )
444         {
445             rtl::OUString aTmp;
446             Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME );
447             aRet >>= aTmp;
448             rBrandName = aTmp;
449 
450             aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTXMLFILEFORMATNAME );
451             aRet >>= aTmp;
452             rXMLFileFormatName = aTmp;
453 
454             aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTXMLFILEFORMATVERSION );
455             aRet >>= aTmp;
456             rXMLFileFormatVersion = aTmp;
457 
458             aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTVERSION );
459             aRet >>= aTmp;
460             rVersion = aTmp;
461 
462             aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::ABOUTBOXPRODUCTVERSION );
463             aRet >>= aTmp;
464             rAboutBoxVersion = aTmp;
465 
466             if ( !rExtension.Len() )
467             {
468                 aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTEXTENSION );
469                 aRet >>= aTmp;
470                 rExtension = aTmp;
471             }
472         }
473 
474         nPro++;
475         rStr.SearchAndReplaceAllAscii( "%PRODUCTNAME", rBrandName );
476         rStr.SearchAndReplaceAllAscii( "%PRODUCTVERSION", rVersion );
477         rStr.SearchAndReplaceAllAscii( "%ABOUTBOXPRODUCTVERSION", rAboutBoxVersion );
478         rStr.SearchAndReplaceAllAscii( "%PRODUCTEXTENSION", rExtension );
479         rStr.SearchAndReplaceAllAscii( "%PRODUCTXMLFILEFORMATNAME", rXMLFileFormatName );
480         rStr.SearchAndReplaceAllAscii( "%PRODUCTXMLFILEFORMATVERSION", rXMLFileFormatVersion );
481     }
482     if ( rStr.SearchAscii( "%OOOVENDOR" ) != STRING_NOTFOUND )
483     {
484         String &rOOOVendor = OOOVendor::get();
485 
486         if ( !rOOOVendor.Len() )
487         {
488             rtl::OUString aTmp;
489             Any aRet = ::utl::ConfigManager::GetDirectConfigProperty(
490                     ::utl::ConfigManager::OOOVENDOR );
491             aRet >>= aTmp;
492             rOOOVendor = aTmp;
493 
494         }
495         rStr.SearchAndReplaceAllAscii( "%OOOVENDOR" ,rOOOVendor );
496     }
497 
498     if ( rStr.SearchAscii( "%WRITERCOMPATIBILITYVERSIONOOO11" ) != STRING_NOTFOUND )
499     {
500         String &rWriterCompatibilityVersionOOo11 = WriterCompatibilityVersionOOo11::get();
501         if ( !rWriterCompatibilityVersionOOo11.Len() )
502         {
503             rtl::OUString aTmp;
504             Any aRet = ::utl::ConfigManager::GetDirectConfigProperty(
505                     ::utl::ConfigManager::WRITERCOMPATIBILITYVERSIONOOO11 );
506             aRet >>= aTmp;
507             rWriterCompatibilityVersionOOo11 = aTmp;
508         }
509 
510         rStr.SearchAndReplaceAllAscii( "%WRITERCOMPATIBILITYVERSIONOOO11",
511                                         rWriterCompatibilityVersionOOo11 );
512     }
513 }
514 
515 static const char      pLastSyncFileName[]     = "lastsynchronized";
516 static const sal_Int32 nStrLenLastSync         = 16;
517 
518 static bool needsSynchronization(
519     ::rtl::OUString const & baseSynchronizedURL, ::rtl::OUString const & userSynchronizedURL )
520 {
521     bool bNeedsSync( false );
522 
523     ::osl::DirectoryItem itemUserFile;
524     ::osl::File::RC err1 =
525           ::osl::DirectoryItem::get(userSynchronizedURL, itemUserFile);
526 
527     //If it does not exist, then there is nothing to be done
528     if (err1 == ::osl::File::E_NOENT)
529     {
530         return true;
531     }
532     else if (err1 != ::osl::File::E_None)
533     {
534         OSL_ENSURE(0, "Cannot access lastsynchronized in user layer");
535         return true; //sync just in case
536     }
537 
538     //If last synchronized does not exist in base layer, then do nothing
539     ::osl::DirectoryItem itemBaseFile;
540     ::osl::File::RC err2 = ::osl::DirectoryItem::get(baseSynchronizedURL, itemBaseFile);
541     if (err2 == ::osl::File::E_NOENT)
542     {
543         return true;
544 
545     }
546     else if (err2 != ::osl::File::E_None)
547     {
548         OSL_ENSURE(0, "Cannot access file lastsynchronized in base layer");
549         return true; //sync just in case
550     }
551 
552     //compare the modification time of the extension folder and the last
553     //modified file
554     ::osl::FileStatus statUser(FileStatusMask_ModifyTime);
555     ::osl::FileStatus statBase(FileStatusMask_ModifyTime);
556     if (itemUserFile.getFileStatus(statUser) == ::osl::File::E_None)
557     {
558         if (itemBaseFile.getFileStatus(statBase) == ::osl::File::E_None)
559         {
560             TimeValue timeUser = statUser.getModifyTime();
561             TimeValue timeBase = statBase.getModifyTime();
562 
563             if (timeUser.Seconds < timeBase.Seconds)
564                 bNeedsSync = true;
565         }
566         else
567         {
568             OSL_ASSERT(0);
569             bNeedsSync = true;
570         }
571     }
572     else
573     {
574         OSL_ASSERT(0);
575         bNeedsSync = true;
576     }
577 
578     return bNeedsSync;
579 }
580 
581 static ::rtl::OUString getBrandSharePreregBundledPathURL()
582 {
583     ::rtl::OUString url(
584         RTL_CONSTASCII_USTRINGPARAM("$BRAND_BASE_DIR/share/prereg/bundled"));
585 
586     ::rtl::Bootstrap::expandMacros(url);
587     return url;
588 }
589 
590 static ::rtl::OUString getUserBundledExtPathURL()
591 {
592     ::rtl::OUString folder( RTL_CONSTASCII_USTRINGPARAM( "$BUNDLED_EXTENSIONS_USER" ));
593     ::rtl::Bootstrap::expandMacros(folder);
594 
595     return folder;
596 }
597 
598 static ::rtl::OUString getLastSyncFileURLFromBrandInstallation()
599 {
600     ::rtl::OUString aURL = getBrandSharePreregBundledPathURL();
601     ::sal_Int32    nLastIndex         = aURL.lastIndexOf('/');
602 
603     ::rtl::OUStringBuffer aTmp( aURL );
604 
605     if ( nLastIndex != aURL.getLength()-1 )
606         aTmp.appendAscii( "/" );
607     aTmp.appendAscii( pLastSyncFileName );
608 
609     return aTmp.makeStringAndClear();
610 }
611 
612 static ::rtl::OUString getLastSyncFileURLFromUserInstallation()
613 {
614     ::rtl::OUString aUserBundledPathURL = getUserBundledExtPathURL();
615     ::sal_Int32    nLastIndex          = aUserBundledPathURL.lastIndexOf('/');
616 
617     ::rtl::OUStringBuffer aTmp( aUserBundledPathURL );
618 
619     if ( nLastIndex != aUserBundledPathURL.getLength()-1 )
620         aTmp.appendAscii( "/" );
621     aTmp.appendAscii( pLastSyncFileName );
622 
623     return aTmp.makeStringAndClear();
624 }
625 //Checks if the argument src is the folder of the help or configuration
626 //backend in the prereg folder
627 static bool excludeTmpFilesAndFolders(const rtl::OUString & src)
628 {
629     const char helpBackend[] = "com.sun.star.comp.deployment.help.PackageRegistryBackend";
630     const char configBackend[] = "com.sun.star.comp.deployment.configuration.PackageRegistryBackend";
631     if (src.endsWithAsciiL(helpBackend, sizeof(helpBackend) - 1 )
632         || src.endsWithAsciiL(configBackend, sizeof(configBackend) - 1))
633     {
634         return true;
635     }
636     return false;
637 }
638 
639 //If we are about to copy the contents of some special folder as determined
640 //by excludeTmpFilesAndFolders, then we omit those files or folders with a name
641 //derived from temporary folders.
642 static bool isExcludedFileOrFolder( const rtl::OUString & name)
643 {
644     char const * allowed[] = {
645         "backenddb.xml",
646         "configmgr.ini",
647         "registered_packages.db"
648     };
649 
650     const unsigned int size = sizeof(allowed) / sizeof (char const *);
651     bool bExclude = true;
652     for (unsigned int i= 0; i < size; i ++)
653     {
654         ::rtl::OUString allowedName = ::rtl::OUString::createFromAscii(allowed[i]);
655         if (allowedName.equals(name))
656         {
657             bExclude = false;
658             break;
659         }
660     }
661     return bExclude;
662 }
663 
664 static osl::FileBase::RC copy_prereg_bundled_recursive(
665     const rtl::OUString& srcUnqPath,
666     const rtl::OUString& dstUnqPath,
667     sal_Int32            TypeToCopy )
668 throw()
669 {
670     osl::FileBase::RC err = osl::FileBase::E_None;
671 
672     if( TypeToCopy == -1 ) // Document
673     {
674         err = osl::File::copy( srcUnqPath,dstUnqPath );
675     }
676     else if( TypeToCopy == +1 ) // Folder
677     {
678         osl::Directory aDir( srcUnqPath );
679         err = aDir.open();
680         if ( err != osl::FileBase::E_None )
681             return err;
682 
683         err = osl::Directory::create( dstUnqPath );
684         osl::FileBase::RC next = err;
685         if( err == osl::FileBase::E_None ||
686             err == osl::FileBase::E_EXIST )
687         {
688             err = osl::FileBase::E_None;
689             sal_Int32 n_Mask = FileStatusMask_FileURL | FileStatusMask_FileName | FileStatusMask_Type;
690 
691             osl::DirectoryItem aDirItem;
692             bool bExcludeFiles = excludeTmpFilesAndFolders(srcUnqPath);
693 
694             while( err == osl::FileBase::E_None && ( next = aDir.getNextItem( aDirItem ) ) == osl::FileBase::E_None )
695             {
696                 sal_Bool IsDoc = false;
697                 sal_Bool bFilter = false;
698                 osl::FileStatus aFileStatus( n_Mask );
699                 aDirItem.getFileStatus( aFileStatus );
700                 if( aFileStatus.isValid( FileStatusMask_Type ) )
701                     IsDoc = aFileStatus.getFileType() == osl::FileStatus::Regular;
702 
703                 // Getting the information for the next recursive copy
704                 sal_Int32 newTypeToCopy = IsDoc ? -1 : +1;
705 
706                 rtl::OUString newSrcUnqPath;
707                 if( aFileStatus.isValid( FileStatusMask_FileURL ) )
708                     newSrcUnqPath = aFileStatus.getFileURL();
709 
710                 rtl::OUString newDstUnqPath = dstUnqPath;
711                 rtl::OUString tit;
712                 if( aFileStatus.isValid( FileStatusMask_FileName ) )
713                 {
714                     ::rtl::OUString aFileName = aFileStatus.getFileName();
715                     tit = rtl::Uri::encode( aFileName,
716                                             rtl_UriCharClassPchar,
717                                             rtl_UriEncodeIgnoreEscapes,
718                                             RTL_TEXTENCODING_UTF8 );
719 
720                     // Special treatment for "lastsychronized" file. Must not be
721                     // copied from the bundled folder!
722                     //Also do not copy *.tmp files and *.tmp_ folders. This affects the files/folders
723                     //from the help and configuration backend
724                     if ( IsDoc && (aFileName.equalsAscii( pLastSyncFileName )
725                                    || bExcludeFiles && isExcludedFileOrFolder(aFileName)))
726                         bFilter = true;
727                     else if (!IsDoc && bExcludeFiles && isExcludedFileOrFolder(aFileName))
728                         bFilter = true;
729                 }
730 
731                 if( newDstUnqPath.lastIndexOf( sal_Unicode('/') ) != newDstUnqPath.getLength()-1 )
732                     newDstUnqPath += rtl::OUString::createFromAscii( "/" );
733 
734                 newDstUnqPath += tit;
735 
736                 if (( newSrcUnqPath != dstUnqPath ) && !bFilter )
737                     err = copy_prereg_bundled_recursive( newSrcUnqPath,newDstUnqPath, newTypeToCopy );
738             }
739 
740             if( err == osl::FileBase::E_None && next != osl::FileBase::E_NOENT )
741                 err = next;
742         }
743         aDir.close();
744     }
745 
746     return err;
747 }
748 
749 
750 //====================================================================================
751 
752 // MinimalCommandEnv: a tribute owed to ExtensionManager being an UNO stronghold
753 class MinimalCommandEnv
754     : public ::cppu::WeakImplHelper3< css::ucb::XCommandEnvironment,
755                                       css::task::XInteractionHandler,
756                                       css::ucb::XProgressHandler >
757 {
758 public:
759     // XCommandEnvironment
760     virtual css::uno::Reference< css::task::XInteractionHandler> SAL_CALL getInteractionHandler()
761         throw (css::uno::RuntimeException)
762 	{ return this;}
763     virtual css::uno::Reference< css::ucb::XProgressHandler> SAL_CALL getProgressHandler()
764         throw (css::uno::RuntimeException)
765 	{ return this;}
766 
767     // XInteractionHandler
768     virtual void SAL_CALL handle( const css::uno::Reference< css::task::XInteractionRequest>&)
769         throw (css::uno::RuntimeException);
770 
771     // XProgressHandler
772     virtual void SAL_CALL push( const css::uno::Any& /*Status*/)
773         throw (css::uno::RuntimeException)
774 	{}
775     virtual void SAL_CALL update( const css::uno::Any& /*Status*/)
776         throw (css::uno::RuntimeException)
777 	{}
778     virtual void SAL_CALL pop()
779         throw (css::uno::RuntimeException)
780 	{}
781 };
782 
783 // MinimalCommandEnv's XInteractionHandler simply approves
784 void MinimalCommandEnv::handle(
785     css::uno::Reference< css::task::XInteractionRequest> const& xRequest)
786     throw ( css::uno::RuntimeException )
787 {
788 	const css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > conts( xRequest->getContinuations());
789 	const css::uno::Reference< css::task::XInteractionContinuation>* pConts = conts.getConstArray();
790 	const sal_Int32 len = conts.getLength();
791 	for( sal_Int32 pos = 0; pos < len; ++pos )
792 	{
793 		css::uno::Reference< css::task::XInteractionApprove> xInteractionApprove( pConts[ pos ], css::uno::UNO_QUERY);
794 		if( xInteractionApprove.is()) {
795 			xInteractionApprove->select();
796 			// don't query again for ongoing continuations:
797 			break;
798 		}
799 	}
800 }
801 
802 
803 /** Check if installBundledExtensionBlobs() has to be run.
804     It uses the time stamps of a marker file (rsMarkerURL) on the one
805     hand and of the files in the given directory on the other.
806     Returns </TRUE> when either the marker does not yet exist or any
807     file in the given directory is newer than the marker.
808 */
809 static bool needsInstallBundledExtensionBlobs (
810     const ::rtl::OUString& rsMarkerURL,
811     ::osl::Directory& rDirectory)
812 {
813     ::osl::DirectoryItem aMarkerItem;
814     if (::osl::DirectoryItem::get(rsMarkerURL, aMarkerItem) == ::osl::File::E_NOENT)
815     {
816         // Marker does not exist.  Extensions where never installed.
817         return true;
818     }
819 
820     ::osl::FileStatus aMarkerStat (FileStatusMask_ModifyTime);
821     if (aMarkerItem.getFileStatus(aMarkerStat) != ::osl::File::E_None)
822     {
823         // Can not get marker state.  Reason?
824         return true;
825     }
826 
827     const TimeValue aMarkerModifyTime (aMarkerStat.getModifyTime());
828 
829     if (rDirectory.open() != osl::File::E_None)
830     {
831         // No extension directory.  Nothing to be done.
832         return false;
833     }
834 
835     ::osl::DirectoryItem aDirectoryItem;
836     while (rDirectory.getNextItem(aDirectoryItem) == osl::File::E_None)
837     {
838         ::osl::FileStatus aFileStat (FileStatusMask_ModifyTime);
839         if (aDirectoryItem.getFileStatus(aFileStat) != ::osl::File::E_None)
840             continue;
841         if (aFileStat.getFileType() != ::osl::FileStatus::Regular)
842             continue;
843         if (aFileStat.getModifyTime().Seconds > aMarkerModifyTime.Seconds)
844         {
845             rDirectory.close();
846             return true;
847         }
848 	}
849     rDirectory.close();
850 
851     // No file in the directory is newer than the marker.
852     return false;
853 }
854 
855 
856 // install bundled but non-pre-registered extension blobs
857 static void installBundledExtensionBlobs()
858 {
859 	rtl::OUString aDirUrl( OUSTR("$BRAND_BASE_DIR/share/extensions/install"));
860 	::rtl::Bootstrap::expandMacros( aDirUrl);
861 	::osl::Directory aDir( aDirUrl);
862 
863     // Find out if we can exit early: only when there is an extension file newer
864     // than the marker we have to install any extension.
865     ::rtl::OUString sMarkerURL (RTL_CONSTASCII_USTRINGPARAM("$BUNDLED_EXTENSIONS_USER/lastsynchronized.bundled"));
866     ::rtl::Bootstrap::expandMacros(sMarkerURL);
867     if ( ! needsInstallBundledExtensionBlobs(sMarkerURL, aDir))
868         return;
869     writeLastModified(sMarkerURL);
870 
871     // get the ExtensionManager
872 	::css::uno::Reference< ::css::uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
873 	::css::uno::Reference< ::css::deployment::XExtensionManager> xEM = ::css::deployment::ExtensionManager::get( xContext);
874 	// provide the minimal set of requirements to call ExtensionManager's methods
875 	MinimalCommandEnv* pMiniCmdEnv = new MinimalCommandEnv;
876 	::css::uno::Reference< css::ucb::XCommandEnvironment> xCmdEnv( static_cast< cppu::OWeakObject*>(pMiniCmdEnv), css::uno::UNO_QUERY);
877 	const ::css::beans::NamedValue aNamedProps( OUSTR("SUPPRESS_LICENSE"), ::css::uno::makeAny( OUSTR("1")));
878 	const ::css::uno::Sequence< ::css::beans::NamedValue> xProperties( &aNamedProps, 1);
879 	::css::uno::Reference< ::css::task::XAbortChannel> xAbortChannel;
880 
881 	// get the list of deployed extensions
882 	typedef std::hash_set< rtl::OUString, ::rtl::OUStringHash> StringSet;
883 	StringSet aExtNameSet;
884 	css::uno::Sequence< css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > > xListOfLists = xEM->getAllExtensions( xAbortChannel, xCmdEnv);
885 	const sal_Int32 nLen1 = xListOfLists.getLength();
886 	for( int i1 = 0; i1 < nLen1; ++i1) {
887 		css::uno::Sequence<css::uno::Reference<css::deployment::XPackage> > xListOfPacks = xListOfLists[i1];
888 		const sal_Int32 nLen2 = xListOfPacks.getLength();
889 		for( int i2 = 0; i2 < nLen2; ++i2) {
890 			css::uno::Reference<css::deployment::XPackage> xPackage = xListOfPacks[i2];
891 			if( !xPackage.is())
892 				continue;
893 			aExtNameSet.insert( xPackage->getName());
894 		}
895 	}
896 
897 	// iterate over the bundled extension blobs
898 	::osl::File::RC rc = aDir.open();
899 	while( rc == osl::File::E_None) {
900 		::osl::DirectoryItem aDI;
901 		if( aDir.getNextItem( aDI) != osl::File::E_None)
902 			break;
903 		::osl::FileStatus aFileStat( FileStatusMask_Type | FileStatusMask_FileURL);
904 		if( aDI.getFileStatus( aFileStat) != ::osl::File::E_None)
905 			continue;
906 		if( aFileStat.getFileType() != ::osl::FileStatus::Regular)
907 			continue;
908 		try {
909 			// check if the extension is already installed
910 			const rtl::OUString& rExtFileUrl = aFileStat.getFileURL();
911 			const sal_Int32 nBaseIndex = rExtFileUrl.lastIndexOf('/');
912 			const ::rtl::OUString aBaseName = (nBaseIndex < 0) ? rExtFileUrl : rExtFileUrl.copy( nBaseIndex+1);
913 			const bool bFound = (aExtNameSet.find( aBaseName) != aExtNameSet.end());
914 			if( bFound)
915 				continue;
916 			// request to install the extension blob
917 			xEM->addExtension( rExtFileUrl, xProperties, OUSTR("user"), xAbortChannel, xCmdEnv);
918 		// ExtensionManager problems are not worth to die for here
919 		} catch( css::uno::RuntimeException&) {
920 		} catch( css::deployment::DeploymentException&) {
921 		}
922 	}
923 }
924 
925 //=============================================================================
926 
927 Desktop::Desktop()
928 : m_bServicesRegistered( false )
929 , m_aBootstrapError( BE_OK )
930 , m_pLockfile( NULL )
931 {
932     RTL_LOGFILE_TRACE( "desktop (cd100003) ::Desktop::Desktop" );
933 }
934 
935 Desktop::~Desktop()
936 {
937 }
938 
939 void Desktop::Init()
940 {
941     RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::Init" );
942     SetBootstrapStatus(BS_OK);
943 
944     // Check for lastsynchronized file for pre-registered bundled extensions in the user directory
945     // and test if synchronzation is necessary!
946     {
947         ::rtl::OUString aUserLastSyncFilePathURL = getLastSyncFileURLFromUserInstallation();
948         ::rtl::OUString aPreregSyncFilePathURL = getLastSyncFileURLFromBrandInstallation();
949 
950         if ( needsSynchronization( aPreregSyncFilePathURL, aUserLastSyncFilePathURL ))
951         {
952             rtl::OUString aUserPath = getUserBundledExtPathURL();
953             rtl::OUString aPreregBundledPath = getBrandSharePreregBundledPathURL();
954 
955             // copy bundled folder to the user directory
956             osl::FileBase::RC rc = osl::Directory::createPath(aUserPath);
957             (void) rc;
958             copy_prereg_bundled_recursive( aPreregBundledPath, aUserPath, +1 );
959         }
960     }
961 
962     // create service factory...
963     Reference < XMultiServiceFactory > rSMgr = CreateApplicationServiceManager();
964     if( rSMgr.is() )
965     {
966         ::comphelper::setProcessServiceFactory( rSMgr );
967     }
968     else
969     {
970         SetBootstrapError( BE_UNO_SERVICEMANAGER );
971     }
972 
973     if ( GetBootstrapError() == BE_OK )
974     {
975         // prepare language
976         if ( !LanguageSelection::prepareLanguage() )
977         {
978             if ( LanguageSelection::getStatus() == LanguageSelection::LS_STATUS_CANNOT_DETERMINE_LANGUAGE )
979                 SetBootstrapError( BE_LANGUAGE_MISSING );
980             else
981                 SetBootstrapError( BE_OFFICECONFIG_BROKEN );
982         }
983     }
984 
985     if ( GetBootstrapError() == BE_OK )
986     {
987         CommandLineArgs* pCmdLineArgs = GetCommandLineArgs();
988 #ifdef UNX
989     //  check whether we need to print cmdline help
990     if ( pCmdLineArgs->IsHelp() ) {
991         displayCmdlineHelp();
992         SetBootstrapStatus(BS_TERMINATE);
993     }
994 #endif
995         // start ipc thread only for non-remote offices
996         RTL_LOGFILE_CONTEXT( aLog2, "desktop (cd100003) ::OfficeIPCThread::EnableOfficeIPCThread" );
997         OfficeIPCThread::Status aStatus = OfficeIPCThread::EnableOfficeIPCThread();
998         if ( aStatus == OfficeIPCThread::IPC_STATUS_BOOTSTRAP_ERROR )
999         {
1000             SetBootstrapError( BE_PATHINFO_MISSING );
1001 
1002         }
1003         else if ( aStatus == OfficeIPCThread::IPC_STATUS_MULTI_TS_ERROR )
1004         {
1005             SetBootstrapError( BE_MUTLISESSION_NOT_SUPPROTED );
1006         }
1007         else if ( aStatus == OfficeIPCThread::IPC_STATUS_2ND_OFFICE )
1008         {
1009             // 2nd office startup should terminate after sending cmdlineargs through pipe
1010             SetBootstrapStatus(BS_TERMINATE);
1011         }
1012         else if ( pCmdLineArgs->IsHelp() )
1013         {
1014             // disable IPC thread in an instance that is just showing a help message
1015             OfficeIPCThread::DisableOfficeIPCThread();
1016         }
1017         pSignalHandler = new SalMainPipeExchangeSignalHandler;
1018     }
1019 }
1020 
1021 void Desktop::DeInit()
1022 {
1023     RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::DeInit" );
1024 
1025     try {
1026         // instead of removing of the configManager just let it commit all the changes
1027         RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
1028         utl::ConfigManager::GetConfigManager()->StoreConfigItems();
1029         FlushConfiguration();
1030         RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
1031 
1032         // close splashscreen if it's still open
1033         CloseSplashScreen();
1034         Reference<XMultiServiceFactory> xXMultiServiceFactory(::comphelper::getProcessServiceFactory());
1035         DestroyApplicationServiceManager( xXMultiServiceFactory );
1036         // nobody should get a destroyd service factory...
1037         ::comphelper::setProcessServiceFactory( NULL );
1038 
1039         // clear lockfile
1040         if (m_pLockfile != NULL)
1041             m_pLockfile->clean();
1042 
1043         OfficeIPCThread::DisableOfficeIPCThread();
1044         if( pSignalHandler )
1045             DELETEZ( pSignalHandler );
1046     } catch (RuntimeException&) {
1047         // someone threw an exception during shutdown
1048         // this will leave some garbage behind..
1049     }
1050 
1051     RTL_LOGFILE_CONTEXT_TRACE( aLog, "FINISHED WITH Destop::DeInit" );
1052 }
1053 
1054 sal_Bool Desktop::QueryExit()
1055 {
1056     try
1057     {
1058         RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
1059         utl::ConfigManager::GetConfigManager()->StoreConfigItems();
1060         RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- store config items" );
1061     }
1062     catch ( RuntimeException& )
1063     {
1064     }
1065 
1066     const sal_Char SUSPEND_QUICKSTARTVETO[] = "SuspendQuickstartVeto";
1067 
1068     Reference< ::com::sun::star::frame::XDesktop >
1069             xDesktop( ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
1070                 UNO_QUERY );
1071 
1072     Reference < ::com::sun::star::beans::XPropertySet > xPropertySet( xDesktop, UNO_QUERY );
1073     if ( xPropertySet.is() )
1074     {
1075         Any a;
1076         a <<= (sal_Bool)sal_True;
1077         xPropertySet->setPropertyValue( OUSTRING(RTL_CONSTASCII_USTRINGPARAM( SUSPEND_QUICKSTARTVETO )), a );
1078     }
1079 
1080     sal_Bool bExit = ( !xDesktop.is() || xDesktop->terminate() );
1081 
1082 
1083     if ( !bExit && xPropertySet.is() )
1084     {
1085         Any a;
1086         a <<= (sal_Bool)sal_False;
1087         xPropertySet->setPropertyValue( OUSTRING(RTL_CONSTASCII_USTRINGPARAM( SUSPEND_QUICKSTARTVETO )), a );
1088     }
1089     else
1090     {
1091         FlushConfiguration();
1092         try
1093         {
1094             // it is no problem to call DisableOfficeIPCThread() more than once
1095             // it also looks to be threadsafe
1096             OfficeIPCThread::DisableOfficeIPCThread();
1097         }
1098         catch ( RuntimeException& )
1099         {
1100         }
1101 
1102         if (m_pLockfile != NULL) m_pLockfile->clean();
1103     }
1104 
1105     return bExit;
1106 }
1107 
1108 void Desktop::HandleBootstrapPathErrors( ::utl::Bootstrap::Status aBootstrapStatus, const OUString& aDiagnosticMessage )
1109 {
1110     if ( aBootstrapStatus != ::utl::Bootstrap::DATA_OK )
1111     {
1112         sal_Bool            bWorkstationInstallation = sal_False;
1113         ::rtl::OUString        aBaseInstallURL;
1114         ::rtl::OUString        aUserInstallURL;
1115         ::rtl::OUString        aProductKey;
1116         ::rtl::OUString        aTemp;
1117         ::vos::OStartupInfo aInfo;
1118 
1119         aInfo.getExecutableFile( aProductKey );
1120         sal_uInt32     lastIndex = aProductKey.lastIndexOf('/');
1121         if ( lastIndex > 0 )
1122             aProductKey = aProductKey.copy( lastIndex+1 );
1123 
1124         aTemp = ::utl::Bootstrap::getProductKey( aProductKey );
1125         if ( aTemp.getLength() > 0 )
1126             aProductKey = aTemp;
1127 
1128         ::utl::Bootstrap::PathStatus aBaseInstallStatus = ::utl::Bootstrap::locateBaseInstallation( aBaseInstallURL );
1129         ::utl::Bootstrap::PathStatus aUserInstallStatus = ::utl::Bootstrap::locateUserInstallation( aUserInstallURL );
1130 
1131         if (( aBaseInstallStatus == ::utl::Bootstrap::PATH_EXISTS &&
1132               aUserInstallStatus == ::utl::Bootstrap::PATH_EXISTS        ))
1133         {
1134             if ( aBaseInstallURL != aUserInstallURL )
1135                 bWorkstationInstallation = sal_True;
1136         }
1137 
1138         OUString        aMessage;
1139         OUStringBuffer    aBuffer( 100 );
1140         aBuffer.append( aDiagnosticMessage );
1141 
1142         aBuffer.appendAscii( "\n" );
1143 
1144         ErrorBox aBootstrapFailedBox( NULL, WB_OK, aMessage );
1145         aBootstrapFailedBox.SetText( aProductKey );
1146         aBootstrapFailedBox.Execute();
1147     }
1148 }
1149 
1150 // Create a error message depending on bootstrap failure code and an optional file url
1151 ::rtl::OUString    Desktop::CreateErrorMsgString(
1152     utl::Bootstrap::FailureCode nFailureCode,
1153     const ::rtl::OUString& aFileURL )
1154 {
1155     OUString        aMsg;
1156     OUString        aFilePath;
1157     sal_Bool        bFileInfo = sal_True;
1158 
1159     switch ( nFailureCode )
1160     {
1161         /// the shared installation directory could not be located
1162         case ::utl::Bootstrap::MISSING_INSTALL_DIRECTORY:
1163         {
1164             aMsg = GetMsgString( STR_BOOTSTRAP_ERR_PATH_INVALID,
1165                         OUString( RTL_CONSTASCII_USTRINGPARAM( "The installation path is not available." )) );
1166             bFileInfo = sal_False;
1167         }
1168         break;
1169 
1170         /// the bootstrap INI file could not be found or read
1171         case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE:
1172         {
1173             aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_MISSING,
1174                         OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration file \"$1\" is missing." )) );
1175         }
1176         break;
1177 
1178         /// the bootstrap INI is missing a required entry
1179         /// the bootstrap INI contains invalid data
1180          case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY:
1181          case ::utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY:
1182         {
1183             aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_CORRUPT,
1184                         OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration file \"$1\" is corrupt." )) );
1185         }
1186         break;
1187 
1188         /// the version locator INI file could not be found or read
1189         case ::utl::Bootstrap::MISSING_VERSION_FILE:
1190         {
1191             aMsg = GetMsgString( STR_BOOTSTRAP_ERR_FILE_MISSING,
1192                         OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration file \"$1\" is missing." )) );
1193         }
1194         break;
1195 
1196         /// the version locator INI has no entry for this version
1197          case ::utl::Bootstrap::MISSING_VERSION_FILE_ENTRY:
1198         {
1199             aMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_SUPPORT,
1200                         OUString( RTL_CONSTASCII_USTRINGPARAM( "The main configuration file \"$1\" does not support the current version." )) );
1201         }
1202         break;
1203 
1204         /// the user installation directory does not exist
1205            case ::utl::Bootstrap::MISSING_USER_DIRECTORY:
1206         {
1207             aMsg = GetMsgString( STR_BOOTSTRAP_ERR_DIR_MISSING,
1208                         OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration directory \"$1\" is missing." )) );
1209         }
1210         break;
1211 
1212         /// some bootstrap data was invalid in unexpected ways
1213         case ::utl::Bootstrap::INVALID_BOOTSTRAP_DATA:
1214         {
1215             aMsg = GetMsgString( STR_BOOTSTRAP_ERR_INTERNAL,
1216                         OUString( RTL_CONSTASCII_USTRINGPARAM( "An internal failure occurred." )) );
1217             bFileInfo = sal_False;
1218         }
1219         break;
1220 
1221         case ::utl::Bootstrap::INVALID_VERSION_FILE_ENTRY:
1222         {
1223             // This needs to be improved, see #i67575#:
1224             aMsg = OUString(
1225                 RTL_CONSTASCII_USTRINGPARAM( "Invalid version file entry" ) );
1226             bFileInfo = sal_False;
1227         }
1228         break;
1229 
1230         case ::utl::Bootstrap::NO_FAILURE:
1231         {
1232             OSL_ASSERT(false);
1233         }
1234         break;
1235     }
1236 
1237     if ( bFileInfo )
1238     {
1239         String aMsgString( aMsg );
1240 
1241         osl::File::getSystemPathFromFileURL( aFileURL, aFilePath );
1242 
1243         aMsgString.SearchAndReplaceAscii( "$1", aFilePath );
1244         aMsg = aMsgString;
1245     }
1246 
1247     return MakeStartupErrorMessage( aMsg );
1248 }
1249 
1250 void Desktop::HandleBootstrapErrors( BootstrapError aBootstrapError )
1251 {
1252 	if ( aBootstrapError == BE_MUTLISESSION_NOT_SUPPROTED ) {
1253 		OUString        aMessage;
1254 		aMessage = GetMsgString( STR_BOOTSTRAP_ERR_MULTISESSION,
1255                         OUString( RTL_CONSTASCII_USTRINGPARAM( "You have another instance running in a different terminal session. Close that instance and then try again." )) );
1256         FatalError(aMessage,sal_False);
1257 
1258 	} else if ( aBootstrapError == BE_PATHINFO_MISSING )
1259     {
1260         OUString                    aErrorMsg;
1261         OUString                    aBuffer;
1262         utl::Bootstrap::Status        aBootstrapStatus;
1263         utl::Bootstrap::FailureCode    nFailureCode;
1264 
1265         aBootstrapStatus = ::utl::Bootstrap::checkBootstrapStatus( aBuffer, nFailureCode );
1266         if ( aBootstrapStatus != ::utl::Bootstrap::DATA_OK )
1267         {
1268             switch ( nFailureCode )
1269             {
1270                 case ::utl::Bootstrap::MISSING_INSTALL_DIRECTORY:
1271                 case ::utl::Bootstrap::INVALID_BOOTSTRAP_DATA:
1272                 {
1273                     aErrorMsg = CreateErrorMsgString( nFailureCode, OUString() );
1274                 }
1275                 break;
1276 
1277                 /// the bootstrap INI file could not be found or read
1278                 /// the bootstrap INI is missing a required entry
1279                 /// the bootstrap INI contains invalid data
1280                  case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY:
1281                  case ::utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY:
1282                 case ::utl::Bootstrap::MISSING_BOOTSTRAP_FILE:
1283                 {
1284                     OUString aBootstrapFileURL;
1285 
1286                     utl::Bootstrap::locateBootstrapFile( aBootstrapFileURL );
1287                     aErrorMsg = CreateErrorMsgString( nFailureCode, aBootstrapFileURL );
1288                 }
1289                 break;
1290 
1291                 /// the version locator INI file could not be found or read
1292                 /// the version locator INI has no entry for this version
1293                 /// the version locator INI entry is not a valid directory URL
1294                    case ::utl::Bootstrap::INVALID_VERSION_FILE_ENTRY:
1295                  case ::utl::Bootstrap::MISSING_VERSION_FILE_ENTRY:
1296                  case ::utl::Bootstrap::MISSING_VERSION_FILE:
1297                 {
1298                     OUString aVersionFileURL;
1299 
1300                     utl::Bootstrap::locateVersionFile( aVersionFileURL );
1301                     aErrorMsg = CreateErrorMsgString( nFailureCode, aVersionFileURL );
1302                 }
1303                 break;
1304 
1305                 /// the user installation directory does not exist
1306                    case ::utl::Bootstrap::MISSING_USER_DIRECTORY:
1307                 {
1308                     OUString aUserInstallationURL;
1309 
1310                     utl::Bootstrap::locateUserInstallation( aUserInstallationURL );
1311                     aErrorMsg = CreateErrorMsgString( nFailureCode, aUserInstallationURL );
1312                 }
1313                 break;
1314 
1315                 case ::utl::Bootstrap::NO_FAILURE:
1316                 {
1317                     OSL_ASSERT(false);
1318                 }
1319                 break;
1320             }
1321 
1322             HandleBootstrapPathErrors( aBootstrapStatus, aErrorMsg );
1323         }
1324     }
1325     else if ( aBootstrapError == BE_UNO_SERVICEMANAGER || aBootstrapError == BE_UNO_SERVICE_CONFIG_MISSING )
1326     {
1327         // Uno service manager is not available. VCL needs a uno service manager to display a message box!!!
1328         // Currently we are not able to display a message box with a service manager due to this limitations inside VCL.
1329 
1330         // When UNO is not properly initialized, all kinds of things can fail
1331         // and cause the process to crash (e.g., a call to GetMsgString may
1332         // crash when somewhere deep within that call Any::operator <= is used
1333         // with a PropertyValue, and no binary UNO type description for
1334         // PropertyValue is available).  To give the user a hint even if
1335         // generating and displaying a message box below crashes, print a
1336         // hard-coded message on stderr first:
1337         fputs(
1338             aBootstrapError == BE_UNO_SERVICEMANAGER
1339             ? ("The application cannot be started. " "\n"
1340                "The component manager is not available." "\n")
1341                 // STR_BOOTSTRAP_ERR_CANNOT_START, STR_BOOTSTRAP_ERR_NO_SERVICE
1342             : ("The application cannot be started. " "\n"
1343                "The configuration service is not available." "\n"),
1344                 // STR_BOOTSTRAP_ERR_CANNOT_START,
1345                 // STR_BOOTSTRAP_ERR_NO_CFG_SERVICE
1346             stderr);
1347 
1348         // First sentence. We cannot bootstrap office further!
1349         OUString            aMessage;
1350         OUStringBuffer        aDiagnosticMessage( 100 );
1351 
1352         OUString aErrorMsg;
1353 
1354         if ( aBootstrapError == BE_UNO_SERVICEMANAGER )
1355             aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_SERVICE,
1356                             OUString( RTL_CONSTASCII_USTRINGPARAM( "The service manager is not available." )) );
1357         else
1358             aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_NO_CFG_SERVICE,
1359                             OUString( RTL_CONSTASCII_USTRINGPARAM( "The configuration service is not available." )) );
1360 
1361         aDiagnosticMessage.append( aErrorMsg );
1362         aDiagnosticMessage.appendAscii( "\n" );
1363 
1364         // Due to the fact the we haven't a backup applicat.rdb file anymore it is not possible to
1365         // repair the installation with the setup executable besides the office executable. Now
1366         // we have to ask the user to start the setup on CD/installation directory manually!!
1367         OUString aStartSetupManually( GetMsgString(
1368             STR_ASK_START_SETUP_MANUALLY,
1369             OUString( RTL_CONSTASCII_USTRINGPARAM( "Start setup application to repair the installation from CD, or the folder containing the installation packages." )) ));
1370 
1371         aDiagnosticMessage.append( aStartSetupManually );
1372         aMessage = MakeStartupErrorMessage( aDiagnosticMessage.makeStringAndClear() );
1373 
1374         FatalError( aMessage);
1375     }
1376     else if ( aBootstrapError == BE_OFFICECONFIG_BROKEN )
1377     {
1378         OUString aMessage;
1379         OUStringBuffer aDiagnosticMessage( 100 );
1380         OUString aErrorMsg;
1381         aErrorMsg = GetMsgString( STR_CONFIG_ERR_ACCESS_GENERAL,
1382             OUString( RTL_CONSTASCII_USTRINGPARAM( "A general error occurred while accessing your central configuration." )) );
1383         aDiagnosticMessage.append( aErrorMsg );
1384         aMessage = MakeStartupErrorMessage( aDiagnosticMessage.makeStringAndClear() );
1385         FatalError(aMessage);
1386     }
1387     else if ( aBootstrapError == BE_USERINSTALL_FAILED )
1388     {
1389         OUString aMessage;
1390         OUStringBuffer aDiagnosticMessage( 100 );
1391         OUString aErrorMsg;
1392         aErrorMsg = GetMsgString( STR_BOOTSTRAP_ERR_INTERNAL,
1393             OUString( RTL_CONSTASCII_USTRINGPARAM( "User installation could not be completed" )) );
1394         aDiagnosticMessage.append( aErrorMsg );
1395         aMessage = MakeStartupErrorMessage( aDiagnosticMessage.makeStringAndClear() );
1396         FatalError(aMessage);
1397     }
1398     else if ( aBootstrapError == BE_LANGUAGE_MISSING )
1399     {
1400         OUString aMessage;
1401         OUStringBuffer aDiagnosticMessage( 100 );
1402         OUString aErrorMsg;
1403         aErrorMsg = GetMsgString(
1404             //@@@ FIXME: should use an own resource string => #i36213#
1405             STR_BOOTSTRAP_ERR_LANGUAGE_MISSING,
1406             OUString( RTL_CONSTASCII_USTRINGPARAM(
1407                 "Language could not be determined." )) );
1408         aDiagnosticMessage.append( aErrorMsg );
1409         aMessage = MakeStartupErrorMessage(
1410             aDiagnosticMessage.makeStringAndClear() );
1411         FatalError(aMessage);
1412     }
1413     else if (( aBootstrapError == BE_USERINSTALL_NOTENOUGHDISKSPACE ) ||
1414              ( aBootstrapError == BE_USERINSTALL_NOWRITEACCESS      ))
1415     {
1416         OUString       aUserInstallationURL;
1417         OUString       aUserInstallationPath;
1418         OUString       aMessage;
1419         OUString       aErrorMsg;
1420         OUStringBuffer aDiagnosticMessage( 100 );
1421 
1422         utl::Bootstrap::locateUserInstallation( aUserInstallationURL );
1423 
1424         if ( aBootstrapError == BE_USERINSTALL_NOTENOUGHDISKSPACE )
1425             aErrorMsg = GetMsgString(
1426                 STR_BOOSTRAP_ERR_NOTENOUGHDISKSPACE,
1427                 OUString( RTL_CONSTASCII_USTRINGPARAM(
1428                     "User installation could not be completed due to insufficient free disk space." )) );
1429         else
1430             aErrorMsg = GetMsgString(
1431                 STR_BOOSTRAP_ERR_NOACCESSRIGHTS,
1432                 OUString( RTL_CONSTASCII_USTRINGPARAM(
1433                     "User installation could not be processed due to missing access rights." )) );
1434 
1435         osl::File::getSystemPathFromFileURL( aUserInstallationURL, aUserInstallationPath );
1436 
1437         aDiagnosticMessage.append( aErrorMsg );
1438         aDiagnosticMessage.append( aUserInstallationPath );
1439         aMessage = MakeStartupErrorMessage(
1440             aDiagnosticMessage.makeStringAndClear() );
1441         FatalError(aMessage);
1442     }
1443 
1444     return;
1445 }
1446 
1447 
1448 void Desktop::retrieveCrashReporterState()
1449 {
1450     static const ::rtl::OUString CFG_PACKAGE_RECOVERY   = ::rtl::OUString::createFromAscii("org.openoffice.Office.Recovery/");
1451     static const ::rtl::OUString CFG_PATH_CRASHREPORTER = ::rtl::OUString::createFromAscii("CrashReporter"                  );
1452     static const ::rtl::OUString CFG_ENTRY_ENABLED      = ::rtl::OUString::createFromAscii("Enabled"                        );
1453 
1454     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
1455 
1456     sal_Bool bEnabled( sal_True );
1457     if ( xSMGR.is() )
1458     {
1459         css::uno::Any aVal = ::comphelper::ConfigurationHelper::readDirectKey(
1460                                     xSMGR,
1461                                     CFG_PACKAGE_RECOVERY,
1462                                     CFG_PATH_CRASHREPORTER,
1463                                     CFG_ENTRY_ENABLED,
1464                                     ::comphelper::ConfigurationHelper::E_READONLY);
1465         aVal >>= bEnabled;
1466     }
1467     _bCrashReporterEnabled = bEnabled;
1468 }
1469 
1470 sal_Bool Desktop::isUIOnSessionShutdownAllowed()
1471 {
1472     static const ::rtl::OUString CFG_PACKAGE_RECOVERY = ::rtl::OUString::createFromAscii("org.openoffice.Office.Recovery/");
1473     static const ::rtl::OUString CFG_PATH_SESSION     = ::rtl::OUString::createFromAscii("SessionShutdown"                );
1474     static const ::rtl::OUString CFG_ENTRY_UIENABLED  = ::rtl::OUString::createFromAscii("DocumentStoreUIEnabled"         );
1475 
1476     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
1477 
1478     sal_Bool bResult = sal_False;
1479     if ( xSMGR.is() )
1480     {
1481         css::uno::Any aVal = ::comphelper::ConfigurationHelper::readDirectKey(
1482                                     xSMGR,
1483                                     CFG_PACKAGE_RECOVERY,
1484                                     CFG_PATH_SESSION,
1485                                     CFG_ENTRY_UIENABLED,
1486                                     ::comphelper::ConfigurationHelper::E_READONLY);
1487         aVal >>= bResult;
1488     }
1489 
1490     return bResult;
1491 }
1492 
1493 //-----------------------------------------------
1494 /** @short  check if crash reporter feature is enabled or
1495             disabled.
1496 */
1497 sal_Bool Desktop::isCrashReporterEnabled()
1498 {
1499     return _bCrashReporterEnabled;
1500 }
1501 
1502 //-----------------------------------------------
1503 /** @short  check if recovery must be started or not.
1504 
1505     @param  bCrashed [boolean ... out!]
1506             the office crashed last times.
1507             But may be there are no recovery data.
1508             Usefull to trigger the error report tool without
1509             showing the recovery UI.
1510 
1511     @param  bRecoveryDataExists [boolean ... out!]
1512             there exists some recovery data.
1513 
1514     @param  bSessionDataExists [boolean ... out!]
1515             there exists some session data.
1516             Because the user may be logged out last time from it's
1517             unix session...
1518 */
1519 void impl_checkRecoveryState(sal_Bool& bCrashed           ,
1520                              sal_Bool& bRecoveryDataExists,
1521                              sal_Bool& bSessionDataExists )
1522 {
1523     static const ::rtl::OUString SERVICENAME_RECOVERYCORE = ::rtl::OUString::createFromAscii("com.sun.star.frame.AutoRecovery");
1524     static const ::rtl::OUString PROP_CRASHED             = ::rtl::OUString::createFromAscii("Crashed"                        );
1525     static const ::rtl::OUString PROP_EXISTSRECOVERY      = ::rtl::OUString::createFromAscii("ExistsRecoveryData"             );
1526     static const ::rtl::OUString PROP_EXISTSSESSION       = ::rtl::OUString::createFromAscii("ExistsSessionData"              );
1527     static const ::rtl::OUString CFG_PACKAGE_RECOVERY     = ::rtl::OUString::createFromAscii("org.openoffice.Office.Recovery/");
1528     static const ::rtl::OUString CFG_PATH_RECOVERYINFO    = ::rtl::OUString::createFromAscii("RecoveryInfo"                   );
1529 
1530     bCrashed            = sal_False;
1531     bRecoveryDataExists = sal_False;
1532     bSessionDataExists  = sal_False;
1533 
1534     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
1535     try
1536     {
1537         css::uno::Reference< css::beans::XPropertySet > xRecovery(
1538             xSMGR->createInstance(SERVICENAME_RECOVERYCORE),
1539             css::uno::UNO_QUERY_THROW);
1540 
1541         xRecovery->getPropertyValue(PROP_CRASHED       ) >>= bCrashed           ;
1542         xRecovery->getPropertyValue(PROP_EXISTSRECOVERY) >>= bRecoveryDataExists;
1543         xRecovery->getPropertyValue(PROP_EXISTSSESSION ) >>= bSessionDataExists ;
1544     }
1545     catch(const css::uno::Exception&) {}
1546 }
1547 
1548 //-----------------------------------------------
1549 /*  @short  start the recovery wizard.
1550 
1551     @param  bEmergencySave
1552             differs between EMERGENCY_SAVE and RECOVERY
1553 */
1554 sal_Bool impl_callRecoveryUI(sal_Bool bEmergencySave     ,
1555                              sal_Bool bCrashed           ,
1556                              sal_Bool bExistsRecoveryData)
1557 {
1558     static ::rtl::OUString SERVICENAME_RECOVERYUI = ::rtl::OUString::createFromAscii("com.sun.star.comp.svx.RecoveryUI"          );
1559     static ::rtl::OUString SERVICENAME_URLPARSER  = ::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer"          );
1560     static ::rtl::OUString COMMAND_EMERGENCYSAVE  = ::rtl::OUString::createFromAscii("vnd.sun.star.autorecovery:/doEmergencySave");
1561     static ::rtl::OUString COMMAND_RECOVERY       = ::rtl::OUString::createFromAscii("vnd.sun.star.autorecovery:/doAutoRecovery" );
1562     static ::rtl::OUString COMMAND_CRASHREPORT    = ::rtl::OUString::createFromAscii("vnd.sun.star.autorecovery:/doCrashReport"  );
1563 
1564     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
1565 
1566     css::uno::Reference< css::frame::XSynchronousDispatch > xRecoveryUI(
1567         xSMGR->createInstance(SERVICENAME_RECOVERYUI),
1568         css::uno::UNO_QUERY_THROW);
1569 
1570     css::uno::Reference< css::util::XURLTransformer > xURLParser(
1571         xSMGR->createInstance(SERVICENAME_URLPARSER),
1572         css::uno::UNO_QUERY_THROW);
1573 
1574     css::util::URL aURL;
1575     if (bEmergencySave)
1576         aURL.Complete = COMMAND_EMERGENCYSAVE;
1577     else
1578     {
1579         if (bExistsRecoveryData)
1580             aURL.Complete = COMMAND_RECOVERY;
1581         else
1582         if (bCrashed && Desktop::isCrashReporterEnabled() )
1583             aURL.Complete = COMMAND_CRASHREPORT;
1584     }
1585 
1586     sal_Bool bRet = sal_False;
1587     if ( aURL.Complete.getLength() > 0 )
1588     {
1589         xURLParser->parseStrict(aURL);
1590 
1591         css::uno::Any aRet = xRecoveryUI->dispatchWithReturnValue(aURL, css::uno::Sequence< css::beans::PropertyValue >());
1592         aRet >>= bRet;
1593     }
1594     return bRet;
1595 }
1596 
1597 /*
1598  * Save all open documents so they will be reopened
1599  * the next time the application ist started
1600  *
1601  * returns sal_True if at least one document could be saved...
1602  *
1603  */
1604 
1605 sal_Bool Desktop::_bTasksSaved = sal_False;
1606 
1607 sal_Bool Desktop::SaveTasks()
1608 {
1609     return impl_callRecoveryUI(
1610         sal_True , // sal_True => force emergency save
1611         sal_False, // 2. and 3. param not used if 1. = true!
1612         sal_False);
1613 }
1614 
1615 namespace {
1616 
1617 void restartOnMac(bool passArguments) {
1618 #if defined MACOSX
1619     OfficeIPCThread::DisableOfficeIPCThread();
1620     rtl::OUString execUrl;
1621     OSL_VERIFY(osl_getExecutableFile(&execUrl.pData) == osl_Process_E_None);
1622     rtl::OUString execPath;
1623     rtl::OString execPath8;
1624     if ((osl::FileBase::getSystemPathFromFileURL(execUrl, execPath)
1625          != osl::FileBase::E_None) ||
1626         !execPath.convertToString(
1627             &execPath8, osl_getThreadTextEncoding(),
1628             (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
1629              RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
1630     {
1631         std::abort();
1632     }
1633     std::vector< rtl::OString > args;
1634     args.push_back(execPath8);
1635     bool wait = false;
1636     if (passArguments) {
1637         sal_uInt32 n = osl_getCommandArgCount();
1638         for (sal_uInt32 i = 0; i < n; ++i) {
1639             rtl::OUString arg;
1640             OSL_VERIFY(osl_getCommandArg(i, &arg.pData) == osl_Process_E_None);
1641             if (arg.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("-accept="))) {
1642                 wait = true;
1643             }
1644             rtl::OString arg8;
1645             if (!arg.convertToString(
1646                     &arg8, osl_getThreadTextEncoding(),
1647                     (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
1648                      RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
1649             {
1650                 std::abort();
1651             }
1652             args.push_back(arg8);
1653         }
1654     }
1655     std::vector< char const * > argPtrs;
1656     for (std::vector< rtl::OString >::iterator i(args.begin()); i != args.end();
1657          ++i)
1658     {
1659         argPtrs.push_back(i->getStr());
1660     }
1661     argPtrs.push_back(0);
1662     execv(execPath8.getStr(), const_cast< char ** >(&argPtrs[0]));
1663     if (errno == ENOTSUP) { // happens when multithreaded on OS X < 10.6
1664         pid_t pid = fork();
1665         if (pid == 0) {
1666             execv(execPath8.getStr(), const_cast< char ** >(&argPtrs[0]));
1667         } else if (pid > 0) {
1668             // Two simultaneously running soffice processes lead to two dock
1669             // icons, so avoid waiting here unless it must be assumed that the
1670             // process invoking soffice itself wants to wait for soffice to
1671             // finish:
1672             if (!wait) {
1673                 return;
1674             }
1675             int stat;
1676             if (waitpid(pid, &stat, 0) == pid && WIFEXITED(stat)) {
1677                 _exit(WEXITSTATUS(stat));
1678             }
1679         }
1680     }
1681     std::abort();
1682 #else
1683     (void) passArguments; // avoid warnings
1684 #endif
1685 }
1686 
1687 }
1688 
1689 sal_uInt16 Desktop::Exception(sal_uInt16 nError)
1690 {
1691     // protect against recursive calls
1692     static sal_Bool bInException = sal_False;
1693 
1694     sal_uInt16 nOldMode = Application::GetSystemWindowMode();
1695     Application::SetSystemWindowMode( nOldMode & ~SYSTEMWINDOW_MODE_NOAUTOMODE );
1696     Application::SetDefDialogParent( NULL );
1697 
1698     if ( bInException )
1699     {
1700         String aDoubleExceptionString;
1701         Application::Abort( aDoubleExceptionString );
1702     }
1703 
1704     bInException = sal_True;
1705     CommandLineArgs* pArgs = GetCommandLineArgs();
1706 
1707     // save all modified documents ... if it's allowed doing so.
1708     sal_Bool bRestart                           = sal_False;
1709     sal_Bool bAllowRecoveryAndSessionManagement = (
1710                                                     ( !pArgs->IsNoRestore()                    ) && // some use cases of office must work without recovery
1711                                                     ( !pArgs->IsHeadless()                     ) &&
1712                                                     ( !pArgs->IsServer()                       ) &&
1713                                                     (( nError & EXC_MAJORTYPE ) != EXC_DISPLAY ) && // recovery cant work without UI ... but UI layer seams to be the reason for this crash
1714                                                     ( Application::IsInExecute()               )    // crashes during startup and shutdown should be ignored (they indicates a corrupt installation ...)
1715                                                   );
1716     if ( bAllowRecoveryAndSessionManagement )
1717         bRestart = SaveTasks();
1718 
1719     FlushConfiguration();
1720 
1721     switch( nError & EXC_MAJORTYPE )
1722     {
1723         case EXC_RSCNOTLOADED:
1724         {
1725             String aResExceptionString;
1726             Application::Abort( aResExceptionString );
1727             break;
1728         }
1729 
1730         case EXC_SYSOBJNOTCREATED:
1731         {
1732             String aSysResExceptionString;
1733             Application::Abort( aSysResExceptionString );
1734             break;
1735         }
1736 
1737         default:
1738         {
1739             if (m_pLockfile != NULL) {
1740                 m_pLockfile->clean();
1741             }
1742             if( bRestart )
1743             {
1744                 OfficeIPCThread::DisableOfficeIPCThread();
1745                 if( pSignalHandler )
1746                     DELETEZ( pSignalHandler );
1747                 restartOnMac(false);
1748                 _exit( ExitHelper::E_CRASH_WITH_RESTART );
1749             }
1750             else
1751             {
1752                 Application::Abort( String() );
1753             }
1754 
1755             break;
1756         }
1757     }
1758 
1759     OSL_ASSERT(false); // unreachable
1760     return 0;
1761 }
1762 
1763 void Desktop::AppEvent( const ApplicationEvent& rAppEvent )
1764 {
1765     HandleAppEvent( rAppEvent );
1766 }
1767 
1768 struct ExecuteGlobals
1769 {
1770 	Reference < css::document::XEventListener > xGlobalBroadcaster;
1771 	sal_Bool bRestartRequested;
1772 	sal_Bool bUseSystemFileDialog;
1773 	std::auto_ptr<SvtLanguageOptions> pLanguageOptions;
1774     std::auto_ptr<SvtPathOptions> pPathOptions;
1775 
1776     ExecuteGlobals()
1777     : bRestartRequested( sal_False )
1778     , bUseSystemFileDialog( sal_True )
1779     {}
1780 };
1781 
1782 static ExecuteGlobals* pExecGlobals = NULL;
1783 
1784 void Desktop::Main()
1785 {
1786     pExecGlobals = new ExecuteGlobals();
1787 
1788     RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::Main" );
1789 
1790     // Remember current context object
1791     com::sun::star::uno::ContextLayer layer(
1792         com::sun::star::uno::getCurrentContext() );
1793 
1794     BootstrapError eError = GetBootstrapError();
1795     if ( eError != BE_OK )
1796     {
1797         HandleBootstrapErrors( eError );
1798         return;
1799     }
1800 
1801     BootstrapStatus eStatus = GetBootstrapStatus();
1802     if (eStatus == BS_TERMINATE) {
1803         return;
1804     }
1805 
1806     // Detect desktop environment - need to do this as early as possible
1807     com::sun::star::uno::setCurrentContext(
1808         new DesktopContext( com::sun::star::uno::getCurrentContext() ) );
1809 
1810     CommandLineArgs* pCmdLineArgs = GetCommandLineArgs();
1811 
1812     // setup configuration error handling
1813     ConfigurationErrorHandler aConfigErrHandler;
1814     if (!ShouldSuppressUI(pCmdLineArgs))
1815         aConfigErrHandler.activate();
1816 
1817     ResMgr::SetReadStringHook( ReplaceStringHookProc );
1818 
1819     // Startup screen
1820     RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main { OpenSplashScreen" );
1821     OpenSplashScreen();
1822     RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main } OpenSplashScreen" );
1823 
1824     {
1825         UserInstall::UserInstallError instErr_fin = UserInstall::finalize();
1826         if ( instErr_fin != UserInstall::E_None)
1827         {
1828             OSL_ENSURE(sal_False, "userinstall failed");
1829             if ( instErr_fin == UserInstall::E_NoDiskSpace )
1830                 HandleBootstrapErrors( BE_USERINSTALL_NOTENOUGHDISKSPACE );
1831             else if ( instErr_fin == UserInstall::E_NoWriteAccess )
1832                 HandleBootstrapErrors( BE_USERINSTALL_NOWRITEACCESS );
1833             else
1834                 HandleBootstrapErrors( BE_USERINSTALL_FAILED );
1835             return;
1836         }
1837         // refresh path information
1838         utl::Bootstrap::reloadData();
1839         SetSplashScreenProgress(25);
1840     }
1841 
1842     Reference< XMultiServiceFactory > xSMgr =
1843         ::comphelper::getProcessServiceFactory();
1844 
1845     Reference< ::com::sun::star::task::XRestartManager > xRestartManager;
1846     int         nAcquireCount( 0 );
1847     try
1848     {
1849         RegisterServices( xSMgr );
1850 
1851         //SetSplashScreenProgress(15);
1852 
1853 #ifndef UNX
1854         if ( pCmdLineArgs->IsHelp() ) {
1855             displayCmdlineHelp();
1856             return;
1857         }
1858 #endif
1859 
1860         // check user installation directory for lockfile so we can be sure
1861         // there is no other instance using our data files from a remote host
1862         RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main -> Lockfile" );
1863         m_pLockfile = new Lockfile;
1864         if ( !pCmdLineArgs->IsHeadless() && !pCmdLineArgs->IsInvisible() &&
1865              !pCmdLineArgs->IsNoLockcheck() && !m_pLockfile->check( Lockfile_execWarning )) {
1866             // Lockfile exists, and user clicked 'no'
1867             return;
1868         }
1869         RTL_LOGFILE_CONTEXT_TRACE( aLog, "desktop (lo119109) Desktop::Main <- Lockfile" );
1870 
1871         // check if accessibility is enabled but not working and allow to quit
1872         RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ GetEnableATToolSupport" );
1873         if( Application::GetSettings().GetMiscSettings().GetEnableATToolSupport() )
1874         {
1875             sal_Bool bQuitApp;
1876 
1877             if( !InitAccessBridge( true, bQuitApp ) )
1878                 if( bQuitApp )
1879                     return;
1880         }
1881         RTL_LOGFILE_CONTEXT_TRACE( aLog, "} GetEnableATToolSupport" );
1882 
1883         // terminate if requested...
1884         if( pCmdLineArgs->IsTerminateAfterInit() ) return;
1885 
1886         //  Read the common configuration items for optimization purpose
1887         if ( !InitializeConfiguration() ) return;
1888 
1889         //SetSplashScreenProgress(20);
1890 
1891         // set static variable to enabled/disable crash reporter
1892         retrieveCrashReporterState();
1893         if ( !isCrashReporterEnabled() )
1894         {
1895             osl_setErrorReporting( sal_False );
1896             // disable stack trace feature
1897         }
1898 
1899         // create title string
1900         sal_Bool bCheckOk = sal_False;
1901         ::com::sun::star::lang::Locale aLocale;
1902         String aMgrName = String::CreateFromAscii( "ofa" );
1903         ResMgr* pLabelResMgr = ResMgr::SearchCreateResMgr( U2S( aMgrName ), aLocale );
1904         String aTitle = pLabelResMgr ? String( ResId( RID_APPTITLE, *pLabelResMgr ) ) : String();
1905         delete pLabelResMgr;
1906 
1907         // Check for StarOffice/Suite specific extensions runs also with OpenOffice installation sets
1908         OUString aTitleString( aTitle );
1909         bCheckOk = CheckInstallation( aTitleString );
1910         if ( !bCheckOk )
1911             return;
1912         else
1913             aTitle = aTitleString;
1914 
1915 #ifdef DBG_UTIL
1916         //include version ID in non product builds
1917         ::rtl::OUString aDefault;
1918         aTitle += DEFINE_CONST_UNICODE(" [");
1919         String aVerId( utl::Bootstrap::getBuildIdData( aDefault ));
1920         aTitle += aVerId;
1921         aTitle += ']';
1922 #endif
1923 
1924         SetDisplayName( aTitle );
1925         RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ create SvtPathOptions and SvtLanguageOptions" );
1926         pExecGlobals->pPathOptions.reset( new SvtPathOptions);
1927         SetSplashScreenProgress(40);
1928         RTL_LOGFILE_CONTEXT_TRACE( aLog, "} create SvtPathOptions and SvtLanguageOptions" );
1929 
1930         // Check special env variable #111015#
1931         std::vector< String > aUnrestrictedFolders;
1932         svt::getUnrestrictedFolders( aUnrestrictedFolders );
1933 
1934         if ( aUnrestrictedFolders.size() > 0 )
1935         {
1936             // Set different working directory. The first entry is
1937             // the new work path.
1938             String aWorkPath = aUnrestrictedFolders[0];
1939             SvtPathOptions().SetWorkPath( aWorkPath );
1940         }
1941 
1942 	    // create service for loadin SFX (still needed in startup)
1943         pExecGlobals->xGlobalBroadcaster = Reference < css::document::XEventListener >
1944 			( xSMgr->createInstance(
1945             DEFINE_CONST_UNICODE( "com.sun.star.frame.GlobalEventBroadcaster" ) ), UNO_QUERY );
1946 
1947         /* ensure existance of a default window that messages can be dispatched to
1948            This is for the benefit of testtool which uses PostUserEvent extensively
1949            and else can deadlock while creating this window from another tread while
1950            the main thread is not yet in the event loop.
1951         */
1952         Application::GetDefaultDevice();
1953 
1954         // initialize test-tool library (if available)
1955         RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ tools::InitTestToolLib" );
1956         tools::InitTestToolLib();
1957         RTL_LOGFILE_CONTEXT_TRACE( aLog, "} tools::InitTestToolLib" );
1958 
1959         // Check if bundled or shared extensions were added /removed
1960         // and process those extensions (has to be done before checking
1961         // the extension dependencies!
1962         SynchronizeExtensionRepositories();
1963         bool bAbort = CheckExtensionDependencies();
1964         if ( bAbort )
1965             return;
1966 
1967         {
1968             ::comphelper::ComponentContext aContext( xSMgr );
1969             xRestartManager.set( aContext.getSingleton( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.OfficeRestartManager" ) ) ), UNO_QUERY );
1970         }
1971 
1972 		// check whether the shutdown is caused by restart
1973 		pExecGlobals->bRestartRequested = ( xRestartManager.is() && xRestartManager->isRestartRequested( sal_True ) );
1974 
1975         // First Start Wizard allowed ?
1976         if ( ! pCmdLineArgs->IsNoFirstStartWizard() && !pExecGlobals->bRestartRequested )
1977         {
1978             RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ FirstStartWizard" );
1979 
1980             if (IsFirstStartWizardNeeded())
1981             {
1982                 Reference< XJob > xFirstStartJob( xSMgr->createInstance(
1983                     DEFINE_CONST_UNICODE( "com.sun.star.comp.desktop.FirstStart" ) ), UNO_QUERY );
1984                 if (xFirstStartJob.is())
1985                 {
1986                    // mark first start as done
1987                    FinishFirstStart();
1988                 }
1989             }
1990 
1991             RTL_LOGFILE_CONTEXT_TRACE( aLog, "} FirstStartWizard" );
1992         }
1993 
1994         // process non-pre-registered extensions
1995         installBundledExtensionBlobs();
1996 
1997 		// keep a language options instance...
1998 		pExecGlobals->pLanguageOptions.reset( new SvtLanguageOptions(sal_True));
1999 
2000         if (pExecGlobals->xGlobalBroadcaster.is())
2001         {
2002             css::document::EventObject aEvent;
2003             aEvent.EventName = ::rtl::OUString::createFromAscii("OnStartApp");
2004             pExecGlobals->xGlobalBroadcaster->notifyEvent(aEvent);
2005         }
2006 
2007         SetSplashScreenProgress(50);
2008 
2009         // Backing Component
2010         sal_Bool bCrashed            = sal_False;
2011         sal_Bool bExistsRecoveryData = sal_False;
2012         sal_Bool bExistsSessionData  = sal_False;
2013 
2014         RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ impl_checkRecoveryState" );
2015         impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData);
2016         RTL_LOGFILE_CONTEXT_TRACE( aLog, "} impl_checkRecoveryState" );
2017 
2018         {
2019             ::comphelper::ComponentContext aContext( xSMgr );
2020             xRestartManager.set( aContext.getSingleton( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.OfficeRestartManager" ) ) ), UNO_QUERY );
2021         }
2022 
2023         // check whether the shutdown is caused by restart
2024         pExecGlobals->bRestartRequested = ( xRestartManager.is() && xRestartManager->isRestartRequested( sal_True ) );
2025 
2026         if ( pCmdLineArgs->IsHeadless() )
2027         {
2028             // Ensure that we use not the system file dialogs as
2029             // headless mode relies on Application::EnableHeadlessMode()
2030             // which does only work for VCL dialogs!!
2031             SvtMiscOptions aMiscOptions;
2032             pExecGlobals->bUseSystemFileDialog = aMiscOptions.UseSystemFileDialog();
2033             aMiscOptions.SetUseSystemFileDialog( sal_False );
2034         }
2035 
2036         if ( !pExecGlobals->bRestartRequested )
2037         {
2038             if ((!pCmdLineArgs->WantsToLoadDocument() && !pCmdLineArgs->IsInvisible() && !pCmdLineArgs->IsHeadless() && !pCmdLineArgs->IsQuickstart()) &&
2039                 (SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SSTARTMODULE)) &&
2040                 (!bExistsRecoveryData                                                  ) &&
2041                 (!bExistsSessionData                                                   ) &&
2042                 (!Application::AnyInput( INPUT_APPEVENT )                              ))
2043             {
2044                  RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ create BackingComponent" );
2045                  Reference< XFrame > xDesktopFrame( xSMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ))), UNO_QUERY );
2046                  if (xDesktopFrame.is())
2047                  {
2048                    Reference< XFrame > xBackingFrame;
2049                    Reference< ::com::sun::star::awt::XWindow > xContainerWindow;
2050 
2051                    xBackingFrame = xDesktopFrame->findFrame(OUString( RTL_CONSTASCII_USTRINGPARAM( "_blank" )), 0);
2052                    if (xBackingFrame.is())
2053                        xContainerWindow = xBackingFrame->getContainerWindow();
2054                    if (xContainerWindow.is())
2055                    {
2056                        // set the WB_EXT_DOCUMENT style. Normally, this is done by the TaskCreator service when a "_blank"
2057                        // frame/window is created. Since we do not use the TaskCreator here, we need to mimic its behavior,
2058                        // otherwise documents loaded into this frame will later on miss functionality depending on the style.
2059                        Window* pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
2060                        OSL_ENSURE( pContainerWindow, "Desktop::Main: no implementation access to the frame's container window!" );
2061                        pContainerWindow->SetExtendedStyle( pContainerWindow->GetExtendedStyle() | WB_EXT_DOCUMENT );
2062 
2063                        SetSplashScreenProgress(75);
2064                        Sequence< Any > lArgs(1);
2065                        lArgs[0] <<= xContainerWindow;
2066 
2067                        Reference< XController > xBackingComp(
2068                            xSMgr->createInstanceWithArguments(OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.StartModule") ), lArgs), UNO_QUERY);
2069                         if (xBackingComp.is())
2070                         {
2071                             Reference< ::com::sun::star::awt::XWindow > xBackingWin(xBackingComp, UNO_QUERY);
2072                             // Attention: You MUST(!) call setComponent() before you call attachFrame().
2073                             // Because the backing component set the property "IsBackingMode" of the frame
2074                             // to true inside attachFrame(). But setComponent() reset this state everytimes ...
2075                             xBackingFrame->setComponent(xBackingWin, xBackingComp);
2076                             SetSplashScreenProgress(100);
2077                             xBackingComp->attachFrame(xBackingFrame);
2078                             CloseSplashScreen();
2079                             xContainerWindow->setVisible(sal_True);
2080                         }
2081                     }
2082                 }
2083                 RTL_LOGFILE_CONTEXT_TRACE( aLog, "} create BackingComponent" );
2084             }
2085         }
2086     }
2087     catch ( com::sun::star::lang::WrappedTargetException& wte )
2088     {
2089         com::sun::star::uno::Exception te;
2090         wte.TargetException >>= te;
2091         FatalError( MakeStartupConfigAccessErrorMessage(wte.Message + te.Message) );
2092         return;
2093     }
2094     catch ( com::sun::star::uno::Exception& e )
2095     {
2096         FatalError( MakeStartupErrorMessage(e.Message) );
2097         return;
2098     }
2099 
2100     SvtFontSubstConfig().Apply();
2101 
2102     SvtTabAppearanceCfg aAppearanceCfg;
2103     aAppearanceCfg.SetInitialized();
2104     aAppearanceCfg.SetApplicationDefaults( this );
2105     SvtAccessibilityOptions aOptions;
2106     aOptions.SetVCLSettings();
2107 
2108     if ( !pExecGlobals->bRestartRequested )
2109 	{
2110 		Application::SetFilterHdl( LINK( this, Desktop, ImplInitFilterHdl ) );
2111         sal_Bool bTerminateRequested = sal_False;
2112 
2113         // Preload function depends on an initialized sfx application!
2114         SetSplashScreenProgress(75);
2115 
2116         // use system window dialogs
2117         Application::SetSystemWindowMode( SYSTEMWINDOW_MODE_DIALOG );
2118 
2119     //    SetSplashScreenProgress(80);
2120 
2121         if ( !bTerminateRequested && !pCmdLineArgs->IsInvisible() &&
2122              !pCmdLineArgs->IsNoQuickstart() )
2123             InitializeQuickstartMode( xSMgr );
2124 
2125         RTL_LOGFILE_CONTEXT( aLog2, "desktop (cd100003) createInstance com.sun.star.frame.Desktop" );
2126         try
2127         {
2128             Reference< XDesktop > xDesktop( xSMgr->createInstance(
2129                 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ))), UNO_QUERY );
2130             if ( xDesktop.is() )
2131                 xDesktop->addTerminateListener( new OfficeIPCThreadController );
2132             SetSplashScreenProgress(100);
2133         }
2134         catch ( com::sun::star::uno::Exception& e )
2135         {
2136             FatalError( MakeStartupErrorMessage(e.Message) );
2137             return;
2138         }
2139 
2140         // Post user event to startup first application component window
2141         // We have to send this OpenClients message short before execute() to
2142         // minimize the risk that this message overtakes type detection contruction!!
2143         Application::PostUserEvent( LINK( this, Desktop, OpenClients_Impl ) );
2144 
2145         // Post event to enable acceptors
2146         Application::PostUserEvent( LINK( this, Desktop, EnableAcceptors_Impl) );
2147 
2148         // The configuration error handler currently is only for startup
2149         aConfigErrHandler.deactivate();
2150 
2151        // Acquire solar mutex just before we enter our message loop
2152         if ( nAcquireCount )
2153             Application::AcquireSolarMutex( nAcquireCount );
2154 
2155         // call Application::Execute to process messages in vcl message loop
2156         RTL_LOGFILE_PRODUCT_TRACE( "PERFORMANCE - enter Application::Execute()" );
2157 
2158         try
2159         {
2160             // The JavaContext contains an interaction handler which is used when
2161             // the creation of a Java Virtual Machine fails
2162             com::sun::star::uno::ContextLayer layer2(
2163                 new svt::JavaContext( com::sun::star::uno::getCurrentContext() ) );
2164 
2165             // check whether the shutdown is caused by restart just before entering the Execute
2166             pExecGlobals->bRestartRequested = pExecGlobals->bRestartRequested || ( xRestartManager.is() && xRestartManager->isRestartRequested( sal_True ) );
2167 
2168             if ( !pExecGlobals->bRestartRequested )
2169             {
2170                 // if this run of the office is triggered by restart, some additional actions should be done
2171                 DoRestartActionsIfNecessary( !pCmdLineArgs->IsInvisible() && !pCmdLineArgs->IsNoQuickstart() );
2172 
2173                 Execute();
2174             }
2175 		}
2176 		catch(const com::sun::star::document::CorruptedFilterConfigurationException& exFilterCfg)
2177 		{
2178 			OfficeIPCThread::SetDowning();
2179 			FatalError( MakeStartupErrorMessage(exFilterCfg.Message) );
2180 		}
2181 		catch(const com::sun::star::configuration::CorruptedConfigurationException& exAnyCfg)
2182 		{
2183 			OfficeIPCThread::SetDowning();
2184 			FatalError( MakeStartupErrorMessage(exAnyCfg.Message) );
2185 		}
2186 	}
2187 	// CAUTION: you do not necessarily get here e.g. on the Mac.
2188 	// please put all deinitialization code into doShutdown
2189 	doShutdown();
2190 }
2191 
2192 void Desktop::doShutdown()
2193 {
2194     if( ! pExecGlobals )
2195         return;
2196 
2197     if ( pExecGlobals->bRestartRequested )
2198         SetRestartState();
2199 
2200 	if (pExecGlobals->xGlobalBroadcaster.is())
2201     {
2202         css::document::EventObject aEvent;
2203         aEvent.EventName = ::rtl::OUString::createFromAscii("OnCloseApp");
2204         pExecGlobals->xGlobalBroadcaster->notifyEvent(aEvent);
2205     }
2206 
2207 	delete pResMgr, pResMgr = NULL;
2208     // Restore old value
2209     CommandLineArgs* pCmdLineArgs = GetCommandLineArgs();
2210     if ( pCmdLineArgs->IsHeadless() )
2211         SvtMiscOptions().SetUseSystemFileDialog( pExecGlobals->bUseSystemFileDialog );
2212 
2213     // remove temp directory
2214     RemoveTemporaryDirectory();
2215     FlushConfiguration();
2216     // The acceptors in the AcceptorMap must be released (in DeregisterServices)
2217     // with the solar mutex unlocked, to avoid deadlock:
2218     sal_uLong nAcquireCount = Application::ReleaseSolarMutex();
2219     DeregisterServices();
2220     Application::AcquireSolarMutex(nAcquireCount);
2221     tools::DeInitTestToolLib();
2222     // be sure that path/language options gets destroyed before
2223     // UCB is deinitialized
2224     RTL_LOGFILE_CONTEXT_TRACE( aLog, "-> dispose path/language options" );
2225     pExecGlobals->pLanguageOptions.reset( 0 );
2226     pExecGlobals->pPathOptions.reset( 0 );
2227     RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- dispose path/language options" );
2228 
2229     RTL_LOGFILE_CONTEXT_TRACE( aLog, "-> deinit ucb" );
2230     ::ucbhelper::ContentBroker::deinitialize();
2231     RTL_LOGFILE_CONTEXT_TRACE( aLog, "<- deinit ucb" );
2232 
2233     sal_Bool bRR = pExecGlobals->bRestartRequested;
2234     delete pExecGlobals, pExecGlobals = NULL;
2235 
2236     RTL_LOGFILE_CONTEXT_TRACE( aLog, "FINISHED WITH Destop::Main" );
2237     if ( bRR )
2238     {
2239         restartOnMac(true);
2240         // wouldn't the solution be more clean if SalMain returns the exit code to the system?
2241         _exit( ExitHelper::E_NORMAL_RESTART );
2242     }
2243 }
2244 
2245 IMPL_LINK( Desktop, ImplInitFilterHdl, ConvertData*, pData )
2246 {
2247     return GraphicFilter::GetGraphicFilter()->GetFilterCallback().Call( pData );
2248 }
2249 
2250 sal_Bool Desktop::InitializeConfiguration()
2251 {
2252     sal_Bool bOk = sal_False;
2253 
2254     try
2255     {
2256         bOk = InitConfiguration();
2257     }
2258     catch( ::com::sun::star::lang::ServiceNotRegisteredException& )
2259     {
2260         this->HandleBootstrapErrors( Desktop::BE_UNO_SERVICE_CONFIG_MISSING );
2261     }
2262     catch( ::com::sun::star::configuration::MissingBootstrapFileException& e )
2263     {
2264         OUString aMsg( CreateErrorMsgString( utl::Bootstrap::MISSING_BOOTSTRAP_FILE,
2265                                                 e.BootstrapFileURL ));
2266         HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_USER_INSTALL, aMsg );
2267     }
2268     catch( ::com::sun::star::configuration::InvalidBootstrapFileException& e )
2269     {
2270         OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY,
2271                                                 e.BootstrapFileURL ));
2272         HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg );
2273     }
2274     catch( ::com::sun::star::configuration::InstallationIncompleteException& )
2275     {
2276         OUString aVersionFileURL;
2277         OUString aMsg;
2278         utl::Bootstrap::PathStatus aPathStatus = utl::Bootstrap::locateVersionFile( aVersionFileURL );
2279         if ( aPathStatus == utl::Bootstrap::PATH_EXISTS )
2280             aMsg = CreateErrorMsgString( utl::Bootstrap::MISSING_VERSION_FILE_ENTRY, aVersionFileURL );
2281         else
2282             aMsg = CreateErrorMsgString( utl::Bootstrap::MISSING_VERSION_FILE, aVersionFileURL );
2283 
2284         HandleBootstrapPathErrors( ::utl::Bootstrap::MISSING_USER_INSTALL, aMsg );
2285     }
2286     catch ( com::sun::star::configuration::backend::BackendAccessException& exception)
2287     {
2288         // [cm122549] It is assumed in this case that the message
2289         // coming from InitConfiguration (in fact CreateApplicationConf...)
2290         // is suitable for display directly.
2291         FatalError( MakeStartupErrorMessage( exception.Message ) );
2292     }
2293     catch ( com::sun::star::configuration::backend::BackendSetupException& exception)
2294     {
2295         // [cm122549] It is assumed in this case that the message
2296         // coming from InitConfiguration (in fact CreateApplicationConf...)
2297         // is suitable for display directly.
2298         FatalError( MakeStartupErrorMessage( exception.Message ) );
2299     }
2300     catch ( ::com::sun::star::configuration::CannotLoadConfigurationException& )
2301     {
2302         OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_DATA,
2303                                                 OUString() ));
2304         HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg );
2305     }
2306     catch( ::com::sun::star::uno::Exception& )
2307     {
2308         OUString aMsg( CreateErrorMsgString( utl::Bootstrap::INVALID_BOOTSTRAP_DATA,
2309                                                 OUString() ));
2310         HandleBootstrapPathErrors( ::utl::Bootstrap::INVALID_BASE_INSTALL, aMsg );
2311     }
2312 
2313     return bOk;
2314 }
2315 
2316 void Desktop::FlushConfiguration()
2317 {
2318     Reference < XFlushable > xCFGFlush( ::utl::ConfigManager::GetConfigManager()->GetConfigurationProvider(), UNO_QUERY );
2319     if (xCFGFlush.is())
2320     {
2321         xCFGFlush->flush();
2322     }
2323     else
2324     {
2325         // because there is no method to flush the condiguration data, we must dispose the ConfigManager
2326         Reference < XComponent > xCFGDispose( ::utl::ConfigManager::GetConfigManager()->GetConfigurationProvider(), UNO_QUERY );
2327         if (xCFGDispose.is())
2328             xCFGDispose->dispose();
2329     }
2330 }
2331 
2332 sal_Bool Desktop::InitializeQuickstartMode( Reference< XMultiServiceFactory >& rSMgr )
2333 {
2334     try
2335     {
2336         // the shutdown icon sits in the systray and allows the user to keep
2337         // the office instance running for quicker restart
2338         // this will only be activated if -quickstart was specified on cmdline
2339         RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) createInstance com.sun.star.office.Quickstart" );
2340 
2341         sal_Bool bQuickstart = GetCommandLineArgs()->IsQuickstart();
2342         if ( !bQuickstart )
2343         {
2344             SfxItemSet aOptSet( SFX_APP()->GetPool(), SID_ATTR_QUICKLAUNCHER, SID_ATTR_QUICKLAUNCHER );
2345             SFX_APP()->GetOptions(aOptSet);
2346             const SfxPoolItem* pItem;
2347             if ( SFX_ITEM_SET == aOptSet.GetItemState( SID_ATTR_QUICKLAUNCHER, sal_False, &pItem ) )
2348                 bQuickstart = ((const SfxBoolItem*)pItem)->GetValue();
2349         }
2350 
2351         Sequence< Any > aSeq( 1 );
2352         aSeq[0] <<= bQuickstart;
2353 
2354         // Try to instanciate quickstart service. This service is not mandatory, so
2355         // do nothing if service is not available
2356 
2357         // #i105753# the following if was invented for performance
2358         // unfortunately this broke the QUARTZ behavior which is to always run
2359         // in quickstart mode since Mac applications do not usually quit
2360         // when the last document closes
2361         #ifndef QUARTZ
2362         if ( bQuickstart )
2363         #endif
2364         {
2365             Reference < XComponent > xQuickstart( rSMgr->createInstanceWithArguments(
2366                                                 DEFINE_CONST_UNICODE( "com.sun.star.office.Quickstart" ), aSeq ),
2367                                                 UNO_QUERY );
2368         }
2369         return sal_True;
2370     }
2371     catch( ::com::sun::star::uno::Exception& )
2372     {
2373         return sal_False;
2374     }
2375 }
2376 
2377 void Desktop::SystemSettingsChanging( AllSettings& rSettings, Window* )
2378 {
2379     if ( !SvtTabAppearanceCfg::IsInitialized () )
2380         return;
2381 
2382 #   define DRAGFULL_OPTION_ALL \
2383          ( DRAGFULL_OPTION_WINDOWMOVE | DRAGFULL_OPTION_WINDOWSIZE  \
2384          | DRAGFULL_OPTION_OBJECTMOVE  | DRAGFULL_OPTION_OBJECTSIZE \
2385          | DRAGFULL_OPTION_DOCKING     | DRAGFULL_OPTION_SPLIT      \
2386          | DRAGFULL_OPTION_SCROLL )
2387 #   define DRAGFULL_OPTION_NONE ((sal_uInt32)~DRAGFULL_OPTION_ALL)
2388 
2389     StyleSettings hStyleSettings   = rSettings.GetStyleSettings();
2390     MouseSettings hMouseSettings = rSettings.GetMouseSettings();
2391 
2392     sal_uInt32 nDragFullOptions = hStyleSettings.GetDragFullOptions();
2393 
2394     SvtTabAppearanceCfg aAppearanceCfg;
2395     sal_uInt16 nGet = aAppearanceCfg.GetDragMode();
2396     switch ( nGet )
2397     {
2398     case DragFullWindow:
2399         nDragFullOptions |= DRAGFULL_OPTION_ALL;
2400         break;
2401     case DragFrame:
2402         nDragFullOptions &= DRAGFULL_OPTION_NONE;
2403         break;
2404     case DragSystemDep:
2405     default:
2406         break;
2407     }
2408 
2409     sal_uInt32 nFollow = hMouseSettings.GetFollow();
2410     hMouseSettings.SetFollow( aAppearanceCfg.IsMenuMouseFollow() ? (nFollow|MOUSE_FOLLOW_MENU) : (nFollow&~MOUSE_FOLLOW_MENU));
2411     rSettings.SetMouseSettings(hMouseSettings);
2412 
2413     sal_Bool bUseImagesInMenus = hStyleSettings.GetUseImagesInMenus();
2414 
2415     SvtMenuOptions aMenuOpt;
2416     nGet = aMenuOpt.GetMenuIconsState();
2417     switch ( nGet )
2418     {
2419         case 0:
2420             bUseImagesInMenus = sal_False;
2421             break;
2422         case 1:
2423             bUseImagesInMenus = sal_True;
2424             break;
2425         case 2:
2426         default:
2427             break;
2428     }
2429     hStyleSettings.SetUseImagesInMenus(bUseImagesInMenus);
2430 
2431 	hStyleSettings.SetDragFullOptions( nDragFullOptions );
2432 	rSettings.SetStyleSettings ( hStyleSettings );
2433 }
2434 
2435 // ========================================================================
2436 IMPL_LINK( Desktop, AsyncInitFirstRun, void*, EMPTYARG )
2437 {
2438     DoFirstRunInitializations();
2439     return 0L;
2440 }
2441 
2442 // ========================================================================
2443 
2444 class ExitTimer : public Timer
2445 {
2446   public:
2447     ExitTimer()
2448     {
2449         SetTimeout(500);
2450         Start();
2451     }
2452     virtual void Timeout()
2453     {
2454         exit(42);
2455     }
2456 };
2457 
2458 IMPL_LINK( Desktop, OpenClients_Impl, void*, EMPTYARG )
2459 {
2460     RTL_LOGFILE_PRODUCT_CONTEXT( aLog, "PERFORMANCE - DesktopOpenClients_Impl()" );
2461 
2462     OpenClients();
2463 
2464     OfficeIPCThread::SetReady();
2465 
2466     // CloseStartupScreen();
2467     CloseSplashScreen();
2468     CheckFirstRun( );
2469     EnableOleAutomation();
2470 
2471     if (getenv ("OOO_EXIT_POST_STARTUP"))
2472         new ExitTimer();
2473     return 0;
2474 }
2475 
2476 // enable acceptos
2477 IMPL_LINK( Desktop, EnableAcceptors_Impl, void*, EMPTYARG )
2478 {
2479     enableAcceptors();
2480     return 0;
2481 }
2482 
2483 
2484 // Registers a COM class factory of the service manager with the windows operating system.
2485 void Desktop::EnableOleAutomation()
2486 {
2487       RTL_LOGFILE_CONTEXT( aLog, "desktop (jl97489) ::Desktop::EnableOleAutomation" );
2488 #ifdef WNT
2489     Reference< XMultiServiceFactory > xSMgr=  comphelper::getProcessServiceFactory();
2490     xSMgr->createInstance(DEFINE_CONST_UNICODE("com.sun.star.bridge.OleApplicationRegistration"));
2491     xSMgr->createInstance(DEFINE_CONST_UNICODE("com.sun.star.comp.ole.EmbedServer"));
2492 #endif
2493 }
2494 
2495 sal_Bool Desktop::CheckOEM()
2496 {
2497     Reference<XMultiServiceFactory> rFactory = ::comphelper::getProcessServiceFactory();
2498     Reference<XJob> rOemJob(rFactory->createInstance(
2499         OUString::createFromAscii("com.sun.star.office.OEMPreloadJob")),
2500         UNO_QUERY );
2501     Sequence<NamedValue> args;
2502     sal_Bool bResult = sal_False;
2503     if (rOemJob.is()) {
2504         Any aResult = rOemJob->execute(args);
2505         aResult >>= bResult;
2506         return bResult;
2507     } else {
2508         return sal_True;
2509     }
2510 }
2511 
2512 void Desktop::PreloadModuleData( CommandLineArgs* pArgs )
2513 {
2514     Reference< XMultiServiceFactory > rFactory = ::comphelper::getProcessServiceFactory();
2515 
2516     Sequence < com::sun::star::beans::PropertyValue > args(1);
2517     args[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Hidden"));
2518     args[0].Value <<= sal_True;
2519     Reference < XComponentLoader > xLoader( ::comphelper::getProcessServiceFactory()->createInstance(
2520         ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ), UNO_QUERY );
2521 
2522     if ( !xLoader.is() )
2523         return;
2524 
2525     if ( pArgs->IsWriter() )
2526     {
2527         try
2528         {
2529             Reference < ::com::sun::star::util::XCloseable > xDoc( xLoader->loadComponentFromURL( DEFINE_CONST_UNICODE("private:factory/swriter"),
2530                 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0, args ), UNO_QUERY_THROW );
2531             xDoc->close( sal_False );
2532         }
2533         catch ( com::sun::star::uno::Exception& )
2534         {
2535         }
2536     }
2537     if ( pArgs->IsCalc() )
2538     {
2539         try
2540         {
2541             Reference < ::com::sun::star::util::XCloseable > xDoc( xLoader->loadComponentFromURL( DEFINE_CONST_UNICODE("private:factory/scalc"),
2542                 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0, args ), UNO_QUERY_THROW );
2543             xDoc->close( sal_False );
2544         }
2545         catch ( com::sun::star::uno::Exception& )
2546         {
2547         }
2548     }
2549     if ( pArgs->IsDraw() )
2550     {
2551         try
2552         {
2553             Reference < ::com::sun::star::util::XCloseable > xDoc( xLoader->loadComponentFromURL( DEFINE_CONST_UNICODE("private:factory/sdraw"),
2554                 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0, args ), UNO_QUERY_THROW );
2555             xDoc->close( sal_False );
2556         }
2557         catch ( com::sun::star::uno::Exception& )
2558         {
2559         }
2560     }
2561     if ( pArgs->IsImpress() )
2562     {
2563         try
2564         {
2565             Reference < ::com::sun::star::util::XCloseable > xDoc( xLoader->loadComponentFromURL( DEFINE_CONST_UNICODE("private:factory/simpress"),
2566                 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_blank")), 0, args ), UNO_QUERY_THROW );
2567             xDoc->close( sal_False );
2568         }
2569         catch ( com::sun::star::uno::Exception& )
2570         {
2571         }
2572     }
2573 }
2574 
2575 void Desktop::PreloadConfigurationData()
2576 {
2577     Reference< XMultiServiceFactory > rFactory = ::comphelper::getProcessServiceFactory();
2578     Reference< XNameAccess > xNameAccess( rFactory->createInstance(
2579         DEFINE_CONST_UNICODE( "com.sun.star.frame.UICommandDescription" )), UNO_QUERY );
2580 
2581     rtl::OUString aWriterDoc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextDocument" ));
2582     rtl::OUString aCalcDoc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.SpreadsheetDocument" ));
2583     rtl::OUString aDrawDoc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.DrawingDocument" ));
2584     rtl::OUString aImpressDoc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.PresentationDocument" ));
2585 
2586     // preload commands configuration
2587     if ( xNameAccess.is() )
2588     {
2589         Any a;
2590         Reference< XNameAccess > xCmdAccess;
2591 
2592         try
2593         {
2594             a = xNameAccess->getByName( aWriterDoc );
2595             a >>= xCmdAccess;
2596             if ( xCmdAccess.is() )
2597             {
2598                 xCmdAccess->getByName( DEFINE_CONST_UNICODE( ".uno:BasicShapes" ));
2599                 xCmdAccess->getByName( DEFINE_CONST_UNICODE( ".uno:EditGlossary" ));
2600             }
2601         }
2602         catch ( ::com::sun::star::uno::Exception& )
2603         {
2604         }
2605 
2606         try
2607         {
2608             a = xNameAccess->getByName( aCalcDoc );
2609             a >>= xCmdAccess;
2610             if ( xCmdAccess.is() )
2611                 xCmdAccess->getByName( DEFINE_CONST_UNICODE( ".uno:InsertObjectStarMath" ));
2612         }
2613         catch ( ::com::sun::star::uno::Exception& )
2614         {
2615         }
2616 
2617         try
2618         {
2619             // draw and impress share the same configuration file (DrawImpressCommands.xcu)
2620             a = xNameAccess->getByName( aDrawDoc );
2621             a >>= xCmdAccess;
2622             if ( xCmdAccess.is() )
2623                 xCmdAccess->getByName( DEFINE_CONST_UNICODE( ".uno:Polygon" ));
2624         }
2625         catch ( ::com::sun::star::uno::Exception& )
2626         {
2627         }
2628     }
2629 
2630     // preload window state configuration
2631     xNameAccess = Reference< XNameAccess >( rFactory->createInstance(
2632                     DEFINE_CONST_UNICODE( "com.sun.star.ui.WindowStateConfiguration" )), UNO_QUERY );
2633     if ( xNameAccess.is() )
2634     {
2635         Any a;
2636         Reference< XNameAccess > xWindowAccess;
2637         try
2638         {
2639             a = xNameAccess->getByName( aWriterDoc );
2640             a >>= xWindowAccess;
2641             if ( xWindowAccess.is() )
2642                 xWindowAccess->getByName( DEFINE_CONST_UNICODE( "private:resource/toolbar/standardbar" ));
2643         }
2644         catch ( ::com::sun::star::uno::Exception& )
2645         {
2646         }
2647         try
2648         {
2649             a = xNameAccess->getByName( aCalcDoc );
2650             a >>= xWindowAccess;
2651             if ( xWindowAccess.is() )
2652                 xWindowAccess->getByName( DEFINE_CONST_UNICODE( "private:resource/toolbar/standardbar" ));
2653         }
2654         catch ( ::com::sun::star::uno::Exception& )
2655         {
2656         }
2657         try
2658         {
2659             a = xNameAccess->getByName( aDrawDoc );
2660             a >>= xWindowAccess;
2661             if ( xWindowAccess.is() )
2662                 xWindowAccess->getByName( DEFINE_CONST_UNICODE( "private:resource/toolbar/standardbar" ));
2663         }
2664         catch ( ::com::sun::star::uno::Exception& )
2665         {
2666         }
2667         try
2668         {
2669             a = xNameAccess->getByName( aImpressDoc );
2670             a >>= xWindowAccess;
2671             if ( xWindowAccess.is() )
2672                 xWindowAccess->getByName( DEFINE_CONST_UNICODE( "private:resource/toolbar/standardbar" ));
2673         }
2674         catch ( ::com::sun::star::uno::Exception& )
2675         {
2676         }
2677     }
2678 
2679     // preload user interface element factories
2680     Sequence< Sequence< css::beans::PropertyValue > > aSeqSeqPropValue;
2681     Reference< ::com::sun::star::ui::XUIElementFactoryRegistration > xUIElementFactory(
2682         rFactory->createInstance(
2683             DEFINE_CONST_UNICODE( "com.sun.star.ui.UIElementFactoryManager" )),
2684             UNO_QUERY );
2685     if ( xUIElementFactory.is() )
2686     {
2687         try
2688         {
2689             aSeqSeqPropValue = xUIElementFactory->getRegisteredFactories();
2690         }
2691         catch ( ::com::sun::star::uno::Exception& )
2692         {
2693         }
2694     }
2695 
2696     // preload popup menu controller factories. As all controllers are in the same
2697     // configuration file they also get preloaded!
2698     Reference< ::com::sun::star::frame::XUIControllerRegistration > xPopupMenuControllerFactory(
2699         rFactory->createInstance(
2700             DEFINE_CONST_UNICODE( "com.sun.star.frame.PopupMenuControllerFactory" )),
2701             UNO_QUERY );
2702     if ( xPopupMenuControllerFactory.is() )
2703     {
2704         try
2705         {
2706             xPopupMenuControllerFactory->hasController(
2707                         DEFINE_CONST_UNICODE( ".uno:CharFontName" ),
2708                         OUString() );
2709         }
2710         catch ( ::com::sun::star::uno::Exception& )
2711         {
2712         }
2713     }
2714 
2715     // preload filter configuration
2716     Sequence< OUString > aSeq;
2717     xNameAccess = Reference< XNameAccess >( rFactory->createInstance(
2718                     DEFINE_CONST_UNICODE( "com.sun.star.document.FilterFactory" )), UNO_QUERY );
2719     if ( xNameAccess.is() )
2720     {
2721         try
2722         {
2723              aSeq = xNameAccess->getElementNames();
2724         }
2725         catch ( ::com::sun::star::uno::Exception& )
2726         {
2727         }
2728     }
2729 
2730     // preload type detection configuration
2731     xNameAccess = Reference< XNameAccess >( rFactory->createInstance(
2732                     DEFINE_CONST_UNICODE( "com.sun.star.document.TypeDetection" )), UNO_QUERY );
2733     if ( xNameAccess.is() )
2734     {
2735         try
2736         {
2737              aSeq = xNameAccess->getElementNames();
2738         }
2739         catch ( ::com::sun::star::uno::Exception& )
2740         {
2741         }
2742     }
2743 
2744     static const OUString sConfigSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) );
2745     static const OUString sAccessSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" ) );
2746 
2747     // get configuration provider
2748     Reference< XMultiServiceFactory > xConfigProvider;
2749     xConfigProvider = Reference< XMultiServiceFactory > (
2750                 rFactory->createInstance( sConfigSrvc ),UNO_QUERY );
2751 
2752     if ( xConfigProvider.is() )
2753     {
2754         // preload writer configuration
2755         Sequence< Any > theArgs(1);
2756         theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Writer/MailMergeWizard" );
2757         try
2758         {
2759             xNameAccess = Reference< XNameAccess >(
2760                 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
2761         }
2762         catch (::com::sun::star::uno::Exception& )
2763         {
2764         }
2765 
2766         // WriterWeb
2767         theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.WriterWeb/Content" );
2768         try
2769         {
2770             xNameAccess = Reference< XNameAccess >(
2771                 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
2772         }
2773         catch (::com::sun::star::uno::Exception& )
2774         {
2775         }
2776 
2777         // preload compatibility
2778         theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Compatibility/WriterCompatibilityVersion" );
2779         try
2780         {
2781             xNameAccess = Reference< XNameAccess >(
2782                 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
2783         }
2784         catch (::com::sun::star::uno::Exception& )
2785         {
2786         }
2787 
2788         // preload calc configuration
2789         theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Calc/Content" );
2790         try
2791         {
2792             xNameAccess = Reference< XNameAccess >(
2793                 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
2794         }
2795         catch (::com::sun::star::uno::Exception& )
2796         {
2797         }
2798 
2799         // preload impress configuration
2800         theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.UI.Effects/UserInterface" );
2801         try
2802         {
2803             xNameAccess = Reference< XNameAccess >(
2804                 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
2805         }
2806         catch (::com::sun::star::uno::Exception& )
2807         {
2808         }
2809 
2810         theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Impress/Layout" );
2811         try
2812         {
2813             xNameAccess = Reference< XNameAccess >(
2814                 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
2815         }
2816         catch (::com::sun::star::uno::Exception& )
2817         {
2818         }
2819 
2820         // preload draw configuration
2821         theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Draw/Layout" );
2822         try
2823         {
2824             xNameAccess = Reference< XNameAccess >(
2825                 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
2826         }
2827         catch (::com::sun::star::uno::Exception& )
2828         {
2829         }
2830 
2831         // preload ui configuration
2832         theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.UI/FilterClassification" );
2833         try
2834         {
2835             xNameAccess = Reference< XNameAccess >(
2836                 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
2837         }
2838         catch (::com::sun::star::uno::Exception& )
2839         {
2840         }
2841 
2842         // preload addons configuration
2843         theArgs[ 0 ] <<= OUString::createFromAscii( "org.openoffice.Office.Addons/AddonUI" );
2844         try
2845         {
2846             xNameAccess = Reference< XNameAccess >(
2847                 xConfigProvider->createInstanceWithArguments( sAccessSrvc, theArgs ), UNO_QUERY );
2848         }
2849         catch (::com::sun::star::uno::Exception& )
2850         {
2851         }
2852     }
2853 }
2854 
2855 void Desktop::OpenClients()
2856 {
2857 
2858     // check if a document has been recovered - if there is one of if a document was loaded by cmdline, no default document
2859     // should be created
2860     Reference < XComponent > xFirst;
2861     sal_Bool bLoaded = sal_False;
2862 
2863     CommandLineArgs* pArgs = GetCommandLineArgs();
2864     SvtInternalOptions  aInternalOptions;
2865 
2866     Reference<XMultiServiceFactory> rFactory = ::comphelper::getProcessServiceFactory();
2867 
2868     if (!pArgs->IsQuickstart()) {
2869         sal_Bool bShowHelp = sal_False;
2870         ::rtl::OUStringBuffer aHelpURLBuffer;
2871         if (pArgs->IsHelpWriter()) {
2872             bShowHelp = sal_True;
2873             aHelpURLBuffer.appendAscii("vnd.sun.star.help://swriter/start");
2874         } else if (pArgs->IsHelpCalc()) {
2875             bShowHelp = sal_True;
2876             aHelpURLBuffer.appendAscii("vnd.sun.star.help://scalc/start");
2877         } else if (pArgs->IsHelpDraw()) {
2878             bShowHelp = sal_True;
2879             aHelpURLBuffer.appendAscii("vnd.sun.star.help://sdraw/start");
2880         } else if (pArgs->IsHelpImpress()) {
2881             bShowHelp = sal_True;
2882             aHelpURLBuffer.appendAscii("vnd.sun.star.help://simpress/start");
2883         } else if (pArgs->IsHelpBase()) {
2884             bShowHelp = sal_True;
2885             aHelpURLBuffer.appendAscii("vnd.sun.star.help://sdatabase/start");
2886         } else if (pArgs->IsHelpBasic()) {
2887             bShowHelp = sal_True;
2888             aHelpURLBuffer.appendAscii("vnd.sun.star.help://sbasic/start");
2889         } else if (pArgs->IsHelpMath()) {
2890             bShowHelp = sal_True;
2891             aHelpURLBuffer.appendAscii("vnd.sun.star.help://smath/start");
2892         }
2893         if (bShowHelp) {
2894             Help *pHelp = Application::GetHelp();
2895 
2896             Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::LOCALE );
2897             rtl::OUString aTmp;
2898             aRet >>= aTmp;
2899             aHelpURLBuffer.appendAscii("?Language=");
2900             aHelpURLBuffer.append(aTmp);
2901 #if defined UNX
2902             aHelpURLBuffer.appendAscii("&System=UNX");
2903 #elif defined WNT
2904             aHelpURLBuffer.appendAscii("&System=WIN");
2905 #elif defined OS2
2906             aHelpURLBuffer.appendAscii("&System=OS2");
2907 #endif
2908             pHelp->Start(aHelpURLBuffer.makeStringAndClear(), NULL);
2909             return;
2910         }
2911     }
2912     else
2913     {
2914         OUString            aIniName;
2915         ::vos::OStartupInfo aInfo;
2916 
2917         aInfo.getExecutableFile( aIniName );
2918         sal_uInt32     lastIndex = aIniName.lastIndexOf('/');
2919         if ( lastIndex > 0 )
2920         {
2921             aIniName    = aIniName.copy( 0, lastIndex+1 );
2922             aIniName    += OUString( RTL_CONSTASCII_USTRINGPARAM( "perftune" ));
2923 #if defined(WNT) || defined(OS2)
2924             aIniName    += OUString( RTL_CONSTASCII_USTRINGPARAM( ".ini" ));
2925 #else
2926             aIniName    += OUString( RTL_CONSTASCII_USTRINGPARAM( "rc" ));
2927 #endif
2928         }
2929 
2930         rtl::Bootstrap aPerfTuneIniFile( aIniName );
2931 
2932         OUString aDefault( RTL_CONSTASCII_USTRINGPARAM( "0" ));
2933         OUString aPreloadData;
2934 
2935         aPerfTuneIniFile.getFrom( OUString( RTL_CONSTASCII_USTRINGPARAM( "QuickstartPreloadConfiguration" )), aPreloadData, aDefault );
2936         if ( aPreloadData.equalsAscii( "1" ))
2937         {
2938             if ( pArgs->IsWriter()  ||
2939                  pArgs->IsCalc()    ||
2940                  pArgs->IsDraw()    ||
2941                  pArgs->IsImpress()    )
2942             {
2943                 PreloadModuleData( pArgs );
2944             }
2945 
2946             PreloadConfigurationData();
2947         }
2948     }
2949 
2950     // Disable AutoSave feature in case "-norestore" or a similare command line switch is set on the command line.
2951     // The reason behind: AutoSave/EmergencySave/AutoRecovery share the same data.
2952     // But the require that all documents, which are saved as backup should exists inside
2953     // memory. May be this mechanism will be inconsistent if the configuration exists ...
2954     // but no document inside memory corrspond to this data.
2955     // Furter it's not acceptable to recover such documents without any UI. It can
2956     // need some time, where the user wont see any results and wait for finishing the office startup ...
2957     sal_Bool bAllowRecoveryAndSessionManagement = (
2958                                                     ( !pArgs->IsNoRestore() ) &&
2959                                                     ( !pArgs->IsHeadless()  ) &&
2960                                                     ( !pArgs->IsServer()    )
2961                                                   );
2962 
2963     if ( ! bAllowRecoveryAndSessionManagement )
2964     {
2965         try
2966         {
2967             Reference< XDispatch > xRecovery(
2968                     ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.AutoRecovery")) ),
2969                     ::com::sun::star::uno::UNO_QUERY_THROW );
2970 
2971             Reference< XURLTransformer > xParser(
2972                     ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer")) ),
2973                     ::com::sun::star::uno::UNO_QUERY_THROW );
2974 
2975             css::util::URL aCmd;
2976             aCmd.Complete = ::rtl::OUString::createFromAscii("vnd.sun.star.autorecovery:/disableRecovery");
2977             xParser->parseStrict(aCmd);
2978 
2979             xRecovery->dispatch(aCmd, css::uno::Sequence< css::beans::PropertyValue >());
2980         }
2981         catch(const css::uno::Exception& e)
2982         {
2983             OUString aMessage = OUString::createFromAscii("Could not disable AutoRecovery.\n")
2984                 + e.Message;
2985             OSL_ENSURE(sal_False, OUStringToOString(aMessage, RTL_TEXTENCODING_ASCII_US).getStr());
2986         }
2987     }
2988     else
2989     {
2990         sal_Bool bCrashed            = sal_False;
2991         sal_Bool bExistsRecoveryData = sal_False;
2992         sal_Bool bExistsSessionData  = sal_False;
2993 
2994         impl_checkRecoveryState(bCrashed, bExistsRecoveryData, bExistsSessionData);
2995 
2996         if ( !getenv ("OOO_DISABLE_RECOVERY") &&
2997             ( ! bLoaded ) &&
2998             (
2999                 ( bExistsRecoveryData ) || // => crash with files    => recovery
3000                 ( bCrashed            )    // => crash without files => error report
3001             )
3002            )
3003         {
3004             try
3005             {
3006                 impl_callRecoveryUI(
3007                     sal_False          , // false => force recovery instead of emergency save
3008                     bCrashed           ,
3009                     bExistsRecoveryData);
3010                 /* TODO we cant be shure, that at least one document could be recovered here successfully
3011                     So we set bLoaded=sal_True to supress opening of the default document.
3012                     But we should make it more safe. Otherwhise we have an office without an UI ...
3013                     ...
3014                     May be we can check the desktop if some documents are existing there.
3015                  */
3016                 Reference< XFramesSupplier > xTasksSupplier(
3017                         ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
3018                         ::com::sun::star::uno::UNO_QUERY_THROW );
3019                 Reference< XElementAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY_THROW );
3020                 if ( xList->hasElements() )
3021                     bLoaded = sal_True;
3022             }
3023             catch(const css::uno::Exception& e)
3024             {
3025                 OUString aMessage = OUString::createFromAscii("Error during recovery\n")
3026                     + e.Message;
3027                 OSL_ENSURE(sal_False, OUStringToOString(aMessage, RTL_TEXTENCODING_ASCII_US).getStr());
3028             }
3029         }
3030 
3031         Reference< XInitialization > xSessionListener;
3032         try
3033         {
3034             xSessionListener = Reference< XInitialization >(::comphelper::getProcessServiceFactory()->createInstance(
3035                         OUString::createFromAscii("com.sun.star.frame.SessionListener")), UNO_QUERY_THROW);
3036 
3037             // specifies whether the UI-interaction on Session shutdown is allowed
3038             sal_Bool bAllowUI = isUIOnSessionShutdownAllowed();
3039             css::beans::NamedValue aProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AllowUserInteractionOnQuit" ) ),
3040                                               css::uno::makeAny( bAllowUI ) );
3041             css::uno::Sequence< css::uno::Any > aArgs( 1 );
3042             aArgs[0] <<= aProperty;
3043 
3044             xSessionListener->initialize( aArgs );
3045         }
3046         catch(const com::sun::star::uno::Exception& e)
3047         {
3048             OUString aMessage = OUString::createFromAscii("Registration of session listener failed\n")
3049                 + e.Message;
3050             OSL_ENSURE(sal_False, OUStringToOString(aMessage, RTL_TEXTENCODING_ASCII_US).getStr());
3051         }
3052 
3053         if (
3054             ( ! bLoaded            ) &&
3055             (   bExistsSessionData )
3056            )
3057         {
3058             // session management
3059             try
3060             {
3061                 Reference< XSessionManagerListener > r(xSessionListener, UNO_QUERY_THROW);
3062                 bLoaded = r->doRestore();
3063             }
3064             catch(const com::sun::star::uno::Exception& e)
3065             {
3066                 OUString aMessage = OUString::createFromAscii("Error in session management\n")
3067                     + e.Message;
3068                 OSL_ENSURE(sal_False, OUStringToOString(aMessage, RTL_TEXTENCODING_ASCII_US).getStr());
3069             }
3070         }
3071     }
3072 
3073     OfficeIPCThread::EnableRequests();
3074 
3075     sal_Bool bShutdown( sal_False );
3076     if ( !pArgs->IsServer() )
3077     {
3078         ProcessDocumentsRequest aRequest(pArgs->getCwdUrl());
3079         aRequest.pcProcessed = NULL;
3080 
3081         pArgs->GetOpenList( aRequest.aOpenList );
3082         pArgs->GetViewList( aRequest.aViewList );
3083         pArgs->GetStartList( aRequest.aStartList );
3084         pArgs->GetPrintList( aRequest.aPrintList );
3085         pArgs->GetPrintToList( aRequest.aPrintToList );
3086         pArgs->GetPrinterName( aRequest.aPrinterName );
3087         pArgs->GetForceOpenList( aRequest.aForceOpenList );
3088         pArgs->GetForceNewList( aRequest.aForceNewList );
3089 
3090         if ( aRequest.aOpenList.getLength() > 0 ||
3091              aRequest.aViewList.getLength() > 0 ||
3092              aRequest.aStartList.getLength() > 0 ||
3093              aRequest.aPrintList.getLength() > 0 ||
3094              aRequest.aForceOpenList.getLength() > 0 ||
3095              aRequest.aForceNewList.getLength() > 0 ||
3096              ( aRequest.aPrintToList.getLength() > 0 && aRequest.aPrinterName.getLength() > 0 ))
3097         {
3098             bLoaded = sal_True;
3099 
3100             if ( pArgs->HasModuleParam() )
3101             {
3102                 SvtModuleOptions    aOpt;
3103 
3104                 // Support command line parameters to start a module (as preselection)
3105                 if ( pArgs->IsWriter() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
3106                     aRequest.aModule = aOpt.GetFactoryName( SvtModuleOptions::E_WRITER );
3107                 else if ( pArgs->IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
3108                     aRequest.aModule = aOpt.GetFactoryName( SvtModuleOptions::E_CALC );
3109                 else if ( pArgs->IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
3110                     aRequest.aModule= aOpt.GetFactoryName( SvtModuleOptions::E_IMPRESS );
3111                 else if ( pArgs->IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
3112                     aRequest.aModule= aOpt.GetFactoryName( SvtModuleOptions::E_DRAW );
3113             }
3114 
3115             // check for printing disabled
3116             if( ( aRequest.aPrintList.getLength() || aRequest.aPrintToList.getLength() )
3117                 && Application::GetSettings().GetMiscSettings().GetDisablePrinting() )
3118             {
3119                 aRequest.aPrintList = rtl::OUString();
3120                 aRequest.aPrintToList = rtl::OUString();
3121                 ResMgr* pDtResMgr = GetDesktopResManager();
3122                 if( pDtResMgr )
3123                 {
3124                     ErrorBox aBox( NULL, ResId( EBX_ERR_PRINTDISABLED, *pDtResMgr ) );
3125                     aBox.Execute();
3126                 }
3127             }
3128 
3129             // Process request
3130             bShutdown = OfficeIPCThread::ExecuteCmdLineRequests( aRequest );
3131         }
3132     }
3133 
3134     // Don't do anything if we have successfully called terminate at desktop
3135     if ( bShutdown )
3136         return;
3137 
3138     // no default document if a document was loaded by recovery or by command line or if soffice is used as server
3139     Reference< XFramesSupplier > xTasksSupplier(
3140             ::comphelper::getProcessServiceFactory()->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
3141             ::com::sun::star::uno::UNO_QUERY_THROW );
3142     Reference< XElementAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY_THROW );
3143     if ( xList->hasElements() || pArgs->IsServer() )
3144         return;
3145 
3146     if ( pArgs->IsQuickstart() || pArgs->IsInvisible() || pArgs->IsBean() || Application::AnyInput( INPUT_APPEVENT ) )
3147         // soffice was started as tray icon ...
3148         return;
3149     {
3150         OpenDefault();
3151     }
3152 }
3153 
3154 void Desktop::OpenDefault()
3155 {
3156 
3157     RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::OpenDefault" );
3158 
3159     ::rtl::OUString        aName;
3160     SvtModuleOptions    aOpt;
3161 
3162     CommandLineArgs* pArgs = GetCommandLineArgs();
3163     if ( pArgs->IsNoDefault() ) return;
3164     if ( pArgs->HasModuleParam() )
3165     {
3166         // Support new command line parameters to start a module
3167         if ( pArgs->IsWriter() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
3168             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITER );
3169         else if ( pArgs->IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
3170             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_CALC );
3171         else if ( pArgs->IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
3172             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_IMPRESS );
3173         else if ( pArgs->IsBase() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
3174             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DATABASE );
3175         else if ( pArgs->IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
3176             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DRAW );
3177         else if ( pArgs->IsMath() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SMATH ) )
3178             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_MATH );
3179         else if ( pArgs->IsGlobal() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
3180             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITERGLOBAL );
3181         else if ( pArgs->IsWeb() && aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
3182             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITERWEB );
3183     }
3184 
3185     if ( !aName.getLength() )
3186     {
3187         // Old way to create a default document
3188         if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
3189             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_WRITER );
3190         else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) )
3191             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_CALC );
3192         else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) )
3193             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_IMPRESS );
3194         else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
3195             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DATABASE );
3196         else if ( aOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) )
3197             aName = aOpt.GetFactoryEmptyDocumentURL( SvtModuleOptions::E_DRAW );
3198         else
3199             return;
3200     }
3201 
3202     ProcessDocumentsRequest aRequest(pArgs->getCwdUrl());
3203     aRequest.pcProcessed = NULL;
3204     aRequest.aOpenList   = aName;
3205     OfficeIPCThread::ExecuteCmdLineRequests( aRequest );
3206 }
3207 
3208 
3209 String GetURL_Impl(
3210     const String& rName, boost::optional< rtl::OUString > const & cwdUrl )
3211 {
3212     // if rName is a vnd.sun.star.script URL do not attempt to parse it
3213     // as INetURLObj does not handle handle there URLs
3214     if (rName.CompareToAscii("vnd.sun.star.script" , 19) == COMPARE_EQUAL)
3215     {
3216         return rName;
3217     }
3218 
3219     // dont touch file urls, those should already be in internal form
3220     // they won't get better here (#112849#)
3221     if (rName.CompareToAscii("file:" , 5) == COMPARE_EQUAL)
3222     {
3223         return rName;
3224     }
3225 
3226     if ( rName.CompareToAscii("service:" , 8) == COMPARE_EQUAL )
3227     {
3228         return rName;
3229     }
3230 
3231     // Add path seperator to these directory and make given URL (rName) absolute by using of current working directory
3232     // Attention: "setFianlSlash()" is neccessary for calling "smartRel2Abs()"!!!
3233     // Otherwhise last part will be ignored and wrong result will be returned!!!
3234     // "smartRel2Abs()" interpret given URL as file not as path. So he truncate last element to get the base path ...
3235     // But if we add a seperator - he doesn't do it anymore.
3236     INetURLObject aObj;
3237     if (cwdUrl) {
3238         aObj.SetURL(*cwdUrl);
3239         aObj.setFinalSlash();
3240     }
3241 
3242     // Use the provided parameters for smartRel2Abs to support the usage of '%' in system paths.
3243     // Otherwise this char won't get encoded and we are not able to load such files later,
3244     // see #110156#
3245     bool bWasAbsolute;
3246     INetURLObject aURL     = aObj.smartRel2Abs( rName, bWasAbsolute, false, INetURLObject::WAS_ENCODED,
3247                                                 RTL_TEXTENCODING_UTF8, true );
3248     String        aFileURL = aURL.GetMainURL(INetURLObject::NO_DECODE);
3249 
3250     ::osl::FileStatus aStatus( FileStatusMask_FileURL );
3251     ::osl::DirectoryItem aItem;
3252     if( ::osl::FileBase::E_None == ::osl::DirectoryItem::get( aFileURL, aItem ) &&
3253         ::osl::FileBase::E_None == aItem.getFileStatus( aStatus ) )
3254             aFileURL = aStatus.getFileURL();
3255 
3256     return aFileURL;
3257 }
3258 
3259 void Desktop::HandleAppEvent( const ApplicationEvent& rAppEvent )
3260 {
3261     if ( rAppEvent.GetEvent() == "APPEAR" && !GetCommandLineArgs()->IsInvisible() )
3262     {
3263         css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
3264 
3265         // find active task - the active task is always a visible task
3266         ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFramesSupplier >
3267                 xDesktop( xSMGR->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
3268                 ::com::sun::star::uno::UNO_QUERY );
3269         ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xTask = xDesktop->getActiveFrame();
3270         if ( !xTask.is() )
3271         {
3272             // get any task if there is no active one
3273             ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess > xList( xDesktop->getFrames(), ::com::sun::star::uno::UNO_QUERY );
3274             if ( xList->getCount()>0 )
3275                 xList->getByIndex(0) >>= xTask;
3276         }
3277 
3278         if ( xTask.is() )
3279         {
3280             Reference< com::sun::star::awt::XTopWindow > xTop( xTask->getContainerWindow(), UNO_QUERY );
3281             xTop->toFront();
3282         }
3283         else
3284         {
3285             // no visible task that could be activated found
3286             Reference< XFrame > xBackingFrame;
3287             Reference< ::com::sun::star::awt::XWindow > xContainerWindow;
3288             ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xDesktopFrame( xDesktop, UNO_QUERY );
3289 
3290             xBackingFrame = xDesktopFrame->findFrame(OUString( RTL_CONSTASCII_USTRINGPARAM( "_blank" )), 0);
3291             if (xBackingFrame.is())
3292                 xContainerWindow = xBackingFrame->getContainerWindow();
3293             if (xContainerWindow.is())
3294             {
3295                 Sequence< Any > lArgs(1);
3296                 lArgs[0] <<= xContainerWindow;
3297                 Reference< XController > xBackingComp(
3298                     xSMGR->createInstanceWithArguments(OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.StartModule") ), lArgs),
3299                     UNO_QUERY);
3300                 if (xBackingComp.is())
3301                 {
3302                     Reference< ::com::sun::star::awt::XWindow > xBackingWin(xBackingComp, UNO_QUERY);
3303                     // Attention: You MUST(!) call setComponent() before you call attachFrame().
3304                     // Because the backing component set the property "IsBackingMode" of the frame
3305                     // to true inside attachFrame(). But setComponent() reset this state everytimes ...
3306                     xBackingFrame->setComponent(xBackingWin, xBackingComp);
3307                     xBackingComp->attachFrame(xBackingFrame);
3308                     xContainerWindow->setVisible(sal_True);
3309 
3310                     Window* pCompWindow = VCLUnoHelper::GetWindow(xBackingFrame->getComponentWindow());
3311                     if (pCompWindow)
3312                         pCompWindow->Update();
3313                 }
3314             }
3315         }
3316     }
3317     else if ( rAppEvent.GetEvent() == "QUICKSTART" && !GetCommandLineArgs()->IsInvisible()  )
3318     {
3319         // If the office has been started the second time its command line arguments are sent through a pipe
3320         // connection to the first office. We want to reuse the quickstart option for the first office.
3321         // NOTICE: The quickstart service must be initialized inside the "main thread", so we use the
3322         // application events to do this (they are executed inside main thread)!!!
3323         // Don't start quickstart service if the user specified "-invisible" on the command line!
3324         sal_Bool bQuickstart( sal_True );
3325         Sequence< Any > aSeq( 1 );
3326         aSeq[0] <<= bQuickstart;
3327 
3328         Reference < XInitialization > xQuickstart( ::comphelper::getProcessServiceFactory()->createInstance(
3329                                             DEFINE_CONST_UNICODE( "com.sun.star.office.Quickstart" )),
3330                                             UNO_QUERY );
3331         if ( xQuickstart.is() )
3332             xQuickstart->initialize( aSeq );
3333     }
3334     else if ( rAppEvent.GetEvent() == "ACCEPT" )
3335     {
3336         // every time an accept parameter is used we create an acceptor
3337         // with the corresponding accept-string
3338         OUString aAcceptString(rAppEvent.GetData().GetBuffer());
3339         createAcceptor(aAcceptString);
3340     }
3341     else if ( rAppEvent.GetEvent() == "UNACCEPT" )
3342     {
3343         // try to remove corresponding acceptor
3344         OUString aUnAcceptString(rAppEvent.GetData().GetBuffer());
3345         destroyAcceptor(aUnAcceptString);
3346     }
3347     else if ( rAppEvent.GetEvent() == "SaveDocuments" )
3348     {
3349         Desktop::_bTasksSaved = sal_False;
3350         Desktop::_bTasksSaved = SaveTasks();
3351     }
3352     else if ( rAppEvent.GetEvent() == "OPENHELPURL" )
3353     {
3354         // start help for a specific URL
3355         OUString aHelpURL(rAppEvent.GetData().GetBuffer());
3356         Help *pHelp = Application::GetHelp();
3357         pHelp->Start(aHelpURL, NULL);
3358     }
3359     else if ( rAppEvent.GetEvent() == APPEVENT_OPEN_STRING )
3360     {
3361         OUString aOpenURL(rAppEvent.GetData().GetBuffer());
3362 
3363         CommandLineArgs* pCmdLine = GetCommandLineArgs();
3364         if ( !pCmdLine->IsInvisible() && !pCmdLine->IsTerminateAfterInit() )
3365         {
3366             ProcessDocumentsRequest* pDocsRequest = new ProcessDocumentsRequest(
3367                 pCmdLine->getCwdUrl());
3368             pDocsRequest->aOpenList = aOpenURL;
3369             pDocsRequest->pcProcessed = NULL;
3370 
3371             OfficeIPCThread::ExecuteCmdLineRequests( *pDocsRequest );
3372             delete pDocsRequest;
3373         }
3374     }
3375     else if ( rAppEvent.GetEvent() == APPEVENT_PRINT_STRING )
3376     {
3377         OUString aPrintURL(rAppEvent.GetData().GetBuffer());
3378 
3379         CommandLineArgs* pCmdLine = GetCommandLineArgs();
3380         if ( !pCmdLine->IsInvisible() && !pCmdLine->IsTerminateAfterInit() )
3381         {
3382             ProcessDocumentsRequest* pDocsRequest = new ProcessDocumentsRequest(
3383                 pCmdLine->getCwdUrl());
3384             pDocsRequest->aPrintList = aPrintURL;
3385             pDocsRequest->pcProcessed = NULL;
3386 
3387             OfficeIPCThread::ExecuteCmdLineRequests( *pDocsRequest );
3388             delete pDocsRequest;
3389         }
3390     }
3391 #ifndef UNX
3392     else if ( rAppEvent.GetEvent() == "HELP" )
3393     {
3394         // in non unix version allow showing of cmdline help window
3395         displayCmdlineHelp();
3396     }
3397 #endif
3398     else if ( rAppEvent.GetEvent() == "SHOWDIALOG" )
3399     {
3400         // ignore all errors here. It's clicking a menu entry only ...
3401         // The user will try it again, in case nothing happens .-)
3402         try
3403         {
3404             css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
3405 
3406             com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider >
3407                 xDesktop( xSMGR->createInstance( OUSTRING(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
3408                 ::com::sun::star::uno::UNO_QUERY );
3409 
3410             // check provider ... we know it's weak reference only
3411             if ( ! xDesktop.is())
3412                 return;
3413 
3414             css::uno::Reference< css::util::XURLTransformer > xParser(xSMGR->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer"))), css::uno::UNO_QUERY_THROW);
3415             css::util::URL aCommand;
3416             if( rAppEvent.GetData().EqualsAscii( "PREFERENCES" ) )
3417                 aCommand.Complete = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:OptionsTreeDialog" ) );
3418             else if( rAppEvent.GetData().EqualsAscii( "ABOUT" ) )
3419                 aCommand.Complete = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:About" ) );
3420             if( aCommand.Complete.getLength() )
3421             {
3422                 xParser->parseStrict(aCommand);
3423 
3424                 css::uno::Reference< css::frame::XDispatch > xDispatch = xDesktop->queryDispatch(aCommand, rtl::OUString(), 0);
3425                 if (xDispatch.is())
3426                     xDispatch->dispatch(aCommand, css::uno::Sequence< css::beans::PropertyValue >());
3427             }
3428         }
3429         catch(const css::uno::Exception&)
3430         {}
3431     }
3432     else if( rAppEvent.GetEvent() == "PRIVATE:DOSHUTDOWN" )
3433     {
3434         Desktop* pD = dynamic_cast<Desktop*>(GetpApp());
3435         OSL_ENSURE( pD, "no desktop ?!?" );
3436         if( pD )
3437             pD->doShutdown();
3438     }
3439 }
3440 
3441 void Desktop::OpenSplashScreen()
3442 {
3443     ::rtl::OUString     aTmpString;
3444     CommandLineArgs*    pCmdLine = GetCommandLineArgs();
3445     sal_Bool bVisible = sal_False;
3446     // Show intro only if this is normal start (e.g. no server, no quickstart, no printing )
3447     if ( !pCmdLine->IsInvisible() &&
3448          !pCmdLine->IsHeadless() &&
3449          !pCmdLine->IsQuickstart() &&
3450          !pCmdLine->IsMinimized() &&
3451          !pCmdLine->IsNoLogo() &&
3452          !pCmdLine->IsTerminateAfterInit() &&
3453          !pCmdLine->GetPrintList( aTmpString ) &&
3454          !pCmdLine->GetPrintToList( aTmpString ) )
3455     {
3456         // Determine application name from command line parameters
3457         OUString aAppName;
3458         if ( pCmdLine->IsWriter() )
3459             aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "writer" ));
3460         else if ( pCmdLine->IsCalc() )
3461             aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "calc" ));
3462         else if ( pCmdLine->IsDraw() )
3463             aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "draw" ));
3464         else if ( pCmdLine->IsImpress() )
3465             aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "impress" ));
3466         else if ( pCmdLine->IsBase() )
3467             aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "base" ));
3468         else if ( pCmdLine->IsGlobal() )
3469             aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "global" ));
3470         else if ( pCmdLine->IsMath() )
3471             aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "math" ));
3472         else if ( pCmdLine->IsWeb() )
3473             aAppName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "web" ));
3474 
3475         bVisible = sal_True;
3476         Sequence< Any > aSeq( 2 );
3477         aSeq[0] <<= bVisible;
3478         aSeq[1] <<= aAppName;
3479         m_rSplashScreen = Reference<XStatusIndicator>(
3480             comphelper::getProcessServiceFactory()->createInstanceWithArguments(
3481             OUString::createFromAscii("com.sun.star.office.SplashScreen"),
3482             aSeq), UNO_QUERY);
3483 
3484         if(m_rSplashScreen.is())
3485                 m_rSplashScreen->start(OUString::createFromAscii("SplashScreen"), 100);
3486     }
3487 
3488 }
3489 
3490 void Desktop::SetSplashScreenProgress(sal_Int32 iProgress)
3491 {
3492     if(m_rSplashScreen.is())
3493     {
3494         m_rSplashScreen->setValue(iProgress);
3495     }
3496 }
3497 
3498 void Desktop::SetSplashScreenText( const ::rtl::OUString& rText )
3499 {
3500     if( m_rSplashScreen.is() )
3501     {
3502         m_rSplashScreen->setText( rText );
3503     }
3504 }
3505 
3506 void Desktop::CloseSplashScreen()
3507 {
3508     if(m_rSplashScreen.is())
3509     {
3510         m_rSplashScreen->end();
3511         m_rSplashScreen = NULL;
3512     }
3513 }
3514 
3515 // ========================================================================
3516 void Desktop::DoFirstRunInitializations()
3517 {
3518     try
3519     {
3520         Reference< XJobExecutor > xExecutor( ::comphelper::getProcessServiceFactory()->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.task.JobExecutor" ) ), UNO_QUERY );
3521         if( xExecutor.is() )
3522             xExecutor->trigger( ::rtl::OUString::createFromAscii("onFirstRunInitialization") );
3523     }
3524     catch(const ::com::sun::star::uno::Exception&)
3525     {
3526         OSL_ENSURE( sal_False, "Desktop::DoFirstRunInitializations: caught an exception while trigger job executor ..." );
3527     }
3528 }
3529 
3530 // ========================================================================
3531 void Desktop::CheckFirstRun( )
3532 {
3533     const ::rtl::OUString sCommonMiscNodeName = ::rtl::OUString::createFromAscii( "/org.openoffice.Office.Common/Misc" );
3534     const ::rtl::OUString sFirstRunNodeName = ::rtl::OUString::createFromAscii( "FirstRun" );
3535 
3536     // --------------------------------------------------------------------
3537     // check if this is the first office start
3538 
3539     // for this, open the Common/Misc node where this info is stored
3540     ::utl::OConfigurationTreeRoot aCommonMisc = ::utl::OConfigurationTreeRoot::createWithServiceFactory(
3541         ::comphelper::getProcessServiceFactory( ),
3542         sCommonMiscNodeName,
3543         2,
3544         ::utl::OConfigurationTreeRoot::CM_UPDATABLE
3545     );
3546 
3547     // read the flag
3548     OSL_ENSURE( aCommonMisc.isValid(), "Desktop::CheckFirstRun: could not open the config node needed!" );
3549     sal_Bool bIsFirstRun = sal_False;
3550     aCommonMisc.getNodeValue( sFirstRunNodeName ) >>= bIsFirstRun;
3551 
3552     if ( !bIsFirstRun )
3553         // nothing to do ....
3554         return;
3555 
3556     // --------------------------------------------------------------------
3557     // it is the first run
3558     // this has once been done using a vos timer. this could lead to problems when
3559     // the timer would trigger when the app is already going down again, since VCL would
3560     // no longer be available. Since the old handler would do a postUserEvent to the main
3561     // thread anyway, we can use a vcl timer here to prevent the race contition (#107197#)
3562     m_firstRunTimer.SetTimeout(3000); // 3 sec.
3563     m_firstRunTimer.SetTimeoutHdl(LINK(this, Desktop, AsyncInitFirstRun));
3564     m_firstRunTimer.Start();
3565 
3566     // --------------------------------------------------------------------
3567     // reset the config flag
3568 
3569     // set the value
3570     aCommonMisc.setNodeValue( sFirstRunNodeName, makeAny( (sal_Bool)sal_False ) );
3571     // commit the changes
3572     aCommonMisc.commit();
3573 }
3574 
3575 }
3576