1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
23 #include "unotools/bootstrap.hxx"
25 // ---------------------------------------------------------------------------------------
26 #include <rtl/ustring.hxx>
27 #include <rtl/ustrbuf.hxx>
28 #include <osl/file.hxx>
29 #include <osl/mutex.hxx>
30 #include <osl/diagnose.h>
31 // ---------------------------------------------------------------------------------------
32 #include <rtl/bootstrap.hxx>
33 #include <rtl/instance.hxx>
34 #include <osl/process.h> // for osl_getExecutableFile
35 #include "tools/getprocessworkingdir.hxx"
37 // ---------------------------------------------------------------------------------------
38 // #define this to a non-zero value, if remembering defaults is not supported properly
39 #define RTL_BOOTSTRAP_DEFAULTS_BROKEN 1
41 #define BOOTSTRAP_ITEM_PRODUCT_KEY "ProductKey"
42 #define BOOTSTRAP_ITEM_VERSIONFILE "Location"
43 #define BOOTSTRAP_ITEM_BUILDID "buildid"
44 #define BOOTSTRAP_ITEM_BUILDVERSION "BuildVersion"
46 #define BOOTSTRAP_ITEM_BASEINSTALLATION "BRAND_BASE_DIR"
47 #define BOOTSTRAP_ITEM_USERINSTALLATION "UserInstallation"
49 #define BOOTSTRAP_ITEM_USERDIR "UserDataDir"
51 #define BOOTSTRAP_DEFAULT_BASEINSTALL "$SYSBINDIR/.."
53 #define BOOTSTRAP_DIRNAME_USERDIR "user"
55 // ---------------------------------------------------------------------------------------
56 typedef char const * AsciiString
;
57 // ---------------------------------------------------------------------------------------
61 // ---------------------------------------------------------------------------------------
63 // ---------------------------------------------------------------------------------------
64 // Implementation class: Bootstrap::Impl
65 // ---------------------------------------------------------------------------------------
69 OUString
makeImplName()
72 rtl::Bootstrap::get( OUString("BRAND_BASE_DIR"), uri
);
73 return uri
+ "/program/" SAL_CONFIGFILE("bootstrap");
79 const OUString m_aImplName
;
80 public: // struct to cache the result of a path lookup
88 , status(DATA_UNKNOWN
)
91 public: // data members
93 PathData aBaseInstall_
;
96 PathData aUserInstall_
;
99 PathData aBootstrapINI_
;
100 PathData aVersionINI_
;
105 public: // construction and initialization
106 Impl() : m_aImplName(makeImplName())
114 OUString
getBootstrapValue(OUString
const& _sName
, OUString
const& _sDefault
) const;
115 sal_Bool
getVersionValue(OUString
const& _sName
, OUString
& _rValue
, OUString
const& _sDefault
) const;
117 OUString
getImplName() const { return m_aImplName
; }
119 private: // implementation
120 bool initBaseInstallationData(rtl::Bootstrap
& _rData
);
121 bool initUserInstallationData(rtl::Bootstrap
& _rData
);
126 class theImpl
: public rtl::Static
<Bootstrap::Impl
, theImpl
> {};
129 const Bootstrap::Impl
& Bootstrap::data()
131 return theImpl::get();
134 void Bootstrap::reloadData()
136 theImpl::get().initialize();
139 // ---------------------------------------------------------------------------------------
141 // ---------------------------------------------------------------------------------------
143 typedef Bootstrap::PathStatus PathStatus
;
145 sal_Unicode
const cURLSeparator
= '/';
147 // ---------------------------------------------------------------------------------------
148 // path status utility function
150 PathStatus
implCheckStatusOfURL(OUString
const& _sURL
, osl::DirectoryItem
& aDirItem
)
154 PathStatus eStatus
= Bootstrap::DATA_UNKNOWN
;
156 if (!_sURL
.isEmpty())
158 switch( DirectoryItem::get(_sURL
, aDirItem
) )
160 case DirectoryItem::E_None
: // Success
161 eStatus
= Bootstrap::PATH_EXISTS
;
164 case DirectoryItem::E_NOENT
: // No such file or directory<br>
165 eStatus
= Bootstrap::PATH_VALID
;
168 case DirectoryItem::E_INVAL
: // the format of the parameters was not valid<br>
169 case DirectoryItem::E_NAMETOOLONG
: // File name too long<br>
170 case DirectoryItem::E_NOTDIR
: // A component of the path prefix of path is not a directory<p>
171 eStatus
= Bootstrap::DATA_INVALID
;
174 // how to handle these ?
175 case DirectoryItem::E_LOOP
: // Too many symbolic links encountered<br>
176 case DirectoryItem::E_ACCES
: // permission denied<br>
177 // any other error - what to do ?
179 eStatus
= Bootstrap::DATA_UNKNOWN
;
184 eStatus
= Bootstrap::DATA_MISSING
;
188 // ---------------------------------------------------------------------------------------
191 bool implNormalizeURL(OUString
& _sURL
, osl::DirectoryItem
& aDirItem
)
195 OSL_PRECOND(aDirItem
.is(), "Opened DirItem required");
197 static const sal_uInt32 cosl_FileStatus_Mask
= osl_FileStatus_Mask_FileURL
;
199 FileStatus
aFileStatus(cosl_FileStatus_Mask
);
201 if (aDirItem
.getFileStatus(aFileStatus
) != DirectoryItem::E_None
)
204 OUString aNormalizedURL
= aFileStatus
.getFileURL();
206 if (aNormalizedURL
.isEmpty())
209 // #109863# sal/osl returns final slash for file URLs contradicting
211 if ( aNormalizedURL
.getStr()[aNormalizedURL
.getLength()-1] != cURLSeparator
)
212 _sURL
= aNormalizedURL
;
214 _sURL
= aNormalizedURL
.copy( 0, aNormalizedURL
.getLength()-1 );
218 // ---------------------------------------------------------------------------------------
220 bool implEnsureAbsolute(OUString
& _rsURL
) // also strips embedded dots !!
225 OSL_VERIFY(tools::getProcessWorkingDir(sBasePath
));
228 if ( File::E_None
== File::getAbsoluteFileURL(sBasePath
, _rsURL
, sAbsolute
))
235 OSL_FAIL("Could not get absolute file URL for URL");
240 // ---------------------------------------------------------------------------------------
243 bool implMakeAbsoluteURL(OUString
& _rsPathOrURL
)
250 // check if it already was normalized
251 if ( File::E_None
== File::getSystemPathFromFileURL(_rsPathOrURL
, sOther
) )
256 else if ( File::E_None
== File::getFileURLFromSystemPath(_rsPathOrURL
, sOther
) )
258 _rsPathOrURL
= sOther
;
264 return bURL
&& implEnsureAbsolute(_rsPathOrURL
);
266 // ---------------------------------------------------------------------------------------
267 #if OSL_DEBUG_LEVEL > 0
269 PathStatus
dbgCheckStatusOfURL(OUString
const& _sURL
)
273 DirectoryItem aDirItem
;
275 return implCheckStatusOfURL(_sURL
,aDirItem
);
277 // ---------------------------------------------------------------------------------------
281 PathStatus
checkStatusAndNormalizeURL(OUString
& _sURL
)
285 PathStatus eStatus
= Bootstrap::DATA_UNKNOWN
;
288 eStatus
= Bootstrap::DATA_MISSING
;
290 else if ( !implMakeAbsoluteURL(_sURL
) )
291 eStatus
= Bootstrap::DATA_INVALID
;
295 DirectoryItem aDirItem
;
297 eStatus
= implCheckStatusOfURL(_sURL
,aDirItem
);
299 if (eStatus
== Bootstrap::PATH_EXISTS
)
301 if (!implNormalizeURL(_sURL
,aDirItem
))
302 OSL_FAIL("Unexpected failure getting actual URL for existing object");
309 // ----------------------------------------------------------------------------------
310 // helpers to build and check a nested URL
312 PathStatus
getDerivedPath(
314 OUString
const& _aBaseURL
, PathStatus _aBaseStatus
,
315 OUString
const& _sRelativeURL
,
316 rtl::Bootstrap
& _rData
, OUString
const& _sBootstrapParameter
319 OUString sDerivedURL
;
320 OSL_PRECOND(!_rData
.getFrom(_sBootstrapParameter
,sDerivedURL
),"Setting for derived path is already defined");
321 OSL_PRECOND(!_sRelativeURL
.isEmpty() && _sRelativeURL
[0] != cURLSeparator
,"Invalid Relative URL");
323 PathStatus aStatus
= _aBaseStatus
;
325 // do we have a base path ?
326 if (!_aBaseURL
.isEmpty())
328 OSL_PRECOND(_aBaseURL
[_aBaseURL
.getLength()-1] != cURLSeparator
,"Unexpected: base URL ends in slash");
330 sDerivedURL
= OUStringBuffer(_aBaseURL
).append(cURLSeparator
).append(_sRelativeURL
).makeStringAndClear();
332 // a derived (nested) URL can only exist or have a lesser status, if the parent exists
333 if (aStatus
== Bootstrap::PATH_EXISTS
)
334 aStatus
= checkStatusAndNormalizeURL(sDerivedURL
);
336 else // the relative appendix must be valid
337 OSL_ASSERT(aStatus
!= Bootstrap::PATH_VALID
|| dbgCheckStatusOfURL(sDerivedURL
) == Bootstrap::PATH_VALID
);
339 _rData
.getFrom(_sBootstrapParameter
, _rURL
, sDerivedURL
);
341 OSL_ENSURE(sDerivedURL
== _rURL
,"Could not set derived URL via Bootstrap default parameter");
342 OSL_POSTCOND(RTL_BOOTSTRAP_DEFAULTS_BROKEN
||
343 (_rData
.getFrom(_sBootstrapParameter
,sDerivedURL
) && sDerivedURL
==_rURL
),"Use of default did not affect bootstrap value");
350 // if we have no data it can't be a valid path
351 OSL_ASSERT( aStatus
> Bootstrap::PATH_VALID
);
358 // ----------------------------------------------------------------------------------
361 PathStatus
getDerivedPath(
363 Bootstrap::Impl::PathData
const& _aBaseData
,
364 OUString
const& _sRelativeURL
,
365 rtl::Bootstrap
& _rData
, OUString
const& _sBootstrapParameter
368 return getDerivedPath(_rURL
,_aBaseData
.path
,_aBaseData
.status
,_sRelativeURL
,_rData
,_sBootstrapParameter
);
371 // ---------------------------------------------------------------------------------------
374 OUString
getExecutableBaseName()
376 OUString sExecutable
;
378 if (osl_Process_E_None
== osl_getExecutableFile(&sExecutable
.pData
))
380 // split the executable name
381 sal_Int32 nSepIndex
= sExecutable
.lastIndexOf(cURLSeparator
);
383 sExecutable
= sExecutable
.copy(nSepIndex
+ 1);
385 // ... and get the basename (strip the extension)
386 sal_Unicode
const cExtensionSep
= '.';
388 sal_Int32
const nExtIndex
= sExecutable
.lastIndexOf(cExtensionSep
);
389 sal_Int32
const nExtLength
= sExecutable
.getLength() - nExtIndex
- 1;
390 if (0 < nExtIndex
&& nExtLength
< 4)
391 sExecutable
= sExecutable
.copy(0,nExtIndex
);
394 OSL_TRACE("Cannot get executable name: osl_getExecutableFile failed");
399 // ----------------------------------------------------------------------------------
403 Bootstrap::PathStatus
updateStatus(Bootstrap::Impl::PathData
& _rResult
)
405 return _rResult
.status
= checkStatusAndNormalizeURL(_rResult
.path
);
407 // ---------------------------------------------------------------------------------------
410 Bootstrap::PathStatus
implGetBootstrapFile(rtl::Bootstrap
& _rData
, Bootstrap::Impl::PathData
& _rBootstrapFile
)
412 _rData
.getIniName(_rBootstrapFile
.path
);
414 return updateStatus(_rBootstrapFile
);
416 // ---------------------------------------------------------------------------------------
419 Bootstrap::PathStatus
implGetVersionFile(rtl::Bootstrap
& _rData
, Bootstrap::Impl::PathData
& _rVersionFile
)
421 OUString
const csVersionFileItem(BOOTSTRAP_ITEM_VERSIONFILE
);
423 _rData
.getFrom(csVersionFileItem
,_rVersionFile
.path
);
425 return updateStatus(_rVersionFile
);
427 // ---------------------------------------------------------------------------------------
430 static char const IS_MISSING
[] = "is missing";
431 static char const IS_INVALID
[] = "is corrupt";
432 static char const PERIOD
[] = ". ";
434 // ---------------------------------------------------------------------------------------
435 static void addFileError(OUStringBuffer
& _rBuf
, OUString
const& _aPath
, AsciiString _sWhat
)
437 OUString sSimpleFileName
= _aPath
.copy(1 +_aPath
.lastIndexOf(cURLSeparator
));
439 _rBuf
.appendAscii("The configuration file");
440 _rBuf
.appendAscii(" '").append(sSimpleFileName
).appendAscii("' ");
441 _rBuf
.appendAscii(_sWhat
).appendAscii(PERIOD
);
443 // ---------------------------------------------------------------------------------------
445 static void addMissingDirectoryError(OUStringBuffer
& _rBuf
, OUString
const& _aPath
)
447 _rBuf
.appendAscii("The configuration directory");
448 _rBuf
.appendAscii(" '").append(_aPath
).appendAscii("' ");
449 _rBuf
.appendAscii(IS_MISSING
).appendAscii(PERIOD
);
451 // ---------------------------------------------------------------------------------------
453 static void addUnexpectedError(OUStringBuffer
& _rBuf
, AsciiString _sExtraInfo
= NULL
)
455 if (NULL
== _sExtraInfo
)
456 _sExtraInfo
= "An internal failure occurred";
458 _rBuf
.appendAscii(_sExtraInfo
).appendAscii(PERIOD
);
460 // ---------------------------------------------------------------------------------------
462 static Bootstrap::FailureCode
describeError(OUStringBuffer
& _rBuf
, Bootstrap::Impl
const& _rData
)
464 Bootstrap::FailureCode eErrCode
= Bootstrap::INVALID_BOOTSTRAP_DATA
;
466 _rBuf
.appendAscii("The program cannot be started. ");
468 switch (_rData
.aUserInstall_
.status
)
470 case Bootstrap::PATH_EXISTS
:
471 switch (_rData
.aBaseInstall_
.status
)
473 case Bootstrap::PATH_VALID
:
474 addMissingDirectoryError(_rBuf
, _rData
.aBaseInstall_
.path
);
475 eErrCode
= Bootstrap::MISSING_INSTALL_DIRECTORY
;
478 case Bootstrap::DATA_INVALID
:
479 addUnexpectedError(_rBuf
,"The installation path is invalid");
482 case Bootstrap::DATA_MISSING
:
483 addUnexpectedError(_rBuf
,"The installation path is not available");
486 case Bootstrap::PATH_EXISTS
: // seems to be all fine (?)
487 addUnexpectedError(_rBuf
,"");
490 default: OSL_ASSERT(false);
491 addUnexpectedError(_rBuf
);
496 case Bootstrap::PATH_VALID
:
497 addMissingDirectoryError(_rBuf
, _rData
.aUserInstall_
.path
);
498 eErrCode
= Bootstrap::MISSING_USER_DIRECTORY
;
502 case Bootstrap::DATA_INVALID
:
503 if (_rData
.aVersionINI_
.status
== Bootstrap::PATH_EXISTS
)
505 addFileError(_rBuf
, _rData
.aVersionINI_
.path
, IS_INVALID
);
506 eErrCode
= Bootstrap::INVALID_VERSION_FILE_ENTRY
;
511 case Bootstrap::DATA_MISSING
:
512 switch (_rData
.aVersionINI_
.status
)
514 case Bootstrap::PATH_EXISTS
:
515 addFileError(_rBuf
, _rData
.aVersionINI_
.path
, "does not support the current version");
516 eErrCode
= Bootstrap::MISSING_VERSION_FILE_ENTRY
;
519 case Bootstrap::PATH_VALID
:
520 addFileError(_rBuf
, _rData
.aVersionINI_
.path
, IS_MISSING
);
521 eErrCode
= Bootstrap::MISSING_VERSION_FILE
;
525 switch (_rData
.aBootstrapINI_
.status
)
527 case Bootstrap::PATH_EXISTS
:
528 addFileError(_rBuf
, _rData
.aBootstrapINI_
.path
, IS_INVALID
);
530 if (_rData
.aVersionINI_
.status
== Bootstrap::DATA_MISSING
)
531 eErrCode
= Bootstrap::MISSING_BOOTSTRAP_FILE_ENTRY
;
533 eErrCode
= Bootstrap::INVALID_BOOTSTRAP_FILE_ENTRY
;
536 case Bootstrap::DATA_INVALID
: OSL_ASSERT(false);
537 case Bootstrap::PATH_VALID
:
538 addFileError(_rBuf
, _rData
.aBootstrapINI_
.path
, IS_MISSING
);
539 eErrCode
= Bootstrap::MISSING_BOOTSTRAP_FILE
;
543 addUnexpectedError(_rBuf
);
550 default: OSL_ASSERT(false);
551 addUnexpectedError(_rBuf
);
557 // ---------------------------------------------------------------------------------------
558 // ---------------------------------------------------------------------------------------
560 // ---------------------------------------------------------------------------------------
562 OUString
Bootstrap::getProductKey()
564 OUString
const csProductKeyItem(BOOTSTRAP_ITEM_PRODUCT_KEY
);
566 OUString
const sDefaultProductKey
= getExecutableBaseName();
568 return data().getBootstrapValue( csProductKeyItem
, sDefaultProductKey
);
570 // ---------------------------------------------------------------------------------------
572 OUString
Bootstrap::getProductKey(OUString
const& _sDefault
)
574 OUString
const csProductKeyItem(BOOTSTRAP_ITEM_PRODUCT_KEY
);
576 return data().getBootstrapValue( csProductKeyItem
, _sDefault
);
578 // ---------------------------------------------------------------------------------------
580 OUString
Bootstrap::getBuildVersion(OUString
const& _sDefault
)
582 OUString
const csBuildVersionItem(BOOTSTRAP_ITEM_BUILDVERSION
);
584 OUString sBuildVersion
;
585 // read BuildVersion from version.ini (versionrc)
586 data().getVersionValue( csBuildVersionItem
, sBuildVersion
, _sDefault
);
587 return sBuildVersion
;
589 // ---------------------------------------------------------------------------------------
591 OUString
Bootstrap::getBuildIdData(OUString
const& _sDefault
)
593 OUString
const csBuildIdItem(BOOTSTRAP_ITEM_BUILDID
);
596 // read buildid from version.ini (versionrc), if it doesn't exist or buildid is empty
597 if ( data().getVersionValue( csBuildIdItem
, sBuildId
, _sDefault
) != sal_True
||
599 // read buildid from bootstrap.ini (bootstraprc)
600 sBuildId
= data().getBootstrapValue( csBuildIdItem
, _sDefault
);
604 // ---------------------------------------------------------------------------------------
606 Bootstrap::PathStatus
Bootstrap::locateBaseInstallation(OUString
& _rURL
)
608 Impl::PathData
const& aPathData
= data().aBaseInstall_
;
610 _rURL
= aPathData
.path
;
611 return aPathData
.status
;
613 // ---------------------------------------------------------------------------------------
615 PathStatus
Bootstrap::locateUserInstallation(OUString
& _rURL
)
617 Impl::PathData
const& aPathData
= data().aUserInstall_
;
619 _rURL
= aPathData
.path
;
620 return aPathData
.status
;
623 // ---------------------------------------------------------------------------------------
625 PathStatus
Bootstrap::locateUserData(OUString
& _rURL
)
627 OUString
const csUserDirItem(BOOTSTRAP_ITEM_USERDIR
);
629 rtl::Bootstrap
aData( data().getImplName() );
631 if ( aData
.getFrom(csUserDirItem
, _rURL
) )
633 return checkStatusAndNormalizeURL(_rURL
);
637 OUString
const csUserDir(BOOTSTRAP_DIRNAME_USERDIR
);
638 return getDerivedPath(_rURL
, data().aUserInstall_
,csUserDir
, aData
, csUserDirItem
);
641 // ---------------------------------------------------------------------------------------
643 PathStatus
Bootstrap::locateBootstrapFile(OUString
& _rURL
)
645 Impl::PathData
const& aPathData
= data().aBootstrapINI_
;
647 _rURL
= aPathData
.path
;
648 return aPathData
.status
;
650 // ---------------------------------------------------------------------------------------
652 PathStatus
Bootstrap::locateVersionFile(OUString
& _rURL
)
654 Impl::PathData
const& aPathData
= data().aVersionINI_
;
656 _rURL
= aPathData
.path
;
657 return aPathData
.status
;
659 // ---------------------------------------------------------------------------------------
661 Bootstrap::Status
Bootstrap::checkBootstrapStatus(OUString
& _rDiagnosticMessage
, FailureCode
& _rErrCode
)
663 Impl
const& aData
= data();
665 Status result
= aData
.status_
;
667 // maybe do further checks here
669 OUStringBuffer sErrorBuffer
;
670 if (result
!= DATA_OK
)
671 _rErrCode
= describeError(sErrorBuffer
,aData
);
674 _rErrCode
= NO_FAILURE
;
676 _rDiagnosticMessage
= sErrorBuffer
.makeStringAndClear();
681 // ---------------------------------------------------------------------------------------
682 // class Bootstrap::Impl
683 // ---------------------------------------------------------------------------------------
685 bool Bootstrap::Impl::initBaseInstallationData(rtl::Bootstrap
& _rData
)
687 OUString
const csBaseInstallItem( BOOTSTRAP_ITEM_BASEINSTALLATION
);
688 OUString
const csBaseInstallDefault( BOOTSTRAP_DEFAULT_BASEINSTALL
);
690 _rData
.getFrom(csBaseInstallItem
, aBaseInstall_
.path
, csBaseInstallDefault
);
692 bool bResult
= (PATH_EXISTS
== updateStatus(aBaseInstall_
));
694 implGetBootstrapFile(_rData
, aBootstrapINI_
);
698 // ---------------------------------------------------------------------------------------
700 bool Bootstrap::Impl::initUserInstallationData(rtl::Bootstrap
& _rData
)
702 OUString
const csUserInstallItem( BOOTSTRAP_ITEM_USERINSTALLATION
);
704 if (_rData
.getFrom(csUserInstallItem
, aUserInstall_
.path
))
706 updateStatus(aUserInstall_
);
710 // should we do just this
711 aUserInstall_
.status
= DATA_MISSING
;
713 // .. or this - look for a single-user user directory ?
714 OUString
const csUserDirItem(BOOTSTRAP_ITEM_USERDIR
);
716 // look for $BASEINSTALLATION/user only if default UserDir setting is used
717 if (! _rData
.getFrom(csUserDirItem
, sDummy
))
719 OUString
const csUserDir(BOOTSTRAP_DIRNAME_USERDIR
);
721 if ( PATH_EXISTS
== getDerivedPath(sDummy
, aBaseInstall_
, csUserDir
, _rData
, csUserDirItem
) )
722 aUserInstall_
= aBaseInstall_
;
726 bool bResult
= (PATH_EXISTS
== aUserInstall_
.status
);
728 implGetVersionFile(_rData
, aVersionINI_
);
732 // ---------------------------------------------------------------------------------------
734 void Bootstrap::Impl::initialize()
736 rtl::Bootstrap
aData( m_aImplName
);
738 if (!initBaseInstallationData(aData
))
740 status_
= INVALID_BASE_INSTALL
;
742 else if (!initUserInstallationData(aData
))
744 status_
= INVALID_USER_INSTALL
;
746 if (aUserInstall_
.status
>= DATA_MISSING
)
748 switch (aVersionINI_
.status
)
752 status_
= MISSING_USER_INSTALL
;
757 status_
= INVALID_BASE_INSTALL
;
769 // ---------------------------------------------------------------------------------------
771 OUString
Bootstrap::Impl::getBootstrapValue(OUString
const& _sName
, OUString
const& _sDefault
) const
773 rtl::Bootstrap
aData( m_aImplName
);
776 aData
.getFrom(_sName
,sResult
,_sDefault
);
779 // ---------------------------------------------------------------------------------------
781 sal_Bool
Bootstrap::Impl::getVersionValue(OUString
const& _sName
, OUString
& _rValue
, OUString
const& _sDefault
) const
783 // try to open version.ini (versionrc)
785 rtl::Bootstrap::get( OUString("BRAND_BASE_DIR"), uri
);
786 rtl::Bootstrap
aData( uri
+ "/program/" SAL_CONFIGFILE("version") );
787 if ( aData
.getHandle() == NULL
)
788 // version.ini (versionrc) doesn't exist
792 aData
.getFrom(_sName
,_rValue
,_sDefault
);
795 // ---------------------------------------------------------------------------------------
799 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */