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 .
22 #include "file_url.hxx"
23 #include "path_helper.hxx"
26 #include <osl/diagnose.h>
27 #include <osl/profile.h>
28 #include <osl/process.h>
29 #include <osl/thread.h>
31 #include <rtl/alloc.h>
32 #include <sal/macros.h>
33 #include <sal/log.hxx>
34 #include <o3tl/char16_t2wchar_t.hxx>
38 static void copy_ustr_n( void *dest
, const void *source
, size_t length
) { memcpy(dest
, source
, length
*sizeof(sal_Unicode
)); }
42 #define SECTIONS_INI 5
43 #define SECTIONS_ADD 3
47 #define STR_INI_EXTENSION L".ini"
48 #define STR_INI_METAHOME "?~"
49 #define STR_INI_METASYS "?$"
50 #define STR_INI_METACFG "?^"
51 #define STR_INI_METAINS "?#"
53 #define STR_INI_BOOLYES "yes"
54 #define STR_INI_BOOLON "on"
55 #define STR_INI_BOOLONE "1"
56 #define STR_INI_BOOLNO "no"
57 #define STR_INI_BOOLOFF "off"
58 #define STR_INI_BOOLZERO "0"
60 #define FLG_USER 0x00FF
61 #define FLG_AUTOOPEN 0x0100
62 #define FLG_MODIFIED 0x0200
64 #define SVERSION_LOCATION STR_INI_METACFG
65 #define SVERSION_FALLBACK STR_INI_METASYS
66 #define SVERSION_NAME "sversion"
67 #define SVERSION_SECTION "Versions"
68 #define SVERSION_SOFFICE "StarOffice"
69 #define SVERSION_PROFILE "soffice.ini"
70 #define SVERSION_DIRS { "bin", "program" }
71 #define SVERSION_USER "user"
73 /*#define DEBUG_OSL_PROFILE 1*/
75 typedef FILETIME osl_TStamp
;
81 un_lock
, read_lock
, write_lock
90 sal_uInt32 m_nWriteBufLen
;
91 sal_uInt32 m_nWriteBufFree
;
94 struct osl_TProfileEntry
101 struct osl_TProfileSection
106 sal_uInt32 m_NoEntries
;
107 sal_uInt32 m_MaxEntries
;
108 osl_TProfileEntry
* m_Entries
;
112 Profile-data structure hidden behind oslProfile:
114 struct osl_TProfileImpl
119 sal_uInt32 m_NoLines
;
120 sal_uInt32 m_MaxLines
;
121 sal_uInt32 m_NoSections
;
122 sal_uInt32 m_MaxSections
;
124 rtl_uString
*m_strFileName
;
125 osl_TProfileSection
* m_Sections
;
130 static osl_TFile
* openFileImpl(rtl_uString
* strFileName
, oslProfileOption ProfileFlags
);
131 static osl_TStamp
closeFileImpl(osl_TFile
* pFile
);
132 static bool lockFile(const osl_TFile
* pFile
, osl_TLockMode eMode
);
133 static bool rewindFile(osl_TFile
* pFile
, bool bTruncate
);
134 static osl_TStamp
getFileStamp(osl_TFile
* pFile
);
136 static bool getLine(osl_TFile
* pFile
, char *pszLine
, int MaxLen
);
137 static bool putLine(osl_TFile
* pFile
, const char *pszLine
);
138 static const char* stripBlanks(const char* String
, sal_uInt32
* pLen
);
139 static const char* addLine(osl_TProfileImpl
* pProfile
, const char* Line
);
140 static const char* insertLine(osl_TProfileImpl
* pProfile
, const char* Line
, sal_uInt32 LineNo
);
141 static void removeLine(osl_TProfileImpl
* pProfile
, sal_uInt32 LineNo
);
142 static void setEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
* pSection
,
143 sal_uInt32 NoEntry
, sal_uInt32 Line
,
144 const char* Entry
, sal_uInt32 Len
);
145 static bool addEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
,
146 int Line
, const char* Entry
, sal_uInt32 Len
);
147 static void removeEntry(osl_TProfileSection
*pSection
, sal_uInt32 NoEntry
);
148 static bool addSection(osl_TProfileImpl
* pProfile
, int Line
, const char* Section
, sal_uInt32 Len
);
149 static void removeSection(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
);
150 static osl_TProfileSection
* findEntry(osl_TProfileImpl
* pProfile
, const char* Section
,
151 const char* Entry
, sal_uInt32
*pNoEntry
);
152 static bool loadProfile(osl_TFile
* pFile
, osl_TProfileImpl
* pProfile
);
153 static bool storeProfile(osl_TProfileImpl
* pProfile
, bool bCleanup
);
154 static osl_TProfileImpl
* acquireProfile(oslProfile Profile
, bool bWriteable
);
155 static bool releaseProfile(osl_TProfileImpl
* pProfile
);
156 static bool lookupProfile(const sal_Unicode
*strPath
, const sal_Unicode
*strFile
, sal_Unicode
*strProfile
);
158 static bool writeProfileImpl (osl_TFile
* pFile
);
159 static osl_TFile
* osl_openTmpProfileImpl(osl_TProfileImpl
*);
160 static bool osl_ProfileSwapProfileNames(osl_TProfileImpl
*);
161 static rtl_uString
* osl_ProfileGenerateExtension(rtl_uString
* ustrFileName
, rtl_uString
* ustrExtension
);
163 static bool osl_getProfileName(rtl_uString
* strPath
, rtl_uString
* strName
, rtl_uString
** strProfileName
);
165 oslProfile SAL_CALL
osl_openProfile(rtl_uString
*strProfileName
, oslProfileOption Flags
)
167 osl_TFile
* pFile
= nullptr;
168 osl_TProfileImpl
* pProfile
;
169 rtl_uString
*FileName
=nullptr;
171 OSL_VERIFY(strProfileName
);
173 if (rtl_uString_getLength(strProfileName
) == 0 )
175 OSL_VERIFY(osl_getProfileName(nullptr, nullptr, &FileName
));
179 rtl_uString_assign(&FileName
, strProfileName
);
182 osl_getSystemPathFromFileURL(FileName
, &FileName
);
184 #ifdef DEBUG_OSL_PROFILE
185 Flags
=osl_Profile_FLUSHWRITE
;
187 if ( Flags
== osl_Profile_DEFAULT
)
189 SAL_INFO("sal.osl", "with osl_Profile_DEFAULT");
191 if ( Flags
& osl_Profile_SYSTEM
)
193 SAL_INFO("sal.osl", "with osl_Profile_SYSTEM");
195 if ( Flags
& osl_Profile_READLOCK
)
197 SAL_INFO("sal.osl", "with osl_Profile_READLOCK");
199 if ( Flags
& osl_Profile_WRITELOCK
)
201 SAL_INFO("sal.osl", "with osl_Profile_WRITELOCK");
203 if ( Flags
& osl_Profile_FLUSHWRITE
)
205 SAL_INFO("sal.osl", "with osl_Profile_FLUSHWRITE");
209 if ( (! (Flags
& osl_Profile_SYSTEM
)) && ( (pFile
= openFileImpl(FileName
, Flags
) ) == nullptr ) )
212 rtl_uString_release( FileName
);
217 pProfile
= static_cast<osl_TProfileImpl
*>(calloc(1, sizeof(osl_TProfileImpl
)));
221 pProfile
->m_Flags
= Flags
& FLG_USER
;
222 osl_getSystemPathFromFileURL(strProfileName
, &pProfile
->m_strFileName
);
224 if (Flags
& (osl_Profile_READLOCK
| osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
))
225 pProfile
->m_pFile
= pFile
;
227 pProfile
->m_Stamp
= getFileStamp(pFile
);
229 loadProfile(pFile
, pProfile
);
231 if (pProfile
->m_pFile
== nullptr)
232 closeFileImpl(pFile
);
235 rtl_uString_release( FileName
);
240 sal_Bool SAL_CALL
osl_closeProfile(oslProfile Profile
)
242 osl_TProfileImpl
* pProfile
= static_cast<osl_TProfileImpl
*>(Profile
);
245 if ( Profile
== nullptr )
250 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
252 pProfile
= acquireProfile(Profile
,true);
254 if ( pProfile
!= nullptr )
256 if ( !( pProfile
->m_Flags
& osl_Profile_READLOCK
) && ( pProfile
->m_Flags
& FLG_MODIFIED
) )
258 storeProfile(pProfile
, false);
263 pProfile
= acquireProfile(Profile
,false);
266 if ( pProfile
== nullptr )
271 if (pProfile
->m_pFile
!= nullptr)
272 closeFileImpl(pProfile
->m_pFile
);
275 pProfile
->m_pFile
= nullptr;
276 rtl_uString_release(pProfile
->m_strFileName
);
277 pProfile
->m_strFileName
= nullptr;
279 /* release whole profile data types memory */
280 if ( pProfile
->m_NoLines
> 0)
282 unsigned int index
=0;
283 if ( pProfile
->m_Lines
!= nullptr )
285 for ( index
= 0 ; index
< pProfile
->m_NoLines
; ++index
)
287 if ( pProfile
->m_Lines
[index
] != nullptr )
289 free(pProfile
->m_Lines
[index
]);
292 free(pProfile
->m_Lines
);
294 if ( pProfile
->m_Sections
!= nullptr )
296 for ( index
= 0 ; index
< pProfile
->m_NoSections
; ++index
)
298 if ( pProfile
->m_Sections
[index
].m_Entries
!= nullptr )
299 free(pProfile
->m_Sections
[index
].m_Entries
);
301 free(pProfile
->m_Sections
);
310 sal_Bool SAL_CALL
osl_flushProfile(oslProfile Profile
)
312 osl_TProfileImpl
* pProfile
= static_cast<osl_TProfileImpl
*>(Profile
);
317 if ( pProfile
== nullptr )
322 pFile
= pProfile
->m_pFile
;
323 if ( pFile
== nullptr || pFile
->m_Handle
== INVALID_HANDLE_VALUE
)
328 if ( pProfile
->m_Flags
& FLG_MODIFIED
)
330 #ifdef DEBUG_OSL_PROFILE
331 SAL_INFO("sal.osl", "swapping to storeprofile");
333 bRet
= storeProfile(pProfile
,false);
339 static bool writeProfileImpl(osl_TFile
* pFile
)
341 DWORD BytesWritten
=0;
344 if ( pFile
== nullptr || pFile
->m_Handle
== INVALID_HANDLE_VALUE
|| ( pFile
->m_pWriteBuf
== nullptr ) )
349 bRet
=WriteFile(pFile
->m_Handle
, pFile
->m_pWriteBuf
, pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
,&BytesWritten
,nullptr);
351 if ( !bRet
|| BytesWritten
== 0 )
353 OSL_ENSURE(bRet
,"WriteFile failed!!!");
354 SAL_WARN("sal.osl", "write failed " << strerror(errno
));
359 free(pFile
->m_pWriteBuf
);
360 pFile
->m_pWriteBuf
=nullptr;
361 pFile
->m_nWriteBufLen
=0;
362 pFile
->m_nWriteBufFree
=0;
368 // Use Unicode version of GetPrivateProfileString, to work with Multi-language paths
369 DWORD
GetPrivateProfileStringWrapper(const osl_TProfileImpl
* pProfile
,
370 const char* pszSection
, const char* pszEntry
,
371 char* pszString
, sal_uInt32 MaxLen
,
372 const char* pszDefault
)
374 OSL_ASSERT(pProfile
&& (!MaxLen
|| pszString
));
376 rtl_uString
*pSection
= nullptr, *pEntry
= nullptr, *pDefault
= nullptr;
379 rtl_string2UString(&pSection
, pszSection
, strlen(pszSection
), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
380 OSL_ASSERT(pSection
);
384 rtl_string2UString(&pEntry
, pszEntry
, strlen(pszEntry
), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
389 rtl_string2UString(&pDefault
, pszDefault
, strlen(pszDefault
), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
390 OSL_ASSERT(pDefault
);
393 LPCWSTR pWSection
= (pSection
? o3tl::toW(rtl_uString_getStr(pSection
)) : nullptr),
394 pWEntry
= (pEntry
? o3tl::toW(rtl_uString_getStr(pEntry
)) : nullptr),
395 pWDefault
= (pDefault
? o3tl::toW(rtl_uString_getStr(pDefault
)) : nullptr);
397 std::vector
<wchar_t> aBuf(MaxLen
+ 1);
398 GetPrivateProfileStringW(pWSection
, pWEntry
, pWDefault
, aBuf
.data(), MaxLen
, o3tl::toW(rtl_uString_getStr(pProfile
->m_strFileName
)));
401 rtl_uString_release(pDefault
);
403 rtl_uString_release(pEntry
);
405 rtl_uString_release(pSection
);
407 return WideCharToMultiByte(CP_ACP
, 0, aBuf
.data(), -1, pszString
, MaxLen
, nullptr, nullptr);
410 // Use Unicode version of WritePrivateProfileString, to work with Multi-language paths
411 bool WritePrivateProfileStringWrapper(const osl_TProfileImpl
* pProfile
,
412 const char* pszSection
, const char* pszEntry
,
413 const char* pszString
)
415 OSL_ASSERT(pProfile
&& pszSection
);
416 rtl_uString
*pSection
, *pEntry
= nullptr, *pString
= nullptr;
417 rtl_string2UString(&pSection
, pszSection
, strlen(pszSection
), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
418 OSL_ASSERT(pSection
);
421 rtl_string2UString(&pEntry
, pszEntry
, strlen(pszEntry
), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
426 rtl_string2UString(&pString
, pszString
, strlen(pszString
), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
430 LPCWSTR pWSection
= o3tl::toW(pSection
->buffer
),
431 pWEntry
= (pEntry
? o3tl::toW(rtl_uString_getStr(pEntry
)) : nullptr),
432 pWString
= (pString
? o3tl::toW(rtl_uString_getStr(pString
)) : nullptr);
434 bool bResult
= WritePrivateProfileStringW(pWSection
, pWEntry
, pWString
, o3tl::toW(rtl_uString_getStr(pProfile
->m_strFileName
)));
437 rtl_uString_release(pString
);
439 rtl_uString_release(pEntry
);
440 rtl_uString_release(pSection
);
446 sal_Bool SAL_CALL
osl_readProfileString(oslProfile Profile
,
447 const char* pszSection
, const char* pszEntry
,
448 char* pszString
, sal_uInt32 MaxLen
,
449 const char* pszDefault
)
452 const char* pStr
= nullptr;
453 osl_TProfileImpl
* pProfile
= nullptr;
455 pProfile
= acquireProfile(Profile
, false);
457 if (pProfile
== nullptr)
462 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
464 osl_TProfileSection
* pSec
;
465 if (((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) != nullptr) &&
466 (NoEntry
< pSec
->m_NoEntries
) &&
467 ((pStr
= strchr(pProfile
->m_Lines
[pSec
->m_Entries
[NoEntry
].m_Line
],
473 if ( pStr
!= nullptr )
475 pStr
= stripBlanks(pStr
, nullptr);
476 MaxLen
= (MaxLen
- 1 < strlen(pStr
)) ? (MaxLen
- 1) : strlen(pStr
);
477 pStr
= stripBlanks(pStr
, &MaxLen
);
478 strncpy(pszString
, pStr
, MaxLen
);
479 pszString
[MaxLen
] = '\0';
484 if (GetPrivateProfileStringWrapper(pProfile
, pszSection
, pszEntry
, pszString
, MaxLen
, pszDefault
) > 0)
485 pStr
= pszString
; // required to return true below
488 releaseProfile(pProfile
);
490 if ( pStr
== nullptr )
498 sal_Bool SAL_CALL
osl_readProfileBool(oslProfile Profile
,
499 const char* pszSection
, const char* pszEntry
,
504 if (osl_readProfileString(Profile
, pszSection
, pszEntry
, Line
, sizeof(Line
), ""))
506 if ((stricmp(Line
, STR_INI_BOOLYES
) == 0) ||
507 (stricmp(Line
, STR_INI_BOOLON
) == 0) ||
508 (stricmp(Line
, STR_INI_BOOLONE
) == 0))
511 if ((stricmp(Line
, STR_INI_BOOLNO
) == 0) ||
512 (stricmp(Line
, STR_INI_BOOLOFF
) == 0) ||
513 (stricmp(Line
, STR_INI_BOOLZERO
) == 0))
520 sal_uInt32 SAL_CALL
osl_readProfileIdent(oslProfile Profile
,
521 const char* pszSection
, const char* pszEntry
,
522 sal_uInt32 FirstId
, const char* Strings
[],
528 if (osl_readProfileString(Profile
, pszSection
, pszEntry
, Line
, sizeof(Line
), ""))
531 while (Strings
[i
] != nullptr)
533 if (stricmp(Line
, Strings
[i
]) == 0)
535 Default
= i
+ FirstId
;
545 sal_Bool SAL_CALL
osl_writeProfileString(oslProfile Profile
,
546 const char* pszSection
, const char* pszEntry
,
547 const char* pszString
)
554 osl_TProfileSection
* pSec
;
555 osl_TProfileImpl
* pProfile
= nullptr;
557 pProfile
= acquireProfile(Profile
, true);
559 if (pProfile
== nullptr)
564 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
566 if ((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) == nullptr)
569 addLine(pProfile
, Line
);
572 strcpy(&Line
[1], pszSection
);
573 Line
[1 + strlen(pszSection
)] = ']';
574 Line
[2 + strlen(pszSection
)] = '\0';
576 if (((pStr
= addLine(pProfile
, Line
)) == nullptr) ||
577 (! addSection(pProfile
, pProfile
->m_NoLines
- 1, &pStr
[1], strlen(pszSection
))))
579 releaseProfile(pProfile
);
583 pSec
= &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1];
584 NoEntry
= pSec
->m_NoEntries
;
588 strcpy(&Line
[0], pszEntry
);
589 Line
[0 + strlen(pszEntry
)] = '=';
590 strcpy(&Line
[1 + strlen(pszEntry
)], pszString
);
592 if (NoEntry
>= pSec
->m_NoEntries
)
594 if (pSec
->m_NoEntries
> 0)
595 i
= pSec
->m_Entries
[pSec
->m_NoEntries
- 1].m_Line
+ 1;
597 i
= pSec
->m_Line
+ 1;
599 if (((pStr
= insertLine(pProfile
, Line
, i
)) == nullptr) ||
600 (! addEntry(pProfile
, pSec
, i
, pStr
, strlen(pszEntry
))))
602 releaseProfile(pProfile
);
606 pProfile
->m_Flags
|= FLG_MODIFIED
;
610 i
= pSec
->m_Entries
[NoEntry
].m_Line
;
611 free(pProfile
->m_Lines
[i
]);
612 pProfile
->m_Lines
[i
] = strdup(Line
);
613 setEntry(pProfile
, pSec
, NoEntry
, i
, pProfile
->m_Lines
[i
], strlen(pszEntry
));
615 pProfile
->m_Flags
|= FLG_MODIFIED
;
620 WritePrivateProfileStringWrapper(pProfile
, pszSection
, pszEntry
, pszString
);
623 bRet
= releaseProfile(pProfile
);
627 sal_Bool SAL_CALL
osl_writeProfileBool(oslProfile Profile
,
628 const char* pszSection
, const char* pszEntry
,
634 bRet
=osl_writeProfileString(Profile
, pszSection
, pszEntry
, STR_INI_BOOLONE
);
636 bRet
=osl_writeProfileString(Profile
, pszSection
, pszEntry
, STR_INI_BOOLZERO
);
641 sal_Bool SAL_CALL
osl_writeProfileIdent(oslProfile Profile
,
642 const char* pszSection
, const char* pszEntry
,
643 sal_uInt32 FirstId
, const char* Strings
[],
649 for (n
= 0; Strings
[n
] != nullptr; n
++);
651 if ((i
= Value
- FirstId
) >= n
)
654 bRet
=osl_writeProfileString(Profile
, pszSection
, pszEntry
, Strings
[i
]);
659 sal_Bool SAL_CALL
osl_removeProfileEntry(oslProfile Profile
,
660 const char *pszSection
, const char *pszEntry
)
663 osl_TProfileImpl
* pProfile
= nullptr;
666 pProfile
= acquireProfile(Profile
, true);
668 if (pProfile
== nullptr)
671 if (!(pProfile
->m_Flags
& osl_Profile_SYSTEM
))
673 osl_TProfileSection
* pSec
;
674 if (((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) != nullptr) &&
675 (NoEntry
< pSec
->m_NoEntries
))
677 removeLine(pProfile
, pSec
->m_Entries
[NoEntry
].m_Line
);
678 removeEntry(pSec
, NoEntry
);
679 if (pSec
->m_NoEntries
== 0)
681 removeLine(pProfile
, pSec
->m_Line
);
683 /* remove any empty separation line */
684 if ((pSec
->m_Line
> 0) && (pProfile
->m_Lines
[pSec
->m_Line
- 1][0] == '\0'))
685 removeLine(pProfile
, pSec
->m_Line
- 1);
687 removeSection(pProfile
, pSec
);
690 pProfile
->m_Flags
|= FLG_MODIFIED
;
695 WritePrivateProfileStringWrapper(pProfile
, pszSection
, pszEntry
, nullptr);
698 bRet
= releaseProfile(pProfile
);
702 sal_uInt32 SAL_CALL
osl_getProfileSectionEntries(oslProfile Profile
, const char *pszSection
,
703 char* pszBuffer
, sal_uInt32 MaxLen
)
707 osl_TProfileImpl
* pProfile
= nullptr;
709 pProfile
= acquireProfile(Profile
, false);
711 if (pProfile
== nullptr)
714 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
716 osl_TProfileSection
* pSec
;
717 if ((pSec
= findEntry(pProfile
, pszSection
, "", &NoEntry
)) != nullptr)
721 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
723 if ((n
+ pSec
->m_Entries
[i
].m_Len
+ 1) < MaxLen
)
725 strncpy(&pszBuffer
[n
], &pProfile
->m_Lines
[pSec
->m_Entries
[i
].m_Line
]
726 [pSec
->m_Entries
[i
].m_Offset
], pSec
->m_Entries
[i
].m_Len
);
727 n
+= pSec
->m_Entries
[i
].m_Len
;
728 pszBuffer
[n
++] = '\0';
737 pszBuffer
[n
++] = '\0';
741 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
743 n
+= pSec
->m_Entries
[i
].m_Len
+ 1;
756 n
= GetPrivateProfileStringWrapper(pProfile
, pszSection
, nullptr, pszBuffer
, MaxLen
, nullptr);
759 releaseProfile(pProfile
);
764 bool osl_getProfileName(rtl_uString
* strPath
, rtl_uString
* strName
, rtl_uString
** strProfileName
)
767 ::osl::LongPathBuffer
< sal_Unicode
> aFile( MAX_LONG_PATH
);
768 ::osl::LongPathBuffer
< sal_Unicode
> aPath( MAX_LONG_PATH
);
769 sal_uInt32 nFileLen
= 0;
770 sal_uInt32 nPathLen
= 0;
772 rtl_uString
* strTmp
= nullptr;
775 /* build file name */
776 if (strName
&& strName
->length
)
778 if( ::sal::static_int_cast
< sal_uInt32
>( strName
->length
) >= aFile
.getBufSizeInSymbols() )
781 copy_ustr_n( aFile
, strName
->buffer
, strName
->length
+1);
782 nFileLen
= strName
->length
;
784 if (rtl_ustr_indexOfChar( aFile
, L
'.' ) == -1)
786 if (nFileLen
+ wcslen(STR_INI_EXTENSION
) >= aFile
.getBufSizeInSymbols())
789 /* add default extension */
790 copy_ustr_n( aFile
+ nFileLen
, STR_INI_EXTENSION
, wcslen(STR_INI_EXTENSION
)+1 );
791 nFileLen
+= wcslen(STR_INI_EXTENSION
);
796 rtl_uString
*strProgName
= nullptr;
797 sal_Unicode
*pProgName
;
798 sal_Int32 nOffset
= 0;
802 if (osl_getExecutableFile(&strProgName
) != osl_Process_E_None
)
805 /* remove path and extension from filename */
806 pProgName
= strProgName
->buffer
;
807 nLen
= strProgName
->length
;
809 if ((nPos
= rtl_ustr_lastIndexOfChar( pProgName
, L
'/' )) != -1)
811 else if ((nPos
= rtl_ustr_lastIndexOfChar( pProgName
, L
':' )) != -1)
814 if ((nPos
= rtl_ustr_lastIndexOfChar( pProgName
, L
'.' )) != -1 )
817 if ((nFileLen
= nLen
- nOffset
) >= aFile
.getBufSizeInSymbols())
820 copy_ustr_n(aFile
, pProgName
+ nOffset
, nFileLen
);
822 if (nFileLen
+ wcslen(STR_INI_EXTENSION
) >= aFile
.getBufSizeInSymbols())
825 /* add default extension */
826 copy_ustr_n(aFile
+ nFileLen
, STR_INI_EXTENSION
, wcslen(STR_INI_EXTENSION
)+1);
827 nFileLen
+= wcslen(STR_INI_EXTENSION
);
829 rtl_uString_release( strProgName
);
835 /* build directory path */
836 if (strPath
&& strPath
->length
)
838 sal_Unicode
*pPath
= rtl_uString_getStr(strPath
);
839 sal_Int32 nLen
= rtl_uString_getLength(strPath
);
841 if ((rtl_ustr_ascii_compare_WithLength(pPath
, RTL_CONSTASCII_LENGTH(STR_INI_METAHOME
) , STR_INI_METAHOME
) == 0) &&
842 ((nLen
== RTL_CONSTASCII_LENGTH(STR_INI_METAHOME
)) || (pPath
[RTL_CONSTASCII_LENGTH(STR_INI_METAHOME
)] == '/')))
844 rtl_uString
* strHome
= nullptr;
845 oslSecurity security
= osl_getCurrentSecurity();
847 bFailed
= ! osl_getHomeDir(security
, &strHome
);
848 osl_freeSecurityHandle(security
);
850 if (bFailed
) return false;
852 if ( ::sal::static_int_cast
< sal_uInt32
>( strHome
->length
) >= aPath
.getBufSizeInSymbols())
855 copy_ustr_n( aPath
, strHome
->buffer
, strHome
->length
+1);
856 nPathLen
= strHome
->length
;
858 if (nLen
> RTL_CONSTASCII_LENGTH(STR_INI_METAHOME
))
860 pPath
+= RTL_CONSTASCII_LENGTH(STR_INI_METAHOME
);
861 nLen
-= RTL_CONSTASCII_LENGTH(STR_INI_METAHOME
);
863 if (nLen
+ nPathLen
>= aPath
.getBufSizeInSymbols())
866 copy_ustr_n(aPath
+ nPathLen
, pPath
, nLen
+1);
870 rtl_uString_release(strHome
);
873 else if ((rtl_ustr_ascii_compare_WithLength(pPath
, RTL_CONSTASCII_LENGTH(STR_INI_METACFG
), STR_INI_METACFG
) == 0) &&
874 ((nLen
== RTL_CONSTASCII_LENGTH(STR_INI_METACFG
)) || (pPath
[RTL_CONSTASCII_LENGTH(STR_INI_METACFG
)] == '/')))
876 rtl_uString
* strConfig
= nullptr;
877 oslSecurity security
= osl_getCurrentSecurity();
879 bFailed
= ! osl_getConfigDir(security
, &strConfig
);
880 osl_freeSecurityHandle(security
);
882 if (bFailed
) return false;
884 if ( ::sal::static_int_cast
< sal_uInt32
>( strConfig
->length
) >= aPath
.getBufSizeInSymbols())
887 copy_ustr_n( aPath
, strConfig
->buffer
, strConfig
->length
+1 );
888 nPathLen
= strConfig
->length
;
890 if (nLen
> RTL_CONSTASCII_LENGTH(STR_INI_METACFG
))
892 pPath
+= RTL_CONSTASCII_LENGTH(STR_INI_METACFG
);
893 nLen
-= RTL_CONSTASCII_LENGTH(STR_INI_METACFG
);
895 if (nLen
+ nPathLen
>= aPath
.getBufSizeInSymbols())
898 copy_ustr_n(aPath
+ nPathLen
, pPath
, nLen
+1);
902 rtl_uString_release(strConfig
);
905 else if ((rtl_ustr_ascii_compare_WithLength(pPath
, RTL_CONSTASCII_LENGTH(STR_INI_METASYS
), STR_INI_METASYS
) == 0) &&
906 ((nLen
== RTL_CONSTASCII_LENGTH(STR_INI_METASYS
)) || (pPath
[RTL_CONSTASCII_LENGTH(STR_INI_METASYS
)] == '/')))
908 if (((nPathLen
= GetWindowsDirectoryW(o3tl::toW(aPath
), aPath
.getBufSizeInSymbols())) == 0) || (nPathLen
>= aPath
.getBufSizeInSymbols()))
911 if (nLen
> RTL_CONSTASCII_LENGTH(STR_INI_METASYS
))
913 pPath
+= RTL_CONSTASCII_LENGTH(STR_INI_METASYS
);
914 nLen
-= RTL_CONSTASCII_LENGTH(STR_INI_METASYS
);
916 if (nLen
+ nPathLen
>= aPath
.getBufSizeInSymbols())
919 copy_ustr_n(aPath
+ nPathLen
, pPath
, nLen
+1);
924 else if ((rtl_ustr_ascii_compare_WithLength(pPath
, RTL_CONSTASCII_LENGTH(STR_INI_METAINS
), STR_INI_METAINS
) == 0) &&
925 ((nLen
== RTL_CONSTASCII_LENGTH(STR_INI_METAINS
)) || (pPath
[RTL_CONSTASCII_LENGTH(STR_INI_METAINS
)] == '/') ||
926 (pPath
[RTL_CONSTASCII_LENGTH(STR_INI_METAINS
)] == '"') ) )
928 if (! lookupProfile(pPath
+ RTL_CONSTASCII_LENGTH(STR_INI_METAINS
), aFile
, aPath
))
931 nPathLen
= rtl_ustr_getLength(aPath
);
934 else if( ::sal::static_int_cast
< sal_uInt32
>( nLen
) < aPath
.getBufSizeInSymbols())
936 copy_ustr_n(aPath
, pPath
, nLen
+1);
937 nPathLen
= rtl_ustr_getLength(aPath
);
944 rtl_uString
* strConfigDir
= nullptr;
945 oslSecurity security
= osl_getCurrentSecurity();
947 bFailed
= ! osl_getConfigDir(security
, &strConfigDir
);
948 osl_freeSecurityHandle(security
);
950 if (bFailed
) return false;
951 if ( ::sal::static_int_cast
< sal_uInt32
>( strConfigDir
->length
) >= aPath
.getBufSizeInSymbols() )
954 copy_ustr_n(aPath
, strConfigDir
->buffer
, strConfigDir
->length
+1);
955 nPathLen
= strConfigDir
->length
;
958 if (nPathLen
&& (aPath
[nPathLen
- 1] != L
'/') && (aPath
[nPathLen
- 1] != L
'\\'))
960 aPath
[nPathLen
++] = L
'\\';
964 if (nPathLen
+ nFileLen
>= aPath
.getBufSizeInSymbols())
967 /* append file name */
968 copy_ustr_n(aPath
+ nPathLen
, aFile
, nFileLen
+1);
969 nPathLen
+= nFileLen
;
972 rtl_uString_newFromStr_WithLength(&strTmp
, aPath
, nPathLen
);
973 nError
= osl_getFileURLFromSystemPath(strTmp
, strProfileName
);
974 rtl_uString_release(strTmp
);
976 return nError
== osl_File_E_None
;
979 sal_uInt32 SAL_CALL
osl_getProfileSections(oslProfile Profile
, char* pszBuffer
, sal_uInt32 MaxLen
)
982 osl_TProfileImpl
* pProfile
= acquireProfile(Profile
, false);
984 if (pProfile
== nullptr)
987 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
991 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
993 osl_TProfileSection
* pSec
= &pProfile
->m_Sections
[i
];
995 if ((n
+ pSec
->m_Len
+ 1) < MaxLen
)
997 strncpy(&pszBuffer
[n
], &pProfile
->m_Lines
[pSec
->m_Line
][pSec
->m_Offset
],
1000 pszBuffer
[n
++] = '\0';
1006 pszBuffer
[n
++] = '\0';
1010 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1011 n
+= pProfile
->m_Sections
[i
].m_Len
+ 1;
1018 std::vector
<wchar_t> aBuf(MaxLen
+ 1);
1019 GetPrivateProfileSectionNamesW(aBuf
.data(), MaxLen
, o3tl::toW(rtl_uString_getStr(pProfile
->m_strFileName
)));
1021 n
= WideCharToMultiByte(CP_ACP
, 0, aBuf
.data(), -1, pszBuffer
, MaxLen
, nullptr, nullptr);
1024 releaseProfile(pProfile
);
1029 static osl_TStamp
getFileStamp(osl_TFile
* pFile
)
1033 if ((pFile
->m_Handle
== INVALID_HANDLE_VALUE
) ||
1034 (! GetFileTime(pFile
->m_Handle
, nullptr, nullptr, &FileTime
)))
1035 memset(&FileTime
, 0, sizeof(FileTime
));
1040 static bool lockFile(const osl_TFile
* pFile
, osl_TLockMode eMode
)
1042 bool status
= false;
1043 OVERLAPPED Overlapped
= {};
1045 if (pFile
->m_Handle
== INVALID_HANDLE_VALUE
)
1051 status
= UnlockFileEx(
1052 pFile
->m_Handle
, 0, 0xFFFFFFFF, 0, &Overlapped
);
1056 status
= LockFileEx(
1057 pFile
->m_Handle
, 0, 0, 0xFFFFFFFF, 0, &Overlapped
);
1061 status
= LockFileEx(
1062 pFile
->m_Handle
, LOCKFILE_EXCLUSIVE_LOCK
, 0, 0xFFFFFFFF, 0,
1070 static osl_TFile
* openFileImpl(rtl_uString
* strFileName
, oslProfileOption ProfileFlags
)
1072 osl_TFile
* pFile
= static_cast< osl_TFile
*>( calloc( 1, sizeof(osl_TFile
) ) );
1075 bool bWriteable
= false;
1077 if ( ProfileFlags
& ( osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
) )
1079 #ifdef DEBUG_OSL_PROFILE
1080 SAL_INFO("sal.osl", "setting bWriteable to TRUE");
1087 pFile
->m_Handle
= CreateFileW( o3tl::toW(rtl_uString_getStr( strFileName
)), GENERIC_READ
,
1088 FILE_SHARE_READ
| FILE_SHARE_WRITE
, nullptr,
1089 OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, nullptr);
1091 /* mfe: argghh!!! do not check if the file could be opened */
1092 /* default mode expects it that way!!! */
1096 #ifdef DEBUG_OSL_PROFILE
1097 SAL_INFO("sal.osl", "opening read/write " << pszFilename
);
1100 if ((pFile
->m_Handle
= CreateFileW( o3tl::toW(rtl_uString_getStr( strFileName
)), GENERIC_READ
| GENERIC_WRITE
,
1101 FILE_SHARE_READ
| FILE_SHARE_WRITE
, nullptr,
1102 OPEN_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, nullptr))
1103 == INVALID_HANDLE_VALUE
)
1110 pFile
->m_pWriteBuf
=nullptr;
1111 pFile
->m_nWriteBufFree
=0;
1112 pFile
->m_nWriteBufLen
=0;
1114 if ( ProfileFlags
& (osl_Profile_WRITELOCK
| osl_Profile_READLOCK
) )
1116 #ifdef DEBUG_OSL_PROFILE
1117 SAL_INFO("sal.osl", "locking file " << pszFilename
);
1120 lockFile(pFile
, bWriteable
? write_lock
: read_lock
);
1126 static osl_TStamp
closeFileImpl(osl_TFile
* pFile
)
1128 osl_TStamp stamp
= {0, 0};
1130 if ( pFile
== nullptr )
1135 if (pFile
->m_Handle
!= INVALID_HANDLE_VALUE
)
1137 stamp
= getFileStamp(pFile
);
1139 lockFile(pFile
, un_lock
);
1141 CloseHandle(pFile
->m_Handle
);
1142 pFile
->m_Handle
= INVALID_HANDLE_VALUE
;
1145 if ( pFile
->m_pWriteBuf
!= nullptr )
1147 free(pFile
->m_pWriteBuf
);
1155 static bool rewindFile(osl_TFile
* pFile
, bool bTruncate
)
1157 if (pFile
->m_Handle
!= INVALID_HANDLE_VALUE
)
1159 pFile
->m_pReadPtr
= pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
);
1161 SetFilePointer(pFile
->m_Handle
, 0, nullptr, FILE_BEGIN
);
1164 SetEndOfFile(pFile
->m_Handle
);
1170 static bool getLine(osl_TFile
* pFile
, char *pszLine
, int MaxLen
)
1175 char* pLine
= pszLine
;
1177 if (pFile
->m_Handle
== INVALID_HANDLE_VALUE
)
1184 size_t Bytes
= sizeof(pFile
->m_ReadBuf
) - (pFile
->m_pReadPtr
- pFile
->m_ReadBuf
);
1189 memcpy(pFile
->m_ReadBuf
, pFile
->m_pReadPtr
, Bytes
);
1190 pFile
->m_pReadPtr
= pFile
->m_ReadBuf
;
1192 Free
= sizeof(pFile
->m_ReadBuf
) - Bytes
;
1194 if (! ReadFile(pFile
->m_Handle
, &pFile
->m_ReadBuf
[Bytes
], Free
, &Max
, nullptr))
1202 if ((Max
== 0) && (pLine
== pszLine
))
1208 pFile
->m_ReadBuf
[Bytes
+ Max
] = '\0';
1212 for (pChr
= pFile
->m_pReadPtr
;
1213 (*pChr
!= '\n') && (*pChr
!= '\r') && (*pChr
!= '\0') &&
1214 (pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
) - 1));
1217 Max
= min(static_cast<int>(pChr
- pFile
->m_pReadPtr
), MaxLen
);
1218 memcpy(pLine
, pFile
->m_pReadPtr
, Max
);
1222 if (pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
) - 1))
1226 if ((pChr
[0] == '\r') && (pChr
[1] == '\n'))
1232 if ((pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
))) &&
1234 pChr
= pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
);
1238 /* setting MaxLen to -1 indicates terminating read loop */
1242 pFile
->m_pReadPtr
= pChr
;
1249 static bool putLine(osl_TFile
* pFile
, const char *pszLine
)
1251 unsigned int Len
= strlen(pszLine
);
1253 if ( pFile
== nullptr || pFile
->m_Handle
== INVALID_HANDLE_VALUE
)
1258 if ( pFile
->m_pWriteBuf
== nullptr )
1260 pFile
->m_pWriteBuf
= static_cast<char*>(malloc(Len
+3));
1261 pFile
->m_nWriteBufLen
= Len
+3;
1262 pFile
->m_nWriteBufFree
= Len
+3;
1266 if ( pFile
->m_nWriteBufFree
<= Len
+ 3 )
1270 pTmp
=static_cast<char*>(realloc(pFile
->m_pWriteBuf
,( ( pFile
->m_nWriteBufLen
+ Len
) * 2) ));
1271 if ( pTmp
== nullptr )
1275 pFile
->m_pWriteBuf
= pTmp
;
1276 pFile
->m_nWriteBufFree
= pFile
->m_nWriteBufFree
+ pFile
->m_nWriteBufLen
+ ( 2 * Len
);
1277 pFile
->m_nWriteBufLen
= ( pFile
->m_nWriteBufLen
+ Len
) * 2;
1278 memset( (pFile
->m_pWriteBuf
) + ( pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
), 0, pFile
->m_nWriteBufFree
);
1282 memcpy(pFile
->m_pWriteBuf
+ ( pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
),pszLine
,Len
+1);
1284 pFile
->m_pWriteBuf
[pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
+ Len
]='\r';
1285 pFile
->m_pWriteBuf
[pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
+ Len
+ 1]='\n';
1286 pFile
->m_pWriteBuf
[pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
+ Len
+ 2]='\0';
1288 pFile
->m_nWriteBufFree
-=Len
+2;
1293 /* platform specific end */
1295 static const char* stripBlanks(const char* String
, sal_uInt32
* pLen
)
1297 if ( (pLen
!= nullptr) && ( *pLen
!= 0 ) )
1299 while ((String
[*pLen
- 1] == ' ') || (String
[*pLen
- 1] == '\t'))
1302 while ((*String
== ' ') || (*String
== '\t'))
1309 while ((*String
== ' ') || (*String
== '\t'))
1315 static const char* addLine(osl_TProfileImpl
* pProfile
, const char* Line
)
1317 if (pProfile
->m_NoLines
>= pProfile
->m_MaxLines
)
1319 if (pProfile
->m_Lines
== nullptr)
1321 pProfile
->m_MaxLines
= LINES_INI
;
1322 pProfile
->m_Lines
= static_cast<char **>(calloc(pProfile
->m_MaxLines
, sizeof(char *)));
1326 unsigned int index
=0;
1327 unsigned int oldmax
=pProfile
->m_MaxLines
;
1329 pProfile
->m_MaxLines
+= LINES_ADD
;
1330 if (auto p
= static_cast<char **>(realloc(pProfile
->m_Lines
, pProfile
->m_MaxLines
* sizeof(char *))))
1332 pProfile
->m_Lines
= p
;
1334 for ( index
= oldmax
; index
< pProfile
->m_MaxLines
; ++index
)
1336 pProfile
->m_Lines
[index
]=nullptr;
1341 free(pProfile
->m_Lines
);
1342 pProfile
->m_Lines
= nullptr;
1346 if (pProfile
->m_Lines
== nullptr)
1348 pProfile
->m_NoLines
= 0;
1349 pProfile
->m_MaxLines
= 0;
1355 if ( pProfile
->m_Lines
!= nullptr && pProfile
->m_Lines
[pProfile
->m_NoLines
] != nullptr )
1357 free(pProfile
->m_Lines
[pProfile
->m_NoLines
]);
1359 pProfile
->m_Lines
[pProfile
->m_NoLines
++] = strdup(Line
);
1361 return pProfile
->m_Lines
[pProfile
->m_NoLines
- 1];
1364 static const char* insertLine(osl_TProfileImpl
* pProfile
, const char* Line
, sal_uInt32 LineNo
)
1366 if (pProfile
->m_NoLines
>= pProfile
->m_MaxLines
)
1368 if (pProfile
->m_Lines
== nullptr)
1370 pProfile
->m_MaxLines
= LINES_INI
;
1371 pProfile
->m_Lines
= static_cast<char **>(calloc(pProfile
->m_MaxLines
, sizeof(char *)));
1375 pProfile
->m_MaxLines
+= LINES_ADD
;
1376 if (auto p
= static_cast<char**>(
1377 realloc(pProfile
->m_Lines
, pProfile
->m_MaxLines
* sizeof(char*))))
1379 pProfile
->m_Lines
= p
;
1381 memset(&pProfile
->m_Lines
[pProfile
->m_NoLines
], 0,
1382 (pProfile
->m_MaxLines
- pProfile
->m_NoLines
- 1) * sizeof(char*));
1386 free(pProfile
->m_Lines
);
1387 pProfile
->m_Lines
= nullptr;
1391 if (pProfile
->m_Lines
== nullptr)
1393 pProfile
->m_NoLines
= 0;
1394 pProfile
->m_MaxLines
= 0;
1399 LineNo
= std::min(LineNo
, pProfile
->m_NoLines
);
1401 if (LineNo
< pProfile
->m_NoLines
)
1405 memmove(&pProfile
->m_Lines
[LineNo
+ 1], &pProfile
->m_Lines
[LineNo
],
1406 (pProfile
->m_NoLines
- LineNo
) * sizeof(char *));
1408 /* adjust line references */
1409 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1411 osl_TProfileSection
* pSec
= &pProfile
->m_Sections
[i
];
1413 if (pSec
->m_Line
>= LineNo
)
1416 for (n
= 0; n
< pSec
->m_NoEntries
; n
++)
1417 if (pSec
->m_Entries
[n
].m_Line
>= LineNo
)
1418 pSec
->m_Entries
[n
].m_Line
++;
1422 pProfile
->m_NoLines
++;
1424 pProfile
->m_Lines
[LineNo
] = strdup(Line
);
1426 return pProfile
->m_Lines
[LineNo
];
1429 static void removeLine(osl_TProfileImpl
* pProfile
, sal_uInt32 LineNo
)
1431 if (LineNo
< pProfile
->m_NoLines
)
1433 free(pProfile
->m_Lines
[LineNo
]);
1434 pProfile
->m_Lines
[LineNo
]=nullptr;
1435 if (pProfile
->m_NoLines
- LineNo
> 1)
1439 memmove(&pProfile
->m_Lines
[LineNo
], &pProfile
->m_Lines
[LineNo
+ 1],
1440 (pProfile
->m_NoLines
- LineNo
- 1) * sizeof(char *));
1442 memset(&pProfile
->m_Lines
[pProfile
->m_NoLines
- 1],
1444 (pProfile
->m_MaxLines
- pProfile
->m_NoLines
) * sizeof(char*));
1446 /* adjust line references */
1447 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1449 osl_TProfileSection
* pSec
= &pProfile
->m_Sections
[i
];
1451 if (pSec
->m_Line
> LineNo
)
1454 for (n
= 0; n
< pSec
->m_NoEntries
; n
++)
1455 if (pSec
->m_Entries
[n
].m_Line
> LineNo
)
1456 pSec
->m_Entries
[n
].m_Line
--;
1461 pProfile
->m_Lines
[LineNo
] = nullptr;
1464 pProfile
->m_NoLines
--;
1470 static void setEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
* pSection
,
1471 sal_uInt32 NoEntry
, sal_uInt32 Line
,
1472 const char* Entry
, sal_uInt32 Len
)
1474 Entry
= stripBlanks(Entry
, &Len
);
1475 pSection
->m_Entries
[NoEntry
].m_Line
= Line
;
1476 pSection
->m_Entries
[NoEntry
].m_Offset
= Entry
- pProfile
->m_Lines
[Line
];
1477 pSection
->m_Entries
[NoEntry
].m_Len
= Len
;
1482 static bool addEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
,
1483 int Line
, const char* Entry
, sal_uInt32 Len
)
1485 if (pSection
!= nullptr)
1487 if (pSection
->m_NoEntries
>= pSection
->m_MaxEntries
)
1489 if (pSection
->m_Entries
== nullptr)
1491 pSection
->m_MaxEntries
= ENTRIES_INI
;
1492 pSection
->m_Entries
= static_cast<osl_TProfileEntry
*>(malloc(
1493 pSection
->m_MaxEntries
* sizeof(osl_TProfileEntry
)));
1497 pSection
->m_MaxEntries
+= ENTRIES_ADD
;
1498 if (auto p
= static_cast<osl_TProfileEntry
*>(realloc(
1499 pSection
->m_Entries
, pSection
->m_MaxEntries
* sizeof(osl_TProfileEntry
))))
1500 pSection
->m_Entries
= p
;
1503 free(pSection
->m_Entries
);
1504 pSection
->m_Entries
= nullptr;
1508 if (pSection
->m_Entries
== nullptr)
1510 pSection
->m_NoEntries
= 0;
1511 pSection
->m_MaxEntries
= 0;
1516 pSection
->m_NoEntries
++;
1518 Entry
= stripBlanks(Entry
, &Len
);
1519 setEntry(pProfile
, pSection
, pSection
->m_NoEntries
- 1, Line
,
1528 static void removeEntry(osl_TProfileSection
*pSection
, sal_uInt32 NoEntry
)
1530 if (NoEntry
< pSection
->m_NoEntries
)
1532 if (pSection
->m_NoEntries
- NoEntry
> 1)
1534 memmove(&pSection
->m_Entries
[NoEntry
],
1535 &pSection
->m_Entries
[NoEntry
+ 1],
1536 (pSection
->m_NoEntries
- NoEntry
- 1) * sizeof(osl_TProfileEntry
));
1537 pSection
->m_Entries
[pSection
->m_NoEntries
- 1].m_Line
=0;
1538 pSection
->m_Entries
[pSection
->m_NoEntries
- 1].m_Offset
=0;
1539 pSection
->m_Entries
[pSection
->m_NoEntries
- 1].m_Len
=0;
1542 pSection
->m_NoEntries
--;
1548 static bool addSection(osl_TProfileImpl
* pProfile
, int Line
, const char* Section
, sal_uInt32 Len
)
1550 if (pProfile
->m_NoSections
>= pProfile
->m_MaxSections
)
1552 if (pProfile
->m_Sections
== nullptr)
1554 pProfile
->m_MaxSections
= SECTIONS_INI
;
1555 pProfile
->m_Sections
= static_cast<osl_TProfileSection
*>(calloc(pProfile
->m_MaxSections
, sizeof(osl_TProfileSection
)));
1559 unsigned int index
=0;
1560 unsigned int oldmax
=pProfile
->m_MaxSections
;
1562 pProfile
->m_MaxSections
+= SECTIONS_ADD
;
1563 if (auto p
= static_cast<osl_TProfileSection
*>(realloc(
1564 pProfile
->m_Sections
, pProfile
->m_MaxSections
* sizeof(osl_TProfileSection
))))
1566 pProfile
->m_Sections
= p
;
1567 for ( index
= oldmax
; index
< pProfile
->m_MaxSections
; ++index
)
1569 pProfile
->m_Sections
[index
].m_Entries
=nullptr;
1574 free(pProfile
->m_Sections
);
1575 pProfile
->m_Sections
= nullptr;
1579 if (pProfile
->m_Sections
== nullptr)
1581 pProfile
->m_NoSections
= 0;
1582 pProfile
->m_MaxSections
= 0;
1587 pProfile
->m_NoSections
++;
1589 if ( pProfile
->m_Sections
[(pProfile
->m_NoSections
) - 1].m_Entries
!= nullptr )
1591 free(pProfile
->m_Sections
[(pProfile
->m_NoSections
) - 1].m_Entries
);
1593 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Entries
= nullptr;
1594 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_NoEntries
= 0;
1595 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_MaxEntries
= 0;
1597 Section
= stripBlanks(Section
, &Len
);
1598 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Line
= Line
;
1599 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Offset
= Section
- pProfile
->m_Lines
[Line
];
1600 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Len
= Len
;
1605 static void removeSection(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
)
1609 if ((Section
= pSection
- pProfile
->m_Sections
) < pProfile
->m_NoSections
)
1611 free (pSection
->m_Entries
);
1612 pSection
->m_Entries
=nullptr;
1613 if (pProfile
->m_NoSections
- Section
> 1)
1615 memmove(&pProfile
->m_Sections
[Section
], &pProfile
->m_Sections
[Section
+ 1],
1616 (pProfile
->m_NoSections
- Section
- 1) * sizeof(osl_TProfileSection
));
1618 memset(&pProfile
->m_Sections
[pProfile
->m_NoSections
- 1],
1620 (pProfile
->m_MaxSections
- pProfile
->m_NoSections
) * sizeof(osl_TProfileSection
));
1621 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Entries
= nullptr;
1625 pSection
->m_Entries
= nullptr;
1628 pProfile
->m_NoSections
--;
1634 static osl_TProfileSection
* findEntry(osl_TProfileImpl
* pProfile
, const char* Section
,
1635 const char* Entry
, sal_uInt32
*pNoEntry
)
1637 static sal_uInt32 Sect
= 0;
1640 osl_TProfileSection
* pSec
= nullptr;
1642 Len
= strlen(Section
);
1643 Section
= stripBlanks(Section
, &Len
);
1647 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1649 n
%= pProfile
->m_NoSections
;
1650 pSec
= &pProfile
->m_Sections
[n
];
1651 if ((Len
== pSec
->m_Len
) &&
1652 (strnicmp(Section
, &pProfile
->m_Lines
[pSec
->m_Line
][pSec
->m_Offset
], pSec
->m_Len
)
1660 if (i
< pProfile
->m_NoSections
)
1662 Len
= strlen(Entry
);
1663 Entry
= stripBlanks(Entry
, &Len
);
1665 *pNoEntry
= pSec
->m_NoEntries
;
1667 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
1669 const char* pStr
= &pProfile
->m_Lines
[pSec
->m_Entries
[i
].m_Line
]
1670 [pSec
->m_Entries
[i
].m_Offset
];
1671 if ((Len
== pSec
->m_Entries
[i
].m_Len
) &&
1672 (strnicmp(Entry
, pStr
, pSec
->m_Entries
[i
].m_Len
)
1686 static bool loadProfile(osl_TFile
* pFile
, osl_TProfileImpl
* pProfile
)
1693 pProfile
->m_NoLines
= 0;
1694 pProfile
->m_NoSections
= 0;
1696 OSL_VERIFY(rewindFile(pFile
, false));
1698 while (getLine(pFile
, Line
, sizeof(Line
)))
1700 if (! addLine(pProfile
, Line
))
1704 for (i
= 0; i
< pProfile
->m_NoLines
; i
++)
1706 pStr
= stripBlanks(pProfile
->m_Lines
[i
], nullptr);
1708 if ((*pStr
== '\0') || (*pStr
== ';'))
1711 if ((*pStr
!= '[') || ((pChar
= strrchr(pStr
, ']')) == nullptr) ||
1712 ((pChar
- pStr
) <= 2))
1716 if (pProfile
->m_NoSections
< 1)
1719 if ((pChar
= strchr(pStr
, '=')) == nullptr)
1720 pChar
= pStr
+ strlen(pStr
);
1722 if (! addEntry(pProfile
, &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1],
1723 i
, pStr
, pChar
- pStr
))
1729 if (! addSection(pProfile
, i
, pStr
+ 1, pChar
- pStr
- 1))
1737 static bool storeProfile(osl_TProfileImpl
* pProfile
, bool bCleanup
)
1739 if (pProfile
->m_Lines
!= nullptr)
1741 if (pProfile
->m_Flags
& FLG_MODIFIED
)
1745 osl_TFile
* pTmpFile
= osl_openTmpProfileImpl(pProfile
);
1747 if ( pTmpFile
== nullptr )
1752 OSL_VERIFY(rewindFile(pTmpFile
, true));
1754 for (i
= 0; i
< pProfile
->m_NoLines
; i
++)
1756 OSL_VERIFY(putLine(pTmpFile
, pProfile
->m_Lines
[i
]));
1759 if ( ! writeProfileImpl(pTmpFile
) )
1761 if ( pTmpFile
->m_pWriteBuf
!= nullptr )
1763 free(pTmpFile
->m_pWriteBuf
);
1766 pTmpFile
->m_pWriteBuf
=nullptr;
1767 pTmpFile
->m_nWriteBufLen
=0;
1768 pTmpFile
->m_nWriteBufFree
=0;
1770 closeFileImpl(pTmpFile
);
1775 pProfile
->m_Flags
&= ~FLG_MODIFIED
;
1777 closeFileImpl(pProfile
->m_pFile
);
1778 closeFileImpl(pTmpFile
);
1780 osl_ProfileSwapProfileNames(pProfile
);
1782 pProfile
->m_pFile
= openFileImpl(pProfile
->m_strFileName
,pProfile
->m_Flags
);
1788 while (pProfile
->m_NoLines
> 0)
1789 removeLine(pProfile
, pProfile
->m_NoLines
- 1);
1791 free(pProfile
->m_Lines
);
1792 pProfile
->m_Lines
= nullptr;
1793 pProfile
->m_MaxLines
= 0;
1795 while (pProfile
->m_NoSections
> 0)
1796 removeSection(pProfile
, &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1]);
1798 free(pProfile
->m_Sections
);
1799 pProfile
->m_Sections
= nullptr;
1800 pProfile
->m_MaxSections
= 0;
1807 static osl_TFile
* osl_openTmpProfileImpl(osl_TProfileImpl
* pProfile
)
1809 osl_TFile
* pFile
=nullptr;
1810 rtl_uString
* ustrExtension
=nullptr;
1811 rtl_uString
* ustrTmpName
=nullptr;
1812 oslProfileOption PFlags
=0;
1814 rtl_uString_newFromAscii(&ustrExtension
,"tmp");
1816 /* generate tmp profilename */
1817 ustrTmpName
=osl_ProfileGenerateExtension(pProfile
->m_strFileName
,ustrExtension
);
1818 rtl_uString_release(ustrExtension
);
1820 if (ustrTmpName
== nullptr)
1823 if (!(pProfile
->m_Flags
& osl_Profile_READLOCK
))
1824 PFlags
|= osl_Profile_WRITELOCK
;
1826 /* open this file */
1827 pFile
= openFileImpl(ustrTmpName
,pProfile
->m_Flags
| PFlags
);
1829 /* return new pFile */
1833 static bool osl_ProfileSwapProfileNames(osl_TProfileImpl
* pProfile
)
1835 rtl_uString
* ustrBakFile
=nullptr;
1836 rtl_uString
* ustrTmpFile
=nullptr;
1837 rtl_uString
* ustrIniFile
=nullptr;
1838 rtl_uString
* ustrExtension
=nullptr;
1840 rtl_uString_newFromAscii(&ustrExtension
,"bak");
1842 ustrBakFile
=osl_ProfileGenerateExtension(pProfile
->m_strFileName
,ustrExtension
);
1843 rtl_uString_release(ustrExtension
);
1844 ustrExtension
=nullptr;
1846 rtl_uString_newFromAscii(&ustrExtension
,"ini");
1848 ustrIniFile
=osl_ProfileGenerateExtension(pProfile
->m_strFileName
,ustrExtension
);
1849 rtl_uString_release(ustrExtension
);
1850 ustrExtension
=nullptr;
1852 rtl_uString_newFromAscii(&ustrExtension
,"tmp");
1854 ustrTmpFile
=osl_ProfileGenerateExtension(pProfile
->m_strFileName
,ustrExtension
);
1855 rtl_uString_release(ustrExtension
);
1856 ustrExtension
=nullptr;
1859 DeleteFileW( o3tl::toW(rtl_uString_getStr( ustrBakFile
)) );
1861 /* rename ini bak */
1862 MoveFileExW( o3tl::toW(rtl_uString_getStr( ustrIniFile
)), o3tl::toW(rtl_uString_getStr( ustrBakFile
)), MOVEFILE_COPY_ALLOWED
| MOVEFILE_WRITE_THROUGH
);
1864 /* rename tmp ini */
1865 MoveFileExW( o3tl::toW(rtl_uString_getStr( ustrTmpFile
)), o3tl::toW(rtl_uString_getStr( ustrIniFile
)), MOVEFILE_COPY_ALLOWED
| MOVEFILE_WRITE_THROUGH
);
1870 static rtl_uString
* osl_ProfileGenerateExtension(rtl_uString
* ustrFileName
, rtl_uString
* ustrExtension
)
1872 rtl_uString
* ustrNewFileName
= nullptr;
1873 rtl_uString
* ustrOldExtension
= nullptr;
1875 sal_Unicode
* pFileNameBuf
= rtl_uString_getStr(ustrFileName
);
1877 rtl_uString_newFromAscii(&ustrOldExtension
, ".");
1879 sal_Unicode
* pExtensionBuf
= rtl_uString_getStr(ustrOldExtension
);
1881 sal_Int32 nIndex
= rtl_ustr_lastIndexOfChar(pFileNameBuf
, *pExtensionBuf
);
1883 rtl_uString_newReplaceStrAt(&ustrNewFileName
,
1889 return ustrNewFileName
;
1892 static osl_TProfileImpl
* acquireProfile(oslProfile Profile
, bool bWriteable
)
1894 osl_TProfileImpl
* pProfile
= static_cast<osl_TProfileImpl
*>(Profile
);
1895 oslProfileOption PFlags
=0;
1899 PFlags
= osl_Profile_DEFAULT
| osl_Profile_WRITELOCK
;
1903 PFlags
= osl_Profile_DEFAULT
;
1906 if (pProfile
== nullptr)
1908 #ifdef DEBUG_OSL_PROFILE
1909 SAL_INFO("sal.osl", "AUTOOPEN MODE");
1912 if ( ( pProfile
= static_cast<osl_TProfileImpl
*>(osl_openProfile( nullptr, PFlags
)) ) != nullptr )
1914 pProfile
->m_Flags
|= FLG_AUTOOPEN
;
1919 #ifdef DEBUG_OSL_PROFILE
1920 SAL_INFO("sal.osl", "try to acquire");
1923 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
1925 if (! (pProfile
->m_Flags
& (osl_Profile_READLOCK
|
1926 osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
)))
1929 #ifdef DEBUG_OSL_PROFILE
1930 SAL_INFO("sal.osl", "DEFAULT MODE");
1932 pProfile
->m_pFile
= openFileImpl(
1933 pProfile
->m_strFileName
, pProfile
->m_Flags
| PFlags
);
1934 if (!pProfile
->m_pFile
)
1937 Stamp
= getFileStamp(pProfile
->m_pFile
);
1939 if (memcmp(&Stamp
, &(pProfile
->m_Stamp
), sizeof(osl_TStamp
)))
1941 pProfile
->m_Stamp
= Stamp
;
1943 loadProfile(pProfile
->m_pFile
, pProfile
);
1948 #ifdef DEBUG_OSL_PROFILE
1949 SAL_INFO("sal.osl", "READ/WRITELOCK MODE");
1952 /* A readlock file could not be written */
1953 if ((pProfile
->m_Flags
& osl_Profile_READLOCK
) && bWriteable
)
1964 static bool releaseProfile(osl_TProfileImpl
* pProfile
)
1966 if ( pProfile
== nullptr )
1971 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
1973 if (pProfile
->m_Flags
& FLG_AUTOOPEN
)
1975 return osl_closeProfile(static_cast<oslProfile
>(pProfile
));
1979 #ifdef DEBUG_OSL_PROFILE
1980 SAL_INFO("sal.osl", "DEFAULT MODE");
1982 if (! (pProfile
->m_Flags
& (osl_Profile_READLOCK
|
1983 osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
)))
1985 if (pProfile
->m_Flags
& FLG_MODIFIED
)
1986 storeProfile(pProfile
, false);
1988 closeFileImpl(pProfile
->m_pFile
);
1989 pProfile
->m_pFile
= nullptr;
1997 static bool lookupProfile(const sal_Unicode
*strPath
, const sal_Unicode
*strFile
, sal_Unicode
*strProfile
)
2000 char Buffer
[4096] = "";
2001 char Product
[132] = "";
2003 ::osl::LongPathBuffer
< sal_Unicode
> aPath( MAX_LONG_PATH
);
2006 if (*strPath
== L
'"')
2012 while ((strPath
[i
] != L
'"') && (strPath
[i
] != L
'\0'))
2015 WideCharToMultiByte(CP_ACP
,0, o3tl::toW(strPath
), i
, Product
, sizeof(Product
), nullptr, nullptr);
2019 if (*strPath
== L
'"')
2022 if ( (*strPath
== L
'/') || (*strPath
== L
'\\') )
2030 /* if we have not product identification, do a special handling for soffice.ini */
2031 if (rtl_ustr_ascii_compare(strFile
, SVERSION_PROFILE
) == 0)
2033 rtl_uString
* strSVProfile
= nullptr;
2034 rtl_uString
* strSVFallback
= nullptr;
2035 rtl_uString
* strSVLocation
= nullptr;
2036 rtl_uString
* strSVName
= nullptr;
2037 ::osl::LongPathBuffer
< char > aDir( MAX_LONG_PATH
);
2038 oslProfile hProfile
;
2040 rtl_uString_newFromAscii(&strSVFallback
, SVERSION_FALLBACK
);
2041 rtl_uString_newFromAscii(&strSVLocation
, SVERSION_LOCATION
);
2042 rtl_uString_newFromAscii(&strSVName
, SVERSION_NAME
);
2044 /* open sversion.ini in the system directory, and try to locate the entry
2045 with the highest version for StarOffice */
2046 if (osl_getProfileName( strSVFallback
, strSVName
, &strSVProfile
))
2048 hProfile
= osl_openProfile(strSVProfile
, osl_Profile_READLOCK
);
2051 osl_getProfileSectionEntries(
2052 hProfile
, SVERSION_SECTION
, Buffer
, sizeof(Buffer
));
2054 for (pChr
= Buffer
; *pChr
!= '\0'; pChr
+= strlen(pChr
) + 1)
2057 pChr
, SVERSION_SOFFICE
,
2058 sizeof(SVERSION_SOFFICE
) - 1)
2060 && (stricmp(Product
, pChr
) < 0))
2062 osl_readProfileString(
2063 hProfile
, SVERSION_SECTION
, pChr
, aDir
,
2064 aDir
.getBufSizeInSymbols(), "");
2066 /* check for existence of path */
2067 if (access(aDir
, 0) >= 0)
2068 strcpy(Product
, pChr
);
2072 osl_closeProfile(hProfile
);
2074 rtl_uString_release(strSVProfile
);
2075 strSVProfile
= nullptr;
2078 /* open sversion.ini in the users directory, and try to locate the entry
2079 with the highest version for StarOffice */
2080 if ( osl_getProfileName(strSVLocation
, strSVName
, &strSVProfile
) )
2082 hProfile
= osl_openProfile(strSVProfile
, osl_Profile_READLOCK
);
2085 osl_getProfileSectionEntries(
2086 hProfile
, SVERSION_SECTION
, Buffer
, sizeof(Buffer
));
2088 for (pChr
= Buffer
; *pChr
!= '\0'; pChr
+= strlen(pChr
) + 1)
2091 pChr
, SVERSION_SOFFICE
,
2092 sizeof(SVERSION_SOFFICE
) - 1)
2094 && (stricmp(Product
, pChr
) < 0))
2096 osl_readProfileString(
2097 hProfile
, SVERSION_SECTION
, pChr
, aDir
,
2098 aDir
.getBufSizeInSymbols(), "");
2100 /* check for existence of path */
2101 if (access(aDir
, 0) >= 0)
2102 strcpy(Product
, pChr
);
2106 osl_closeProfile(hProfile
);
2108 rtl_uString_release(strSVProfile
);
2111 rtl_uString_release(strSVFallback
);
2112 rtl_uString_release(strSVLocation
);
2113 rtl_uString_release(strSVName
);
2115 /* remove any trailing build number */
2116 if ((pChr
= strrchr(Product
, '/')) != nullptr)
2121 rtl_uString
* strExecutable
= nullptr;
2122 rtl_uString
* strTmp
= nullptr;
2125 /* try to find the file in the directory of the executable */
2126 if (osl_getExecutableFile(&strTmp
) != osl_Process_E_None
)
2129 /* convert to native path */
2130 if (osl_getSystemPathFromFileURL(strTmp
, &strExecutable
) != osl_File_E_None
)
2132 rtl_uString_release(strTmp
);
2136 rtl_uString_release(strTmp
);
2138 DWORD dwPathLen
= 0;
2140 /* separate path from filename */
2141 if ((nPos
= rtl_ustr_lastIndexOfChar(strExecutable
->buffer
, L
'\\')) == -1)
2143 if ((nPos
= rtl_ustr_lastIndexOfChar(strExecutable
->buffer
, L
':')) == -1)
2145 rtl_uString_release(strExecutable
);
2150 copy_ustr_n(aPath
, strExecutable
->buffer
, nPos
);
2157 copy_ustr_n(aPath
, strExecutable
->buffer
, nPos
);
2159 aPath
[dwPathLen
] = 0;
2162 /* if we have no product identification use the executable file name */
2165 WideCharToMultiByte(CP_ACP
,0, o3tl::toW(strExecutable
->buffer
+ nPos
+ 1), -1, Product
, sizeof(Product
), nullptr, nullptr);
2167 /* remove extension */
2168 if ((pChr
= strrchr(Product
, '.')) != nullptr)
2172 rtl_uString_release(strExecutable
);
2174 /* remember last subdir */
2175 nPos
= rtl_ustr_lastIndexOfChar(aPath
, L
'\\');
2177 copy_ustr_n(aPath
+ dwPathLen
++, L
"\\", 2);
2181 copy_ustr_n(aPath
+ dwPathLen
, strPath
, rtl_ustr_getLength(strPath
)+1);
2182 dwPathLen
+= rtl_ustr_getLength(strPath
);
2186 ::osl::LongPathBuffer
< char > aTmpPath( MAX_LONG_PATH
);
2188 WideCharToMultiByte(CP_ACP
,0, o3tl::toW(aPath
), -1, aTmpPath
, aTmpPath
.getBufSizeInSymbols(), nullptr, nullptr);
2190 /* if file not exists, remove any specified subdirectories
2191 like "bin" or "program" */
2193 if (((access(aTmpPath
, 0) < 0) && (nPos
!= -1)) || (*strPath
== 0))
2195 static const char *SubDirs
[] = SVERSION_DIRS
;
2198 char *pStr
= aTmpPath
+ nPos
;
2200 for (i
= 0; i
< SAL_N_ELEMENTS(SubDirs
); i
++)
2201 if (strnicmp(pStr
+ 1, SubDirs
[i
], strlen(SubDirs
[i
])) == 0)
2205 strcpy(pStr
+ 1,SVERSION_USER
);
2206 if ( access(aTmpPath
, 0) < 0 )
2212 dwPathLen
= nPos
+ MultiByteToWideChar( CP_ACP
, 0, SVERSION_USER
, -1, o3tl::toW(aPath
+ nPos
+ 1), aPath
.getBufSizeInSymbols() - (nPos
+ 1) );
2217 copy_ustr_n(aPath
+ nPos
+ 1, strPath
, rtl_ustr_getLength(strPath
)+1);
2218 dwPathLen
= nPos
+ 1 + rtl_ustr_getLength(strPath
);
2226 if ((aPath
[dwPathLen
- 1] != L
'/') && (aPath
[dwPathLen
- 1] != L
'\\'))
2228 aPath
[dwPathLen
++] = L
'\\';
2229 aPath
[dwPathLen
] = 0;
2232 copy_ustr_n(aPath
+ dwPathLen
, strFile
, rtl_ustr_getLength(strFile
)+1);
2235 ::osl::LongPathBuffer
< char > aTmpPath( MAX_LONG_PATH
);
2237 WideCharToMultiByte(CP_ACP
,0, o3tl::toW(aPath
), -1, aTmpPath
, aTmpPath
.getBufSizeInSymbols(), nullptr, nullptr);
2239 if ((access(aTmpPath
, 0) < 0) && (Product
[0] != '\0'))
2241 rtl_uString
* strSVFallback
= nullptr;
2242 rtl_uString
* strSVProfile
= nullptr;
2243 rtl_uString
* strSVLocation
= nullptr;
2244 rtl_uString
* strSVName
= nullptr;
2245 oslProfile hProfile
;
2247 rtl_uString_newFromAscii(&strSVFallback
, SVERSION_FALLBACK
);
2248 rtl_uString_newFromAscii(&strSVLocation
, SVERSION_LOCATION
);
2249 rtl_uString_newFromAscii(&strSVName
, SVERSION_NAME
);
2251 /* open sversion.ini in the system directory, and try to locate the entry
2252 with the highest version for StarOffice */
2253 if (osl_getProfileName(strSVLocation
, strSVName
, &strSVProfile
))
2255 hProfile
= osl_openProfile(
2256 strSVProfile
, osl_Profile_READLOCK
);
2259 osl_readProfileString(
2260 hProfile
, SVERSION_SECTION
, Product
, Buffer
,
2261 sizeof(Buffer
), "");
2262 osl_closeProfile(hProfile
);
2264 /* if not found, try the fallback */
2265 if (Buffer
[0] == '\0')
2267 if (osl_getProfileName(
2268 strSVFallback
, strSVName
, &strSVProfile
))
2270 hProfile
= osl_openProfile(
2271 strSVProfile
, osl_Profile_READLOCK
);
2274 osl_readProfileString(
2275 hProfile
, SVERSION_SECTION
, Product
,
2276 Buffer
, sizeof(Buffer
), "");
2280 osl_closeProfile(hProfile
);
2283 if (Buffer
[0] != '\0')
2285 dwPathLen
= MultiByteToWideChar(
2286 CP_ACP
, 0, Buffer
, -1, o3tl::toW(aPath
), aPath
.getBufSizeInSymbols() );
2289 /* build full path */
2290 if ((aPath
[dwPathLen
- 1] != L
'/')
2291 && (aPath
[dwPathLen
- 1] != L
'\\'))
2293 copy_ustr_n(aPath
+ dwPathLen
++, L
"\\", 2);
2298 copy_ustr_n(aPath
+ dwPathLen
, strPath
, rtl_ustr_getLength(strPath
)+1);
2299 dwPathLen
+= rtl_ustr_getLength(strPath
);
2303 ::osl::LongPathBuffer
< char > aTmpPath2( MAX_LONG_PATH
);
2306 if ((n
= WideCharToMultiByte(
2307 CP_ACP
,0, o3tl::toW(aPath
), -1, aTmpPath2
,
2308 aTmpPath2
.getBufSizeInSymbols(), nullptr, nullptr))
2311 strcpy(aTmpPath2
+ n
, SVERSION_USER
);
2312 if (access(aTmpPath2
, 0) >= 0)
2314 dwPathLen
+= MultiByteToWideChar(
2315 CP_ACP
, 0, SVERSION_USER
, -1,
2316 o3tl::toW(aPath
+ dwPathLen
),
2317 aPath
.getBufSizeInSymbols() - dwPathLen
);
2324 rtl_uString_release(strSVProfile
);
2327 rtl_uString_release(strSVFallback
);
2328 rtl_uString_release(strSVLocation
);
2329 rtl_uString_release(strSVName
);
2333 aPath
[dwPathLen
] = 0;
2336 copy_ustr_n(strProfile
, aPath
, dwPathLen
+1);
2341 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */