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 inline 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
;
79 un_lock
, read_lock
, write_lock
86 sal_Char m_ReadBuf
[512];
87 sal_Char
* m_pWriteBuf
;
88 sal_uInt32 m_nWriteBufLen
;
89 sal_uInt32 m_nWriteBufFree
;
92 struct osl_TProfileEntry
99 struct osl_TProfileSection
104 sal_uInt32 m_NoEntries
;
105 sal_uInt32 m_MaxEntries
;
106 osl_TProfileEntry
* m_Entries
;
110 Profile-data structure hidden behind oslProfile:
112 struct osl_TProfileImpl
117 sal_uInt32 m_NoLines
;
118 sal_uInt32 m_MaxLines
;
119 sal_uInt32 m_NoSections
;
120 sal_uInt32 m_MaxSections
;
122 rtl_uString
*m_strFileName
;
123 osl_TProfileSection
* m_Sections
;
126 static osl_TFile
* openFileImpl(rtl_uString
* strFileName
, oslProfileOption ProfileFlags
);
127 static osl_TStamp
closeFileImpl(osl_TFile
* pFile
);
128 static bool lockFile(const osl_TFile
* pFile
, osl_TLockMode eMode
);
129 static bool rewindFile(osl_TFile
* pFile
, bool bTruncate
);
130 static osl_TStamp
getFileStamp(osl_TFile
* pFile
);
132 static bool getLine(osl_TFile
* pFile
, sal_Char
*pszLine
, int MaxLen
);
133 static bool putLine(osl_TFile
* pFile
, const sal_Char
*pszLine
);
134 static const sal_Char
* stripBlanks(const sal_Char
* String
, sal_uInt32
* pLen
);
135 static const sal_Char
* addLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
);
136 static const sal_Char
* insertLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
, sal_uInt32 LineNo
);
137 static void removeLine(osl_TProfileImpl
* pProfile
, sal_uInt32 LineNo
);
138 static void setEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
* pSection
,
139 sal_uInt32 NoEntry
, sal_uInt32 Line
,
140 const sal_Char
* Entry
, sal_uInt32 Len
);
141 static bool addEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
,
142 int Line
, const sal_Char
* Entry
, sal_uInt32 Len
);
143 static void removeEntry(osl_TProfileSection
*pSection
, sal_uInt32 NoEntry
);
144 static bool addSection(osl_TProfileImpl
* pProfile
, int Line
, const sal_Char
* Section
, sal_uInt32 Len
);
145 static void removeSection(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
);
146 static osl_TProfileSection
* findEntry(osl_TProfileImpl
* pProfile
, const sal_Char
* Section
,
147 const sal_Char
* Entry
, sal_uInt32
*pNoEntry
);
148 static bool loadProfile(osl_TFile
* pFile
, osl_TProfileImpl
* pProfile
);
149 static bool storeProfile(osl_TProfileImpl
* pProfile
, bool bCleanup
);
150 static osl_TProfileImpl
* acquireProfile(oslProfile Profile
, bool bWriteable
);
151 static bool releaseProfile(osl_TProfileImpl
* pProfile
);
152 static bool lookupProfile(const sal_Unicode
*strPath
, const sal_Unicode
*strFile
, sal_Unicode
*strProfile
);
154 static bool writeProfileImpl (osl_TFile
* pFile
);
155 static osl_TFile
* osl_openTmpProfileImpl(osl_TProfileImpl
*);
156 static bool osl_ProfileSwapProfileNames(osl_TProfileImpl
*);
157 static rtl_uString
* osl_ProfileGenerateExtension(rtl_uString
* ustrFileName
, rtl_uString
* ustrExtension
);
159 static bool osl_getProfileName(rtl_uString
* strPath
, rtl_uString
* strName
, rtl_uString
** strProfileName
);
161 oslProfile SAL_CALL
osl_openProfile(rtl_uString
*strProfileName
, sal_uInt32 Flags
)
163 osl_TFile
* pFile
= nullptr;
164 osl_TProfileImpl
* pProfile
;
165 rtl_uString
*FileName
=nullptr;
167 OSL_VERIFY(strProfileName
);
169 if (rtl_uString_getLength(strProfileName
) == 0 )
171 OSL_VERIFY(osl_getProfileName(nullptr, nullptr, &FileName
));
175 rtl_uString_assign(&FileName
, strProfileName
);
178 osl_getSystemPathFromFileURL(FileName
, &FileName
);
180 #ifdef DEBUG_OSL_PROFILE
181 Flags
=osl_Profile_FLUSHWRITE
;
183 if ( Flags
== osl_Profile_DEFAULT
)
185 SAL_INFO("sal.osl", "with osl_Profile_DEFAULT");
187 if ( Flags
& osl_Profile_SYSTEM
)
189 SAL_INFO("sal.osl", "with osl_Profile_SYSTEM");
191 if ( Flags
& osl_Profile_READLOCK
)
193 SAL_INFO("sal.osl", "with osl_Profile_READLOCK");
195 if ( Flags
& osl_Profile_WRITELOCK
)
197 SAL_INFO("sal.osl", "with osl_Profile_WRITELOCK");
199 if ( Flags
& osl_Profile_FLUSHWRITE
)
201 SAL_INFO("sal.osl", "with osl_Profile_FLUSHWRITE");
205 if ( (! (Flags
& osl_Profile_SYSTEM
)) && ( (pFile
= openFileImpl(FileName
, Flags
) ) == nullptr ) )
208 rtl_uString_release( FileName
);
213 pProfile
= static_cast<osl_TProfileImpl
*>(calloc(1, sizeof(osl_TProfileImpl
)));
217 pProfile
->m_Flags
= Flags
& FLG_USER
;
218 osl_getSystemPathFromFileURL(strProfileName
, &pProfile
->m_strFileName
);
220 if (Flags
& (osl_Profile_READLOCK
| osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
))
221 pProfile
->m_pFile
= pFile
;
223 pProfile
->m_Stamp
= getFileStamp(pFile
);
225 loadProfile(pFile
, pProfile
);
227 if (pProfile
->m_pFile
== nullptr)
228 closeFileImpl(pFile
);
231 rtl_uString_release( FileName
);
236 sal_Bool SAL_CALL
osl_closeProfile(oslProfile Profile
)
238 osl_TProfileImpl
* pProfile
= static_cast<osl_TProfileImpl
*>(Profile
);
241 if ( Profile
== nullptr )
246 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
248 pProfile
= acquireProfile(Profile
,true);
250 if ( pProfile
!= nullptr )
252 if ( !( pProfile
->m_Flags
& osl_Profile_READLOCK
) && ( pProfile
->m_Flags
& FLG_MODIFIED
) )
254 storeProfile(pProfile
, false);
259 pProfile
= acquireProfile(Profile
,false);
262 if ( pProfile
== nullptr )
267 if (pProfile
->m_pFile
!= nullptr)
268 closeFileImpl(pProfile
->m_pFile
);
271 pProfile
->m_pFile
= nullptr;
272 rtl_uString_release(pProfile
->m_strFileName
);
273 pProfile
->m_strFileName
= nullptr;
275 /* release whole profile data types memory */
276 if ( pProfile
->m_NoLines
> 0)
278 unsigned int index
=0;
279 if ( pProfile
->m_Lines
!= nullptr )
281 for ( index
= 0 ; index
< pProfile
->m_NoLines
; ++index
)
283 if ( pProfile
->m_Lines
[index
] != nullptr )
285 free(pProfile
->m_Lines
[index
]);
288 free(pProfile
->m_Lines
);
290 if ( pProfile
->m_Sections
!= nullptr )
292 for ( index
= 0 ; index
< pProfile
->m_NoSections
; ++index
)
294 if ( pProfile
->m_Sections
[index
].m_Entries
!= nullptr )
295 free(pProfile
->m_Sections
[index
].m_Entries
);
297 free(pProfile
->m_Sections
);
306 sal_Bool SAL_CALL
osl_flushProfile(oslProfile Profile
)
308 osl_TProfileImpl
* pProfile
= static_cast<osl_TProfileImpl
*>(Profile
);
313 if ( pProfile
== nullptr )
318 pFile
= pProfile
->m_pFile
;
319 if ( pFile
== nullptr || pFile
->m_Handle
== INVALID_HANDLE_VALUE
)
324 if ( pProfile
->m_Flags
& FLG_MODIFIED
)
326 #ifdef DEBUG_OSL_PROFILE
327 SAL_INFO("sal.osl", "swapping to storeprofile");
329 bRet
= storeProfile(pProfile
,false);
335 static bool writeProfileImpl(osl_TFile
* pFile
)
337 DWORD BytesWritten
=0;
340 if ( !( pFile
!= nullptr && pFile
->m_Handle
!= INVALID_HANDLE_VALUE
) || ( pFile
->m_pWriteBuf
== nullptr ) )
345 bRet
=WriteFile(pFile
->m_Handle
, pFile
->m_pWriteBuf
, pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
,&BytesWritten
,nullptr);
347 if ( bRet
== 0 || BytesWritten
== 0 )
349 OSL_ENSURE(bRet
,"WriteFile failed!!!");
350 SAL_WARN("sal.osl", "write failed " << strerror(errno
));
355 free(pFile
->m_pWriteBuf
);
356 pFile
->m_pWriteBuf
=nullptr;
357 pFile
->m_nWriteBufLen
=0;
358 pFile
->m_nWriteBufFree
=0;
364 // Use Unicode version of GetPrivateProfileString, to work with Multi-language paths
365 DWORD
GetPrivateProfileStringWrapper(const osl_TProfileImpl
* pProfile
,
366 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
367 sal_Char
* pszString
, sal_uInt32 MaxLen
,
368 const sal_Char
* pszDefault
)
370 OSL_ASSERT(pProfile
&& (!MaxLen
|| pszString
));
372 rtl_uString
*pSection
= nullptr, *pEntry
= nullptr, *pDefault
= nullptr;
375 rtl_string2UString(&pSection
, pszSection
, strlen(pszSection
), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
376 OSL_ASSERT(pSection
);
380 rtl_string2UString(&pEntry
, pszEntry
, strlen(pszEntry
), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
385 rtl_string2UString(&pDefault
, pszDefault
, strlen(pszDefault
), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
386 OSL_ASSERT(pDefault
);
389 LPCWSTR pWSection
= (pSection
? o3tl::toW(rtl_uString_getStr(pSection
)) : nullptr),
390 pWEntry
= (pEntry
? o3tl::toW(rtl_uString_getStr(pEntry
)) : nullptr),
391 pWDefault
= (pDefault
? o3tl::toW(rtl_uString_getStr(pDefault
)) : nullptr);
393 std::vector
<wchar_t> aBuf(MaxLen
+ 1);
394 GetPrivateProfileStringW(pWSection
, pWEntry
, pWDefault
, &aBuf
[0], MaxLen
, o3tl::toW(rtl_uString_getStr(pProfile
->m_strFileName
)));
397 rtl_uString_release(pDefault
);
399 rtl_uString_release(pEntry
);
401 rtl_uString_release(pSection
);
403 return WideCharToMultiByte(CP_ACP
, 0, &aBuf
[0], -1, pszString
, MaxLen
, nullptr, nullptr);
406 // Use Unicode version of WritePrivateProfileString, to work with Multi-language paths
407 BOOL
WritePrivateProfileStringWrapper(const osl_TProfileImpl
* pProfile
,
408 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
409 const sal_Char
* pszString
)
411 OSL_ASSERT(pProfile
&& pszSection
);
412 rtl_uString
*pSection
, *pEntry
= nullptr, *pString
= nullptr;
413 rtl_string2UString(&pSection
, pszSection
, strlen(pszSection
), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
414 OSL_ASSERT(pSection
);
417 rtl_string2UString(&pEntry
, pszEntry
, strlen(pszEntry
), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
422 rtl_string2UString(&pString
, pszString
, strlen(pszString
), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
426 LPCWSTR pWSection
= o3tl::toW(pSection
->buffer
),
427 pWEntry
= (pEntry
? o3tl::toW(rtl_uString_getStr(pEntry
)) : nullptr),
428 pWString
= (pString
? o3tl::toW(rtl_uString_getStr(pString
)) : nullptr);
430 BOOL bResult
= WritePrivateProfileStringW(pWSection
, pWEntry
, pWString
, o3tl::toW(rtl_uString_getStr(pProfile
->m_strFileName
)));
433 rtl_uString_release(pString
);
435 rtl_uString_release(pEntry
);
436 rtl_uString_release(pSection
);
442 sal_Bool SAL_CALL
osl_readProfileString(oslProfile Profile
,
443 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
444 sal_Char
* pszString
, sal_uInt32 MaxLen
,
445 const sal_Char
* pszDefault
)
448 const sal_Char
* pStr
= nullptr;
449 osl_TProfileImpl
* pProfile
= nullptr;
451 pProfile
= acquireProfile(Profile
, false);
453 if (pProfile
== nullptr)
458 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
460 osl_TProfileSection
* pSec
;
461 if (((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) != nullptr) &&
462 (NoEntry
< pSec
->m_NoEntries
) &&
463 ((pStr
= strchr(pProfile
->m_Lines
[pSec
->m_Entries
[NoEntry
].m_Line
],
469 if ( pStr
!= nullptr )
471 pStr
= stripBlanks(pStr
, nullptr);
472 MaxLen
= (MaxLen
- 1 < strlen(pStr
)) ? (MaxLen
- 1) : strlen(pStr
);
473 pStr
= stripBlanks(pStr
, &MaxLen
);
474 strncpy(pszString
, pStr
, MaxLen
);
475 pszString
[MaxLen
] = '\0';
480 if (GetPrivateProfileStringWrapper(pProfile
, pszSection
, pszEntry
, pszString
, MaxLen
, pszDefault
) > 0)
481 pStr
= pszString
; // required to return true below
484 releaseProfile(pProfile
);
486 if ( pStr
== nullptr )
494 sal_Bool SAL_CALL
osl_readProfileBool(oslProfile Profile
,
495 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
500 if (osl_readProfileString(Profile
, pszSection
, pszEntry
, Line
, sizeof(Line
), ""))
502 if ((stricmp(Line
, STR_INI_BOOLYES
) == 0) ||
503 (stricmp(Line
, STR_INI_BOOLON
) == 0) ||
504 (stricmp(Line
, STR_INI_BOOLONE
) == 0))
507 if ((stricmp(Line
, STR_INI_BOOLNO
) == 0) ||
508 (stricmp(Line
, STR_INI_BOOLOFF
) == 0) ||
509 (stricmp(Line
, STR_INI_BOOLZERO
) == 0))
516 sal_uInt32 SAL_CALL
osl_readProfileIdent(oslProfile Profile
,
517 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
518 sal_uInt32 FirstId
, const sal_Char
* Strings
[],
524 if (osl_readProfileString(Profile
, pszSection
, pszEntry
, Line
, sizeof(Line
), ""))
527 while (Strings
[i
] != nullptr)
529 if (stricmp(Line
, Strings
[i
]) == 0)
531 Default
= i
+ FirstId
;
541 sal_Bool SAL_CALL
osl_writeProfileString(oslProfile Profile
,
542 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
543 const sal_Char
* pszString
)
548 const sal_Char
* pStr
;
550 osl_TProfileSection
* pSec
;
551 osl_TProfileImpl
* pProfile
= nullptr;
553 pProfile
= acquireProfile(Profile
, true);
555 if (pProfile
== nullptr)
560 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
562 if ((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) == nullptr)
565 addLine(pProfile
, Line
);
568 strcpy(&Line
[1], pszSection
);
569 Line
[1 + strlen(pszSection
)] = ']';
570 Line
[2 + strlen(pszSection
)] = '\0';
572 if (((pStr
= addLine(pProfile
, Line
)) == nullptr) ||
573 (! addSection(pProfile
, pProfile
->m_NoLines
- 1, &pStr
[1], strlen(pszSection
))))
575 releaseProfile(pProfile
);
579 pSec
= &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1];
580 NoEntry
= pSec
->m_NoEntries
;
584 strcpy(&Line
[0], pszEntry
);
585 Line
[0 + strlen(pszEntry
)] = '=';
586 strcpy(&Line
[1 + strlen(pszEntry
)], pszString
);
588 if (NoEntry
>= pSec
->m_NoEntries
)
590 if (pSec
->m_NoEntries
> 0)
591 i
= pSec
->m_Entries
[pSec
->m_NoEntries
- 1].m_Line
+ 1;
593 i
= pSec
->m_Line
+ 1;
595 if (((pStr
= insertLine(pProfile
, Line
, i
)) == nullptr) ||
596 (! addEntry(pProfile
, pSec
, i
, pStr
, strlen(pszEntry
))))
598 releaseProfile(pProfile
);
602 pProfile
->m_Flags
|= FLG_MODIFIED
;
606 i
= pSec
->m_Entries
[NoEntry
].m_Line
;
607 free(pProfile
->m_Lines
[i
]);
608 pProfile
->m_Lines
[i
] = strdup(Line
);
609 setEntry(pProfile
, pSec
, NoEntry
, i
, pProfile
->m_Lines
[i
], strlen(pszEntry
));
611 pProfile
->m_Flags
|= FLG_MODIFIED
;
616 WritePrivateProfileStringWrapper(pProfile
, pszSection
, pszEntry
, pszString
);
619 bRet
= releaseProfile(pProfile
);
623 sal_Bool SAL_CALL
osl_writeProfileBool(oslProfile Profile
,
624 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
630 bRet
=osl_writeProfileString(Profile
, pszSection
, pszEntry
, STR_INI_BOOLONE
);
632 bRet
=osl_writeProfileString(Profile
, pszSection
, pszEntry
, STR_INI_BOOLZERO
);
637 sal_Bool SAL_CALL
osl_writeProfileIdent(oslProfile Profile
,
638 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
639 sal_uInt32 FirstId
, const sal_Char
* Strings
[],
645 for (n
= 0; Strings
[n
] != nullptr; n
++);
647 if ((i
= Value
- FirstId
) >= n
)
650 bRet
=osl_writeProfileString(Profile
, pszSection
, pszEntry
, Strings
[i
]);
655 sal_Bool SAL_CALL
osl_removeProfileEntry(oslProfile Profile
,
656 const sal_Char
*pszSection
, const sal_Char
*pszEntry
)
659 osl_TProfileImpl
* pProfile
= nullptr;
662 pProfile
= acquireProfile(Profile
, true);
664 if (pProfile
== nullptr)
667 if (!(pProfile
->m_Flags
& osl_Profile_SYSTEM
))
669 osl_TProfileSection
* pSec
;
670 if (((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) != nullptr) &&
671 (NoEntry
< pSec
->m_NoEntries
))
673 removeLine(pProfile
, pSec
->m_Entries
[NoEntry
].m_Line
);
674 removeEntry(pSec
, NoEntry
);
675 if (pSec
->m_NoEntries
== 0)
677 removeLine(pProfile
, pSec
->m_Line
);
679 /* remove any empty separation line */
680 if ((pSec
->m_Line
> 0) && (pProfile
->m_Lines
[pSec
->m_Line
- 1][0] == '\0'))
681 removeLine(pProfile
, pSec
->m_Line
- 1);
683 removeSection(pProfile
, pSec
);
686 pProfile
->m_Flags
|= FLG_MODIFIED
;
691 WritePrivateProfileStringWrapper(pProfile
, pszSection
, pszEntry
, nullptr);
694 bRet
= releaseProfile(pProfile
);
698 sal_uInt32 SAL_CALL
osl_getProfileSectionEntries(oslProfile Profile
, const sal_Char
*pszSection
,
699 sal_Char
* pszBuffer
, sal_uInt32 MaxLen
)
703 osl_TProfileImpl
* pProfile
= nullptr;
705 pProfile
= acquireProfile(Profile
, false);
707 if (pProfile
== nullptr)
710 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
712 osl_TProfileSection
* pSec
;
713 if ((pSec
= findEntry(pProfile
, pszSection
, "", &NoEntry
)) != nullptr)
717 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
719 if ((n
+ pSec
->m_Entries
[i
].m_Len
+ 1) < MaxLen
)
721 strncpy(&pszBuffer
[n
], &pProfile
->m_Lines
[pSec
->m_Entries
[i
].m_Line
]
722 [pSec
->m_Entries
[i
].m_Offset
], pSec
->m_Entries
[i
].m_Len
);
723 n
+= pSec
->m_Entries
[i
].m_Len
;
724 pszBuffer
[n
++] = '\0';
733 pszBuffer
[n
++] = '\0';
737 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
739 n
+= pSec
->m_Entries
[i
].m_Len
+ 1;
752 n
= GetPrivateProfileStringWrapper(pProfile
, pszSection
, nullptr, pszBuffer
, MaxLen
, nullptr);
755 releaseProfile(pProfile
);
760 bool osl_getProfileName(rtl_uString
* strPath
, rtl_uString
* strName
, rtl_uString
** strProfileName
)
763 ::osl::LongPathBuffer
< sal_Unicode
> aFile( MAX_LONG_PATH
);
764 ::osl::LongPathBuffer
< sal_Unicode
> aPath( MAX_LONG_PATH
);
765 sal_uInt32 nFileLen
= 0;
766 sal_uInt32 nPathLen
= 0;
768 rtl_uString
* strTmp
= nullptr;
771 /* build file name */
772 if (strName
&& strName
->length
)
774 if( ::sal::static_int_cast
< sal_uInt32
>( strName
->length
) >= aFile
.getBufSizeInSymbols() )
777 copy_ustr_n( aFile
, strName
->buffer
, strName
->length
+1);
778 nFileLen
= strName
->length
;
780 if (rtl_ustr_indexOfChar( aFile
, L
'.' ) == -1)
782 if (nFileLen
+ wcslen(STR_INI_EXTENSION
) >= aFile
.getBufSizeInSymbols())
785 /* add default extension */
786 copy_ustr_n( aFile
+ nFileLen
, STR_INI_EXTENSION
, wcslen(STR_INI_EXTENSION
)+1 );
787 nFileLen
+= wcslen(STR_INI_EXTENSION
);
792 rtl_uString
*strProgName
= nullptr;
793 sal_Unicode
*pProgName
;
794 sal_Int32 nOffset
= 0;
798 if (osl_getExecutableFile(&strProgName
) != osl_Process_E_None
)
801 /* remove path and extension from filename */
802 pProgName
= strProgName
->buffer
;
803 nLen
= strProgName
->length
;
805 if ((nPos
= rtl_ustr_lastIndexOfChar( pProgName
, L
'/' )) != -1)
807 else if ((nPos
= rtl_ustr_lastIndexOfChar( pProgName
, L
':' )) != -1)
810 if ((nPos
= rtl_ustr_lastIndexOfChar( pProgName
, L
'.' )) != -1 )
813 if ((nFileLen
= nLen
- nOffset
) >= aFile
.getBufSizeInSymbols())
816 copy_ustr_n(aFile
, pProgName
+ nOffset
, nFileLen
);
818 if (nFileLen
+ wcslen(STR_INI_EXTENSION
) >= aFile
.getBufSizeInSymbols())
821 /* add default extension */
822 copy_ustr_n(aFile
+ nFileLen
, STR_INI_EXTENSION
, wcslen(STR_INI_EXTENSION
)+1);
823 nFileLen
+= wcslen(STR_INI_EXTENSION
);
825 rtl_uString_release( strProgName
);
831 /* build directory path */
832 if (strPath
&& strPath
->length
)
834 sal_Unicode
*pPath
= rtl_uString_getStr(strPath
);
835 sal_Int32 nLen
= rtl_uString_getLength(strPath
);
837 if ((rtl_ustr_ascii_compare_WithLength(pPath
, RTL_CONSTASCII_LENGTH(STR_INI_METAHOME
) , STR_INI_METAHOME
) == 0) &&
838 ((nLen
== RTL_CONSTASCII_LENGTH(STR_INI_METAHOME
)) || (pPath
[RTL_CONSTASCII_LENGTH(STR_INI_METAHOME
)] == '/')))
840 rtl_uString
* strHome
= nullptr;
841 oslSecurity security
= osl_getCurrentSecurity();
843 bFailed
= ! osl_getHomeDir(security
, &strHome
);
844 osl_freeSecurityHandle(security
);
846 if (bFailed
) return false;
848 if ( ::sal::static_int_cast
< sal_uInt32
>( strHome
->length
) >= aPath
.getBufSizeInSymbols())
851 copy_ustr_n( aPath
, strHome
->buffer
, strHome
->length
+1);
852 nPathLen
= strHome
->length
;
854 if (nLen
> RTL_CONSTASCII_LENGTH(STR_INI_METAHOME
))
856 pPath
+= RTL_CONSTASCII_LENGTH(STR_INI_METAHOME
);
857 nLen
-= RTL_CONSTASCII_LENGTH(STR_INI_METAHOME
);
859 if (nLen
+ nPathLen
>= aPath
.getBufSizeInSymbols())
862 copy_ustr_n(aPath
+ nPathLen
, pPath
, nLen
+1);
866 rtl_uString_release(strHome
);
869 else if ((rtl_ustr_ascii_compare_WithLength(pPath
, RTL_CONSTASCII_LENGTH(STR_INI_METACFG
), STR_INI_METACFG
) == 0) &&
870 ((nLen
== RTL_CONSTASCII_LENGTH(STR_INI_METACFG
)) || (pPath
[RTL_CONSTASCII_LENGTH(STR_INI_METACFG
)] == '/')))
872 rtl_uString
* strConfig
= nullptr;
873 oslSecurity security
= osl_getCurrentSecurity();
875 bFailed
= ! osl_getConfigDir(security
, &strConfig
);
876 osl_freeSecurityHandle(security
);
878 if (bFailed
) return false;
880 if ( ::sal::static_int_cast
< sal_uInt32
>( strConfig
->length
) >= aPath
.getBufSizeInSymbols())
883 copy_ustr_n( aPath
, strConfig
->buffer
, strConfig
->length
+1 );
884 nPathLen
= strConfig
->length
;
886 if (nLen
> RTL_CONSTASCII_LENGTH(STR_INI_METACFG
))
888 pPath
+= RTL_CONSTASCII_LENGTH(STR_INI_METACFG
);
889 nLen
-= RTL_CONSTASCII_LENGTH(STR_INI_METACFG
);
891 if (nLen
+ nPathLen
>= aPath
.getBufSizeInSymbols())
894 copy_ustr_n(aPath
+ nPathLen
, pPath
, nLen
+1);
898 rtl_uString_release(strConfig
);
901 else if ((rtl_ustr_ascii_compare_WithLength(pPath
, RTL_CONSTASCII_LENGTH(STR_INI_METASYS
), STR_INI_METASYS
) == 0) &&
902 ((nLen
== RTL_CONSTASCII_LENGTH(STR_INI_METASYS
)) || (pPath
[RTL_CONSTASCII_LENGTH(STR_INI_METASYS
)] == '/')))
904 if (((nPathLen
= GetWindowsDirectoryW(o3tl::toW(aPath
), aPath
.getBufSizeInSymbols())) == 0) || (nPathLen
>= aPath
.getBufSizeInSymbols()))
907 if (nLen
> RTL_CONSTASCII_LENGTH(STR_INI_METASYS
))
909 pPath
+= RTL_CONSTASCII_LENGTH(STR_INI_METASYS
);
910 nLen
-= RTL_CONSTASCII_LENGTH(STR_INI_METASYS
);
912 if (nLen
+ nPathLen
>= aPath
.getBufSizeInSymbols())
915 copy_ustr_n(aPath
+ nPathLen
, pPath
, nLen
+1);
920 else if ((rtl_ustr_ascii_compare_WithLength(pPath
, RTL_CONSTASCII_LENGTH(STR_INI_METAINS
), STR_INI_METAINS
) == 0) &&
921 ((nLen
== RTL_CONSTASCII_LENGTH(STR_INI_METAINS
)) || (pPath
[RTL_CONSTASCII_LENGTH(STR_INI_METAINS
)] == '/') ||
922 (pPath
[RTL_CONSTASCII_LENGTH(STR_INI_METAINS
)] == '"') ) )
924 if (! lookupProfile(pPath
+ RTL_CONSTASCII_LENGTH(STR_INI_METAINS
), aFile
, aPath
))
927 nPathLen
= rtl_ustr_getLength(aPath
);
930 else if( ::sal::static_int_cast
< sal_uInt32
>( nLen
) < aPath
.getBufSizeInSymbols())
932 copy_ustr_n(aPath
, pPath
, nLen
+1);
933 nPathLen
= rtl_ustr_getLength(aPath
);
940 rtl_uString
* strConfigDir
= nullptr;
941 oslSecurity security
= osl_getCurrentSecurity();
943 bFailed
= ! osl_getConfigDir(security
, &strConfigDir
);
944 osl_freeSecurityHandle(security
);
946 if (bFailed
) return false;
947 if ( ::sal::static_int_cast
< sal_uInt32
>( strConfigDir
->length
) >= aPath
.getBufSizeInSymbols() )
950 copy_ustr_n(aPath
, strConfigDir
->buffer
, strConfigDir
->length
+1);
951 nPathLen
= strConfigDir
->length
;
954 if (nPathLen
&& (aPath
[nPathLen
- 1] != L
'/') && (aPath
[nPathLen
- 1] != L
'\\'))
956 aPath
[nPathLen
++] = L
'\\';
960 if (nPathLen
+ nFileLen
>= aPath
.getBufSizeInSymbols())
963 /* append file name */
964 copy_ustr_n(aPath
+ nPathLen
, aFile
, nFileLen
+1);
965 nPathLen
+= nFileLen
;
968 rtl_uString_newFromStr_WithLength(&strTmp
, aPath
, nPathLen
);
969 nError
= osl_getFileURLFromSystemPath(strTmp
, strProfileName
);
970 rtl_uString_release(strTmp
);
972 return nError
== osl_File_E_None
;
975 sal_uInt32 SAL_CALL
osl_getProfileSections(oslProfile Profile
, sal_Char
* pszBuffer
, sal_uInt32 MaxLen
)
978 osl_TProfileImpl
* pProfile
= acquireProfile(Profile
, false);
980 if (pProfile
== nullptr)
983 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
987 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
989 osl_TProfileSection
* pSec
= &pProfile
->m_Sections
[i
];
991 if ((n
+ pSec
->m_Len
+ 1) < MaxLen
)
993 strncpy(&pszBuffer
[n
], &pProfile
->m_Lines
[pSec
->m_Line
][pSec
->m_Offset
],
996 pszBuffer
[n
++] = '\0';
1002 pszBuffer
[n
++] = '\0';
1006 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1007 n
+= pProfile
->m_Sections
[i
].m_Len
+ 1;
1014 std::vector
<wchar_t> aBuf(MaxLen
+ 1);
1015 GetPrivateProfileSectionNamesW(&aBuf
[0], MaxLen
, o3tl::toW(rtl_uString_getStr(pProfile
->m_strFileName
)));
1017 n
= WideCharToMultiByte(CP_ACP
, 0, &aBuf
[0], -1, pszBuffer
, MaxLen
, nullptr, nullptr);
1020 releaseProfile(pProfile
);
1025 static osl_TStamp
getFileStamp(osl_TFile
* pFile
)
1029 if ((pFile
->m_Handle
== INVALID_HANDLE_VALUE
) ||
1030 (! GetFileTime(pFile
->m_Handle
, nullptr, nullptr, &FileTime
)))
1031 memset(&FileTime
, 0, sizeof(FileTime
));
1036 static bool lockFile(const osl_TFile
* pFile
, osl_TLockMode eMode
)
1038 bool status
= false;
1039 OVERLAPPED Overlapped
;
1041 if (pFile
->m_Handle
== INVALID_HANDLE_VALUE
)
1044 memset(&Overlapped
, 0, sizeof(Overlapped
));
1049 status
= UnlockFileEx(
1050 pFile
->m_Handle
, 0, 0xFFFFFFFF, 0, &Overlapped
);
1054 status
= LockFileEx(
1055 pFile
->m_Handle
, 0, 0, 0xFFFFFFFF, 0, &Overlapped
);
1059 status
= LockFileEx(
1060 pFile
->m_Handle
, LOCKFILE_EXCLUSIVE_LOCK
, 0, 0xFFFFFFFF, 0,
1068 static osl_TFile
* openFileImpl(rtl_uString
* strFileName
, oslProfileOption ProfileFlags
)
1070 osl_TFile
* pFile
= static_cast< osl_TFile
*>( calloc( 1, sizeof(osl_TFile
) ) );
1073 bool bWriteable
= false;
1075 if ( ProfileFlags
& ( osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
) )
1077 #ifdef DEBUG_OSL_PROFILE
1078 SAL_INFO("sal.osl", "setting bWriteable to TRUE");
1085 pFile
->m_Handle
= CreateFileW( o3tl::toW(rtl_uString_getStr( strFileName
)), GENERIC_READ
,
1086 FILE_SHARE_READ
| FILE_SHARE_WRITE
, nullptr,
1087 OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, nullptr);
1089 /* mfe: argghh!!! do not check if the file could be opened */
1090 /* default mode expects it that way!!! */
1094 #ifdef DEBUG_OSL_PROFILE
1095 SAL_INFO("sal.osl", "opening read/write " << pszFilename
);
1098 if ((pFile
->m_Handle
= CreateFileW( o3tl::toW(rtl_uString_getStr( strFileName
)), GENERIC_READ
| GENERIC_WRITE
,
1099 FILE_SHARE_READ
| FILE_SHARE_WRITE
, nullptr,
1100 OPEN_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, nullptr))
1101 == INVALID_HANDLE_VALUE
)
1108 pFile
->m_pWriteBuf
=nullptr;
1109 pFile
->m_nWriteBufFree
=0;
1110 pFile
->m_nWriteBufLen
=0;
1112 if ( ProfileFlags
& (osl_Profile_WRITELOCK
| osl_Profile_READLOCK
) )
1114 #ifdef DEBUG_OSL_PROFILE
1115 SAL_INFO("sal.osl", "locking file " << pszFilename
);
1118 lockFile(pFile
, bWriteable
? write_lock
: read_lock
);
1124 static osl_TStamp
closeFileImpl(osl_TFile
* pFile
)
1126 osl_TStamp stamp
= {0, 0};
1128 if ( pFile
== nullptr )
1133 if (pFile
->m_Handle
!= INVALID_HANDLE_VALUE
)
1135 stamp
= getFileStamp(pFile
);
1137 lockFile(pFile
, un_lock
);
1139 CloseHandle(pFile
->m_Handle
);
1140 pFile
->m_Handle
= INVALID_HANDLE_VALUE
;
1143 if ( pFile
->m_pWriteBuf
!= nullptr )
1145 free(pFile
->m_pWriteBuf
);
1153 static bool rewindFile(osl_TFile
* pFile
, bool bTruncate
)
1155 if (pFile
->m_Handle
!= INVALID_HANDLE_VALUE
)
1157 pFile
->m_pReadPtr
= pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
);
1159 SetFilePointer(pFile
->m_Handle
, 0, nullptr, FILE_BEGIN
);
1162 SetEndOfFile(pFile
->m_Handle
);
1168 static bool getLine(osl_TFile
* pFile
, sal_Char
*pszLine
, int MaxLen
)
1173 sal_Char
* pLine
= pszLine
;
1175 if (pFile
->m_Handle
== INVALID_HANDLE_VALUE
)
1182 size_t Bytes
= sizeof(pFile
->m_ReadBuf
) - (pFile
->m_pReadPtr
- pFile
->m_ReadBuf
);
1187 memcpy(pFile
->m_ReadBuf
, pFile
->m_pReadPtr
, Bytes
);
1188 pFile
->m_pReadPtr
= pFile
->m_ReadBuf
;
1190 Free
= sizeof(pFile
->m_ReadBuf
) - Bytes
;
1192 if (! ReadFile(pFile
->m_Handle
, &pFile
->m_ReadBuf
[Bytes
], Free
, &Max
, nullptr))
1200 if ((Max
== 0) && (pLine
== pszLine
))
1206 pFile
->m_ReadBuf
[Bytes
+ Max
] = '\0';
1210 for (pChr
= pFile
->m_pReadPtr
;
1211 (*pChr
!= '\n') && (*pChr
!= '\r') && (*pChr
!= '\0') &&
1212 (pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
) - 1));
1215 Max
= min(static_cast<int>(pChr
- pFile
->m_pReadPtr
), MaxLen
);
1216 memcpy(pLine
, pFile
->m_pReadPtr
, Max
);
1220 if (pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
) - 1))
1224 if ((pChr
[0] == '\r') && (pChr
[1] == '\n'))
1230 if ((pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
))) &&
1232 pChr
= pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
);
1236 /* setting MaxLen to -1 indicates terminating read loop */
1240 pFile
->m_pReadPtr
= pChr
;
1247 static bool putLine(osl_TFile
* pFile
, const sal_Char
*pszLine
)
1249 unsigned int Len
= strlen(pszLine
);
1251 if ( pFile
== nullptr || pFile
->m_Handle
== INVALID_HANDLE_VALUE
)
1256 if ( pFile
->m_pWriteBuf
== nullptr )
1258 pFile
->m_pWriteBuf
= static_cast<sal_Char
*>(malloc(Len
+3));
1259 pFile
->m_nWriteBufLen
= Len
+3;
1260 pFile
->m_nWriteBufFree
= Len
+3;
1264 if ( pFile
->m_nWriteBufFree
<= Len
+ 3 )
1268 pTmp
=static_cast<sal_Char
*>(realloc(pFile
->m_pWriteBuf
,( ( pFile
->m_nWriteBufLen
+ Len
) * 2) ));
1269 if ( pTmp
== nullptr )
1273 pFile
->m_pWriteBuf
= pTmp
;
1274 pFile
->m_nWriteBufFree
= pFile
->m_nWriteBufFree
+ pFile
->m_nWriteBufLen
+ ( 2 * Len
);
1275 pFile
->m_nWriteBufLen
= ( pFile
->m_nWriteBufLen
+ Len
) * 2;
1276 memset( (pFile
->m_pWriteBuf
) + ( pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
), 0, pFile
->m_nWriteBufFree
);
1280 memcpy(pFile
->m_pWriteBuf
+ ( pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
),pszLine
,Len
+1);
1282 pFile
->m_pWriteBuf
[pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
+ Len
]='\r';
1283 pFile
->m_pWriteBuf
[pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
+ Len
+ 1]='\n';
1284 pFile
->m_pWriteBuf
[pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
+ Len
+ 2]='\0';
1286 pFile
->m_nWriteBufFree
-=Len
+2;
1291 /* platform specific end */
1293 static const sal_Char
* stripBlanks(const sal_Char
* String
, sal_uInt32
* pLen
)
1295 if ( (pLen
!= nullptr) && ( *pLen
!= 0 ) )
1297 while ((String
[*pLen
- 1] == ' ') || (String
[*pLen
- 1] == '\t'))
1300 while ((*String
== ' ') || (*String
== '\t'))
1307 while ((*String
== ' ') || (*String
== '\t'))
1313 static const sal_Char
* addLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
)
1315 if (pProfile
->m_NoLines
>= pProfile
->m_MaxLines
)
1317 if (pProfile
->m_Lines
== nullptr)
1319 pProfile
->m_MaxLines
= LINES_INI
;
1320 pProfile
->m_Lines
= static_cast<sal_Char
**>(calloc(pProfile
->m_MaxLines
, sizeof(sal_Char
*)));
1324 unsigned int index
=0;
1325 unsigned int oldmax
=pProfile
->m_MaxLines
;
1327 pProfile
->m_MaxLines
+= LINES_ADD
;
1328 if (auto p
= static_cast<sal_Char
**>(realloc(pProfile
->m_Lines
, pProfile
->m_MaxLines
* sizeof(sal_Char
*))))
1330 pProfile
->m_Lines
= p
;
1332 for ( index
= oldmax
; index
< pProfile
->m_MaxLines
; ++index
)
1334 pProfile
->m_Lines
[index
]=nullptr;
1339 free(pProfile
->m_Lines
);
1340 pProfile
->m_Lines
= nullptr;
1344 if (pProfile
->m_Lines
== nullptr)
1346 pProfile
->m_NoLines
= 0;
1347 pProfile
->m_MaxLines
= 0;
1353 if ( pProfile
->m_Lines
!= nullptr && pProfile
->m_Lines
[pProfile
->m_NoLines
] != nullptr )
1355 free(pProfile
->m_Lines
[pProfile
->m_NoLines
]);
1357 pProfile
->m_Lines
[pProfile
->m_NoLines
++] = strdup(Line
);
1359 return pProfile
->m_Lines
[pProfile
->m_NoLines
- 1];
1362 static const sal_Char
* insertLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
, sal_uInt32 LineNo
)
1364 if (pProfile
->m_NoLines
>= pProfile
->m_MaxLines
)
1366 if (pProfile
->m_Lines
== nullptr)
1368 pProfile
->m_MaxLines
= LINES_INI
;
1369 pProfile
->m_Lines
= static_cast<sal_Char
**>(calloc(pProfile
->m_MaxLines
, sizeof(sal_Char
*)));
1373 pProfile
->m_MaxLines
+= LINES_ADD
;
1374 if (auto p
= static_cast<sal_Char
**>(
1375 realloc(pProfile
->m_Lines
, pProfile
->m_MaxLines
* sizeof(sal_Char
*))))
1377 pProfile
->m_Lines
= p
;
1379 memset(&pProfile
->m_Lines
[pProfile
->m_NoLines
], 0,
1380 (pProfile
->m_MaxLines
- pProfile
->m_NoLines
- 1) * sizeof(sal_Char
*));
1384 free(pProfile
->m_Lines
);
1385 pProfile
->m_Lines
= nullptr;
1389 if (pProfile
->m_Lines
== nullptr)
1391 pProfile
->m_NoLines
= 0;
1392 pProfile
->m_MaxLines
= 0;
1397 LineNo
= std::min(LineNo
, pProfile
->m_NoLines
);
1399 if (LineNo
< pProfile
->m_NoLines
)
1403 memmove(&pProfile
->m_Lines
[LineNo
+ 1], &pProfile
->m_Lines
[LineNo
],
1404 (pProfile
->m_NoLines
- LineNo
) * sizeof(sal_Char
*));
1406 /* adjust line references */
1407 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1409 osl_TProfileSection
* pSec
= &pProfile
->m_Sections
[i
];
1411 if (pSec
->m_Line
>= LineNo
)
1414 for (n
= 0; n
< pSec
->m_NoEntries
; n
++)
1415 if (pSec
->m_Entries
[n
].m_Line
>= LineNo
)
1416 pSec
->m_Entries
[n
].m_Line
++;
1420 pProfile
->m_NoLines
++;
1422 pProfile
->m_Lines
[LineNo
] = strdup(Line
);
1424 return pProfile
->m_Lines
[LineNo
];
1427 static void removeLine(osl_TProfileImpl
* pProfile
, sal_uInt32 LineNo
)
1429 if (LineNo
< pProfile
->m_NoLines
)
1431 free(pProfile
->m_Lines
[LineNo
]);
1432 pProfile
->m_Lines
[LineNo
]=nullptr;
1433 if (pProfile
->m_NoLines
- LineNo
> 1)
1437 memmove(&pProfile
->m_Lines
[LineNo
], &pProfile
->m_Lines
[LineNo
+ 1],
1438 (pProfile
->m_NoLines
- LineNo
- 1) * sizeof(sal_Char
*));
1440 memset(&pProfile
->m_Lines
[pProfile
->m_NoLines
- 1],
1442 (pProfile
->m_MaxLines
- pProfile
->m_NoLines
) * sizeof(sal_Char
*));
1444 /* adjust line references */
1445 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1447 osl_TProfileSection
* pSec
= &pProfile
->m_Sections
[i
];
1449 if (pSec
->m_Line
> LineNo
)
1452 for (n
= 0; n
< pSec
->m_NoEntries
; n
++)
1453 if (pSec
->m_Entries
[n
].m_Line
> LineNo
)
1454 pSec
->m_Entries
[n
].m_Line
--;
1459 pProfile
->m_Lines
[LineNo
] = nullptr;
1462 pProfile
->m_NoLines
--;
1468 static void setEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
* pSection
,
1469 sal_uInt32 NoEntry
, sal_uInt32 Line
,
1470 const sal_Char
* Entry
, sal_uInt32 Len
)
1472 Entry
= stripBlanks(Entry
, &Len
);
1473 pSection
->m_Entries
[NoEntry
].m_Line
= Line
;
1474 pSection
->m_Entries
[NoEntry
].m_Offset
= Entry
- pProfile
->m_Lines
[Line
];
1475 pSection
->m_Entries
[NoEntry
].m_Len
= Len
;
1480 static bool addEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
,
1481 int Line
, const sal_Char
* Entry
, sal_uInt32 Len
)
1483 if (pSection
!= nullptr)
1485 if (pSection
->m_NoEntries
>= pSection
->m_MaxEntries
)
1487 if (pSection
->m_Entries
== nullptr)
1489 pSection
->m_MaxEntries
= ENTRIES_INI
;
1490 pSection
->m_Entries
= static_cast<osl_TProfileEntry
*>(malloc(
1491 pSection
->m_MaxEntries
* sizeof(osl_TProfileEntry
)));
1495 pSection
->m_MaxEntries
+= ENTRIES_ADD
;
1496 if (auto p
= static_cast<osl_TProfileEntry
*>(realloc(
1497 pSection
->m_Entries
, pSection
->m_MaxEntries
* sizeof(osl_TProfileEntry
))))
1498 pSection
->m_Entries
= p
;
1501 free(pSection
->m_Entries
);
1502 pSection
->m_Entries
= nullptr;
1506 if (pSection
->m_Entries
== nullptr)
1508 pSection
->m_NoEntries
= 0;
1509 pSection
->m_MaxEntries
= 0;
1514 pSection
->m_NoEntries
++;
1516 Entry
= stripBlanks(Entry
, &Len
);
1517 setEntry(pProfile
, pSection
, pSection
->m_NoEntries
- 1, Line
,
1526 static void removeEntry(osl_TProfileSection
*pSection
, sal_uInt32 NoEntry
)
1528 if (NoEntry
< pSection
->m_NoEntries
)
1530 if (pSection
->m_NoEntries
- NoEntry
> 1)
1532 memmove(&pSection
->m_Entries
[NoEntry
],
1533 &pSection
->m_Entries
[NoEntry
+ 1],
1534 (pSection
->m_NoEntries
- NoEntry
- 1) * sizeof(osl_TProfileEntry
));
1535 pSection
->m_Entries
[pSection
->m_NoEntries
- 1].m_Line
=0;
1536 pSection
->m_Entries
[pSection
->m_NoEntries
- 1].m_Offset
=0;
1537 pSection
->m_Entries
[pSection
->m_NoEntries
- 1].m_Len
=0;
1540 pSection
->m_NoEntries
--;
1546 static bool addSection(osl_TProfileImpl
* pProfile
, int Line
, const sal_Char
* Section
, sal_uInt32 Len
)
1548 if (pProfile
->m_NoSections
>= pProfile
->m_MaxSections
)
1550 if (pProfile
->m_Sections
== nullptr)
1552 pProfile
->m_MaxSections
= SECTIONS_INI
;
1553 pProfile
->m_Sections
= static_cast<osl_TProfileSection
*>(calloc(pProfile
->m_MaxSections
, sizeof(osl_TProfileSection
)));
1557 unsigned int index
=0;
1558 unsigned int oldmax
=pProfile
->m_MaxSections
;
1560 pProfile
->m_MaxSections
+= SECTIONS_ADD
;
1561 if (auto p
= static_cast<osl_TProfileSection
*>(realloc(
1562 pProfile
->m_Sections
, pProfile
->m_MaxSections
* sizeof(osl_TProfileSection
))))
1564 pProfile
->m_Sections
= p
;
1565 for ( index
= oldmax
; index
< pProfile
->m_MaxSections
; ++index
)
1567 pProfile
->m_Sections
[index
].m_Entries
=nullptr;
1572 free(pProfile
->m_Sections
);
1573 pProfile
->m_Sections
= nullptr;
1577 if (pProfile
->m_Sections
== nullptr)
1579 pProfile
->m_NoSections
= 0;
1580 pProfile
->m_MaxSections
= 0;
1585 pProfile
->m_NoSections
++;
1587 if ( pProfile
->m_Sections
[(pProfile
->m_NoSections
) - 1].m_Entries
!= nullptr )
1589 free(pProfile
->m_Sections
[(pProfile
->m_NoSections
) - 1].m_Entries
);
1591 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Entries
= nullptr;
1592 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_NoEntries
= 0;
1593 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_MaxEntries
= 0;
1595 Section
= stripBlanks(Section
, &Len
);
1596 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Line
= Line
;
1597 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Offset
= Section
- pProfile
->m_Lines
[Line
];
1598 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Len
= Len
;
1603 static void removeSection(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
)
1607 if ((Section
= pSection
- pProfile
->m_Sections
) < pProfile
->m_NoSections
)
1609 free (pSection
->m_Entries
);
1610 pSection
->m_Entries
=nullptr;
1611 if (pProfile
->m_NoSections
- Section
> 1)
1613 memmove(&pProfile
->m_Sections
[Section
], &pProfile
->m_Sections
[Section
+ 1],
1614 (pProfile
->m_NoSections
- Section
- 1) * sizeof(osl_TProfileSection
));
1616 memset(&pProfile
->m_Sections
[pProfile
->m_NoSections
- 1],
1618 (pProfile
->m_MaxSections
- pProfile
->m_NoSections
) * sizeof(osl_TProfileSection
));
1619 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Entries
= nullptr;
1623 pSection
->m_Entries
= nullptr;
1626 pProfile
->m_NoSections
--;
1632 static osl_TProfileSection
* findEntry(osl_TProfileImpl
* pProfile
, const sal_Char
* Section
,
1633 const sal_Char
* Entry
, sal_uInt32
*pNoEntry
)
1635 static sal_uInt32 Sect
= 0;
1638 osl_TProfileSection
* pSec
= nullptr;
1640 Len
= strlen(Section
);
1641 Section
= stripBlanks(Section
, &Len
);
1645 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1647 n
%= pProfile
->m_NoSections
;
1648 pSec
= &pProfile
->m_Sections
[n
];
1649 if ((Len
== pSec
->m_Len
) &&
1650 (strnicmp(Section
, &pProfile
->m_Lines
[pSec
->m_Line
][pSec
->m_Offset
], pSec
->m_Len
)
1658 if (i
< pProfile
->m_NoSections
)
1660 Len
= strlen(Entry
);
1661 Entry
= stripBlanks(Entry
, &Len
);
1663 *pNoEntry
= pSec
->m_NoEntries
;
1665 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
1667 const sal_Char
* pStr
= &pProfile
->m_Lines
[pSec
->m_Entries
[i
].m_Line
]
1668 [pSec
->m_Entries
[i
].m_Offset
];
1669 if ((Len
== pSec
->m_Entries
[i
].m_Len
) &&
1670 (strnicmp(Entry
, pStr
, pSec
->m_Entries
[i
].m_Len
)
1684 static bool loadProfile(osl_TFile
* pFile
, osl_TProfileImpl
* pProfile
)
1687 sal_Char
const * pStr
;
1688 sal_Char
const * pChar
;
1689 sal_Char Line
[4096];
1691 pProfile
->m_NoLines
= 0;
1692 pProfile
->m_NoSections
= 0;
1694 OSL_VERIFY(rewindFile(pFile
, false));
1696 while (getLine(pFile
, Line
, sizeof(Line
)))
1698 if (! addLine(pProfile
, Line
))
1702 for (i
= 0; i
< pProfile
->m_NoLines
; i
++)
1704 pStr
= stripBlanks(pProfile
->m_Lines
[i
], nullptr);
1706 if ((*pStr
== '\0') || (*pStr
== ';'))
1709 if ((*pStr
!= '[') || ((pChar
= strrchr(pStr
, ']')) == nullptr) ||
1710 ((pChar
- pStr
) <= 2))
1714 if (pProfile
->m_NoSections
< 1)
1717 if ((pChar
= strchr(pStr
, '=')) == nullptr)
1718 pChar
= pStr
+ strlen(pStr
);
1720 if (! addEntry(pProfile
, &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1],
1721 i
, pStr
, pChar
- pStr
))
1727 if (! addSection(pProfile
, i
, pStr
+ 1, pChar
- pStr
- 1))
1735 static bool storeProfile(osl_TProfileImpl
* pProfile
, bool bCleanup
)
1737 if (pProfile
->m_Lines
!= nullptr)
1739 if (pProfile
->m_Flags
& FLG_MODIFIED
)
1743 osl_TFile
* pTmpFile
= osl_openTmpProfileImpl(pProfile
);
1745 if ( pTmpFile
== nullptr )
1750 OSL_VERIFY(rewindFile(pTmpFile
, true));
1752 for (i
= 0; i
< pProfile
->m_NoLines
; i
++)
1754 OSL_VERIFY(putLine(pTmpFile
, pProfile
->m_Lines
[i
]));
1757 if ( ! writeProfileImpl(pTmpFile
) )
1759 if ( pTmpFile
->m_pWriteBuf
!= nullptr )
1761 free(pTmpFile
->m_pWriteBuf
);
1764 pTmpFile
->m_pWriteBuf
=nullptr;
1765 pTmpFile
->m_nWriteBufLen
=0;
1766 pTmpFile
->m_nWriteBufFree
=0;
1768 closeFileImpl(pTmpFile
);
1773 pProfile
->m_Flags
&= ~FLG_MODIFIED
;
1775 closeFileImpl(pProfile
->m_pFile
);
1776 closeFileImpl(pTmpFile
);
1778 osl_ProfileSwapProfileNames(pProfile
);
1780 pProfile
->m_pFile
= openFileImpl(pProfile
->m_strFileName
,pProfile
->m_Flags
);
1786 while (pProfile
->m_NoLines
> 0)
1787 removeLine(pProfile
, pProfile
->m_NoLines
- 1);
1789 free(pProfile
->m_Lines
);
1790 pProfile
->m_Lines
= nullptr;
1791 pProfile
->m_MaxLines
= 0;
1793 while (pProfile
->m_NoSections
> 0)
1794 removeSection(pProfile
, &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1]);
1796 free(pProfile
->m_Sections
);
1797 pProfile
->m_Sections
= nullptr;
1798 pProfile
->m_MaxSections
= 0;
1805 static osl_TFile
* osl_openTmpProfileImpl(osl_TProfileImpl
* pProfile
)
1807 osl_TFile
* pFile
=nullptr;
1808 rtl_uString
* ustrExtension
=nullptr;
1809 rtl_uString
* ustrTmpName
=nullptr;
1810 oslProfileOption PFlags
=0;
1812 rtl_uString_newFromAscii(&ustrExtension
,"tmp");
1814 /* generate tmp profilename */
1815 ustrTmpName
=osl_ProfileGenerateExtension(pProfile
->m_strFileName
,ustrExtension
);
1816 rtl_uString_release(ustrExtension
);
1818 if (ustrTmpName
== nullptr)
1821 if (!(pProfile
->m_Flags
& osl_Profile_READLOCK
))
1822 PFlags
|= osl_Profile_WRITELOCK
;
1824 /* open this file */
1825 pFile
= openFileImpl(ustrTmpName
,pProfile
->m_Flags
| PFlags
);
1827 /* return new pFile */
1831 static bool osl_ProfileSwapProfileNames(osl_TProfileImpl
* pProfile
)
1833 rtl_uString
* ustrBakFile
=nullptr;
1834 rtl_uString
* ustrTmpFile
=nullptr;
1835 rtl_uString
* ustrIniFile
=nullptr;
1836 rtl_uString
* ustrExtension
=nullptr;
1838 rtl_uString_newFromAscii(&ustrExtension
,"bak");
1840 ustrBakFile
=osl_ProfileGenerateExtension(pProfile
->m_strFileName
,ustrExtension
);
1841 rtl_uString_release(ustrExtension
);
1842 ustrExtension
=nullptr;
1844 rtl_uString_newFromAscii(&ustrExtension
,"ini");
1846 ustrIniFile
=osl_ProfileGenerateExtension(pProfile
->m_strFileName
,ustrExtension
);
1847 rtl_uString_release(ustrExtension
);
1848 ustrExtension
=nullptr;
1850 rtl_uString_newFromAscii(&ustrExtension
,"tmp");
1852 ustrTmpFile
=osl_ProfileGenerateExtension(pProfile
->m_strFileName
,ustrExtension
);
1853 rtl_uString_release(ustrExtension
);
1854 ustrExtension
=nullptr;
1857 DeleteFileW( o3tl::toW(rtl_uString_getStr( ustrBakFile
)) );
1859 /* rename ini bak */
1860 MoveFileExW( o3tl::toW(rtl_uString_getStr( ustrIniFile
)), o3tl::toW(rtl_uString_getStr( ustrBakFile
)), MOVEFILE_COPY_ALLOWED
| MOVEFILE_WRITE_THROUGH
);
1862 /* rename tmp ini */
1863 MoveFileExW( o3tl::toW(rtl_uString_getStr( ustrTmpFile
)), o3tl::toW(rtl_uString_getStr( ustrIniFile
)), MOVEFILE_COPY_ALLOWED
| MOVEFILE_WRITE_THROUGH
);
1868 static rtl_uString
* osl_ProfileGenerateExtension(rtl_uString
* ustrFileName
, rtl_uString
* ustrExtension
)
1870 rtl_uString
* ustrNewFileName
= nullptr;
1871 rtl_uString
* ustrOldExtension
= nullptr;
1873 sal_Unicode
* pFileNameBuf
= rtl_uString_getStr(ustrFileName
);
1875 rtl_uString_newFromAscii(&ustrOldExtension
, ".");
1877 sal_Unicode
* pExtensionBuf
= rtl_uString_getStr(ustrOldExtension
);
1879 sal_Int32 nIndex
= rtl_ustr_lastIndexOfChar(pFileNameBuf
, *pExtensionBuf
);
1881 rtl_uString_newReplaceStrAt(&ustrNewFileName
,
1887 return ustrNewFileName
;
1890 static osl_TProfileImpl
* acquireProfile(oslProfile Profile
, bool bWriteable
)
1892 osl_TProfileImpl
* pProfile
= static_cast<osl_TProfileImpl
*>(Profile
);
1893 oslProfileOption PFlags
=0;
1897 PFlags
= osl_Profile_DEFAULT
| osl_Profile_WRITELOCK
;
1901 PFlags
= osl_Profile_DEFAULT
;
1904 if (pProfile
== nullptr)
1906 #ifdef DEBUG_OSL_PROFILE
1907 SAL_INFO("sal.osl", "AUTOOPEN MODE");
1910 if ( ( pProfile
= static_cast<osl_TProfileImpl
*>(osl_openProfile( nullptr, PFlags
)) ) != nullptr )
1912 pProfile
->m_Flags
|= FLG_AUTOOPEN
;
1917 #ifdef DEBUG_OSL_PROFILE
1918 SAL_INFO("sal.osl", "try to acquire");
1921 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
1923 if (! (pProfile
->m_Flags
& (osl_Profile_READLOCK
|
1924 osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
)))
1927 #ifdef DEBUG_OSL_PROFILE
1928 SAL_INFO("sal.osl", "DEFAULT MODE");
1930 pProfile
->m_pFile
= openFileImpl(
1931 pProfile
->m_strFileName
, pProfile
->m_Flags
| PFlags
);
1932 if (!pProfile
->m_pFile
)
1935 Stamp
= getFileStamp(pProfile
->m_pFile
);
1937 if (memcmp(&Stamp
, &(pProfile
->m_Stamp
), sizeof(osl_TStamp
)))
1939 pProfile
->m_Stamp
= Stamp
;
1941 loadProfile(pProfile
->m_pFile
, pProfile
);
1946 #ifdef DEBUG_OSL_PROFILE
1947 SAL_INFO("sal.osl", "READ/WRITELOCK MODE");
1950 /* A readlock file could not be written */
1951 if ((pProfile
->m_Flags
& osl_Profile_READLOCK
) && bWriteable
)
1962 static bool releaseProfile(osl_TProfileImpl
* pProfile
)
1964 if ( pProfile
== nullptr )
1969 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
1971 if (pProfile
->m_Flags
& FLG_AUTOOPEN
)
1973 return osl_closeProfile(static_cast<oslProfile
>(pProfile
));
1977 #ifdef DEBUG_OSL_PROFILE
1978 SAL_INFO("sal.osl", "DEFAULT MODE");
1980 if (! (pProfile
->m_Flags
& (osl_Profile_READLOCK
|
1981 osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
)))
1983 if (pProfile
->m_Flags
& FLG_MODIFIED
)
1984 storeProfile(pProfile
, false);
1986 closeFileImpl(pProfile
->m_pFile
);
1987 pProfile
->m_pFile
= nullptr;
1995 static bool lookupProfile(const sal_Unicode
*strPath
, const sal_Unicode
*strFile
, sal_Unicode
*strProfile
)
1998 sal_Char Buffer
[4096] = "";
1999 sal_Char Product
[132] = "";
2001 ::osl::LongPathBuffer
< sal_Unicode
> aPath( MAX_LONG_PATH
);
2004 if (*strPath
== L
'"')
2010 while ((strPath
[i
] != L
'"') && (strPath
[i
] != L
'\0'))
2013 WideCharToMultiByte(CP_ACP
,0, o3tl::toW(strPath
), i
, Product
, sizeof(Product
), nullptr, nullptr);
2017 if (*strPath
== L
'"')
2020 if ( (*strPath
== L
'/') || (*strPath
== L
'\\') )
2028 /* if we have not product identification, do a special handling for soffice.ini */
2029 if (rtl_ustr_ascii_compare(strFile
, SVERSION_PROFILE
) == 0)
2031 rtl_uString
* strSVProfile
= nullptr;
2032 rtl_uString
* strSVFallback
= nullptr;
2033 rtl_uString
* strSVLocation
= nullptr;
2034 rtl_uString
* strSVName
= nullptr;
2035 ::osl::LongPathBuffer
< sal_Char
> aDir( MAX_LONG_PATH
);
2036 oslProfile hProfile
;
2038 rtl_uString_newFromAscii(&strSVFallback
, SVERSION_FALLBACK
);
2039 rtl_uString_newFromAscii(&strSVLocation
, SVERSION_LOCATION
);
2040 rtl_uString_newFromAscii(&strSVName
, SVERSION_NAME
);
2042 /* open sversion.ini in the system directory, and try to locate the entry
2043 with the highest version for StarOffice */
2044 if (osl_getProfileName( strSVFallback
, strSVName
, &strSVProfile
))
2046 hProfile
= osl_openProfile(strSVProfile
, osl_Profile_READLOCK
);
2049 osl_getProfileSectionEntries(
2050 hProfile
, SVERSION_SECTION
, Buffer
, sizeof(Buffer
));
2052 for (pChr
= Buffer
; *pChr
!= '\0'; pChr
+= strlen(pChr
) + 1)
2055 pChr
, SVERSION_SOFFICE
,
2056 sizeof(SVERSION_SOFFICE
) - 1)
2058 && (stricmp(Product
, pChr
) < 0))
2060 osl_readProfileString(
2061 hProfile
, SVERSION_SECTION
, pChr
, aDir
,
2062 aDir
.getBufSizeInSymbols(), "");
2064 /* check for existence of path */
2065 if (access(aDir
, 0) >= 0)
2066 strcpy(Product
, pChr
);
2070 osl_closeProfile(hProfile
);
2072 rtl_uString_release(strSVProfile
);
2073 strSVProfile
= nullptr;
2076 /* open sversion.ini in the users directory, and try to locate the entry
2077 with the highest version for StarOffice */
2078 if ( osl_getProfileName(strSVLocation
, strSVName
, &strSVProfile
) )
2080 hProfile
= osl_openProfile(strSVProfile
, osl_Profile_READLOCK
);
2083 osl_getProfileSectionEntries(
2084 hProfile
, SVERSION_SECTION
, Buffer
, sizeof(Buffer
));
2086 for (pChr
= Buffer
; *pChr
!= '\0'; pChr
+= strlen(pChr
) + 1)
2089 pChr
, SVERSION_SOFFICE
,
2090 sizeof(SVERSION_SOFFICE
) - 1)
2092 && (stricmp(Product
, pChr
) < 0))
2094 osl_readProfileString(
2095 hProfile
, SVERSION_SECTION
, pChr
, aDir
,
2096 aDir
.getBufSizeInSymbols(), "");
2098 /* check for existence of path */
2099 if (access(aDir
, 0) >= 0)
2100 strcpy(Product
, pChr
);
2104 osl_closeProfile(hProfile
);
2106 rtl_uString_release(strSVProfile
);
2109 rtl_uString_release(strSVFallback
);
2110 rtl_uString_release(strSVLocation
);
2111 rtl_uString_release(strSVName
);
2113 /* remove any trailing build number */
2114 if ((pChr
= strrchr(Product
, '/')) != nullptr)
2119 rtl_uString
* strExecutable
= nullptr;
2120 rtl_uString
* strTmp
= nullptr;
2123 /* try to find the file in the directory of the executable */
2124 if (osl_getExecutableFile(&strTmp
) != osl_Process_E_None
)
2127 /* convert to native path */
2128 if (osl_getSystemPathFromFileURL(strTmp
, &strExecutable
) != osl_File_E_None
)
2130 rtl_uString_release(strTmp
);
2134 rtl_uString_release(strTmp
);
2136 DWORD dwPathLen
= 0;
2138 /* separate path from filename */
2139 if ((nPos
= rtl_ustr_lastIndexOfChar(strExecutable
->buffer
, L
'\\')) == -1)
2141 if ((nPos
= rtl_ustr_lastIndexOfChar(strExecutable
->buffer
, L
':')) == -1)
2143 rtl_uString_release(strExecutable
);
2148 copy_ustr_n(aPath
, strExecutable
->buffer
, nPos
);
2155 copy_ustr_n(aPath
, strExecutable
->buffer
, nPos
);
2157 aPath
[dwPathLen
] = 0;
2160 /* if we have no product identification use the executable file name */
2163 WideCharToMultiByte(CP_ACP
,0, o3tl::toW(strExecutable
->buffer
+ nPos
+ 1), -1, Product
, sizeof(Product
), nullptr, nullptr);
2165 /* remove extension */
2166 if ((pChr
= strrchr(Product
, '.')) != nullptr)
2170 rtl_uString_release(strExecutable
);
2172 /* remember last subdir */
2173 nPos
= rtl_ustr_lastIndexOfChar(aPath
, L
'\\');
2175 copy_ustr_n(aPath
+ dwPathLen
++, L
"\\", 2);
2179 copy_ustr_n(aPath
+ dwPathLen
, strPath
, rtl_ustr_getLength(strPath
)+1);
2180 dwPathLen
+= rtl_ustr_getLength(strPath
);
2184 ::osl::LongPathBuffer
< sal_Char
> aTmpPath( MAX_LONG_PATH
);
2186 WideCharToMultiByte(CP_ACP
,0, o3tl::toW(aPath
), -1, aTmpPath
, aTmpPath
.getBufSizeInSymbols(), nullptr, nullptr);
2188 /* if file not exists, remove any specified subdirectories
2189 like "bin" or "program" */
2191 if (((access(aTmpPath
, 0) < 0) && (nPos
!= -1)) || (*strPath
== 0))
2193 static const sal_Char
*SubDirs
[] = SVERSION_DIRS
;
2196 sal_Char
*pStr
= aTmpPath
+ nPos
;
2198 for (i
= 0; i
< SAL_N_ELEMENTS(SubDirs
); i
++)
2199 if (strnicmp(pStr
+ 1, SubDirs
[i
], strlen(SubDirs
[i
])) == 0)
2203 strcpy(pStr
+ 1,SVERSION_USER
);
2204 if ( access(aTmpPath
, 0) < 0 )
2210 dwPathLen
= nPos
+ MultiByteToWideChar( CP_ACP
, 0, SVERSION_USER
, -1, o3tl::toW(aPath
+ nPos
+ 1), aPath
.getBufSizeInSymbols() - (nPos
+ 1) );
2215 copy_ustr_n(aPath
+ nPos
+ 1, strPath
, rtl_ustr_getLength(strPath
)+1);
2216 dwPathLen
= nPos
+ 1 + rtl_ustr_getLength(strPath
);
2224 if ((aPath
[dwPathLen
- 1] != L
'/') && (aPath
[dwPathLen
- 1] != L
'\\'))
2226 aPath
[dwPathLen
++] = L
'\\';
2227 aPath
[dwPathLen
] = 0;
2230 copy_ustr_n(aPath
+ dwPathLen
, strFile
, rtl_ustr_getLength(strFile
)+1);
2233 ::osl::LongPathBuffer
< sal_Char
> aTmpPath( MAX_LONG_PATH
);
2235 WideCharToMultiByte(CP_ACP
,0, o3tl::toW(aPath
), -1, aTmpPath
, aTmpPath
.getBufSizeInSymbols(), nullptr, nullptr);
2237 if ((access(aTmpPath
, 0) < 0) && (Product
[0] != '\0'))
2239 rtl_uString
* strSVFallback
= nullptr;
2240 rtl_uString
* strSVProfile
= nullptr;
2241 rtl_uString
* strSVLocation
= nullptr;
2242 rtl_uString
* strSVName
= nullptr;
2243 oslProfile hProfile
;
2245 rtl_uString_newFromAscii(&strSVFallback
, SVERSION_FALLBACK
);
2246 rtl_uString_newFromAscii(&strSVLocation
, SVERSION_LOCATION
);
2247 rtl_uString_newFromAscii(&strSVName
, SVERSION_NAME
);
2249 /* open sversion.ini in the system directory, and try to locate the entry
2250 with the highest version for StarOffice */
2251 if (osl_getProfileName(strSVLocation
, strSVName
, &strSVProfile
))
2253 hProfile
= osl_openProfile(
2254 strSVProfile
, osl_Profile_READLOCK
);
2257 osl_readProfileString(
2258 hProfile
, SVERSION_SECTION
, Product
, Buffer
,
2259 sizeof(Buffer
), "");
2260 osl_closeProfile(hProfile
);
2262 /* if not found, try the fallback */
2263 if (Buffer
[0] == '\0')
2265 if (osl_getProfileName(
2266 strSVFallback
, strSVName
, &strSVProfile
))
2268 hProfile
= osl_openProfile(
2269 strSVProfile
, osl_Profile_READLOCK
);
2272 osl_readProfileString(
2273 hProfile
, SVERSION_SECTION
, Product
,
2274 Buffer
, sizeof(Buffer
), "");
2278 osl_closeProfile(hProfile
);
2281 if (Buffer
[0] != '\0')
2283 dwPathLen
= MultiByteToWideChar(
2284 CP_ACP
, 0, Buffer
, -1, o3tl::toW(aPath
), aPath
.getBufSizeInSymbols() );
2287 /* build full path */
2288 if ((aPath
[dwPathLen
- 1] != L
'/')
2289 && (aPath
[dwPathLen
- 1] != L
'\\'))
2291 copy_ustr_n(aPath
+ dwPathLen
++, L
"\\", 2);
2296 copy_ustr_n(aPath
+ dwPathLen
, strPath
, rtl_ustr_getLength(strPath
)+1);
2297 dwPathLen
+= rtl_ustr_getLength(strPath
);
2301 ::osl::LongPathBuffer
< sal_Char
> aTmpPath2( MAX_LONG_PATH
);
2304 if ((n
= WideCharToMultiByte(
2305 CP_ACP
,0, o3tl::toW(aPath
), -1, aTmpPath2
,
2306 aTmpPath2
.getBufSizeInSymbols(), nullptr, nullptr))
2309 strcpy(aTmpPath2
+ n
, SVERSION_USER
);
2310 if (access(aTmpPath2
, 0) >= 0)
2312 dwPathLen
+= MultiByteToWideChar(
2313 CP_ACP
, 0, SVERSION_USER
, -1,
2314 o3tl::toW(aPath
+ dwPathLen
),
2315 aPath
.getBufSizeInSymbols() - dwPathLen
);
2322 rtl_uString_release(strSVProfile
);
2325 rtl_uString_release(strSVFallback
);
2326 rtl_uString_release(strSVLocation
);
2327 rtl_uString_release(strSVName
);
2331 aPath
[dwPathLen
] = 0;
2334 copy_ustr_n(strProfile
, aPath
, dwPathLen
+1);
2339 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */