Version 4.2.0.1, tag libreoffice-4.2.0.1
[LibreOffice.git] / sal / osl / w32 / profile.cxx
blob571e47a5e7c29e56f824e88f4035570db15cfc21
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include "system.h"
22 #include "file_url.h"
23 #include "path_helper.hxx"
25 #include <string.h>
26 #include <osl/diagnose.h>
27 #include <osl/profile.h>
28 #include <osl/process.h>
29 #include <osl/file.h>
30 #include <rtl/alloc.h>
31 #include <sal/macros.h>
32 #include <algorithm>
33 using std::min;
34 static inline void copy_ustr_n( void *dest, const void *source, size_t length ) { memcpy(dest, source, length*sizeof(sal_Unicode)); }
36 #define LINES_INI 32
37 #define LINES_ADD 10
38 #define SECTIONS_INI 5
39 #define SECTIONS_ADD 3
40 #define ENTRIES_INI 5
41 #define ENTRIES_ADD 3
44 #define STR_INI_EXTENSION L".ini"
45 #define STR_INI_METAHOME "?~"
46 #define STR_INI_METASYS "?$"
47 #define STR_INI_METACFG "?^"
48 #define STR_INI_METAINS "?#"
50 #define STR_INI_BOOLYES "yes"
51 #define STR_INI_BOOLON "on"
52 #define STR_INI_BOOLONE "1"
53 #define STR_INI_BOOLNO "no"
54 #define STR_INI_BOOLOFF "off"
55 #define STR_INI_BOOLZERO "0"
57 #define FLG_USER 0x00FF
58 #define FLG_AUTOOPEN 0x0100
59 #define FLG_MODIFIED 0x0200
61 #define SVERSION_LOCATION STR_INI_METACFG
62 #define SVERSION_FALLBACK STR_INI_METASYS
63 #define SVERSION_NAME "sversion"
64 #define SVERSION_SECTION "Versions"
65 #define SVERSION_SOFFICE "StarOffice"
66 #define SVERSION_PROFILE "soffice.ini"
67 #define SVERSION_OPTION "userid:"
68 #define SVERSION_DIRS { "bin", "program" }
69 #define SVERSION_USER "user"
71 /*#define DEBUG_OSL_PROFILE 1*/
72 /*#define TRACE_OSL_PROFILE 1*/
75 /*****************************************************************************/
76 /* Data Type Definition */
77 /*****************************************************************************/
79 typedef FILETIME osl_TStamp;
81 typedef enum _osl_TLockMode
83 un_lock, read_lock, write_lock
84 } osl_TLockMode;
86 typedef struct _osl_TFile
88 HANDLE m_Handle;
89 sal_Char* m_pReadPtr;
90 sal_Char m_ReadBuf[512];
91 sal_Char* m_pWriteBuf;
92 sal_uInt32 m_nWriteBufLen;
93 sal_uInt32 m_nWriteBufFree;
94 } osl_TFile;
96 typedef struct _osl_TProfileEntry
98 sal_uInt32 m_Line;
99 sal_uInt32 m_Offset;
100 sal_uInt32 m_Len;
101 } osl_TProfileEntry;
103 typedef struct _osl_TProfileSection
105 sal_uInt32 m_Line;
106 sal_uInt32 m_Offset;
107 sal_uInt32 m_Len;
108 sal_uInt32 m_NoEntries;
109 sal_uInt32 m_MaxEntries;
110 osl_TProfileEntry* m_Entries;
111 } osl_TProfileSection;
115 Profile-data structure hidden behind oslProfile:
117 typedef struct _osl_TProfileImpl
119 sal_uInt32 m_Flags;
120 osl_TFile* m_pFile;
121 osl_TStamp m_Stamp;
122 sal_uInt32 m_NoLines;
123 sal_uInt32 m_MaxLines;
124 sal_uInt32 m_NoSections;
125 sal_uInt32 m_MaxSections;
126 sal_Char** m_Lines;
127 rtl_uString *m_strFileName;
128 osl_TProfileSection* m_Sections;
129 } osl_TProfileImpl;
132 /*****************************************************************************/
133 /* Static Module Function Declarations */
134 /*****************************************************************************/
136 static osl_TFile* openFileImpl(rtl_uString * strFileName, oslProfileOption ProfileFlags );
137 static osl_TStamp closeFileImpl(osl_TFile* pFile);
138 static sal_Bool lockFile(const osl_TFile* pFile, osl_TLockMode eMode);
139 static sal_Bool rewindFile(osl_TFile* pFile, sal_Bool bTruncate);
140 static osl_TStamp getFileStamp(osl_TFile* pFile);
142 static sal_Bool getLine(osl_TFile* pFile, const sal_Char *pszLine, int MaxLen);
143 static sal_Bool putLine(osl_TFile* pFile, const sal_Char *pszLine);
144 static const sal_Char* stripBlanks(const sal_Char* String, sal_uInt32* pLen);
145 static const sal_Char* addLine(osl_TProfileImpl* pProfile, const sal_Char* Line);
146 static const sal_Char* insertLine(osl_TProfileImpl* pProfile, const sal_Char* Line, sal_uInt32 LineNo);
147 static void removeLine(osl_TProfileImpl* pProfile, sal_uInt32 LineNo);
148 static void setEntry(osl_TProfileImpl* pProfile, osl_TProfileSection* pSection,
149 sal_uInt32 NoEntry, sal_uInt32 Line,
150 const sal_Char* Entry, sal_uInt32 Len);
151 static sal_Bool addEntry(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection,
152 int Line, const sal_Char* Entry, sal_uInt32 Len);
153 static void removeEntry(osl_TProfileSection *pSection, sal_uInt32 NoEntry);
154 static sal_Bool addSection(osl_TProfileImpl* pProfile, int Line, const sal_Char* Section, sal_uInt32 Len);
155 static void removeSection(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection);
156 static osl_TProfileSection* findEntry(osl_TProfileImpl* pProfile, const sal_Char* Section,
157 const sal_Char* Entry, sal_uInt32 *pNoEntry);
158 static sal_Bool loadProfile(osl_TFile* pFile, osl_TProfileImpl* pProfile);
159 static sal_Bool storeProfile(osl_TProfileImpl* pProfile, sal_Bool bCleanup);
160 static osl_TProfileImpl* acquireProfile(oslProfile Profile, sal_Bool bWriteable);
161 static sal_Bool releaseProfile(osl_TProfileImpl* pProfile);
162 static sal_Bool lookupProfile(const sal_Unicode *strPath, const sal_Unicode *strFile, sal_Unicode *strProfile);
164 static sal_Bool writeProfileImpl (osl_TFile* pFile);
165 static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl*);
166 static sal_Bool osl_ProfileSwapProfileNames(osl_TProfileImpl*);
167 static rtl_uString* osl_ProfileGenerateExtension(rtl_uString* ustrFileName, rtl_uString* ustrExtension);
169 static sal_Bool SAL_CALL osl_getProfileName(rtl_uString* strPath, rtl_uString* strName, rtl_uString** strProfileName);
171 /*****************************************************************************/
172 /* Exported Module Functions */
173 /*****************************************************************************/
175 oslProfile SAL_CALL osl_openProfile(rtl_uString *strProfileName, sal_uInt32 Flags)
177 osl_TFile* pFile = NULL;
178 osl_TProfileImpl* pProfile;
179 rtl_uString *FileName=NULL;
181 #ifdef TRACE_OSL_PROFILE
182 OSL_TRACE("In osl_openProfile");
183 #endif
184 OSL_VERIFY(strProfileName);
186 if (rtl_uString_getLength(strProfileName) == 0 )
188 OSL_VERIFY(osl_getProfileName(NULL, NULL, &FileName));
190 else
192 rtl_uString_assign(&FileName, strProfileName);
196 osl_getSystemPathFromFileURL(FileName, &FileName);
199 #ifdef DEBUG_OSL_PROFILE
200 Flags=osl_Profile_FLUSHWRITE;
202 if ( Flags == osl_Profile_DEFAULT )
204 OSL_TRACE("with osl_Profile_DEFAULT");
206 if ( Flags & osl_Profile_SYSTEM )
208 OSL_TRACE("with osl_Profile_SYSTEM");
210 if ( Flags & osl_Profile_READLOCK )
212 OSL_TRACE("with osl_Profile_READLOCK");
214 if ( Flags & osl_Profile_WRITELOCK )
216 OSL_TRACE("with osl_Profile_WRITELOCK");
218 if ( Flags & osl_Profile_FLUSHWRITE )
220 OSL_TRACE("with osl_Profile_FLUSHWRITE");
222 #endif
224 if ( (! (Flags & osl_Profile_SYSTEM)) && ( (pFile = openFileImpl(FileName, Flags) ) == NULL ) )
226 #ifdef TRACE_OSL_PROFILE
227 OSL_TRACE("Out osl_openProfile [not opened]");
228 #endif
229 if( FileName)
230 rtl_uString_release( FileName);
232 return (NULL);
236 pProfile = (osl_TProfileImpl*)calloc(1, sizeof(osl_TProfileImpl));
239 pProfile->m_Flags = Flags & FLG_USER;
240 osl_getSystemPathFromFileURL(strProfileName, &pProfile->m_strFileName);
242 if (Flags & (osl_Profile_READLOCK | osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE ))
243 pProfile->m_pFile = pFile;
245 pProfile->m_Stamp = getFileStamp(pFile);
247 loadProfile(pFile, pProfile);
249 if (pProfile->m_pFile == NULL)
250 closeFileImpl(pFile);
252 #ifdef TRACE_OSL_PROFILE
253 OSL_TRACE("Out osl_openProfile [ok]");
254 #endif
255 if( FileName)
256 rtl_uString_release( FileName);
258 return (pProfile);
261 sal_Bool SAL_CALL osl_closeProfile(oslProfile Profile)
263 osl_TProfileImpl* pProfile = (osl_TProfileImpl*)Profile;
265 #ifdef TRACE_OSL_PROFILE
266 OSL_TRACE("In osl_closeProfile");
267 #endif
269 if ( Profile == 0 )
271 #ifdef TRACE_OSL_PROFILE
272 OSL_TRACE("Out osl_closeProfile [profile==0]");
273 #endif
274 return sal_False;
277 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
279 pProfile = acquireProfile(Profile,sal_True);
281 if ( pProfile != 0 )
283 if ( !( pProfile->m_Flags & osl_Profile_READLOCK ) && ( pProfile->m_Flags & FLG_MODIFIED ) )
285 storeProfile(pProfile, sal_False);
288 else
290 pProfile = acquireProfile(Profile,sal_False);
293 if ( pProfile == 0 )
295 #ifdef TRACE_OSL_PROFILE
296 OSL_TRACE("Out osl_closeProfile [pProfile==0]");
297 #endif
298 return sal_False;
301 if (pProfile->m_pFile != NULL)
302 closeFileImpl(pProfile->m_pFile);
305 pProfile->m_pFile = NULL;
306 rtl_uString_release(pProfile->m_strFileName);
307 pProfile->m_strFileName = NULL;
309 /* release whole profile data types memory */
310 if ( pProfile->m_NoLines > 0)
312 unsigned int index=0;
313 if ( pProfile->m_Lines != 0 )
315 for ( index = 0 ; index < pProfile->m_NoLines ; ++index)
317 if ( pProfile->m_Lines[index] != 0 )
319 free(pProfile->m_Lines[index]);
322 free(pProfile->m_Lines);
324 if ( pProfile->m_Sections != 0 )
326 for ( index = 0 ; index < pProfile->m_NoSections ; ++index )
328 if ( pProfile->m_Sections[index].m_Entries != 0 )
329 free(pProfile->m_Sections[index].m_Entries);
331 free(pProfile->m_Sections);
335 free(pProfile);
337 #ifdef TRACE_OSL_PROFILE
338 OSL_TRACE("Out osl_closeProfile [ok]");
339 #endif
340 return (sal_True);
344 sal_Bool SAL_CALL osl_flushProfile(oslProfile Profile)
346 osl_TProfileImpl* pProfile = (osl_TProfileImpl*) Profile;
347 osl_TFile* pFile;
348 sal_Bool bRet = sal_False;
350 #ifdef TRACE_OSL_PROFILE
351 OSL_TRACE("In osl_flushProfile()");
352 #endif
354 if ( pProfile == 0 )
356 #ifdef TRACE_OSL_PROFILE
357 OSL_TRACE("Out osl_flushProfile() [pProfile == 0]");
358 #endif
359 return sal_False;
362 pFile = pProfile->m_pFile;
363 if ( pFile == 0 || pFile->m_Handle == INVALID_HANDLE_VALUE )
365 #ifdef TRACE_OSL_PROFILE
366 OSL_TRACE("Out osl_flushProfile() [invalid file]");
367 #endif
368 return sal_False;
371 if ( pProfile->m_Flags & FLG_MODIFIED )
373 #ifdef DEBUG_OSL_PROFILE
374 OSL_TRACE("swapping to storeprofile");
375 #endif
376 bRet = storeProfile(pProfile,sal_False);
379 #ifdef TRACE_OSL_PROFILE
380 OSL_TRACE("Out osl_flushProfile() [ok]");
381 #endif
382 return bRet;
385 static sal_Bool writeProfileImpl(osl_TFile* pFile)
387 DWORD BytesWritten=0;
388 BOOL bRet;
390 #ifdef TRACE_OSL_PROFILE
391 OSL_TRACE("In osl_writeProfileImpl()");
392 #endif
394 if ( !( pFile != 0 && pFile->m_Handle != INVALID_HANDLE_VALUE ) || ( pFile->m_pWriteBuf == 0 ) )
396 #ifdef TRACE_OSL_PROFILE
397 OSL_TRACE("Out osl_writeProfileImpl() [invalid args]");
398 #endif
399 return sal_False;
402 bRet=WriteFile(pFile->m_Handle, pFile->m_pWriteBuf, pFile->m_nWriteBufLen - pFile->m_nWriteBufFree,&BytesWritten,NULL);
404 if ( bRet == 0 || BytesWritten <= 0 )
406 OSL_ENSURE(bRet,"WriteFile failed!!!");
407 OSL_TRACE("write failed '%s'",strerror(errno));
409 return (sal_False);
412 free(pFile->m_pWriteBuf);
413 pFile->m_pWriteBuf=0;
414 pFile->m_nWriteBufLen=0;
415 pFile->m_nWriteBufFree=0;
417 #ifdef TRACE_OSL_PROFILE
418 OSL_TRACE("Out osl_writeProfileImpl() [ok]");
419 #endif
420 return sal_True;
424 sal_Bool SAL_CALL osl_readProfileString(oslProfile Profile,
425 const sal_Char* pszSection, const sal_Char* pszEntry,
426 sal_Char* pszString, sal_uInt32 MaxLen,
427 const sal_Char* pszDefault)
429 sal_uInt32 NoEntry;
430 const sal_Char* pStr = 0;
431 osl_TProfileSection* pSec;
432 osl_TProfileImpl* pProfile = 0;
435 #ifdef TRACE_OSL_PROFILE
436 OSL_TRACE("In osl_readProfileString");
437 #endif
439 pProfile = acquireProfile(Profile, sal_False);
441 if (pProfile == NULL)
443 #ifdef TRACE_OSL_PROFILE
444 OSL_TRACE("Out osl_readProfileString [pProfile==0]");
445 #endif
447 return (sal_False);
451 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
453 if (((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) != NULL) &&
454 (NoEntry < pSec->m_NoEntries) &&
455 ((pStr = strchr(pProfile->m_Lines[pSec->m_Entries[NoEntry].m_Line],
456 '=')) != NULL))
457 pStr++;
458 else
459 pStr = pszDefault;
461 if ( pStr != 0 )
463 pStr = stripBlanks(pStr, NULL);
464 MaxLen = (MaxLen - 1 < strlen(pStr)) ? (MaxLen - 1) : strlen(pStr);
465 pStr = stripBlanks(pStr, &MaxLen);
466 strncpy(pszString, pStr, MaxLen);
467 pszString[MaxLen] = '\0';
470 else
472 ::osl::LongPathBuffer< sal_Char > aFileName( MAX_LONG_PATH );
474 WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(pProfile->m_strFileName->buffer), -1, aFileName, aFileName.getBufSizeInSymbols(), NULL, NULL);
475 GetPrivateProfileString(pszSection, pszEntry, pszDefault, pszString, MaxLen, aFileName);
478 releaseProfile(pProfile);
480 if ( pStr == 0 )
482 #ifdef TRACE_OSL_PROFILE
483 OSL_TRACE("Out osl_readProfileString [pStr==0]");
484 #endif
486 return (sal_False);
489 #ifdef TRACE_OSL_PROFILE
490 OSL_TRACE("Out osl_readProfileString [ok]");
491 #endif
493 return (sal_True);
497 sal_Bool SAL_CALL osl_readProfileBool(oslProfile Profile,
498 const sal_Char* pszSection, const sal_Char* pszEntry,
499 sal_Bool Default)
501 sal_Char Line[32];
503 #ifdef TRACE_OSL_PROFILE
504 OSL_TRACE("In osl_readProfileBool");
505 #endif
507 if (osl_readProfileString(Profile, pszSection, pszEntry, Line, sizeof(Line), ""))
509 if ((stricmp(Line, STR_INI_BOOLYES) == 0) ||
510 (stricmp(Line, STR_INI_BOOLON) == 0) ||
511 (stricmp(Line, STR_INI_BOOLONE) == 0))
512 Default = sal_True;
513 else
514 if ((stricmp(Line, STR_INI_BOOLNO) == 0) ||
515 (stricmp(Line, STR_INI_BOOLOFF) == 0) ||
516 (stricmp(Line, STR_INI_BOOLZERO) == 0))
517 Default = sal_False;
520 #ifdef TRACE_OSL_PROFILE
521 OSL_TRACE("Out osl_readProfileBool [ok]");
522 #endif
524 return (Default);
528 sal_uInt32 SAL_CALL osl_readProfileIdent(oslProfile Profile,
529 const sal_Char* pszSection, const sal_Char* pszEntry,
530 sal_uInt32 FirstId, const sal_Char* Strings[],
531 sal_uInt32 Default)
533 sal_uInt32 i;
534 sal_Char Line[256];
536 #ifdef TRACE_OSL_PROFILE
537 OSL_TRACE("In osl_readProfileIdent");
538 #endif
540 if (osl_readProfileString(Profile, pszSection, pszEntry, Line, sizeof(Line), ""))
542 i = 0;
543 while (Strings[i] != NULL)
545 if (stricmp(Line, Strings[i]) == 0)
547 Default = i + FirstId;
548 break;
550 i++;
554 #ifdef TRACE_OSL_PROFILE
555 OSL_TRACE("Out osl_readProfileIdent [ok]");
556 #endif
557 return (Default);
560 sal_Bool SAL_CALL osl_writeProfileString(oslProfile Profile,
561 const sal_Char* pszSection, const sal_Char* pszEntry,
562 const sal_Char* pszString)
564 sal_uInt32 i;
565 sal_Bool bRet = sal_False;
566 sal_uInt32 NoEntry;
567 const sal_Char* pStr;
568 sal_Char Line[4096];
569 osl_TProfileSection* pSec;
570 osl_TProfileImpl* pProfile = 0;
572 #ifdef TRACE_OSL_PROFILE
573 OSL_TRACE("In osl_writeProfileString");
574 #endif
576 pProfile = acquireProfile(Profile, sal_True);
578 if (pProfile == NULL)
580 #ifdef TRACE_OSL_PROFILE
581 OSL_TRACE("Out osl_writeProfileString [pProfile==0]");
582 #endif
583 return (sal_False);
587 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
589 if ((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) == NULL)
591 Line[0] = '\0';
592 addLine(pProfile, Line);
594 Line[0] = '[';
595 strcpy(&Line[1], pszSection);
596 Line[1 + strlen(pszSection)] = ']';
597 Line[2 + strlen(pszSection)] = '\0';
599 if (((pStr = addLine(pProfile, Line)) == NULL) ||
600 (! addSection(pProfile, pProfile->m_NoLines - 1, &pStr[1], strlen(pszSection))))
602 releaseProfile(pProfile);
603 #ifdef TRACE_OSL_PROFILE
604 OSL_TRACE("Out osl_writeProfileString [not added]");
605 #endif
606 return (sal_False);
609 pSec = &pProfile->m_Sections[pProfile->m_NoSections - 1];
610 NoEntry = pSec->m_NoEntries;
613 Line[0] = '\0';
614 strcpy(&Line[0], pszEntry);
615 Line[0 + strlen(pszEntry)] = '=';
616 strcpy(&Line[1 + strlen(pszEntry)], pszString);
618 if (NoEntry >= pSec->m_NoEntries)
620 if (pSec->m_NoEntries > 0)
621 i = pSec->m_Entries[pSec->m_NoEntries - 1].m_Line + 1;
622 else
623 i = pSec->m_Line + 1;
625 if (((pStr = insertLine(pProfile, Line, i)) == NULL) ||
626 (! addEntry(pProfile, pSec, i, pStr, strlen(pszEntry))))
628 releaseProfile(pProfile);
629 #ifdef TRACE_OSL_PROFILE
630 OSL_TRACE("Out osl_writeProfileString [not inserted]");
631 #endif
632 return (sal_False);
635 pProfile->m_Flags |= FLG_MODIFIED;
637 else
639 i = pSec->m_Entries[NoEntry].m_Line;
640 free(pProfile->m_Lines[i]);
641 pProfile->m_Lines[i] = strdup(Line);
642 setEntry(pProfile, pSec, NoEntry, i, pProfile->m_Lines[i], strlen(pszEntry));
644 pProfile->m_Flags |= FLG_MODIFIED;
647 else
649 ::osl::LongPathBuffer< sal_Char > aFileName( MAX_LONG_PATH );
651 WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(pProfile->m_strFileName->buffer), -1, aFileName, aFileName.getBufSizeInSymbols(), NULL, NULL);
652 WritePrivateProfileString(pszSection, pszEntry, pszString, aFileName);
655 bRet = releaseProfile(pProfile);
656 #ifdef TRACE_OSL_PROFILE
657 OSL_TRACE("Out osl_writeProfileString [ok]");
658 #endif
659 return bRet;
663 sal_Bool SAL_CALL osl_writeProfileBool(oslProfile Profile,
664 const sal_Char* pszSection, const sal_Char* pszEntry,
665 sal_Bool Value)
667 sal_Bool bRet = sal_False;
669 #ifdef TRACE_OSL_PROFILE
670 OSL_TRACE("In osl_writeProfileBool");
671 #endif
673 if (Value)
674 bRet=osl_writeProfileString(Profile, pszSection, pszEntry, STR_INI_BOOLONE);
675 else
676 bRet=osl_writeProfileString(Profile, pszSection, pszEntry, STR_INI_BOOLZERO);
678 #ifdef TRACE_OSL_PROFILE
679 OSL_TRACE("Out osl_writeProfileBool [ok]");
680 #endif
682 return bRet;
686 sal_Bool SAL_CALL osl_writeProfileIdent(oslProfile Profile,
687 const sal_Char* pszSection, const sal_Char* pszEntry,
688 sal_uInt32 FirstId, const sal_Char* Strings[],
689 sal_uInt32 Value)
691 int i, n;
692 sal_Bool bRet = sal_False;
694 #ifdef TRACE_OSL_PROFILE
695 OSL_TRACE("In osl_writeProfileIdent");
696 #endif
698 for (n = 0; Strings[n] != NULL; n++);
700 if ((i = Value - FirstId) >= n)
701 bRet=sal_False;
702 else
703 bRet=osl_writeProfileString(Profile, pszSection, pszEntry, Strings[i]);
705 #ifdef TRACE_OSL_PROFILE
706 OSL_TRACE("Out osl_writeProfileIdent");
707 #endif
708 return bRet;
712 sal_Bool SAL_CALL osl_removeProfileEntry(oslProfile Profile,
713 const sal_Char *pszSection, const sal_Char *pszEntry)
715 sal_uInt32 NoEntry;
716 osl_TProfileSection* pSec;
717 osl_TProfileImpl* pProfile = 0;
718 sal_Bool bRet = sal_False;
720 #ifdef TRACE_OSL_PROFILE
721 OSL_TRACE("In osl_removeProfileEntry");
722 #endif
724 pProfile = acquireProfile(Profile, sal_True);
726 if (pProfile == NULL)
728 #ifdef TRACE_OSL_PROFILE
729 OSL_TRACE("Out osl_removeProfileEntry [pProfile==0]");
730 #endif
733 return (sal_False);
737 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
739 if (((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) != NULL) &&
740 (NoEntry < pSec->m_NoEntries))
742 removeLine(pProfile, pSec->m_Entries[NoEntry].m_Line);
743 removeEntry(pSec, NoEntry);
744 if (pSec->m_NoEntries == 0)
746 removeLine(pProfile, pSec->m_Line);
748 /* remove any empty separation line */
749 if ((pSec->m_Line > 0) && (pProfile->m_Lines[pSec->m_Line - 1][0] == '\0'))
750 removeLine(pProfile, pSec->m_Line - 1);
752 removeSection(pProfile, pSec);
755 pProfile->m_Flags |= FLG_MODIFIED;
758 else
760 ::osl::LongPathBuffer< sal_Char > aFileName( MAX_LONG_PATH );
762 WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(pProfile->m_strFileName->buffer), -1, aFileName, aFileName.getBufSizeInSymbols(), NULL, NULL);
763 WritePrivateProfileString(pszSection, pszEntry, NULL, aFileName);
766 bRet = releaseProfile(pProfile);
767 #ifdef TRACE_OSL_PROFILE
768 OSL_TRACE("Out osl_removeProfileEntry [ok]");
769 #endif
770 return bRet;
774 sal_uInt32 SAL_CALL osl_getProfileSectionEntries(oslProfile Profile, const sal_Char *pszSection,
775 sal_Char* pszBuffer, sal_uInt32 MaxLen)
777 sal_uInt32 i, n = 0;
778 sal_uInt32 NoEntry;
779 osl_TProfileSection* pSec;
780 osl_TProfileImpl* pProfile = 0;
782 #ifdef TRACE_OSL_PROFILE
783 OSL_TRACE("In osl_getProfileSectionEntries");
784 #endif
786 pProfile = acquireProfile(Profile, sal_False);
788 if (pProfile == NULL)
790 #ifdef TRACE_OSL_PROFILE
791 OSL_TRACE("Out osl_getProfileSectionEntries [pProfile=0]");
792 #endif
795 return (0);
799 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
801 if ((pSec = findEntry(pProfile, pszSection, "", &NoEntry)) != NULL)
803 if (MaxLen != 0)
805 for (i = 0; i < pSec->m_NoEntries; i++)
807 if ((n + pSec->m_Entries[i].m_Len + 1) < MaxLen)
809 strncpy(&pszBuffer[n], &pProfile->m_Lines[pSec->m_Entries[i].m_Line]
810 [pSec->m_Entries[i].m_Offset], pSec->m_Entries[i].m_Len);
811 n += pSec->m_Entries[i].m_Len;
812 pszBuffer[n++] = '\0';
814 else
815 break;
819 pszBuffer[n++] = '\0';
821 else
823 for (i = 0; i < pSec->m_NoEntries; i++)
824 n += pSec->m_Entries[i].m_Len + 1;
826 n += 1;
829 else
830 n = 0;
832 else
834 ::osl::LongPathBuffer< sal_Char > aFileName( MAX_LONG_PATH );
836 WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(pProfile->m_strFileName->buffer), -1, aFileName, aFileName.getBufSizeInSymbols(), NULL, NULL);
837 n = GetPrivateProfileString(pszSection, NULL, NULL, pszBuffer, MaxLen, aFileName);
840 releaseProfile(pProfile);
842 #ifdef TRACE_OSL_PROFILE
843 OSL_TRACE("Out osl_getProfileSectionEntries [ok]");
844 #endif
846 return (n);
850 sal_Bool SAL_CALL osl_getProfileName(rtl_uString* strPath, rtl_uString* strName, rtl_uString** strProfileName)
852 sal_Bool bFailed;
853 ::osl::LongPathBuffer< sal_Unicode > aFile( MAX_LONG_PATH );
854 ::osl::LongPathBuffer< sal_Unicode > aPath( MAX_LONG_PATH );
855 sal_uInt32 nFileLen = 0;
856 sal_uInt32 nPathLen = 0;
858 rtl_uString * strTmp = NULL;
859 oslFileError nError;
861 /* build file name */
862 if (strName && strName->length)
864 if( ::sal::static_int_cast< sal_uInt32 >( strName->length ) >= aFile.getBufSizeInSymbols() )
865 return sal_False;
867 copy_ustr_n( aFile, strName->buffer, strName->length+1);
868 nFileLen = strName->length;
870 if (rtl_ustr_indexOfChar( aFile, L'.' ) == -1)
872 if (nFileLen + wcslen(STR_INI_EXTENSION) >= aFile.getBufSizeInSymbols())
873 return sal_False;
875 /* add default extension */
876 copy_ustr_n( aFile + nFileLen, STR_INI_EXTENSION, wcslen(STR_INI_EXTENSION)+1 );
877 nFileLen += wcslen(STR_INI_EXTENSION);
880 else
882 rtl_uString *strProgName = NULL;
883 sal_Unicode *pProgName;
884 sal_Int32 nOffset = 0;
885 sal_Int32 nLen;
886 sal_Int32 nPos;
888 if (osl_getExecutableFile(&strProgName) != osl_Process_E_None)
889 return sal_False;
891 /* remove path and extension from filename */
892 pProgName = strProgName->buffer;
893 nLen = strProgName->length ;
895 if ((nPos = rtl_ustr_lastIndexOfChar( pProgName, L'/' )) != -1)
896 nOffset = nPos + 1;
897 else if ((nPos = rtl_ustr_lastIndexOfChar( pProgName, L':' )) != -1)
898 nOffset = nPos + 1;
900 if ((nPos = rtl_ustr_lastIndexOfChar( pProgName, L'.' )) != -1 )
901 nLen -= 4;
903 if ((nFileLen = nLen - nOffset) >= aFile.getBufSizeInSymbols())
904 return sal_False;
906 copy_ustr_n(aFile, pProgName + nOffset, nFileLen);
908 if (nFileLen + wcslen(STR_INI_EXTENSION) >= aFile.getBufSizeInSymbols())
909 return sal_False;
911 /* add default extension */
912 copy_ustr_n(aFile + nFileLen, STR_INI_EXTENSION, wcslen(STR_INI_EXTENSION)+1);
913 nFileLen += wcslen(STR_INI_EXTENSION);
915 rtl_uString_release( strProgName );
918 if (aFile[0] == 0)
919 return sal_False;
921 /* build directory path */
922 if (strPath && strPath->length)
924 sal_Unicode *pPath = rtl_uString_getStr(strPath);
925 sal_Int32 nLen = rtl_uString_getLength(strPath);
927 if ((rtl_ustr_ascii_compare_WithLength(pPath, RTL_CONSTASCII_LENGTH(STR_INI_METAHOME) , STR_INI_METAHOME) == 0) &&
928 ((nLen == RTL_CONSTASCII_LENGTH(STR_INI_METAHOME)) || (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METAHOME)] == '/')))
930 rtl_uString * strHome = NULL;
931 oslSecurity security = osl_getCurrentSecurity();
933 bFailed = ! osl_getHomeDir(security, &strHome);
934 osl_freeSecurityHandle(security);
936 if (bFailed) return (sal_False);
938 if ( ::sal::static_int_cast< sal_uInt32 >( strHome->length ) >= aPath.getBufSizeInSymbols())
939 return sal_False;
941 copy_ustr_n( aPath, strHome->buffer, strHome->length+1);
942 nPathLen = strHome->length;
944 if (nLen > RTL_CONSTASCII_LENGTH(STR_INI_METAHOME))
946 pPath += RTL_CONSTASCII_LENGTH(STR_INI_METAHOME);
947 nLen -= RTL_CONSTASCII_LENGTH(STR_INI_METAHOME);
949 if (nLen + nPathLen >= aPath.getBufSizeInSymbols())
950 return sal_False;
952 copy_ustr_n(aPath + nPathLen, pPath, nLen+1);
953 nPathLen += nLen;
956 rtl_uString_release(strHome);
959 else if ((rtl_ustr_ascii_compare_WithLength(pPath, RTL_CONSTASCII_LENGTH(STR_INI_METACFG), STR_INI_METACFG) == 0) &&
960 ((nLen == RTL_CONSTASCII_LENGTH(STR_INI_METACFG)) || (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METACFG)] == '/')))
962 rtl_uString * strConfig = NULL;
963 oslSecurity security = osl_getCurrentSecurity();
965 bFailed = ! osl_getConfigDir(security, &strConfig);
966 osl_freeSecurityHandle(security);
968 if (bFailed) return (sal_False);
970 if ( ::sal::static_int_cast< sal_uInt32 >( strConfig->length ) >= aPath.getBufSizeInSymbols())
971 return sal_False;
973 copy_ustr_n( aPath, strConfig->buffer, strConfig->length+1 );
974 nPathLen = strConfig->length;
976 if (nLen > RTL_CONSTASCII_LENGTH(STR_INI_METACFG))
978 pPath += RTL_CONSTASCII_LENGTH(STR_INI_METACFG);
979 nLen -= RTL_CONSTASCII_LENGTH(STR_INI_METACFG);
981 if (nLen + nPathLen >= aPath.getBufSizeInSymbols())
982 return sal_False;
984 copy_ustr_n(aPath + nPathLen, pPath, nLen+1);
985 nPathLen += nLen;
988 rtl_uString_release(strConfig);
991 else if ((rtl_ustr_ascii_compare_WithLength(pPath, RTL_CONSTASCII_LENGTH(STR_INI_METASYS), STR_INI_METASYS) == 0) &&
992 ((nLen == RTL_CONSTASCII_LENGTH(STR_INI_METASYS)) || (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METASYS)] == '/')))
994 if (((nPathLen = GetWindowsDirectoryW(::osl::mingw_reinterpret_cast<LPWSTR>(aPath), aPath.getBufSizeInSymbols())) == 0) || (nPathLen >= aPath.getBufSizeInSymbols()))
995 return (sal_False);
997 if (nLen > RTL_CONSTASCII_LENGTH(STR_INI_METASYS))
999 pPath += RTL_CONSTASCII_LENGTH(STR_INI_METASYS);
1000 nLen -= RTL_CONSTASCII_LENGTH(STR_INI_METASYS);
1002 if (nLen + nPathLen >= aPath.getBufSizeInSymbols())
1003 return sal_False;
1005 copy_ustr_n(aPath + nPathLen, pPath, nLen+1);
1006 nPathLen += nLen;
1010 else if ((rtl_ustr_ascii_compare_WithLength(pPath, RTL_CONSTASCII_LENGTH(STR_INI_METAINS), STR_INI_METAINS) == 0) &&
1011 ((nLen == RTL_CONSTASCII_LENGTH(STR_INI_METAINS)) || (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METAINS)] == '/') ||
1012 (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METAINS)] == '"') ) )
1014 if (! lookupProfile(pPath + RTL_CONSTASCII_LENGTH(STR_INI_METAINS), aFile, aPath))
1015 return (sal_False);
1017 nPathLen = rtl_ustr_getLength(aPath);
1020 else if( ::sal::static_int_cast< sal_uInt32 >( nLen ) < aPath.getBufSizeInSymbols())
1022 copy_ustr_n(aPath, pPath, nLen+1);
1023 nPathLen = rtl_ustr_getLength(aPath);
1025 else
1026 return sal_False;
1028 else
1030 rtl_uString * strConfigDir = NULL;
1031 oslSecurity security = osl_getCurrentSecurity();
1033 bFailed = ! osl_getConfigDir(security, &strConfigDir);
1034 osl_freeSecurityHandle(security);
1036 if (bFailed) return (sal_False);
1037 if ( ::sal::static_int_cast< sal_uInt32 >( strConfigDir->length ) >= aPath.getBufSizeInSymbols() )
1038 return sal_False;
1040 copy_ustr_n(aPath, strConfigDir->buffer, strConfigDir->length+1);
1041 nPathLen = strConfigDir->length;
1044 if (nPathLen && (aPath[nPathLen - 1] != L'/') && (aPath[nPathLen - 1] != L'\\'))
1046 aPath[nPathLen++] = L'\\';
1047 aPath[nPathLen] = 0;
1050 if (nPathLen + nFileLen >= aPath.getBufSizeInSymbols())
1051 return sal_False;
1053 /* append file name */
1054 copy_ustr_n(aPath + nPathLen, aFile, nFileLen+1);
1055 nPathLen += nFileLen;
1057 /* copy filename */
1058 rtl_uString_newFromStr_WithLength(&strTmp, aPath, nPathLen);
1059 nError = osl_getFileURLFromSystemPath(strTmp, strProfileName);
1060 rtl_uString_release(strTmp);
1062 return (sal_Bool) (nError == osl_File_E_None);
1066 sal_uInt32 SAL_CALL osl_getProfileSections(oslProfile Profile, sal_Char* pszBuffer, sal_uInt32 MaxLen)
1068 sal_uInt32 i, n = 0;
1069 osl_TProfileSection* pSec;
1070 osl_TProfileImpl* pProfile = acquireProfile(Profile, sal_False);
1072 if (pProfile == NULL)
1073 return (0);
1075 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
1077 if (MaxLen != 0)
1079 for (i = 0; i < pProfile->m_NoSections; i++)
1081 pSec = &pProfile->m_Sections[i];
1083 if ((n + pSec->m_Len + 1) < MaxLen)
1085 strncpy(&pszBuffer[n], &pProfile->m_Lines[pSec->m_Line][pSec->m_Offset],
1086 pSec->m_Len);
1087 n += pSec->m_Len;
1088 pszBuffer[n++] = '\0';
1090 else
1091 break;
1094 pszBuffer[n++] = '\0';
1096 else
1098 for (i = 0; i < pProfile->m_NoSections; i++)
1099 n += pProfile->m_Sections[i].m_Len + 1;
1101 n += 1;
1104 else
1106 ::osl::LongPathBuffer< sal_Char > aFileName( MAX_LONG_PATH );
1108 WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(pProfile->m_strFileName->buffer), -1, aFileName, aFileName.getBufSizeInSymbols(), NULL, NULL);
1109 n = GetPrivateProfileSectionNames(pszBuffer, MaxLen, aFileName);
1112 releaseProfile(pProfile);
1114 return (n);
1118 /*****************************************************************************/
1119 /* Static Module Functions */
1120 /*****************************************************************************/
1122 static osl_TStamp getFileStamp(osl_TFile* pFile)
1124 FILETIME FileTime;
1126 if ((pFile->m_Handle == INVALID_HANDLE_VALUE) ||
1127 (! GetFileTime(pFile->m_Handle, NULL, NULL, &FileTime)))
1128 memset(&FileTime, 0, sizeof(FileTime));
1130 return (FileTime);
1135 static sal_Bool lockFile(const osl_TFile* pFile, osl_TLockMode eMode)
1137 sal_Bool status = sal_False;
1138 OVERLAPPED Overlapped;
1140 if (pFile->m_Handle == INVALID_HANDLE_VALUE)
1141 return (sal_False);
1143 memset(&Overlapped, 0, sizeof(Overlapped));
1145 switch (eMode)
1147 case un_lock:
1148 status = (sal_Bool) UnlockFileEx(
1149 pFile->m_Handle, 0, 0xFFFFFFFF, 0, &Overlapped);
1150 break;
1152 case read_lock:
1153 status = (sal_Bool) LockFileEx(
1154 pFile->m_Handle, 0, 0, 0xFFFFFFFF, 0, &Overlapped);
1155 break;
1157 case write_lock:
1158 status = (sal_Bool) LockFileEx(
1159 pFile->m_Handle, LOCKFILE_EXCLUSIVE_LOCK, 0, 0xFFFFFFFF, 0,
1160 &Overlapped);
1161 break;
1164 return (status);
1168 static osl_TFile* openFileImpl(rtl_uString * strFileName, oslProfileOption ProfileFlags )
1170 osl_TFile* pFile = reinterpret_cast< osl_TFile*>( calloc( 1, sizeof(osl_TFile) ) );
1171 sal_Bool bWriteable = sal_False;
1173 if ( ProfileFlags & ( osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE ) )
1175 #ifdef DEBUG_OSL_PROFILE
1176 OSL_TRACE("setting bWriteable to TRUE");
1177 #endif
1178 bWriteable=sal_True;
1181 if (! bWriteable)
1183 pFile->m_Handle = CreateFileW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( strFileName )), GENERIC_READ,
1184 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1185 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1187 /* mfe: argghh!!! do not check if the file could be openend */
1188 /* default mode expects it that way!!! */
1190 else
1192 #ifdef DEBUG_OSL_PROFILE
1193 OSL_TRACE("opening '%s' read/write",pszFilename);
1194 #endif
1196 if ((pFile->m_Handle = CreateFileW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( strFileName )), GENERIC_READ | GENERIC_WRITE,
1197 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1198 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL))
1199 == INVALID_HANDLE_VALUE)
1201 free(pFile);
1202 return (NULL);
1206 pFile->m_pWriteBuf=0;
1207 pFile->m_nWriteBufFree=0;
1208 pFile->m_nWriteBufLen=0;
1210 if ( ProfileFlags & (osl_Profile_WRITELOCK | osl_Profile_READLOCK ) )
1212 #ifdef DEBUG_OSL_PROFILE
1213 OSL_TRACE("locking '%s' file",pszFilename);
1214 #endif
1216 lockFile(pFile, bWriteable ? write_lock : read_lock);
1219 return (pFile);
1224 static osl_TStamp closeFileImpl(osl_TFile* pFile)
1226 osl_TStamp stamp = {0, 0};
1228 if ( pFile == 0 )
1230 return stamp;
1233 if (pFile->m_Handle != INVALID_HANDLE_VALUE)
1235 stamp = getFileStamp(pFile);
1237 lockFile(pFile, un_lock);
1239 CloseHandle(pFile->m_Handle);
1240 pFile->m_Handle = INVALID_HANDLE_VALUE;
1243 if ( pFile->m_pWriteBuf != 0 )
1245 free(pFile->m_pWriteBuf);
1248 free(pFile);
1250 return(stamp);
1254 static sal_Bool rewindFile(osl_TFile* pFile, sal_Bool bTruncate)
1256 if (pFile->m_Handle != INVALID_HANDLE_VALUE)
1258 pFile->m_pReadPtr = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);
1260 SetFilePointer(pFile->m_Handle, 0, NULL, FILE_BEGIN);
1262 if (bTruncate)
1263 SetEndOfFile(pFile->m_Handle);
1266 return (sal_True);
1270 static sal_Bool getLine(osl_TFile* pFile, const sal_Char *pszLine, int MaxLen)
1272 DWORD Max;
1273 size_t Free, Bytes;
1274 sal_Char* pChr;
1275 sal_Char* pLine = (sal_Char *)pszLine;
1277 if (pFile->m_Handle == INVALID_HANDLE_VALUE)
1278 return (sal_False);
1280 MaxLen -= 1;
1284 Bytes = sizeof(pFile->m_ReadBuf) - (pFile->m_pReadPtr - pFile->m_ReadBuf);
1286 if (Bytes <= 1)
1288 /* refill buffer */
1289 memcpy(pFile->m_ReadBuf, pFile->m_pReadPtr, Bytes);
1290 pFile->m_pReadPtr = pFile->m_ReadBuf;
1292 Free = sizeof(pFile->m_ReadBuf) - Bytes;
1294 if (! ReadFile(pFile->m_Handle, &pFile->m_ReadBuf[Bytes], Free, &Max, NULL))
1296 *pLine = '\0';
1297 return (sal_False);
1300 if (Max < Free)
1302 if ((Max == 0) && (pLine == pszLine))
1304 *pLine = '\0';
1305 return (sal_False);
1308 pFile->m_ReadBuf[Bytes + Max] = '\0';
1312 for (pChr = pFile->m_pReadPtr;
1313 (*pChr != '\n') && (*pChr != '\r') && (*pChr != '\0') &&
1314 (pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf) - 1));
1315 pChr++);
1317 Max = min((int) (pChr - pFile->m_pReadPtr), MaxLen);
1318 memcpy(pLine, pFile->m_pReadPtr, Max);
1319 MaxLen -= Max;
1320 pLine += Max;
1322 if (pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf) - 1))
1324 if (*pChr != '\0')
1326 if ((pChr[0] == '\r') && (pChr[1] == '\n'))
1327 pChr += 2;
1328 else
1329 pChr += 1;
1332 if ((pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf))) &&
1333 (*pChr == '\0'))
1334 pChr = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);
1336 *pLine = '\0';
1338 /* setting MaxLen to -1 indicates terminating read loop */
1339 MaxLen = -1;
1342 pFile->m_pReadPtr = pChr;
1344 while (MaxLen > 0);
1346 return (sal_True);
1350 static sal_Bool putLine(osl_TFile* pFile, const sal_Char *pszLine)
1352 unsigned int Len = strlen(pszLine);
1354 if ( pFile == 0 || pFile->m_Handle == INVALID_HANDLE_VALUE )
1356 return (sal_False);
1359 if ( pFile->m_pWriteBuf == 0 )
1361 pFile->m_pWriteBuf = (sal_Char*) malloc(Len+3);
1362 pFile->m_nWriteBufLen = Len+3;
1363 pFile->m_nWriteBufFree = Len+3;
1365 else
1367 if ( pFile->m_nWriteBufFree <= Len + 3 )
1369 sal_Char* pTmp;
1371 pTmp=(sal_Char*) realloc(pFile->m_pWriteBuf,( ( pFile->m_nWriteBufLen + Len ) * 2) );
1372 if ( pTmp == 0 )
1374 return sal_False;
1376 pFile->m_pWriteBuf = pTmp;
1377 pFile->m_nWriteBufFree = pFile->m_nWriteBufFree + pFile->m_nWriteBufLen + ( 2 * Len );
1378 pFile->m_nWriteBufLen = ( pFile->m_nWriteBufLen + Len ) * 2;
1379 memset( (pFile->m_pWriteBuf) + ( pFile->m_nWriteBufLen - pFile->m_nWriteBufFree ), 0, pFile->m_nWriteBufFree);
1385 memcpy(pFile->m_pWriteBuf + ( pFile->m_nWriteBufLen - pFile->m_nWriteBufFree ),pszLine,Len+1);
1387 pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len]='\r';
1388 pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len + 1]='\n';
1389 pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len + 2]='\0';
1391 pFile->m_nWriteBufFree-=Len+2;
1393 return (sal_True);
1396 /* platform specific end */
1398 static const sal_Char* stripBlanks(const sal_Char* String, sal_uInt32* pLen)
1400 if ( (pLen != NULL) && ( *pLen != 0 ) )
1402 while ((String[*pLen - 1] == ' ') || (String[*pLen - 1] == '\t'))
1403 (*pLen)--;
1405 while ((*String == ' ') || (*String == '\t'))
1407 String++;
1408 (*pLen)--;
1411 else
1412 while ((*String == ' ') || (*String == '\t'))
1413 String++;
1415 return (String);
1418 static const sal_Char* addLine(osl_TProfileImpl* pProfile, const sal_Char* Line)
1420 if (pProfile->m_NoLines >= pProfile->m_MaxLines)
1422 if (pProfile->m_Lines == NULL)
1424 pProfile->m_MaxLines = LINES_INI;
1425 pProfile->m_Lines = (sal_Char **)malloc(pProfile->m_MaxLines * sizeof(sal_Char *));
1426 memset(pProfile->m_Lines,0,pProfile->m_MaxLines * sizeof(sal_Char *));
1428 else
1430 unsigned int index=0;
1431 unsigned int oldmax=pProfile->m_MaxLines;
1433 pProfile->m_MaxLines += LINES_ADD;
1434 pProfile->m_Lines = (sal_Char **)realloc(pProfile->m_Lines, pProfile->m_MaxLines * sizeof(sal_Char *));
1436 for ( index = oldmax ; index < pProfile->m_MaxLines ; ++index )
1438 pProfile->m_Lines[index]=0;
1442 if (pProfile->m_Lines == NULL)
1444 pProfile->m_NoLines = 0;
1445 pProfile->m_MaxLines = 0;
1446 return (NULL);
1451 if ( pProfile->m_Lines != 0 && pProfile->m_Lines[pProfile->m_NoLines] != 0 )
1453 free(pProfile->m_Lines[pProfile->m_NoLines]);
1455 pProfile->m_Lines[pProfile->m_NoLines++] = strdup(Line);
1457 return (pProfile->m_Lines[pProfile->m_NoLines - 1]);
1460 static const sal_Char* insertLine(osl_TProfileImpl* pProfile, const sal_Char* Line, sal_uInt32 LineNo)
1462 if (pProfile->m_NoLines >= pProfile->m_MaxLines)
1464 if (pProfile->m_Lines == NULL)
1466 pProfile->m_MaxLines = LINES_INI;
1467 pProfile->m_Lines = (sal_Char **)malloc(pProfile->m_MaxLines * sizeof(sal_Char *));
1468 memset(pProfile->m_Lines,0,pProfile->m_MaxLines * sizeof(sal_Char *));
1470 else
1472 pProfile->m_MaxLines += LINES_ADD;
1473 pProfile->m_Lines = (sal_Char **)realloc(pProfile->m_Lines,
1474 pProfile->m_MaxLines * sizeof(sal_Char *));
1476 memset(&pProfile->m_Lines[pProfile->m_NoLines],
1478 (pProfile->m_MaxLines - pProfile->m_NoLines - 1) * sizeof(sal_Char*));
1481 if (pProfile->m_Lines == NULL)
1483 pProfile->m_NoLines = 0;
1484 pProfile->m_MaxLines = 0;
1485 return (NULL);
1489 LineNo = LineNo > pProfile->m_NoLines ? pProfile->m_NoLines : LineNo;
1491 if (LineNo < pProfile->m_NoLines)
1493 sal_uInt32 i, n;
1494 osl_TProfileSection* pSec;
1496 memmove(&pProfile->m_Lines[LineNo + 1], &pProfile->m_Lines[LineNo],
1497 (pProfile->m_NoLines - LineNo) * sizeof(sal_Char *));
1500 /* adjust line references */
1501 for (i = 0; i < pProfile->m_NoSections; i++)
1503 pSec = &pProfile->m_Sections[i];
1505 if (pSec->m_Line >= LineNo)
1506 pSec->m_Line++;
1508 for (n = 0; n < pSec->m_NoEntries; n++)
1509 if (pSec->m_Entries[n].m_Line >= LineNo)
1510 pSec->m_Entries[n].m_Line++;
1514 pProfile->m_NoLines++;
1516 pProfile->m_Lines[LineNo] = strdup(Line);
1518 return (pProfile->m_Lines[LineNo]);
1521 static void removeLine(osl_TProfileImpl* pProfile, sal_uInt32 LineNo)
1523 if (LineNo < pProfile->m_NoLines)
1525 free(pProfile->m_Lines[LineNo]);
1526 pProfile->m_Lines[LineNo]=0;
1527 if (pProfile->m_NoLines - LineNo > 1)
1529 sal_uInt32 i, n;
1530 osl_TProfileSection* pSec;
1532 memmove(&pProfile->m_Lines[LineNo], &pProfile->m_Lines[LineNo + 1],
1533 (pProfile->m_NoLines - LineNo - 1) * sizeof(sal_Char *));
1535 memset(&pProfile->m_Lines[pProfile->m_NoLines - 1],
1537 (pProfile->m_MaxLines - pProfile->m_NoLines) * sizeof(sal_Char*));
1539 /* adjust line references */
1540 for (i = 0; i < pProfile->m_NoSections; i++)
1542 pSec = &pProfile->m_Sections[i];
1544 if (pSec->m_Line > LineNo)
1545 pSec->m_Line--;
1547 for (n = 0; n < pSec->m_NoEntries; n++)
1548 if (pSec->m_Entries[n].m_Line > LineNo)
1549 pSec->m_Entries[n].m_Line--;
1552 else
1554 pProfile->m_Lines[LineNo] = 0;
1557 pProfile->m_NoLines--;
1560 return;
1563 static void setEntry(osl_TProfileImpl* pProfile, osl_TProfileSection* pSection,
1564 sal_uInt32 NoEntry, sal_uInt32 Line,
1565 const sal_Char* Entry, sal_uInt32 Len)
1567 Entry = stripBlanks(Entry, &Len);
1568 pSection->m_Entries[NoEntry].m_Line = Line;
1569 pSection->m_Entries[NoEntry].m_Offset = Entry - pProfile->m_Lines[Line];
1570 pSection->m_Entries[NoEntry].m_Len = Len;
1572 return;
1575 static sal_Bool addEntry(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection,
1576 int Line, const sal_Char* Entry, sal_uInt32 Len)
1578 if (pSection != NULL)
1580 if (pSection->m_NoEntries >= pSection->m_MaxEntries)
1582 if (pSection->m_Entries == NULL)
1584 pSection->m_MaxEntries = ENTRIES_INI;
1585 pSection->m_Entries = (osl_TProfileEntry *)malloc(
1586 pSection->m_MaxEntries * sizeof(osl_TProfileEntry));
1588 else
1590 pSection->m_MaxEntries += ENTRIES_ADD;
1591 pSection->m_Entries = (osl_TProfileEntry *)realloc(pSection->m_Entries,
1592 pSection->m_MaxEntries * sizeof(osl_TProfileEntry));
1595 if (pSection->m_Entries == NULL)
1597 pSection->m_NoEntries = 0;
1598 pSection->m_MaxEntries = 0;
1599 return (sal_False);
1603 pSection->m_NoEntries++;
1605 Entry = stripBlanks(Entry, &Len);
1606 setEntry(pProfile, pSection, pSection->m_NoEntries - 1, Line,
1607 Entry, Len);
1609 return (sal_True);
1612 return (sal_False);
1615 static void removeEntry(osl_TProfileSection *pSection, sal_uInt32 NoEntry)
1617 if (NoEntry < pSection->m_NoEntries)
1619 if (pSection->m_NoEntries - NoEntry > 1)
1621 memmove(&pSection->m_Entries[NoEntry],
1622 &pSection->m_Entries[NoEntry + 1],
1623 (pSection->m_NoEntries - NoEntry - 1) * sizeof(osl_TProfileEntry));
1624 pSection->m_Entries[pSection->m_NoEntries - 1].m_Line=0;
1625 pSection->m_Entries[pSection->m_NoEntries - 1].m_Offset=0;
1626 pSection->m_Entries[pSection->m_NoEntries - 1].m_Len=0;
1629 pSection->m_NoEntries--;
1632 return;
1635 static sal_Bool addSection(osl_TProfileImpl* pProfile, int Line, const sal_Char* Section, sal_uInt32 Len)
1637 if (pProfile->m_NoSections >= pProfile->m_MaxSections)
1639 if (pProfile->m_Sections == NULL)
1641 pProfile->m_MaxSections = SECTIONS_INI;
1642 pProfile->m_Sections = (osl_TProfileSection *)malloc(pProfile->m_MaxSections * sizeof(osl_TProfileSection));
1643 memset(pProfile->m_Sections,0,pProfile->m_MaxSections * sizeof(osl_TProfileSection));
1645 else
1647 unsigned int index=0;
1648 unsigned int oldmax=pProfile->m_MaxSections;
1650 pProfile->m_MaxSections += SECTIONS_ADD;
1651 pProfile->m_Sections = (osl_TProfileSection *)realloc(pProfile->m_Sections,
1652 pProfile->m_MaxSections * sizeof(osl_TProfileSection));
1653 for ( index = oldmax ; index < pProfile->m_MaxSections ; ++index )
1655 pProfile->m_Sections[index].m_Entries=0;
1659 if (pProfile->m_Sections == NULL)
1661 pProfile->m_NoSections = 0;
1662 pProfile->m_MaxSections = 0;
1663 return (sal_False);
1667 pProfile->m_NoSections++;
1669 if ( pProfile->m_Sections[(pProfile->m_NoSections) - 1].m_Entries != 0 )
1671 free(pProfile->m_Sections[(pProfile->m_NoSections) - 1].m_Entries);
1673 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Entries = NULL;
1674 pProfile->m_Sections[pProfile->m_NoSections - 1].m_NoEntries = 0;
1675 pProfile->m_Sections[pProfile->m_NoSections - 1].m_MaxEntries = 0;
1677 Section = (sal_Char *)stripBlanks(Section, &Len);
1678 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Line = Line;
1679 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Offset = Section - pProfile->m_Lines[Line];
1680 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Len = Len;
1682 return (sal_True);
1685 static void removeSection(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection)
1687 sal_uInt32 Section;
1689 if ((Section = pSection - pProfile->m_Sections) < pProfile->m_NoSections)
1691 free (pSection->m_Entries);
1692 pSection->m_Entries=0;
1693 if (pProfile->m_NoSections - Section > 1)
1695 memmove(&pProfile->m_Sections[Section], &pProfile->m_Sections[Section + 1],
1696 (pProfile->m_NoSections - Section - 1) * sizeof(osl_TProfileSection));
1698 memset(&pProfile->m_Sections[pProfile->m_NoSections - 1],
1700 (pProfile->m_MaxSections - pProfile->m_NoSections) * sizeof(osl_TProfileSection));
1701 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Entries = 0;
1703 else
1705 pSection->m_Entries = 0;
1708 pProfile->m_NoSections--;
1711 return;
1714 static osl_TProfileSection* findEntry(osl_TProfileImpl* pProfile, const sal_Char* Section,
1715 const sal_Char* Entry, sal_uInt32 *pNoEntry)
1717 static sal_uInt32 Sect = 0;
1718 sal_uInt32 i, n;
1719 sal_uInt32 Len;
1720 const sal_Char* pStr;
1721 osl_TProfileSection* pSec = NULL;
1723 Len = strlen(Section);
1724 Section = (sal_Char *)stripBlanks(Section, &Len);
1726 n = Sect;
1728 for (i = 0; i < pProfile->m_NoSections; i++)
1730 n %= pProfile->m_NoSections;
1731 pSec = &pProfile->m_Sections[n];
1732 if ((Len == pSec->m_Len) &&
1733 (strnicmp(Section, &pProfile->m_Lines[pSec->m_Line][pSec->m_Offset], pSec->m_Len)
1734 == 0))
1735 break;
1736 n++;
1739 Sect = n;
1741 if (i < pProfile->m_NoSections)
1743 Len = strlen(Entry);
1744 Entry = stripBlanks(Entry, &Len);
1746 *pNoEntry = pSec->m_NoEntries;
1748 for (i = 0; i < pSec->m_NoEntries; i++)
1750 pStr = &pProfile->m_Lines[pSec->m_Entries[i].m_Line]
1751 [pSec->m_Entries[i].m_Offset];
1752 if ((Len == pSec->m_Entries[i].m_Len) &&
1753 (strnicmp(Entry, pStr, pSec->m_Entries[i].m_Len)
1754 == 0))
1756 *pNoEntry = i;
1757 break;
1761 else
1762 pSec = NULL;
1764 return (pSec);
1767 static sal_Bool loadProfile(osl_TFile* pFile, osl_TProfileImpl* pProfile)
1769 sal_uInt32 i;
1770 sal_Char* pStr;
1771 sal_Char* pChar;
1772 sal_Char Line[4096];
1774 pProfile->m_NoLines = 0;
1775 pProfile->m_NoSections = 0;
1777 OSL_VERIFY(rewindFile(pFile, sal_False));
1779 while (getLine(pFile, Line, sizeof(Line)))
1781 if (! addLine(pProfile, Line))
1782 return (sal_False);
1785 for (i = 0; i < pProfile->m_NoLines; i++)
1787 pStr = (sal_Char *)stripBlanks(pProfile->m_Lines[i], NULL);
1789 if ((*pStr == '\0') || (*pStr == ';'))
1790 continue;
1792 if ((*pStr != '[') || ((pChar = strrchr(pStr, ']')) == NULL) ||
1793 ((pChar - pStr) <= 2))
1795 /* insert entry */
1797 if (pProfile->m_NoSections < 1)
1798 continue;
1800 if ((pChar = strchr(pStr, '=')) == NULL)
1801 pChar = pStr + strlen(pStr);
1803 if (! addEntry(pProfile, &pProfile->m_Sections[pProfile->m_NoSections - 1],
1804 i, pStr, pChar - pStr))
1805 return (sal_False);
1807 else
1809 /* new section */
1810 if (! addSection(pProfile, i, pStr + 1, pChar - pStr - 1))
1811 return (sal_False);
1815 return (sal_True);
1819 static sal_Bool storeProfile(osl_TProfileImpl* pProfile, sal_Bool bCleanup)
1821 #ifdef TRACE_OSL_PROFILE
1822 OSL_TRACE("In storeProfile");
1823 #endif
1825 if (pProfile->m_Lines != NULL)
1827 if (pProfile->m_Flags & FLG_MODIFIED)
1829 sal_uInt32 i;
1831 osl_TFile* pTmpFile = osl_openTmpProfileImpl(pProfile);
1833 if ( pTmpFile == 0 )
1835 return sal_False;
1838 OSL_VERIFY(rewindFile(pTmpFile, sal_True));
1840 for (i = 0; i < pProfile->m_NoLines; i++)
1842 OSL_VERIFY(putLine(pTmpFile, pProfile->m_Lines[i]));
1845 if ( ! writeProfileImpl(pTmpFile) )
1847 if ( pTmpFile->m_pWriteBuf != 0 )
1849 free(pTmpFile->m_pWriteBuf);
1852 pTmpFile->m_pWriteBuf=0;
1853 pTmpFile->m_nWriteBufLen=0;
1854 pTmpFile->m_nWriteBufFree=0;
1856 #ifdef TRACE_OSL_PROFILE
1857 OSL_TRACE("Out storeProfile [not flushed]");
1858 #endif
1859 closeFileImpl(pTmpFile);
1861 return sal_False;
1864 pProfile->m_Flags &= ~FLG_MODIFIED;
1866 closeFileImpl(pProfile->m_pFile);
1867 closeFileImpl(pTmpFile);
1869 osl_ProfileSwapProfileNames(pProfile);
1871 pProfile->m_pFile = openFileImpl(pProfile->m_strFileName,pProfile->m_Flags);
1875 if (bCleanup)
1877 while (pProfile->m_NoLines > 0)
1878 removeLine(pProfile, pProfile->m_NoLines - 1);
1880 free(pProfile->m_Lines);
1881 pProfile->m_Lines = NULL;
1882 pProfile->m_MaxLines = 0;
1884 while (pProfile->m_NoSections > 0)
1885 removeSection(pProfile, &pProfile->m_Sections[pProfile->m_NoSections - 1]);
1887 free(pProfile->m_Sections);
1888 pProfile->m_Sections = NULL;
1889 pProfile->m_MaxSections = 0;
1893 #ifdef TRACE_OSL_PROFILE
1894 OSL_TRACE("Out storeProfile [ok]");
1895 #endif
1896 return (sal_True);
1900 static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl* pProfile)
1902 osl_TFile* pFile=0;
1903 rtl_uString* ustrExtension=0;
1904 rtl_uString* ustrTmpName=0;
1905 oslProfileOption PFlags=0;
1907 rtl_uString_newFromAscii(&ustrExtension,"tmp");
1910 /* generate tmp profilename */
1911 ustrTmpName=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
1912 rtl_uString_release(ustrExtension);
1914 if ( ustrTmpName == 0 )
1916 return 0;
1920 if ( ! ( pProfile->m_Flags & osl_Profile_READLOCK ) )
1922 PFlags |= osl_Profile_WRITELOCK;
1925 /* open this file */
1926 pFile = openFileImpl(ustrTmpName,pProfile->m_Flags | PFlags);
1929 /* return new pFile */
1930 return pFile;
1934 static sal_Bool osl_ProfileSwapProfileNames(osl_TProfileImpl* pProfile)
1936 sal_Bool bRet = sal_False;
1938 rtl_uString* ustrBakFile=0;
1939 rtl_uString* ustrTmpFile=0;
1940 rtl_uString* ustrIniFile=0;
1941 rtl_uString* ustrExtension=0;
1944 rtl_uString_newFromAscii(&ustrExtension,"bak");
1946 ustrBakFile=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
1947 rtl_uString_release(ustrExtension);
1948 ustrExtension=0;
1951 rtl_uString_newFromAscii(&ustrExtension,"ini");
1953 ustrIniFile=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
1954 rtl_uString_release(ustrExtension);
1955 ustrExtension=0;
1958 rtl_uString_newFromAscii(&ustrExtension,"tmp");
1960 ustrTmpFile=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
1961 rtl_uString_release(ustrExtension);
1962 ustrExtension=0;
1965 /* unlink bak */
1966 DeleteFileW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrBakFile )) );
1968 /* rename ini bak */
1969 MoveFileExW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrIniFile )), reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrBakFile )), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH );
1971 /* rename tmp ini */
1972 MoveFileExW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrTmpFile )), reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrIniFile )), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH );
1974 return bRet;
1978 static rtl_uString* osl_ProfileGenerateExtension(rtl_uString* ustrFileName, rtl_uString* ustrExtension)
1980 rtl_uString* ustrNewFileName=0;
1981 rtl_uString* ustrOldExtension = 0;
1982 sal_Unicode* pExtensionBuf = 0;
1983 sal_Unicode* pFileNameBuf = 0;
1984 sal_Int32 nIndex = -1;
1986 pFileNameBuf = rtl_uString_getStr(ustrFileName);
1988 rtl_uString_newFromAscii(&ustrOldExtension,".");
1990 pExtensionBuf = rtl_uString_getStr(ustrOldExtension);
1992 nIndex = rtl_ustr_lastIndexOfChar(pFileNameBuf,*pExtensionBuf);
1994 rtl_uString_newReplaceStrAt(&ustrNewFileName,
1995 ustrFileName,
1996 nIndex+1,
1998 ustrExtension);
2000 return ustrNewFileName;
2004 static osl_TProfileImpl* acquireProfile(oslProfile Profile, sal_Bool bWriteable)
2006 osl_TProfileImpl* pProfile = (osl_TProfileImpl*)Profile;
2007 oslProfileOption PFlags=0;
2010 if ( bWriteable )
2012 PFlags = osl_Profile_DEFAULT | osl_Profile_WRITELOCK;
2014 else
2016 PFlags = osl_Profile_DEFAULT;
2020 if (pProfile == NULL)
2022 #ifdef DEBUG_OSL_PROFILE
2023 OSL_TRACE("AUTOOPEN MODE");
2024 #endif
2026 if ( ( pProfile = (osl_TProfileImpl*)osl_openProfile( NULL, PFlags ) ) != NULL )
2028 pProfile->m_Flags |= FLG_AUTOOPEN;
2031 else
2033 #ifdef DEBUG_OSL_PROFILE
2034 OSL_TRACE("try to acquire");
2035 #endif
2039 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
2041 if (! (pProfile->m_Flags & (osl_Profile_READLOCK |
2042 osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE)))
2044 osl_TStamp Stamp;
2045 #ifdef DEBUG_OSL_PROFILE
2046 OSL_TRACE("DEFAULT MODE");
2047 #endif
2048 pProfile->m_pFile = openFileImpl(
2049 pProfile->m_strFileName, pProfile->m_Flags | PFlags);
2050 if (!pProfile->m_pFile)
2051 return NULL;
2053 Stamp = getFileStamp(pProfile->m_pFile);
2055 if (memcmp(&Stamp, &(pProfile->m_Stamp), sizeof(osl_TStamp)))
2057 pProfile->m_Stamp = Stamp;
2059 loadProfile(pProfile->m_pFile, pProfile);
2062 else
2064 #ifdef DEBUG_OSL_PROFILE
2065 OSL_TRACE("READ/WRITELOCK MODE");
2066 #endif
2069 /* A readlock file could not be written */
2070 if ((pProfile->m_Flags & osl_Profile_READLOCK) && bWriteable)
2072 return (NULL);
2078 return (pProfile);
2081 static sal_Bool releaseProfile(osl_TProfileImpl* pProfile)
2083 #ifdef TRACE_OSL_PROFILE
2084 OSL_TRACE("In releaseProfile");
2085 #endif
2087 if ( pProfile == 0 )
2089 #ifdef TRACE_OSL_PROFILE
2090 OSL_TRACE("Out releaseProfile [profile==0]");
2091 #endif
2092 return sal_False;
2095 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
2097 if (pProfile->m_Flags & FLG_AUTOOPEN)
2099 #ifdef TRACE_OSL_PROFILE
2100 OSL_TRACE("Out releaseProfile [AUTOOPEN]");
2101 #endif
2102 return (osl_closeProfile((oslProfile)pProfile));
2104 else
2106 #ifdef DEBUG_OSL_PROFILE
2107 OSL_TRACE("DEFAULT MODE");
2108 #endif
2109 if (! (pProfile->m_Flags & (osl_Profile_READLOCK |
2110 osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE)))
2112 if (pProfile->m_Flags & FLG_MODIFIED)
2113 storeProfile(pProfile, sal_False);
2115 closeFileImpl(pProfile->m_pFile);
2116 pProfile->m_pFile = NULL;
2121 #ifdef TRACE_OSL_PROFILE
2122 OSL_TRACE("Out releaseProfile [ok]");
2123 #endif
2124 return (sal_True);
2127 static sal_Bool lookupProfile(const sal_Unicode *strPath, const sal_Unicode *strFile, sal_Unicode *strProfile)
2129 sal_Char *pChr, *pStr;
2130 sal_Char Buffer[4096] = "";
2131 sal_Char Product[132] = "";
2133 ::osl::LongPathBuffer< sal_Unicode > aPath( MAX_LONG_PATH );
2134 aPath[0] = 0;
2135 DWORD dwPathLen = 0;
2137 if (*strPath == L'"')
2139 int i = 0;
2141 strPath++;
2143 while ((strPath[i] != L'"') && (strPath[i] != L'\0'))
2144 i++;
2146 WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(strPath), i, Product, sizeof(Product), NULL, NULL);
2147 Product[i] = '\0';
2148 strPath += i;
2150 if (*strPath == L'"')
2151 strPath++;
2153 if ( (*strPath == L'/') || (*strPath == L'\\') )
2155 strPath++;
2159 else
2161 /* if we have not product identfication, do a special handling for soffice.ini */
2162 if (rtl_ustr_ascii_compare(strFile, SVERSION_PROFILE) == 0)
2164 rtl_uString * strSVProfile = NULL;
2165 rtl_uString * strSVFallback = NULL;
2166 rtl_uString * strSVLocation = NULL;
2167 rtl_uString * strSVName = NULL;
2168 ::osl::LongPathBuffer< sal_Char > aDir( MAX_LONG_PATH );
2169 oslProfile hProfile;
2171 rtl_uString_newFromAscii(&strSVFallback, SVERSION_FALLBACK);
2172 rtl_uString_newFromAscii(&strSVLocation, SVERSION_LOCATION);
2173 rtl_uString_newFromAscii(&strSVName, SVERSION_NAME);
2175 /* open sversion.ini in the system directory, and try to locate the entry
2176 with the highest version for StarOffice */
2177 if (osl_getProfileName( strSVFallback, strSVName, &strSVProfile))
2179 hProfile = osl_openProfile(strSVProfile, osl_Profile_READLOCK);
2180 if (hProfile)
2182 osl_getProfileSectionEntries(
2183 hProfile, SVERSION_SECTION, Buffer, sizeof(Buffer));
2185 for (pChr = Buffer; *pChr != '\0'; pChr += strlen(pChr) + 1)
2187 if ((strnicmp(
2188 pChr, SVERSION_SOFFICE,
2189 sizeof(SVERSION_SOFFICE) - 1)
2190 == 0)
2191 && (stricmp(Product, pChr) < 0))
2193 osl_readProfileString(
2194 hProfile, SVERSION_SECTION, pChr, aDir,
2195 aDir.getBufSizeInSymbols(), "");
2197 /* check for existence of path */
2198 if (access(aDir, 0) >= 0)
2199 strcpy(Product, pChr);
2203 osl_closeProfile(hProfile);
2205 rtl_uString_release(strSVProfile);
2206 strSVProfile = NULL;
2209 /* open sversion.ini in the users directory, and try to locate the entry
2210 with the highest version for StarOffice */
2211 if ((strcmp(SVERSION_LOCATION, SVERSION_FALLBACK) != 0) &&
2212 (osl_getProfileName(strSVLocation, strSVName, &strSVProfile)))
2214 hProfile = osl_openProfile(strSVProfile, osl_Profile_READLOCK);
2215 if (hProfile)
2217 osl_getProfileSectionEntries(
2218 hProfile, SVERSION_SECTION, Buffer, sizeof(Buffer));
2220 for (pChr = Buffer; *pChr != '\0'; pChr += strlen(pChr) + 1)
2222 if ((strnicmp(
2223 pChr, SVERSION_SOFFICE,
2224 sizeof(SVERSION_SOFFICE) - 1)
2225 == 0)
2226 && (stricmp(Product, pChr) < 0))
2228 osl_readProfileString(
2229 hProfile, SVERSION_SECTION, pChr, aDir,
2230 aDir.getBufSizeInSymbols(), "");
2232 /* check for existence of path */
2233 if (access(aDir, 0) >= 0)
2234 strcpy(Product, pChr);
2238 osl_closeProfile(hProfile);
2240 rtl_uString_release(strSVProfile);
2243 rtl_uString_release(strSVFallback);
2244 rtl_uString_release(strSVLocation);
2245 rtl_uString_release(strSVName);
2247 /* remove any trailing build number */
2248 if ((pChr = strrchr(Product, '/')) != NULL)
2249 *pChr = '\0';
2253 /* if we have an userid option eg. "-userid:rh[/usr/home/rh/staroffice]",
2254 this will supercede all other locations */
2256 sal_uInt32 n, nArgs = osl_getCommandArgCount();
2258 for (n = 0; n < nArgs; n++)
2260 rtl_uString * strCommandArg = NULL;
2262 if ((osl_getCommandArg( n, &strCommandArg ) == osl_Process_E_None) &&
2263 ((strCommandArg->buffer[0] == L'-') || (strCommandArg->buffer[0] == L'+')) &&
2264 (rtl_ustr_ascii_compare_WithLength(strCommandArg->buffer, RTL_CONSTASCII_LENGTH(SVERSION_OPTION), SVERSION_OPTION)))
2266 sal_Unicode *pCommandArg = strCommandArg->buffer + RTL_CONSTASCII_LENGTH(SVERSION_OPTION);
2267 sal_Int32 nStart, nEnd;
2269 if (((nStart = rtl_ustr_indexOfChar(pCommandArg, L'[')) != -1) &&
2270 ((nEnd = rtl_ustr_indexOfChar(pCommandArg + nStart + 1, L']')) != -1))
2272 dwPathLen = nEnd;
2273 copy_ustr_n(aPath, pCommandArg + nStart + 1, dwPathLen);
2274 aPath[dwPathLen] = 0;
2276 /* build full path */
2277 if ((aPath[dwPathLen - 1] != L'/') && (aPath[dwPathLen - 1] != L'\\'))
2279 copy_ustr_n(aPath + dwPathLen++, L"/", 2);
2282 if (*strPath)
2284 copy_ustr_n(aPath + dwPathLen, strPath, rtl_ustr_getLength(strPath)+1);
2285 dwPathLen += rtl_ustr_getLength(strPath);
2287 else
2289 ::osl::LongPathBuffer< sal_Char > aTmpPath( MAX_LONG_PATH );
2290 int nLen = 0;
2292 if ((nLen = WideCharToMultiByte(CP_ACP,0, ::osl::mingw_reinterpret_cast<LPCWSTR>(aPath), -1, aTmpPath, aTmpPath.getBufSizeInSymbols(), NULL, NULL)) > 0)
2294 strcpy(aTmpPath + nLen, SVERSION_USER);
2295 if (access(aTmpPath, 0) >= 0)
2297 dwPathLen += MultiByteToWideChar( CP_ACP, 0, SVERSION_USER, -1, reinterpret_cast<LPWSTR>(aPath + dwPathLen), aPath.getBufSizeInSymbols() - dwPathLen );
2302 break;
2309 if (dwPathLen == 0)
2311 rtl_uString * strExecutable = NULL;
2312 rtl_uString * strTmp = NULL;
2313 sal_Int32 nPos;
2315 /* try to find the file in the directory of the executbale */
2316 if (osl_getExecutableFile(&strTmp) != osl_Process_E_None)
2317 return (sal_False);
2319 /* convert to native path */
2320 if (osl_getSystemPathFromFileURL(strTmp, &strExecutable) != osl_File_E_None)
2322 rtl_uString_release(strTmp);
2323 return sal_False;
2326 rtl_uString_release(strTmp);
2328 /* separate path from filename */
2329 if ((nPos = rtl_ustr_lastIndexOfChar(strExecutable->buffer, L'\\')) == -1)
2331 if ((nPos = rtl_ustr_lastIndexOfChar(strExecutable->buffer, L':')) == -1)
2333 return sal_False;
2335 else
2337 copy_ustr_n(aPath, strExecutable->buffer, nPos);
2338 aPath[nPos] = 0;
2339 dwPathLen = nPos;
2342 else
2344 copy_ustr_n(aPath, strExecutable->buffer, nPos);
2345 dwPathLen = nPos;
2346 aPath[dwPathLen] = 0;
2349 /* if we have no product identification use the executable file name */
2350 if (*Product == 0)
2352 WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(strExecutable->buffer + nPos + 1), -1, Product, sizeof(Product), NULL, NULL);
2354 /* remove extension */
2355 if ((pChr = strrchr(Product, '.')) != NULL)
2356 *pChr = '\0';
2359 rtl_uString_release(strExecutable);
2361 /* remember last subdir */
2362 nPos = rtl_ustr_lastIndexOfChar(aPath, L'\\');
2364 copy_ustr_n(aPath + dwPathLen++, L"\\", 2);
2366 if (*strPath)
2368 copy_ustr_n(aPath + dwPathLen, strPath, rtl_ustr_getLength(strPath)+1);
2369 dwPathLen += rtl_ustr_getLength(strPath);
2373 ::osl::LongPathBuffer< sal_Char > aTmpPath( MAX_LONG_PATH );
2375 WideCharToMultiByte(CP_ACP,0, ::osl::mingw_reinterpret_cast<LPCWSTR>(aPath), -1, aTmpPath, aTmpPath.getBufSizeInSymbols(), NULL, NULL);
2377 /* if file not exists, remove any specified subdirectories
2378 like "bin" or "program" */
2380 if (((access(aTmpPath, 0) < 0) && (nPos != -1)) || (*strPath == 0))
2382 static const sal_Char *SubDirs[] = SVERSION_DIRS;
2384 unsigned i = 0;
2385 pStr = aTmpPath + nPos;
2387 for (i = 0; i < SAL_N_ELEMENTS(SubDirs); i++)
2388 if (strnicmp(pStr + 1, SubDirs[i], strlen(SubDirs[i])) == 0)
2390 if ( *strPath == 0)
2392 strcpy(pStr + 1,SVERSION_USER);
2393 if ( access(aTmpPath, 0) < 0 )
2395 *(pStr+1)='\0';
2397 else
2399 dwPathLen = nPos + MultiByteToWideChar( CP_ACP, 0, SVERSION_USER, -1, reinterpret_cast<LPWSTR>(aPath + nPos + 1), aPath.getBufSizeInSymbols() - (nPos + 1) );
2402 else
2404 copy_ustr_n(aPath + nPos + 1, strPath, rtl_ustr_getLength(strPath)+1);
2405 dwPathLen = nPos + 1 + rtl_ustr_getLength(strPath);
2408 break;
2413 if ((aPath[dwPathLen - 1] != L'/') && (aPath[dwPathLen - 1] != L'\\'))
2415 aPath[dwPathLen++] = L'\\';
2416 aPath[dwPathLen] = 0;
2419 copy_ustr_n(aPath + dwPathLen, strFile, rtl_ustr_getLength(strFile)+1);
2422 ::osl::LongPathBuffer< sal_Char > aTmpPath( MAX_LONG_PATH );
2424 WideCharToMultiByte(CP_ACP,0, ::osl::mingw_reinterpret_cast<LPCWSTR>(aPath), -1, aTmpPath, aTmpPath.getBufSizeInSymbols(), NULL, NULL);
2426 if ((access(aTmpPath, 0) < 0) && (strlen(Product) > 0))
2428 rtl_uString * strSVFallback = NULL;
2429 rtl_uString * strSVProfile = NULL;
2430 rtl_uString * strSVLocation = NULL;
2431 rtl_uString * strSVName = NULL;
2432 oslProfile hProfile;
2434 rtl_uString_newFromAscii(&strSVFallback, SVERSION_FALLBACK);
2435 rtl_uString_newFromAscii(&strSVLocation, SVERSION_LOCATION);
2436 rtl_uString_newFromAscii(&strSVName, SVERSION_NAME);
2438 /* open sversion.ini in the system directory, and try to locate the entry
2439 with the highest version for StarOffice */
2440 if (osl_getProfileName(strSVLocation, strSVName, &strSVProfile))
2442 hProfile = osl_openProfile(
2443 strSVProfile, osl_Profile_READLOCK);
2444 if (hProfile)
2446 osl_readProfileString(
2447 hProfile, SVERSION_SECTION, Product, Buffer,
2448 sizeof(Buffer), "");
2449 osl_closeProfile(hProfile);
2451 /* if not found, try the fallback */
2452 if ((strlen(Buffer) <= 0)
2453 && (strcmp(SVERSION_LOCATION, SVERSION_FALLBACK)
2454 != 0))
2456 if (osl_getProfileName(
2457 strSVFallback, strSVName, &strSVProfile))
2459 hProfile = osl_openProfile(
2460 strSVProfile, osl_Profile_READLOCK);
2461 if (hProfile)
2463 osl_readProfileString(
2464 hProfile, SVERSION_SECTION, Product,
2465 Buffer, sizeof(Buffer), "");
2469 osl_closeProfile(hProfile);
2472 if (strlen(Buffer) > 0)
2474 dwPathLen = MultiByteToWideChar(
2475 CP_ACP, 0, Buffer, -1, ::osl::mingw_reinterpret_cast<LPWSTR>(aPath), aPath.getBufSizeInSymbols() );
2476 dwPathLen -=1;
2478 /* build full path */
2479 if ((aPath[dwPathLen - 1] != L'/')
2480 && (aPath[dwPathLen - 1] != L'\\'))
2482 copy_ustr_n(aPath + dwPathLen++, L"\\", 2);
2485 if (*strPath)
2487 copy_ustr_n(aPath + dwPathLen, strPath, rtl_ustr_getLength(strPath)+1);
2488 dwPathLen += rtl_ustr_getLength(strPath);
2490 else
2492 ::osl::LongPathBuffer< sal_Char > aTmpPath2( MAX_LONG_PATH );
2493 int n;
2495 if ((n = WideCharToMultiByte(
2496 CP_ACP,0, ::osl::mingw_reinterpret_cast<LPCWSTR>(aPath), -1, aTmpPath2,
2497 aTmpPath2.getBufSizeInSymbols(), NULL, NULL))
2498 > 0)
2500 strcpy(aTmpPath2 + n, SVERSION_USER);
2501 if (access(aTmpPath2, 0) >= 0)
2503 dwPathLen += MultiByteToWideChar(
2504 CP_ACP, 0, SVERSION_USER, -1,
2505 reinterpret_cast<LPWSTR>(aPath + dwPathLen),
2506 aPath.getBufSizeInSymbols() - dwPathLen );
2513 rtl_uString_release(strSVProfile);
2516 rtl_uString_release(strSVFallback);
2517 rtl_uString_release(strSVLocation);
2518 rtl_uString_release(strSVName);
2522 aPath[dwPathLen] = 0;
2525 /* copy filename */
2526 copy_ustr_n(strProfile, aPath, dwPathLen+1);
2528 return sal_True;
2532 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */