Bump version to 4.1-6
[LibreOffice.git] / sal / osl / w32 / profile.cxx
blobf588c837a0fefe869f27fcddbb1574028755dc78
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 <osl/util.h>
31 #include <rtl/alloc.h>
32 #include <sal/macros.h>
33 #include <algorithm>
34 using std::min;
35 static inline void copy_ustr_n( void *dest, const void *source, size_t length ) { memcpy(dest, source, length*sizeof(sal_Unicode)); }
37 #define LINES_INI 32
38 #define LINES_ADD 10
39 #define SECTIONS_INI 5
40 #define SECTIONS_ADD 3
41 #define ENTRIES_INI 5
42 #define ENTRIES_ADD 3
45 #define STR_INI_EXTENSION L".ini"
46 #define STR_INI_METAHOME "?~"
47 #define STR_INI_METASYS "?$"
48 #define STR_INI_METACFG "?^"
49 #define STR_INI_METAINS "?#"
51 #define STR_INI_BOOLYES "yes"
52 #define STR_INI_BOOLON "on"
53 #define STR_INI_BOOLONE "1"
54 #define STR_INI_BOOLNO "no"
55 #define STR_INI_BOOLOFF "off"
56 #define STR_INI_BOOLZERO "0"
58 #define FLG_USER 0x00FF
59 #define FLG_AUTOOPEN 0x0100
60 #define FLG_MODIFIED 0x0200
62 #define SVERSION_LOCATION STR_INI_METACFG
63 #define SVERSION_FALLBACK STR_INI_METASYS
64 #define SVERSION_NAME "sversion"
65 #define SVERSION_SECTION "Versions"
66 #define SVERSION_SOFFICE "StarOffice"
67 #define SVERSION_PROFILE "soffice.ini"
68 #define SVERSION_OPTION "userid:"
69 #define SVERSION_DIRS { "bin", "program" }
70 #define SVERSION_USER "user"
72 /*#define DEBUG_OSL_PROFILE 1*/
73 /*#define TRACE_OSL_PROFILE 1*/
76 /*****************************************************************************/
77 /* Data Type Definition */
78 /*****************************************************************************/
80 typedef FILETIME osl_TStamp;
82 typedef enum _osl_TLockMode
84 un_lock, read_lock, write_lock
85 } osl_TLockMode;
87 typedef struct _osl_TFile
89 HANDLE m_Handle;
90 sal_Char* m_pReadPtr;
91 sal_Char m_ReadBuf[512];
92 sal_Char* m_pWriteBuf;
93 sal_uInt32 m_nWriteBufLen;
94 sal_uInt32 m_nWriteBufFree;
95 } osl_TFile;
97 typedef struct _osl_TProfileEntry
99 sal_uInt32 m_Line;
100 sal_uInt32 m_Offset;
101 sal_uInt32 m_Len;
102 } osl_TProfileEntry;
104 typedef struct _osl_TProfileSection
106 sal_uInt32 m_Line;
107 sal_uInt32 m_Offset;
108 sal_uInt32 m_Len;
109 sal_uInt32 m_NoEntries;
110 sal_uInt32 m_MaxEntries;
111 osl_TProfileEntry* m_Entries;
112 } osl_TProfileSection;
116 Profile-data structure hidden behind oslProfile:
118 typedef struct _osl_TProfileImpl
120 sal_uInt32 m_Flags;
121 osl_TFile* m_pFile;
122 osl_TStamp m_Stamp;
123 sal_uInt32 m_NoLines;
124 sal_uInt32 m_MaxLines;
125 sal_uInt32 m_NoSections;
126 sal_uInt32 m_MaxSections;
127 sal_Char** m_Lines;
128 rtl_uString *m_strFileName;
129 osl_TProfileSection* m_Sections;
130 } osl_TProfileImpl;
133 /*****************************************************************************/
134 /* Static Module Function Declarations */
135 /*****************************************************************************/
137 static osl_TFile* openFileImpl(rtl_uString * strFileName, oslProfileOption ProfileFlags );
138 static osl_TStamp closeFileImpl(osl_TFile* pFile);
139 static sal_Bool lockFile(const osl_TFile* pFile, osl_TLockMode eMode);
140 static sal_Bool rewindFile(osl_TFile* pFile, sal_Bool bTruncate);
141 static osl_TStamp getFileStamp(osl_TFile* pFile);
143 static sal_Bool getLine(osl_TFile* pFile, const sal_Char *pszLine, int MaxLen);
144 static sal_Bool putLine(osl_TFile* pFile, const sal_Char *pszLine);
145 static const sal_Char* stripBlanks(const sal_Char* String, sal_uInt32* pLen);
146 static const sal_Char* addLine(osl_TProfileImpl* pProfile, const sal_Char* Line);
147 static const sal_Char* insertLine(osl_TProfileImpl* pProfile, const sal_Char* Line, sal_uInt32 LineNo);
148 static void removeLine(osl_TProfileImpl* pProfile, sal_uInt32 LineNo);
149 static void setEntry(osl_TProfileImpl* pProfile, osl_TProfileSection* pSection,
150 sal_uInt32 NoEntry, sal_uInt32 Line,
151 const sal_Char* Entry, sal_uInt32 Len);
152 static sal_Bool addEntry(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection,
153 int Line, const sal_Char* Entry, sal_uInt32 Len);
154 static void removeEntry(osl_TProfileSection *pSection, sal_uInt32 NoEntry);
155 static sal_Bool addSection(osl_TProfileImpl* pProfile, int Line, const sal_Char* Section, sal_uInt32 Len);
156 static void removeSection(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection);
157 static osl_TProfileSection* findEntry(osl_TProfileImpl* pProfile, const sal_Char* Section,
158 const sal_Char* Entry, sal_uInt32 *pNoEntry);
159 static sal_Bool loadProfile(osl_TFile* pFile, osl_TProfileImpl* pProfile);
160 static sal_Bool storeProfile(osl_TProfileImpl* pProfile, sal_Bool bCleanup);
161 static osl_TProfileImpl* acquireProfile(oslProfile Profile, sal_Bool bWriteable);
162 static sal_Bool releaseProfile(osl_TProfileImpl* pProfile);
163 static sal_Bool lookupProfile(const sal_Unicode *strPath, const sal_Unicode *strFile, sal_Unicode *strProfile);
165 static sal_Bool writeProfileImpl (osl_TFile* pFile);
166 static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl*);
167 static sal_Bool osl_ProfileSwapProfileNames(osl_TProfileImpl*);
168 static rtl_uString* osl_ProfileGenerateExtension(rtl_uString* ustrFileName, rtl_uString* ustrExtension);
170 static sal_Bool SAL_CALL osl_getProfileName(rtl_uString* strPath, rtl_uString* strName, rtl_uString** strProfileName);
172 /*****************************************************************************/
173 /* Exported Module Functions */
174 /*****************************************************************************/
176 oslProfile SAL_CALL osl_openProfile(rtl_uString *strProfileName, sal_uInt32 Flags)
178 osl_TFile* pFile = NULL;
179 osl_TProfileImpl* pProfile;
180 rtl_uString *FileName=NULL;
182 #ifdef TRACE_OSL_PROFILE
183 OSL_TRACE("In osl_openProfile");
184 #endif
185 OSL_VERIFY(strProfileName);
187 if (rtl_uString_getLength(strProfileName) == 0 )
189 OSL_VERIFY(osl_getProfileName(NULL, NULL, &FileName));
191 else
193 rtl_uString_assign(&FileName, strProfileName);
197 osl_getSystemPathFromFileURL(FileName, &FileName);
200 #ifdef DEBUG_OSL_PROFILE
201 Flags=osl_Profile_FLUSHWRITE;
203 if ( Flags == osl_Profile_DEFAULT )
205 OSL_TRACE("with osl_Profile_DEFAULT");
207 if ( Flags & osl_Profile_SYSTEM )
209 OSL_TRACE("with osl_Profile_SYSTEM");
211 if ( Flags & osl_Profile_READLOCK )
213 OSL_TRACE("with osl_Profile_READLOCK");
215 if ( Flags & osl_Profile_WRITELOCK )
217 OSL_TRACE("with osl_Profile_WRITELOCK");
219 if ( Flags & osl_Profile_FLUSHWRITE )
221 OSL_TRACE("with osl_Profile_FLUSHWRITE");
223 #endif
225 if ( (! (Flags & osl_Profile_SYSTEM)) && ( (pFile = openFileImpl(FileName, Flags) ) == NULL ) )
227 #ifdef TRACE_OSL_PROFILE
228 OSL_TRACE("Out osl_openProfile [not opened]");
229 #endif
230 if( FileName)
231 rtl_uString_release( FileName);
233 return (NULL);
237 pProfile = (osl_TProfileImpl*)calloc(1, sizeof(osl_TProfileImpl));
240 pProfile->m_Flags = Flags & FLG_USER;
241 osl_getSystemPathFromFileURL(strProfileName, &pProfile->m_strFileName);
243 if (Flags & (osl_Profile_READLOCK | osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE ))
244 pProfile->m_pFile = pFile;
246 pProfile->m_Stamp = getFileStamp(pFile);
248 loadProfile(pFile, pProfile);
250 if (pProfile->m_pFile == NULL)
251 closeFileImpl(pFile);
253 #ifdef TRACE_OSL_PROFILE
254 OSL_TRACE("Out osl_openProfile [ok]");
255 #endif
256 if( FileName)
257 rtl_uString_release( FileName);
259 return (pProfile);
262 sal_Bool SAL_CALL osl_closeProfile(oslProfile Profile)
264 osl_TProfileImpl* pProfile = (osl_TProfileImpl*)Profile;
266 #ifdef TRACE_OSL_PROFILE
267 OSL_TRACE("In osl_closeProfile");
268 #endif
270 if ( Profile == 0 )
272 #ifdef TRACE_OSL_PROFILE
273 OSL_TRACE("Out osl_closeProfile [profile==0]");
274 #endif
275 return sal_False;
278 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
280 pProfile = acquireProfile(Profile,sal_True);
282 if ( pProfile != 0 )
284 if ( !( pProfile->m_Flags & osl_Profile_READLOCK ) && ( pProfile->m_Flags & FLG_MODIFIED ) )
286 storeProfile(pProfile, sal_False);
289 else
291 pProfile = acquireProfile(Profile,sal_False);
294 if ( pProfile == 0 )
296 #ifdef TRACE_OSL_PROFILE
297 OSL_TRACE("Out osl_closeProfile [pProfile==0]");
298 #endif
299 return sal_False;
302 if (pProfile->m_pFile != NULL)
303 closeFileImpl(pProfile->m_pFile);
306 pProfile->m_pFile = NULL;
307 rtl_uString_release(pProfile->m_strFileName);
308 pProfile->m_strFileName = NULL;
310 /* release whole profile data types memory */
311 if ( pProfile->m_NoLines > 0)
313 unsigned int index=0;
314 if ( pProfile->m_Lines != 0 )
316 for ( index = 0 ; index < pProfile->m_NoLines ; ++index)
318 if ( pProfile->m_Lines[index] != 0 )
320 free(pProfile->m_Lines[index]);
323 free(pProfile->m_Lines);
325 if ( pProfile->m_Sections != 0 )
327 for ( index = 0 ; index < pProfile->m_NoSections ; ++index )
329 if ( pProfile->m_Sections[index].m_Entries != 0 )
330 free(pProfile->m_Sections[index].m_Entries);
332 free(pProfile->m_Sections);
336 free(pProfile);
338 #ifdef TRACE_OSL_PROFILE
339 OSL_TRACE("Out osl_closeProfile [ok]");
340 #endif
341 return (sal_True);
345 sal_Bool SAL_CALL osl_flushProfile(oslProfile Profile)
347 osl_TProfileImpl* pProfile = (osl_TProfileImpl*) Profile;
348 osl_TFile* pFile;
349 sal_Bool bRet = sal_False;
351 #ifdef TRACE_OSL_PROFILE
352 OSL_TRACE("In osl_flushProfile()");
353 #endif
355 if ( pProfile == 0 )
357 #ifdef TRACE_OSL_PROFILE
358 OSL_TRACE("Out osl_flushProfile() [pProfile == 0]");
359 #endif
360 return sal_False;
363 pFile = pProfile->m_pFile;
364 if ( pFile == 0 || pFile->m_Handle == INVALID_HANDLE_VALUE )
366 #ifdef TRACE_OSL_PROFILE
367 OSL_TRACE("Out osl_flushProfile() [invalid file]");
368 #endif
369 return sal_False;
372 if ( pProfile->m_Flags & FLG_MODIFIED )
374 #ifdef DEBUG_OSL_PROFILE
375 OSL_TRACE("swapping to storeprofile");
376 #endif
377 bRet = storeProfile(pProfile,sal_False);
380 #ifdef TRACE_OSL_PROFILE
381 OSL_TRACE("Out osl_flushProfile() [ok]");
382 #endif
383 return bRet;
386 static sal_Bool writeProfileImpl(osl_TFile* pFile)
388 DWORD BytesWritten=0;
389 BOOL bRet;
391 #ifdef TRACE_OSL_PROFILE
392 OSL_TRACE("In osl_writeProfileImpl()");
393 #endif
395 if ( !( pFile != 0 && pFile->m_Handle != INVALID_HANDLE_VALUE ) || ( pFile->m_pWriteBuf == 0 ) )
397 #ifdef TRACE_OSL_PROFILE
398 OSL_TRACE("Out osl_writeProfileImpl() [invalid args]");
399 #endif
400 return sal_False;
403 bRet=WriteFile(pFile->m_Handle, pFile->m_pWriteBuf, pFile->m_nWriteBufLen - pFile->m_nWriteBufFree,&BytesWritten,NULL);
405 if ( bRet == 0 || BytesWritten <= 0 )
407 OSL_ENSURE(bRet,"WriteFile failed!!!");
408 OSL_TRACE("write failed '%s'",strerror(errno));
410 return (sal_False);
413 free(pFile->m_pWriteBuf);
414 pFile->m_pWriteBuf=0;
415 pFile->m_nWriteBufLen=0;
416 pFile->m_nWriteBufFree=0;
418 #ifdef TRACE_OSL_PROFILE
419 OSL_TRACE("Out osl_writeProfileImpl() [ok]");
420 #endif
421 return sal_True;
425 sal_Bool SAL_CALL osl_readProfileString(oslProfile Profile,
426 const sal_Char* pszSection, const sal_Char* pszEntry,
427 sal_Char* pszString, sal_uInt32 MaxLen,
428 const sal_Char* pszDefault)
430 sal_uInt32 NoEntry;
431 const sal_Char* pStr = 0;
432 osl_TProfileSection* pSec;
433 osl_TProfileImpl* pProfile = 0;
436 #ifdef TRACE_OSL_PROFILE
437 OSL_TRACE("In osl_readProfileString");
438 #endif
440 pProfile = acquireProfile(Profile, sal_False);
442 if (pProfile == NULL)
444 #ifdef TRACE_OSL_PROFILE
445 OSL_TRACE("Out osl_readProfileString [pProfile==0]");
446 #endif
448 return (sal_False);
452 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
454 if (((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) != NULL) &&
455 (NoEntry < pSec->m_NoEntries) &&
456 ((pStr = strchr(pProfile->m_Lines[pSec->m_Entries[NoEntry].m_Line],
457 '=')) != NULL))
458 pStr++;
459 else
460 pStr = pszDefault;
462 if ( pStr != 0 )
464 pStr = stripBlanks(pStr, NULL);
465 MaxLen = (MaxLen - 1 < strlen(pStr)) ? (MaxLen - 1) : strlen(pStr);
466 pStr = stripBlanks(pStr, &MaxLen);
467 strncpy(pszString, pStr, MaxLen);
468 pszString[MaxLen] = '\0';
471 else
473 ::osl::LongPathBuffer< sal_Char > aFileName( MAX_LONG_PATH );
475 WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(pProfile->m_strFileName->buffer), -1, aFileName, aFileName.getBufSizeInSymbols(), NULL, NULL);
476 GetPrivateProfileString(pszSection, pszEntry, pszDefault, pszString, MaxLen, aFileName);
479 releaseProfile(pProfile);
481 if ( pStr == 0 )
483 #ifdef TRACE_OSL_PROFILE
484 OSL_TRACE("Out osl_readProfileString [pStr==0]");
485 #endif
487 return (sal_False);
490 #ifdef TRACE_OSL_PROFILE
491 OSL_TRACE("Out osl_readProfileString [ok]");
492 #endif
494 return (sal_True);
498 sal_Bool SAL_CALL osl_readProfileBool(oslProfile Profile,
499 const sal_Char* pszSection, const sal_Char* pszEntry,
500 sal_Bool Default)
502 sal_Char Line[32];
504 #ifdef TRACE_OSL_PROFILE
505 OSL_TRACE("In osl_readProfileBool");
506 #endif
508 if (osl_readProfileString(Profile, pszSection, pszEntry, Line, sizeof(Line), ""))
510 if ((stricmp(Line, STR_INI_BOOLYES) == 0) ||
511 (stricmp(Line, STR_INI_BOOLON) == 0) ||
512 (stricmp(Line, STR_INI_BOOLONE) == 0))
513 Default = sal_True;
514 else
515 if ((stricmp(Line, STR_INI_BOOLNO) == 0) ||
516 (stricmp(Line, STR_INI_BOOLOFF) == 0) ||
517 (stricmp(Line, STR_INI_BOOLZERO) == 0))
518 Default = sal_False;
521 #ifdef TRACE_OSL_PROFILE
522 OSL_TRACE("Out osl_readProfileBool [ok]");
523 #endif
525 return (Default);
529 sal_uInt32 SAL_CALL osl_readProfileIdent(oslProfile Profile,
530 const sal_Char* pszSection, const sal_Char* pszEntry,
531 sal_uInt32 FirstId, const sal_Char* Strings[],
532 sal_uInt32 Default)
534 sal_uInt32 i;
535 sal_Char Line[256];
537 #ifdef TRACE_OSL_PROFILE
538 OSL_TRACE("In osl_readProfileIdent");
539 #endif
541 if (osl_readProfileString(Profile, pszSection, pszEntry, Line, sizeof(Line), ""))
543 i = 0;
544 while (Strings[i] != NULL)
546 if (stricmp(Line, Strings[i]) == 0)
548 Default = i + FirstId;
549 break;
551 i++;
555 #ifdef TRACE_OSL_PROFILE
556 OSL_TRACE("Out osl_readProfileIdent [ok]");
557 #endif
558 return (Default);
561 sal_Bool SAL_CALL osl_writeProfileString(oslProfile Profile,
562 const sal_Char* pszSection, const sal_Char* pszEntry,
563 const sal_Char* pszString)
565 sal_uInt32 i;
566 sal_Bool bRet = sal_False;
567 sal_uInt32 NoEntry;
568 const sal_Char* pStr;
569 sal_Char Line[4096];
570 osl_TProfileSection* pSec;
571 osl_TProfileImpl* pProfile = 0;
573 #ifdef TRACE_OSL_PROFILE
574 OSL_TRACE("In osl_writeProfileString");
575 #endif
577 pProfile = acquireProfile(Profile, sal_True);
579 if (pProfile == NULL)
581 #ifdef TRACE_OSL_PROFILE
582 OSL_TRACE("Out osl_writeProfileString [pProfile==0]");
583 #endif
584 return (sal_False);
588 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
590 if ((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) == NULL)
592 Line[0] = '\0';
593 addLine(pProfile, Line);
595 Line[0] = '[';
596 strcpy(&Line[1], pszSection);
597 Line[1 + strlen(pszSection)] = ']';
598 Line[2 + strlen(pszSection)] = '\0';
600 if (((pStr = addLine(pProfile, Line)) == NULL) ||
601 (! addSection(pProfile, pProfile->m_NoLines - 1, &pStr[1], strlen(pszSection))))
603 releaseProfile(pProfile);
604 #ifdef TRACE_OSL_PROFILE
605 OSL_TRACE("Out osl_writeProfileString [not added]");
606 #endif
607 return (sal_False);
610 pSec = &pProfile->m_Sections[pProfile->m_NoSections - 1];
611 NoEntry = pSec->m_NoEntries;
614 Line[0] = '\0';
615 strcpy(&Line[0], pszEntry);
616 Line[0 + strlen(pszEntry)] = '=';
617 strcpy(&Line[1 + strlen(pszEntry)], pszString);
619 if (NoEntry >= pSec->m_NoEntries)
621 if (pSec->m_NoEntries > 0)
622 i = pSec->m_Entries[pSec->m_NoEntries - 1].m_Line + 1;
623 else
624 i = pSec->m_Line + 1;
626 if (((pStr = insertLine(pProfile, Line, i)) == NULL) ||
627 (! addEntry(pProfile, pSec, i, pStr, strlen(pszEntry))))
629 releaseProfile(pProfile);
630 #ifdef TRACE_OSL_PROFILE
631 OSL_TRACE("Out osl_writeProfileString [not inserted]");
632 #endif
633 return (sal_False);
636 pProfile->m_Flags |= FLG_MODIFIED;
638 else
640 i = pSec->m_Entries[NoEntry].m_Line;
641 free(pProfile->m_Lines[i]);
642 pProfile->m_Lines[i] = strdup(Line);
643 setEntry(pProfile, pSec, NoEntry, i, pProfile->m_Lines[i], strlen(pszEntry));
645 pProfile->m_Flags |= FLG_MODIFIED;
648 else
650 ::osl::LongPathBuffer< sal_Char > aFileName( MAX_LONG_PATH );
652 WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(pProfile->m_strFileName->buffer), -1, aFileName, aFileName.getBufSizeInSymbols(), NULL, NULL);
653 WritePrivateProfileString(pszSection, pszEntry, pszString, aFileName);
656 bRet = releaseProfile(pProfile);
657 #ifdef TRACE_OSL_PROFILE
658 OSL_TRACE("Out osl_writeProfileString [ok]");
659 #endif
660 return bRet;
664 sal_Bool SAL_CALL osl_writeProfileBool(oslProfile Profile,
665 const sal_Char* pszSection, const sal_Char* pszEntry,
666 sal_Bool Value)
668 sal_Bool bRet = sal_False;
670 #ifdef TRACE_OSL_PROFILE
671 OSL_TRACE("In osl_writeProfileBool");
672 #endif
674 if (Value)
675 bRet=osl_writeProfileString(Profile, pszSection, pszEntry, STR_INI_BOOLONE);
676 else
677 bRet=osl_writeProfileString(Profile, pszSection, pszEntry, STR_INI_BOOLZERO);
679 #ifdef TRACE_OSL_PROFILE
680 OSL_TRACE("Out osl_writeProfileBool [ok]");
681 #endif
683 return bRet;
687 sal_Bool SAL_CALL osl_writeProfileIdent(oslProfile Profile,
688 const sal_Char* pszSection, const sal_Char* pszEntry,
689 sal_uInt32 FirstId, const sal_Char* Strings[],
690 sal_uInt32 Value)
692 int i, n;
693 sal_Bool bRet = sal_False;
695 #ifdef TRACE_OSL_PROFILE
696 OSL_TRACE("In osl_writeProfileIdent");
697 #endif
699 for (n = 0; Strings[n] != NULL; n++);
701 if ((i = Value - FirstId) >= n)
702 bRet=sal_False;
703 else
704 bRet=osl_writeProfileString(Profile, pszSection, pszEntry, Strings[i]);
706 #ifdef TRACE_OSL_PROFILE
707 OSL_TRACE("Out osl_writeProfileIdent");
708 #endif
709 return bRet;
713 sal_Bool SAL_CALL osl_removeProfileEntry(oslProfile Profile,
714 const sal_Char *pszSection, const sal_Char *pszEntry)
716 sal_uInt32 NoEntry;
717 osl_TProfileSection* pSec;
718 osl_TProfileImpl* pProfile = 0;
719 sal_Bool bRet = sal_False;
721 #ifdef TRACE_OSL_PROFILE
722 OSL_TRACE("In osl_removeProfileEntry");
723 #endif
725 pProfile = acquireProfile(Profile, sal_True);
727 if (pProfile == NULL)
729 #ifdef TRACE_OSL_PROFILE
730 OSL_TRACE("Out osl_removeProfileEntry [pProfile==0]");
731 #endif
734 return (sal_False);
738 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
740 if (((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) != NULL) &&
741 (NoEntry < pSec->m_NoEntries))
743 removeLine(pProfile, pSec->m_Entries[NoEntry].m_Line);
744 removeEntry(pSec, NoEntry);
745 if (pSec->m_NoEntries == 0)
747 removeLine(pProfile, pSec->m_Line);
749 /* remove any empty separation line */
750 if ((pSec->m_Line > 0) && (pProfile->m_Lines[pSec->m_Line - 1][0] == '\0'))
751 removeLine(pProfile, pSec->m_Line - 1);
753 removeSection(pProfile, pSec);
756 pProfile->m_Flags |= FLG_MODIFIED;
759 else
761 ::osl::LongPathBuffer< sal_Char > aFileName( MAX_LONG_PATH );
763 WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(pProfile->m_strFileName->buffer), -1, aFileName, aFileName.getBufSizeInSymbols(), NULL, NULL);
764 WritePrivateProfileString(pszSection, pszEntry, NULL, aFileName);
767 bRet = releaseProfile(pProfile);
768 #ifdef TRACE_OSL_PROFILE
769 OSL_TRACE("Out osl_removeProfileEntry [ok]");
770 #endif
771 return bRet;
775 sal_uInt32 SAL_CALL osl_getProfileSectionEntries(oslProfile Profile, const sal_Char *pszSection,
776 sal_Char* pszBuffer, sal_uInt32 MaxLen)
778 sal_uInt32 i, n = 0;
779 sal_uInt32 NoEntry;
780 osl_TProfileSection* pSec;
781 osl_TProfileImpl* pProfile = 0;
783 #ifdef TRACE_OSL_PROFILE
784 OSL_TRACE("In osl_getProfileSectionEntries");
785 #endif
787 pProfile = acquireProfile(Profile, sal_False);
789 if (pProfile == NULL)
791 #ifdef TRACE_OSL_PROFILE
792 OSL_TRACE("Out osl_getProfileSectionEntries [pProfile=0]");
793 #endif
796 return (0);
800 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
802 if ((pSec = findEntry(pProfile, pszSection, "", &NoEntry)) != NULL)
804 if (MaxLen != 0)
806 for (i = 0; i < pSec->m_NoEntries; i++)
808 if ((n + pSec->m_Entries[i].m_Len + 1) < MaxLen)
810 strncpy(&pszBuffer[n], &pProfile->m_Lines[pSec->m_Entries[i].m_Line]
811 [pSec->m_Entries[i].m_Offset], pSec->m_Entries[i].m_Len);
812 n += pSec->m_Entries[i].m_Len;
813 pszBuffer[n++] = '\0';
815 else
816 break;
820 pszBuffer[n++] = '\0';
822 else
824 for (i = 0; i < pSec->m_NoEntries; i++)
825 n += pSec->m_Entries[i].m_Len + 1;
827 n += 1;
830 else
831 n = 0;
833 else
835 ::osl::LongPathBuffer< sal_Char > aFileName( MAX_LONG_PATH );
837 WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(pProfile->m_strFileName->buffer), -1, aFileName, aFileName.getBufSizeInSymbols(), NULL, NULL);
838 n = GetPrivateProfileString(pszSection, NULL, NULL, pszBuffer, MaxLen, aFileName);
841 releaseProfile(pProfile);
843 #ifdef TRACE_OSL_PROFILE
844 OSL_TRACE("Out osl_getProfileSectionEntries [ok]");
845 #endif
847 return (n);
851 sal_Bool SAL_CALL osl_getProfileName(rtl_uString* strPath, rtl_uString* strName, rtl_uString** strProfileName)
853 sal_Bool bFailed;
854 ::osl::LongPathBuffer< sal_Unicode > aFile( MAX_LONG_PATH );
855 ::osl::LongPathBuffer< sal_Unicode > aPath( MAX_LONG_PATH );
856 sal_uInt32 nFileLen = 0;
857 sal_uInt32 nPathLen = 0;
859 rtl_uString * strTmp = NULL;
860 oslFileError nError;
862 /* build file name */
863 if (strName && strName->length)
865 if( ::sal::static_int_cast< sal_uInt32 >( strName->length ) >= aFile.getBufSizeInSymbols() )
866 return sal_False;
868 copy_ustr_n( aFile, strName->buffer, strName->length+1);
869 nFileLen = strName->length;
871 if (rtl_ustr_indexOfChar( aFile, L'.' ) == -1)
873 if (nFileLen + wcslen(STR_INI_EXTENSION) >= aFile.getBufSizeInSymbols())
874 return sal_False;
876 /* add default extension */
877 copy_ustr_n( aFile + nFileLen, STR_INI_EXTENSION, wcslen(STR_INI_EXTENSION)+1 );
878 nFileLen += wcslen(STR_INI_EXTENSION);
881 else
883 rtl_uString *strProgName = NULL;
884 sal_Unicode *pProgName;
885 sal_Int32 nOffset = 0;
886 sal_Int32 nLen;
887 sal_Int32 nPos;
889 if (osl_getExecutableFile(&strProgName) != osl_Process_E_None)
890 return sal_False;
892 /* remove path and extension from filename */
893 pProgName = strProgName->buffer;
894 nLen = strProgName->length ;
896 if ((nPos = rtl_ustr_lastIndexOfChar( pProgName, L'/' )) != -1)
897 nOffset = nPos + 1;
898 else if ((nPos = rtl_ustr_lastIndexOfChar( pProgName, L':' )) != -1)
899 nOffset = nPos + 1;
901 if ((nPos = rtl_ustr_lastIndexOfChar( pProgName, L'.' )) != -1 )
902 nLen -= 4;
904 if ((nFileLen = nLen - nOffset) >= aFile.getBufSizeInSymbols())
905 return sal_False;
907 copy_ustr_n(aFile, pProgName + nOffset, nFileLen);
909 if (nFileLen + wcslen(STR_INI_EXTENSION) >= aFile.getBufSizeInSymbols())
910 return sal_False;
912 /* add default extension */
913 copy_ustr_n(aFile + nFileLen, STR_INI_EXTENSION, wcslen(STR_INI_EXTENSION)+1);
914 nFileLen += wcslen(STR_INI_EXTENSION);
916 rtl_uString_release( strProgName );
919 if (aFile[0] == 0)
920 return sal_False;
922 /* build directory path */
923 if (strPath && strPath->length)
925 sal_Unicode *pPath = rtl_uString_getStr(strPath);
926 sal_Int32 nLen = rtl_uString_getLength(strPath);
928 if ((rtl_ustr_ascii_compare_WithLength(pPath, RTL_CONSTASCII_LENGTH(STR_INI_METAHOME) , STR_INI_METAHOME) == 0) &&
929 ((nLen == RTL_CONSTASCII_LENGTH(STR_INI_METAHOME)) || (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METAHOME)] == '/')))
931 rtl_uString * strHome = NULL;
932 oslSecurity security = osl_getCurrentSecurity();
934 bFailed = ! osl_getHomeDir(security, &strHome);
935 osl_freeSecurityHandle(security);
937 if (bFailed) return (sal_False);
939 if ( ::sal::static_int_cast< sal_uInt32 >( strHome->length ) >= aPath.getBufSizeInSymbols())
940 return sal_False;
942 copy_ustr_n( aPath, strHome->buffer, strHome->length+1);
943 nPathLen = strHome->length;
945 if (nLen > RTL_CONSTASCII_LENGTH(STR_INI_METAHOME))
947 pPath += RTL_CONSTASCII_LENGTH(STR_INI_METAHOME);
948 nLen -= RTL_CONSTASCII_LENGTH(STR_INI_METAHOME);
950 if (nLen + nPathLen >= aPath.getBufSizeInSymbols())
951 return sal_False;
953 copy_ustr_n(aPath + nPathLen, pPath, nLen+1);
954 nPathLen += nLen;
957 rtl_uString_release(strHome);
960 else if ((rtl_ustr_ascii_compare_WithLength(pPath, RTL_CONSTASCII_LENGTH(STR_INI_METACFG), STR_INI_METACFG) == 0) &&
961 ((nLen == RTL_CONSTASCII_LENGTH(STR_INI_METACFG)) || (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METACFG)] == '/')))
963 rtl_uString * strConfig = NULL;
964 oslSecurity security = osl_getCurrentSecurity();
966 bFailed = ! osl_getConfigDir(security, &strConfig);
967 osl_freeSecurityHandle(security);
969 if (bFailed) return (sal_False);
971 if ( ::sal::static_int_cast< sal_uInt32 >( strConfig->length ) >= aPath.getBufSizeInSymbols())
972 return sal_False;
974 copy_ustr_n( aPath, strConfig->buffer, strConfig->length+1 );
975 nPathLen = strConfig->length;
977 if (nLen > RTL_CONSTASCII_LENGTH(STR_INI_METACFG))
979 pPath += RTL_CONSTASCII_LENGTH(STR_INI_METACFG);
980 nLen -= RTL_CONSTASCII_LENGTH(STR_INI_METACFG);
982 if (nLen + nPathLen >= aPath.getBufSizeInSymbols())
983 return sal_False;
985 copy_ustr_n(aPath + nPathLen, pPath, nLen+1);
986 nPathLen += nLen;
989 rtl_uString_release(strConfig);
992 else if ((rtl_ustr_ascii_compare_WithLength(pPath, RTL_CONSTASCII_LENGTH(STR_INI_METASYS), STR_INI_METASYS) == 0) &&
993 ((nLen == RTL_CONSTASCII_LENGTH(STR_INI_METASYS)) || (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METASYS)] == '/')))
995 if (((nPathLen = GetWindowsDirectoryW(::osl::mingw_reinterpret_cast<LPWSTR>(aPath), aPath.getBufSizeInSymbols())) == 0) || (nPathLen >= aPath.getBufSizeInSymbols()))
996 return (sal_False);
998 if (nLen > RTL_CONSTASCII_LENGTH(STR_INI_METASYS))
1000 pPath += RTL_CONSTASCII_LENGTH(STR_INI_METASYS);
1001 nLen -= RTL_CONSTASCII_LENGTH(STR_INI_METASYS);
1003 if (nLen + nPathLen >= aPath.getBufSizeInSymbols())
1004 return sal_False;
1006 copy_ustr_n(aPath + nPathLen, pPath, nLen+1);
1007 nPathLen += nLen;
1011 else if ((rtl_ustr_ascii_compare_WithLength(pPath, RTL_CONSTASCII_LENGTH(STR_INI_METAINS), STR_INI_METAINS) == 0) &&
1012 ((nLen == RTL_CONSTASCII_LENGTH(STR_INI_METAINS)) || (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METAINS)] == '/') ||
1013 (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METAINS)] == '"') ) )
1015 if (! lookupProfile(pPath + RTL_CONSTASCII_LENGTH(STR_INI_METAINS), aFile, aPath))
1016 return (sal_False);
1018 nPathLen = rtl_ustr_getLength(aPath);
1021 else if( ::sal::static_int_cast< sal_uInt32 >( nLen ) < aPath.getBufSizeInSymbols())
1023 copy_ustr_n(aPath, pPath, nLen+1);
1024 nPathLen = rtl_ustr_getLength(aPath);
1026 else
1027 return sal_False;
1029 else
1031 rtl_uString * strConfigDir = NULL;
1032 oslSecurity security = osl_getCurrentSecurity();
1034 bFailed = ! osl_getConfigDir(security, &strConfigDir);
1035 osl_freeSecurityHandle(security);
1037 if (bFailed) return (sal_False);
1038 if ( ::sal::static_int_cast< sal_uInt32 >( strConfigDir->length ) >= aPath.getBufSizeInSymbols() )
1039 return sal_False;
1041 copy_ustr_n(aPath, strConfigDir->buffer, strConfigDir->length+1);
1042 nPathLen = strConfigDir->length;
1045 if (nPathLen && (aPath[nPathLen - 1] != L'/') && (aPath[nPathLen - 1] != L'\\'))
1047 aPath[nPathLen++] = L'\\';
1048 aPath[nPathLen] = 0;
1051 if (nPathLen + nFileLen >= aPath.getBufSizeInSymbols())
1052 return sal_False;
1054 /* append file name */
1055 copy_ustr_n(aPath + nPathLen, aFile, nFileLen+1);
1056 nPathLen += nFileLen;
1058 /* copy filename */
1059 rtl_uString_newFromStr_WithLength(&strTmp, aPath, nPathLen);
1060 nError = osl_getFileURLFromSystemPath(strTmp, strProfileName);
1061 rtl_uString_release(strTmp);
1063 return (sal_Bool) (nError == osl_File_E_None);
1067 sal_uInt32 SAL_CALL osl_getProfileSections(oslProfile Profile, sal_Char* pszBuffer, sal_uInt32 MaxLen)
1069 sal_uInt32 i, n = 0;
1070 osl_TProfileSection* pSec;
1071 osl_TProfileImpl* pProfile = acquireProfile(Profile, sal_False);
1073 if (pProfile == NULL)
1074 return (0);
1076 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
1078 if (MaxLen != 0)
1080 for (i = 0; i < pProfile->m_NoSections; i++)
1082 pSec = &pProfile->m_Sections[i];
1084 if ((n + pSec->m_Len + 1) < MaxLen)
1086 strncpy(&pszBuffer[n], &pProfile->m_Lines[pSec->m_Line][pSec->m_Offset],
1087 pSec->m_Len);
1088 n += pSec->m_Len;
1089 pszBuffer[n++] = '\0';
1091 else
1092 break;
1095 pszBuffer[n++] = '\0';
1097 else
1099 for (i = 0; i < pProfile->m_NoSections; i++)
1100 n += pProfile->m_Sections[i].m_Len + 1;
1102 n += 1;
1105 else
1107 ::osl::LongPathBuffer< sal_Char > aFileName( MAX_LONG_PATH );
1109 WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(pProfile->m_strFileName->buffer), -1, aFileName, aFileName.getBufSizeInSymbols(), NULL, NULL);
1110 n = GetPrivateProfileSectionNames(pszBuffer, MaxLen, aFileName);
1113 releaseProfile(pProfile);
1115 return (n);
1119 /*****************************************************************************/
1120 /* Static Module Functions */
1121 /*****************************************************************************/
1123 static osl_TStamp getFileStamp(osl_TFile* pFile)
1125 FILETIME FileTime;
1127 if ((pFile->m_Handle == INVALID_HANDLE_VALUE) ||
1128 (! GetFileTime(pFile->m_Handle, NULL, NULL, &FileTime)))
1129 memset(&FileTime, 0, sizeof(FileTime));
1131 return (FileTime);
1136 static sal_Bool lockFile(const osl_TFile* pFile, osl_TLockMode eMode)
1138 sal_Bool status = sal_False;
1139 OVERLAPPED Overlapped;
1141 if (pFile->m_Handle == INVALID_HANDLE_VALUE)
1142 return (sal_False);
1144 memset(&Overlapped, 0, sizeof(Overlapped));
1146 switch (eMode)
1148 case un_lock:
1149 status = (sal_Bool) UnlockFileEx(
1150 pFile->m_Handle, 0, 0xFFFFFFFF, 0, &Overlapped);
1151 break;
1153 case read_lock:
1154 status = (sal_Bool) LockFileEx(
1155 pFile->m_Handle, 0, 0, 0xFFFFFFFF, 0, &Overlapped);
1156 break;
1158 case write_lock:
1159 status = (sal_Bool) LockFileEx(
1160 pFile->m_Handle, LOCKFILE_EXCLUSIVE_LOCK, 0, 0xFFFFFFFF, 0,
1161 &Overlapped);
1162 break;
1165 return (status);
1169 static osl_TFile* openFileImpl(rtl_uString * strFileName, oslProfileOption ProfileFlags )
1171 osl_TFile* pFile = reinterpret_cast< osl_TFile*>( calloc( 1, sizeof(osl_TFile) ) );
1172 sal_Bool bWriteable = sal_False;
1174 if ( ProfileFlags & ( osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE ) )
1176 #ifdef DEBUG_OSL_PROFILE
1177 OSL_TRACE("setting bWriteable to TRUE");
1178 #endif
1179 bWriteable=sal_True;
1182 if (! bWriteable)
1184 pFile->m_Handle = CreateFileW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( strFileName )), GENERIC_READ,
1185 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1186 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1188 /* mfe: argghh!!! do not check if the file could be openend */
1189 /* default mode expects it that way!!! */
1191 else
1193 #ifdef DEBUG_OSL_PROFILE
1194 OSL_TRACE("opening '%s' read/write",pszFilename);
1195 #endif
1197 if ((pFile->m_Handle = CreateFileW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( strFileName )), GENERIC_READ | GENERIC_WRITE,
1198 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1199 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL))
1200 == INVALID_HANDLE_VALUE)
1202 free(pFile);
1203 return (NULL);
1207 pFile->m_pWriteBuf=0;
1208 pFile->m_nWriteBufFree=0;
1209 pFile->m_nWriteBufLen=0;
1211 if ( ProfileFlags & (osl_Profile_WRITELOCK | osl_Profile_READLOCK ) )
1213 #ifdef DEBUG_OSL_PROFILE
1214 OSL_TRACE("locking '%s' file",pszFilename);
1215 #endif
1217 lockFile(pFile, bWriteable ? write_lock : read_lock);
1220 return (pFile);
1225 static osl_TStamp closeFileImpl(osl_TFile* pFile)
1227 osl_TStamp stamp = {0, 0};
1229 if ( pFile == 0 )
1231 return stamp;
1234 if (pFile->m_Handle != INVALID_HANDLE_VALUE)
1236 stamp = getFileStamp(pFile);
1238 lockFile(pFile, un_lock);
1240 CloseHandle(pFile->m_Handle);
1241 pFile->m_Handle = INVALID_HANDLE_VALUE;
1244 if ( pFile->m_pWriteBuf != 0 )
1246 free(pFile->m_pWriteBuf);
1249 free(pFile);
1251 return(stamp);
1255 static sal_Bool rewindFile(osl_TFile* pFile, sal_Bool bTruncate)
1257 if (pFile->m_Handle != INVALID_HANDLE_VALUE)
1259 pFile->m_pReadPtr = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);
1261 SetFilePointer(pFile->m_Handle, 0, NULL, FILE_BEGIN);
1263 if (bTruncate)
1264 SetEndOfFile(pFile->m_Handle);
1267 return (sal_True);
1271 static sal_Bool getLine(osl_TFile* pFile, const sal_Char *pszLine, int MaxLen)
1273 DWORD Max;
1274 size_t Free, Bytes;
1275 sal_Char* pChr;
1276 sal_Char* pLine = (sal_Char *)pszLine;
1278 if (pFile->m_Handle == INVALID_HANDLE_VALUE)
1279 return (sal_False);
1281 MaxLen -= 1;
1285 Bytes = sizeof(pFile->m_ReadBuf) - (pFile->m_pReadPtr - pFile->m_ReadBuf);
1287 if (Bytes <= 1)
1289 /* refill buffer */
1290 memcpy(pFile->m_ReadBuf, pFile->m_pReadPtr, Bytes);
1291 pFile->m_pReadPtr = pFile->m_ReadBuf;
1293 Free = sizeof(pFile->m_ReadBuf) - Bytes;
1295 if (! ReadFile(pFile->m_Handle, &pFile->m_ReadBuf[Bytes], Free, &Max, NULL))
1297 *pLine = '\0';
1298 return (sal_False);
1301 if (Max < Free)
1303 if ((Max == 0) && (pLine == pszLine))
1305 *pLine = '\0';
1306 return (sal_False);
1309 pFile->m_ReadBuf[Bytes + Max] = '\0';
1313 for (pChr = pFile->m_pReadPtr;
1314 (*pChr != '\n') && (*pChr != '\r') && (*pChr != '\0') &&
1315 (pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf) - 1));
1316 pChr++);
1318 Max = min((int) (pChr - pFile->m_pReadPtr), MaxLen);
1319 memcpy(pLine, pFile->m_pReadPtr, Max);
1320 MaxLen -= Max;
1321 pLine += Max;
1323 if (pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf) - 1))
1325 if (*pChr != '\0')
1327 if ((pChr[0] == '\r') && (pChr[1] == '\n'))
1328 pChr += 2;
1329 else
1330 pChr += 1;
1333 if ((pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf))) &&
1334 (*pChr == '\0'))
1335 pChr = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);
1337 *pLine = '\0';
1339 /* setting MaxLen to -1 indicates terminating read loop */
1340 MaxLen = -1;
1343 pFile->m_pReadPtr = pChr;
1345 while (MaxLen > 0);
1347 return (sal_True);
1351 static sal_Bool putLine(osl_TFile* pFile, const sal_Char *pszLine)
1353 unsigned int Len = strlen(pszLine);
1355 if ( pFile == 0 || pFile->m_Handle == INVALID_HANDLE_VALUE )
1357 return (sal_False);
1360 if ( pFile->m_pWriteBuf == 0 )
1362 pFile->m_pWriteBuf = (sal_Char*) malloc(Len+3);
1363 pFile->m_nWriteBufLen = Len+3;
1364 pFile->m_nWriteBufFree = Len+3;
1366 else
1368 if ( pFile->m_nWriteBufFree <= Len + 3 )
1370 sal_Char* pTmp;
1372 pTmp=(sal_Char*) realloc(pFile->m_pWriteBuf,( ( pFile->m_nWriteBufLen + Len ) * 2) );
1373 if ( pTmp == 0 )
1375 return sal_False;
1377 pFile->m_pWriteBuf = pTmp;
1378 pFile->m_nWriteBufFree = pFile->m_nWriteBufFree + pFile->m_nWriteBufLen + ( 2 * Len );
1379 pFile->m_nWriteBufLen = ( pFile->m_nWriteBufLen + Len ) * 2;
1380 memset( (pFile->m_pWriteBuf) + ( pFile->m_nWriteBufLen - pFile->m_nWriteBufFree ), 0, pFile->m_nWriteBufFree);
1386 memcpy(pFile->m_pWriteBuf + ( pFile->m_nWriteBufLen - pFile->m_nWriteBufFree ),pszLine,Len+1);
1388 pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len]='\r';
1389 pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len + 1]='\n';
1390 pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len + 2]='\0';
1392 pFile->m_nWriteBufFree-=Len+2;
1394 return (sal_True);
1397 /* platform specific end */
1399 static const sal_Char* stripBlanks(const sal_Char* String, sal_uInt32* pLen)
1401 if ( (pLen != NULL) && ( *pLen != 0 ) )
1403 while ((String[*pLen - 1] == ' ') || (String[*pLen - 1] == '\t'))
1404 (*pLen)--;
1406 while ((*String == ' ') || (*String == '\t'))
1408 String++;
1409 (*pLen)--;
1412 else
1413 while ((*String == ' ') || (*String == '\t'))
1414 String++;
1416 return (String);
1419 static const sal_Char* addLine(osl_TProfileImpl* pProfile, const sal_Char* Line)
1421 if (pProfile->m_NoLines >= pProfile->m_MaxLines)
1423 if (pProfile->m_Lines == NULL)
1425 pProfile->m_MaxLines = LINES_INI;
1426 pProfile->m_Lines = (sal_Char **)malloc(pProfile->m_MaxLines * sizeof(sal_Char *));
1427 memset(pProfile->m_Lines,0,pProfile->m_MaxLines * sizeof(sal_Char *));
1429 else
1431 unsigned int index=0;
1432 unsigned int oldmax=pProfile->m_MaxLines;
1434 pProfile->m_MaxLines += LINES_ADD;
1435 pProfile->m_Lines = (sal_Char **)realloc(pProfile->m_Lines, pProfile->m_MaxLines * sizeof(sal_Char *));
1437 for ( index = oldmax ; index < pProfile->m_MaxLines ; ++index )
1439 pProfile->m_Lines[index]=0;
1443 if (pProfile->m_Lines == NULL)
1445 pProfile->m_NoLines = 0;
1446 pProfile->m_MaxLines = 0;
1447 return (NULL);
1452 if ( pProfile->m_Lines != 0 && pProfile->m_Lines[pProfile->m_NoLines] != 0 )
1454 free(pProfile->m_Lines[pProfile->m_NoLines]);
1456 pProfile->m_Lines[pProfile->m_NoLines++] = strdup(Line);
1458 return (pProfile->m_Lines[pProfile->m_NoLines - 1]);
1461 static const sal_Char* insertLine(osl_TProfileImpl* pProfile, const sal_Char* Line, sal_uInt32 LineNo)
1463 if (pProfile->m_NoLines >= pProfile->m_MaxLines)
1465 if (pProfile->m_Lines == NULL)
1467 pProfile->m_MaxLines = LINES_INI;
1468 pProfile->m_Lines = (sal_Char **)malloc(pProfile->m_MaxLines * sizeof(sal_Char *));
1469 memset(pProfile->m_Lines,0,pProfile->m_MaxLines * sizeof(sal_Char *));
1471 else
1473 pProfile->m_MaxLines += LINES_ADD;
1474 pProfile->m_Lines = (sal_Char **)realloc(pProfile->m_Lines,
1475 pProfile->m_MaxLines * sizeof(sal_Char *));
1477 memset(&pProfile->m_Lines[pProfile->m_NoLines],
1479 (pProfile->m_MaxLines - pProfile->m_NoLines - 1) * sizeof(sal_Char*));
1482 if (pProfile->m_Lines == NULL)
1484 pProfile->m_NoLines = 0;
1485 pProfile->m_MaxLines = 0;
1486 return (NULL);
1490 LineNo = LineNo > pProfile->m_NoLines ? pProfile->m_NoLines : LineNo;
1492 if (LineNo < pProfile->m_NoLines)
1494 sal_uInt32 i, n;
1495 osl_TProfileSection* pSec;
1497 memmove(&pProfile->m_Lines[LineNo + 1], &pProfile->m_Lines[LineNo],
1498 (pProfile->m_NoLines - LineNo) * sizeof(sal_Char *));
1501 /* adjust line references */
1502 for (i = 0; i < pProfile->m_NoSections; i++)
1504 pSec = &pProfile->m_Sections[i];
1506 if (pSec->m_Line >= LineNo)
1507 pSec->m_Line++;
1509 for (n = 0; n < pSec->m_NoEntries; n++)
1510 if (pSec->m_Entries[n].m_Line >= LineNo)
1511 pSec->m_Entries[n].m_Line++;
1515 pProfile->m_NoLines++;
1517 pProfile->m_Lines[LineNo] = strdup(Line);
1519 return (pProfile->m_Lines[LineNo]);
1522 static void removeLine(osl_TProfileImpl* pProfile, sal_uInt32 LineNo)
1524 if (LineNo < pProfile->m_NoLines)
1526 free(pProfile->m_Lines[LineNo]);
1527 pProfile->m_Lines[LineNo]=0;
1528 if (pProfile->m_NoLines - LineNo > 1)
1530 sal_uInt32 i, n;
1531 osl_TProfileSection* pSec;
1533 memmove(&pProfile->m_Lines[LineNo], &pProfile->m_Lines[LineNo + 1],
1534 (pProfile->m_NoLines - LineNo - 1) * sizeof(sal_Char *));
1536 memset(&pProfile->m_Lines[pProfile->m_NoLines - 1],
1538 (pProfile->m_MaxLines - pProfile->m_NoLines) * sizeof(sal_Char*));
1540 /* adjust line references */
1541 for (i = 0; i < pProfile->m_NoSections; i++)
1543 pSec = &pProfile->m_Sections[i];
1545 if (pSec->m_Line > LineNo)
1546 pSec->m_Line--;
1548 for (n = 0; n < pSec->m_NoEntries; n++)
1549 if (pSec->m_Entries[n].m_Line > LineNo)
1550 pSec->m_Entries[n].m_Line--;
1553 else
1555 pProfile->m_Lines[LineNo] = 0;
1558 pProfile->m_NoLines--;
1561 return;
1564 static void setEntry(osl_TProfileImpl* pProfile, osl_TProfileSection* pSection,
1565 sal_uInt32 NoEntry, sal_uInt32 Line,
1566 const sal_Char* Entry, sal_uInt32 Len)
1568 Entry = stripBlanks(Entry, &Len);
1569 pSection->m_Entries[NoEntry].m_Line = Line;
1570 pSection->m_Entries[NoEntry].m_Offset = Entry - pProfile->m_Lines[Line];
1571 pSection->m_Entries[NoEntry].m_Len = Len;
1573 return;
1576 static sal_Bool addEntry(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection,
1577 int Line, const sal_Char* Entry, sal_uInt32 Len)
1579 if (pSection != NULL)
1581 if (pSection->m_NoEntries >= pSection->m_MaxEntries)
1583 if (pSection->m_Entries == NULL)
1585 pSection->m_MaxEntries = ENTRIES_INI;
1586 pSection->m_Entries = (osl_TProfileEntry *)malloc(
1587 pSection->m_MaxEntries * sizeof(osl_TProfileEntry));
1589 else
1591 pSection->m_MaxEntries += ENTRIES_ADD;
1592 pSection->m_Entries = (osl_TProfileEntry *)realloc(pSection->m_Entries,
1593 pSection->m_MaxEntries * sizeof(osl_TProfileEntry));
1596 if (pSection->m_Entries == NULL)
1598 pSection->m_NoEntries = 0;
1599 pSection->m_MaxEntries = 0;
1600 return (sal_False);
1604 pSection->m_NoEntries++;
1606 Entry = stripBlanks(Entry, &Len);
1607 setEntry(pProfile, pSection, pSection->m_NoEntries - 1, Line,
1608 Entry, Len);
1610 return (sal_True);
1613 return (sal_False);
1616 static void removeEntry(osl_TProfileSection *pSection, sal_uInt32 NoEntry)
1618 if (NoEntry < pSection->m_NoEntries)
1620 if (pSection->m_NoEntries - NoEntry > 1)
1622 memmove(&pSection->m_Entries[NoEntry],
1623 &pSection->m_Entries[NoEntry + 1],
1624 (pSection->m_NoEntries - NoEntry - 1) * sizeof(osl_TProfileEntry));
1625 pSection->m_Entries[pSection->m_NoEntries - 1].m_Line=0;
1626 pSection->m_Entries[pSection->m_NoEntries - 1].m_Offset=0;
1627 pSection->m_Entries[pSection->m_NoEntries - 1].m_Len=0;
1630 pSection->m_NoEntries--;
1633 return;
1636 static sal_Bool addSection(osl_TProfileImpl* pProfile, int Line, const sal_Char* Section, sal_uInt32 Len)
1638 if (pProfile->m_NoSections >= pProfile->m_MaxSections)
1640 if (pProfile->m_Sections == NULL)
1642 pProfile->m_MaxSections = SECTIONS_INI;
1643 pProfile->m_Sections = (osl_TProfileSection *)malloc(pProfile->m_MaxSections * sizeof(osl_TProfileSection));
1644 memset(pProfile->m_Sections,0,pProfile->m_MaxSections * sizeof(osl_TProfileSection));
1646 else
1648 unsigned int index=0;
1649 unsigned int oldmax=pProfile->m_MaxSections;
1651 pProfile->m_MaxSections += SECTIONS_ADD;
1652 pProfile->m_Sections = (osl_TProfileSection *)realloc(pProfile->m_Sections,
1653 pProfile->m_MaxSections * sizeof(osl_TProfileSection));
1654 for ( index = oldmax ; index < pProfile->m_MaxSections ; ++index )
1656 pProfile->m_Sections[index].m_Entries=0;
1660 if (pProfile->m_Sections == NULL)
1662 pProfile->m_NoSections = 0;
1663 pProfile->m_MaxSections = 0;
1664 return (sal_False);
1668 pProfile->m_NoSections++;
1670 if ( pProfile->m_Sections[(pProfile->m_NoSections) - 1].m_Entries != 0 )
1672 free(pProfile->m_Sections[(pProfile->m_NoSections) - 1].m_Entries);
1674 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Entries = NULL;
1675 pProfile->m_Sections[pProfile->m_NoSections - 1].m_NoEntries = 0;
1676 pProfile->m_Sections[pProfile->m_NoSections - 1].m_MaxEntries = 0;
1678 Section = (sal_Char *)stripBlanks(Section, &Len);
1679 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Line = Line;
1680 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Offset = Section - pProfile->m_Lines[Line];
1681 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Len = Len;
1683 return (sal_True);
1686 static void removeSection(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection)
1688 sal_uInt32 Section;
1690 if ((Section = pSection - pProfile->m_Sections) < pProfile->m_NoSections)
1692 free (pSection->m_Entries);
1693 pSection->m_Entries=0;
1694 if (pProfile->m_NoSections - Section > 1)
1696 memmove(&pProfile->m_Sections[Section], &pProfile->m_Sections[Section + 1],
1697 (pProfile->m_NoSections - Section - 1) * sizeof(osl_TProfileSection));
1699 memset(&pProfile->m_Sections[pProfile->m_NoSections - 1],
1701 (pProfile->m_MaxSections - pProfile->m_NoSections) * sizeof(osl_TProfileSection));
1702 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Entries = 0;
1704 else
1706 pSection->m_Entries = 0;
1709 pProfile->m_NoSections--;
1712 return;
1715 static osl_TProfileSection* findEntry(osl_TProfileImpl* pProfile, const sal_Char* Section,
1716 const sal_Char* Entry, sal_uInt32 *pNoEntry)
1718 static sal_uInt32 Sect = 0;
1719 sal_uInt32 i, n;
1720 sal_uInt32 Len;
1721 const sal_Char* pStr;
1722 osl_TProfileSection* pSec = NULL;
1724 Len = strlen(Section);
1725 Section = (sal_Char *)stripBlanks(Section, &Len);
1727 n = Sect;
1729 for (i = 0; i < pProfile->m_NoSections; i++)
1731 n %= pProfile->m_NoSections;
1732 pSec = &pProfile->m_Sections[n];
1733 if ((Len == pSec->m_Len) &&
1734 (strnicmp(Section, &pProfile->m_Lines[pSec->m_Line][pSec->m_Offset], pSec->m_Len)
1735 == 0))
1736 break;
1737 n++;
1740 Sect = n;
1742 if (i < pProfile->m_NoSections)
1744 Len = strlen(Entry);
1745 Entry = stripBlanks(Entry, &Len);
1747 *pNoEntry = pSec->m_NoEntries;
1749 for (i = 0; i < pSec->m_NoEntries; i++)
1751 pStr = &pProfile->m_Lines[pSec->m_Entries[i].m_Line]
1752 [pSec->m_Entries[i].m_Offset];
1753 if ((Len == pSec->m_Entries[i].m_Len) &&
1754 (strnicmp(Entry, pStr, pSec->m_Entries[i].m_Len)
1755 == 0))
1757 *pNoEntry = i;
1758 break;
1762 else
1763 pSec = NULL;
1765 return (pSec);
1768 static sal_Bool loadProfile(osl_TFile* pFile, osl_TProfileImpl* pProfile)
1770 sal_uInt32 i;
1771 sal_Char* pStr;
1772 sal_Char* pChar;
1773 sal_Char Line[4096];
1775 pProfile->m_NoLines = 0;
1776 pProfile->m_NoSections = 0;
1778 OSL_VERIFY(rewindFile(pFile, sal_False));
1780 while (getLine(pFile, Line, sizeof(Line)))
1782 if (! addLine(pProfile, Line))
1783 return (sal_False);
1786 for (i = 0; i < pProfile->m_NoLines; i++)
1788 pStr = (sal_Char *)stripBlanks(pProfile->m_Lines[i], NULL);
1790 if ((*pStr == '\0') || (*pStr == ';'))
1791 continue;
1793 if ((*pStr != '[') || ((pChar = strrchr(pStr, ']')) == NULL) ||
1794 ((pChar - pStr) <= 2))
1796 /* insert entry */
1798 if (pProfile->m_NoSections < 1)
1799 continue;
1801 if ((pChar = strchr(pStr, '=')) == NULL)
1802 pChar = pStr + strlen(pStr);
1804 if (! addEntry(pProfile, &pProfile->m_Sections[pProfile->m_NoSections - 1],
1805 i, pStr, pChar - pStr))
1806 return (sal_False);
1808 else
1810 /* new section */
1811 if (! addSection(pProfile, i, pStr + 1, pChar - pStr - 1))
1812 return (sal_False);
1816 return (sal_True);
1820 static sal_Bool storeProfile(osl_TProfileImpl* pProfile, sal_Bool bCleanup)
1822 #ifdef TRACE_OSL_PROFILE
1823 OSL_TRACE("In storeProfile");
1824 #endif
1826 if (pProfile->m_Lines != NULL)
1828 if (pProfile->m_Flags & FLG_MODIFIED)
1830 sal_uInt32 i;
1832 osl_TFile* pTmpFile = osl_openTmpProfileImpl(pProfile);
1834 if ( pTmpFile == 0 )
1836 return sal_False;
1839 OSL_VERIFY(rewindFile(pTmpFile, sal_True));
1841 for (i = 0; i < pProfile->m_NoLines; i++)
1843 OSL_VERIFY(putLine(pTmpFile, pProfile->m_Lines[i]));
1846 if ( ! writeProfileImpl(pTmpFile) )
1848 if ( pTmpFile->m_pWriteBuf != 0 )
1850 free(pTmpFile->m_pWriteBuf);
1853 pTmpFile->m_pWriteBuf=0;
1854 pTmpFile->m_nWriteBufLen=0;
1855 pTmpFile->m_nWriteBufFree=0;
1857 #ifdef TRACE_OSL_PROFILE
1858 OSL_TRACE("Out storeProfile [not flushed]");
1859 #endif
1860 closeFileImpl(pTmpFile);
1862 return sal_False;
1865 pProfile->m_Flags &= ~FLG_MODIFIED;
1867 closeFileImpl(pProfile->m_pFile);
1868 closeFileImpl(pTmpFile);
1870 osl_ProfileSwapProfileNames(pProfile);
1872 pProfile->m_pFile = openFileImpl(pProfile->m_strFileName,pProfile->m_Flags);
1876 if (bCleanup)
1878 while (pProfile->m_NoLines > 0)
1879 removeLine(pProfile, pProfile->m_NoLines - 1);
1881 free(pProfile->m_Lines);
1882 pProfile->m_Lines = NULL;
1883 pProfile->m_MaxLines = 0;
1885 while (pProfile->m_NoSections > 0)
1886 removeSection(pProfile, &pProfile->m_Sections[pProfile->m_NoSections - 1]);
1888 free(pProfile->m_Sections);
1889 pProfile->m_Sections = NULL;
1890 pProfile->m_MaxSections = 0;
1894 #ifdef TRACE_OSL_PROFILE
1895 OSL_TRACE("Out storeProfile [ok]");
1896 #endif
1897 return (sal_True);
1901 static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl* pProfile)
1903 osl_TFile* pFile=0;
1904 rtl_uString* ustrExtension=0;
1905 rtl_uString* ustrTmpName=0;
1906 oslProfileOption PFlags=0;
1908 rtl_uString_newFromAscii(&ustrExtension,"tmp");
1911 /* generate tmp profilename */
1912 ustrTmpName=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
1913 rtl_uString_release(ustrExtension);
1915 if ( ustrTmpName == 0 )
1917 return 0;
1921 if ( ! ( pProfile->m_Flags & osl_Profile_READLOCK ) )
1923 PFlags |= osl_Profile_WRITELOCK;
1926 /* open this file */
1927 pFile = openFileImpl(ustrTmpName,pProfile->m_Flags | PFlags);
1930 /* return new pFile */
1931 return pFile;
1935 static sal_Bool osl_ProfileSwapProfileNames(osl_TProfileImpl* pProfile)
1937 sal_Bool bRet = sal_False;
1939 rtl_uString* ustrBakFile=0;
1940 rtl_uString* ustrTmpFile=0;
1941 rtl_uString* ustrIniFile=0;
1942 rtl_uString* ustrExtension=0;
1945 rtl_uString_newFromAscii(&ustrExtension,"bak");
1947 ustrBakFile=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
1948 rtl_uString_release(ustrExtension);
1949 ustrExtension=0;
1952 rtl_uString_newFromAscii(&ustrExtension,"ini");
1954 ustrIniFile=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
1955 rtl_uString_release(ustrExtension);
1956 ustrExtension=0;
1959 rtl_uString_newFromAscii(&ustrExtension,"tmp");
1961 ustrTmpFile=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
1962 rtl_uString_release(ustrExtension);
1963 ustrExtension=0;
1966 /* unlink bak */
1967 DeleteFileW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrBakFile )) );
1969 /* rename ini bak */
1970 MoveFileExW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrIniFile )), reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrBakFile )), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH );
1972 /* rename tmp ini */
1973 MoveFileExW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrTmpFile )), reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrIniFile )), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH );
1975 return bRet;
1979 static rtl_uString* osl_ProfileGenerateExtension(rtl_uString* ustrFileName, rtl_uString* ustrExtension)
1981 rtl_uString* ustrNewFileName=0;
1982 rtl_uString* ustrOldExtension = 0;
1983 sal_Unicode* pExtensionBuf = 0;
1984 sal_Unicode* pFileNameBuf = 0;
1985 sal_Int32 nIndex = -1;
1987 pFileNameBuf = rtl_uString_getStr(ustrFileName);
1989 rtl_uString_newFromAscii(&ustrOldExtension,".");
1991 pExtensionBuf = rtl_uString_getStr(ustrOldExtension);
1993 nIndex = rtl_ustr_lastIndexOfChar(pFileNameBuf,*pExtensionBuf);
1995 rtl_uString_newReplaceStrAt(&ustrNewFileName,
1996 ustrFileName,
1997 nIndex+1,
1999 ustrExtension);
2001 return ustrNewFileName;
2005 static osl_TProfileImpl* acquireProfile(oslProfile Profile, sal_Bool bWriteable)
2007 osl_TProfileImpl* pProfile = (osl_TProfileImpl*)Profile;
2008 oslProfileOption PFlags=0;
2011 if ( bWriteable )
2013 PFlags = osl_Profile_DEFAULT | osl_Profile_WRITELOCK;
2015 else
2017 PFlags = osl_Profile_DEFAULT;
2021 if (pProfile == NULL)
2023 #ifdef DEBUG_OSL_PROFILE
2024 OSL_TRACE("AUTOOPEN MODE");
2025 #endif
2027 if ( ( pProfile = (osl_TProfileImpl*)osl_openProfile( NULL, PFlags ) ) != NULL )
2029 pProfile->m_Flags |= FLG_AUTOOPEN;
2032 else
2034 #ifdef DEBUG_OSL_PROFILE
2035 OSL_TRACE("try to acquire");
2036 #endif
2040 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
2042 if (! (pProfile->m_Flags & (osl_Profile_READLOCK |
2043 osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE)))
2045 osl_TStamp Stamp;
2046 #ifdef DEBUG_OSL_PROFILE
2047 OSL_TRACE("DEFAULT MODE");
2048 #endif
2049 pProfile->m_pFile = openFileImpl(
2050 pProfile->m_strFileName, pProfile->m_Flags | PFlags);
2051 if (!pProfile->m_pFile)
2052 return NULL;
2054 Stamp = getFileStamp(pProfile->m_pFile);
2056 if (memcmp(&Stamp, &(pProfile->m_Stamp), sizeof(osl_TStamp)))
2058 pProfile->m_Stamp = Stamp;
2060 loadProfile(pProfile->m_pFile, pProfile);
2063 else
2065 #ifdef DEBUG_OSL_PROFILE
2066 OSL_TRACE("READ/WRITELOCK MODE");
2067 #endif
2070 /* A readlock file could not be written */
2071 if ((pProfile->m_Flags & osl_Profile_READLOCK) && bWriteable)
2073 return (NULL);
2079 return (pProfile);
2082 static sal_Bool releaseProfile(osl_TProfileImpl* pProfile)
2084 #ifdef TRACE_OSL_PROFILE
2085 OSL_TRACE("In releaseProfile");
2086 #endif
2088 if ( pProfile == 0 )
2090 #ifdef TRACE_OSL_PROFILE
2091 OSL_TRACE("Out releaseProfile [profile==0]");
2092 #endif
2093 return sal_False;
2096 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
2098 if (pProfile->m_Flags & FLG_AUTOOPEN)
2100 #ifdef TRACE_OSL_PROFILE
2101 OSL_TRACE("Out releaseProfile [AUTOOPEN]");
2102 #endif
2103 return (osl_closeProfile((oslProfile)pProfile));
2105 else
2107 #ifdef DEBUG_OSL_PROFILE
2108 OSL_TRACE("DEFAULT MODE");
2109 #endif
2110 if (! (pProfile->m_Flags & (osl_Profile_READLOCK |
2111 osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE)))
2113 if (pProfile->m_Flags & FLG_MODIFIED)
2114 storeProfile(pProfile, sal_False);
2116 closeFileImpl(pProfile->m_pFile);
2117 pProfile->m_pFile = NULL;
2122 #ifdef TRACE_OSL_PROFILE
2123 OSL_TRACE("Out releaseProfile [ok]");
2124 #endif
2125 return (sal_True);
2128 static sal_Bool lookupProfile(const sal_Unicode *strPath, const sal_Unicode *strFile, sal_Unicode *strProfile)
2130 sal_Char *pChr, *pStr;
2131 sal_Char Buffer[4096] = "";
2132 sal_Char Product[132] = "";
2134 ::osl::LongPathBuffer< sal_Unicode > aPath( MAX_LONG_PATH );
2135 aPath[0] = 0;
2136 DWORD dwPathLen = 0;
2138 if (*strPath == L'"')
2140 int i = 0;
2142 strPath++;
2144 while ((strPath[i] != L'"') && (strPath[i] != L'\0'))
2145 i++;
2147 WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(strPath), i, Product, sizeof(Product), NULL, NULL);
2148 Product[i] = '\0';
2149 strPath += i;
2151 if (*strPath == L'"')
2152 strPath++;
2154 if ( (*strPath == L'/') || (*strPath == L'\\') )
2156 strPath++;
2160 else
2162 /* if we have not product identfication, do a special handling for soffice.ini */
2163 if (rtl_ustr_ascii_compare(strFile, SVERSION_PROFILE) == 0)
2165 rtl_uString * strSVProfile = NULL;
2166 rtl_uString * strSVFallback = NULL;
2167 rtl_uString * strSVLocation = NULL;
2168 rtl_uString * strSVName = NULL;
2169 ::osl::LongPathBuffer< sal_Char > aDir( MAX_LONG_PATH );
2170 oslProfile hProfile;
2172 rtl_uString_newFromAscii(&strSVFallback, SVERSION_FALLBACK);
2173 rtl_uString_newFromAscii(&strSVLocation, SVERSION_LOCATION);
2174 rtl_uString_newFromAscii(&strSVName, SVERSION_NAME);
2176 /* open sversion.ini in the system directory, and try to locate the entry
2177 with the highest version for StarOffice */
2178 if (osl_getProfileName( strSVFallback, strSVName, &strSVProfile))
2180 hProfile = osl_openProfile(strSVProfile, osl_Profile_READLOCK);
2181 if (hProfile)
2183 osl_getProfileSectionEntries(
2184 hProfile, SVERSION_SECTION, Buffer, sizeof(Buffer));
2186 for (pChr = Buffer; *pChr != '\0'; pChr += strlen(pChr) + 1)
2188 if ((strnicmp(
2189 pChr, SVERSION_SOFFICE,
2190 sizeof(SVERSION_SOFFICE) - 1)
2191 == 0)
2192 && (stricmp(Product, pChr) < 0))
2194 osl_readProfileString(
2195 hProfile, SVERSION_SECTION, pChr, aDir,
2196 aDir.getBufSizeInSymbols(), "");
2198 /* check for existence of path */
2199 if (access(aDir, 0) >= 0)
2200 strcpy(Product, pChr);
2204 osl_closeProfile(hProfile);
2206 rtl_uString_release(strSVProfile);
2207 strSVProfile = NULL;
2210 /* open sversion.ini in the users directory, and try to locate the entry
2211 with the highest version for StarOffice */
2212 if ((strcmp(SVERSION_LOCATION, SVERSION_FALLBACK) != 0) &&
2213 (osl_getProfileName(strSVLocation, strSVName, &strSVProfile)))
2215 hProfile = osl_openProfile(strSVProfile, osl_Profile_READLOCK);
2216 if (hProfile)
2218 osl_getProfileSectionEntries(
2219 hProfile, SVERSION_SECTION, Buffer, sizeof(Buffer));
2221 for (pChr = Buffer; *pChr != '\0'; pChr += strlen(pChr) + 1)
2223 if ((strnicmp(
2224 pChr, SVERSION_SOFFICE,
2225 sizeof(SVERSION_SOFFICE) - 1)
2226 == 0)
2227 && (stricmp(Product, pChr) < 0))
2229 osl_readProfileString(
2230 hProfile, SVERSION_SECTION, pChr, aDir,
2231 aDir.getBufSizeInSymbols(), "");
2233 /* check for existence of path */
2234 if (access(aDir, 0) >= 0)
2235 strcpy(Product, pChr);
2239 osl_closeProfile(hProfile);
2241 rtl_uString_release(strSVProfile);
2244 rtl_uString_release(strSVFallback);
2245 rtl_uString_release(strSVLocation);
2246 rtl_uString_release(strSVName);
2248 /* remove any trailing build number */
2249 if ((pChr = strrchr(Product, '/')) != NULL)
2250 *pChr = '\0';
2254 /* if we have an userid option eg. "-userid:rh[/usr/home/rh/staroffice]",
2255 this will supercede all other locations */
2257 sal_uInt32 n, nArgs = osl_getCommandArgCount();
2259 for (n = 0; n < nArgs; n++)
2261 rtl_uString * strCommandArg = NULL;
2263 if ((osl_getCommandArg( n, &strCommandArg ) == osl_Process_E_None) &&
2264 ((strCommandArg->buffer[0] == L'-') || (strCommandArg->buffer[0] == L'+')) &&
2265 (rtl_ustr_ascii_compare_WithLength(strCommandArg->buffer, RTL_CONSTASCII_LENGTH(SVERSION_OPTION), SVERSION_OPTION)))
2267 sal_Unicode *pCommandArg = strCommandArg->buffer + RTL_CONSTASCII_LENGTH(SVERSION_OPTION);
2268 sal_Int32 nStart, nEnd;
2270 if (((nStart = rtl_ustr_indexOfChar(pCommandArg, L'[')) != -1) &&
2271 ((nEnd = rtl_ustr_indexOfChar(pCommandArg + nStart + 1, L']')) != -1))
2273 dwPathLen = nEnd;
2274 copy_ustr_n(aPath, pCommandArg + nStart + 1, dwPathLen);
2275 aPath[dwPathLen] = 0;
2277 /* build full path */
2278 if ((aPath[dwPathLen - 1] != L'/') && (aPath[dwPathLen - 1] != L'\\'))
2280 copy_ustr_n(aPath + dwPathLen++, L"/", 2);
2283 if (*strPath)
2285 copy_ustr_n(aPath + dwPathLen, strPath, rtl_ustr_getLength(strPath)+1);
2286 dwPathLen += rtl_ustr_getLength(strPath);
2288 else
2290 ::osl::LongPathBuffer< sal_Char > aTmpPath( MAX_LONG_PATH );
2291 int nLen = 0;
2293 if ((nLen = WideCharToMultiByte(CP_ACP,0, ::osl::mingw_reinterpret_cast<LPCWSTR>(aPath), -1, aTmpPath, aTmpPath.getBufSizeInSymbols(), NULL, NULL)) > 0)
2295 strcpy(aTmpPath + nLen, SVERSION_USER);
2296 if (access(aTmpPath, 0) >= 0)
2298 dwPathLen += MultiByteToWideChar( CP_ACP, 0, SVERSION_USER, -1, reinterpret_cast<LPWSTR>(aPath + dwPathLen), aPath.getBufSizeInSymbols() - dwPathLen );
2303 break;
2310 if (dwPathLen == 0)
2312 rtl_uString * strExecutable = NULL;
2313 rtl_uString * strTmp = NULL;
2314 sal_Int32 nPos;
2316 /* try to find the file in the directory of the executbale */
2317 if (osl_getExecutableFile(&strTmp) != osl_Process_E_None)
2318 return (sal_False);
2320 /* convert to native path */
2321 if (osl_getSystemPathFromFileURL(strTmp, &strExecutable) != osl_File_E_None)
2323 rtl_uString_release(strTmp);
2324 return sal_False;
2327 rtl_uString_release(strTmp);
2329 /* separate path from filename */
2330 if ((nPos = rtl_ustr_lastIndexOfChar(strExecutable->buffer, L'\\')) == -1)
2332 if ((nPos = rtl_ustr_lastIndexOfChar(strExecutable->buffer, L':')) == -1)
2334 return sal_False;
2336 else
2338 copy_ustr_n(aPath, strExecutable->buffer, nPos);
2339 aPath[nPos] = 0;
2340 dwPathLen = nPos;
2343 else
2345 copy_ustr_n(aPath, strExecutable->buffer, nPos);
2346 dwPathLen = nPos;
2347 aPath[dwPathLen] = 0;
2350 /* if we have no product identification use the executable file name */
2351 if (*Product == 0)
2353 WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(strExecutable->buffer + nPos + 1), -1, Product, sizeof(Product), NULL, NULL);
2355 /* remove extension */
2356 if ((pChr = strrchr(Product, '.')) != NULL)
2357 *pChr = '\0';
2360 rtl_uString_release(strExecutable);
2362 /* remember last subdir */
2363 nPos = rtl_ustr_lastIndexOfChar(aPath, L'\\');
2365 copy_ustr_n(aPath + dwPathLen++, L"\\", 2);
2367 if (*strPath)
2369 copy_ustr_n(aPath + dwPathLen, strPath, rtl_ustr_getLength(strPath)+1);
2370 dwPathLen += rtl_ustr_getLength(strPath);
2374 ::osl::LongPathBuffer< sal_Char > aTmpPath( MAX_LONG_PATH );
2376 WideCharToMultiByte(CP_ACP,0, ::osl::mingw_reinterpret_cast<LPCWSTR>(aPath), -1, aTmpPath, aTmpPath.getBufSizeInSymbols(), NULL, NULL);
2378 /* if file not exists, remove any specified subdirectories
2379 like "bin" or "program" */
2381 if (((access(aTmpPath, 0) < 0) && (nPos != -1)) || (*strPath == 0))
2383 static const sal_Char *SubDirs[] = SVERSION_DIRS;
2385 unsigned i = 0;
2386 pStr = aTmpPath + nPos;
2388 for (i = 0; i < SAL_N_ELEMENTS(SubDirs); i++)
2389 if (strnicmp(pStr + 1, SubDirs[i], strlen(SubDirs[i])) == 0)
2391 if ( *strPath == 0)
2393 strcpy(pStr + 1,SVERSION_USER);
2394 if ( access(aTmpPath, 0) < 0 )
2396 *(pStr+1)='\0';
2398 else
2400 dwPathLen = nPos + MultiByteToWideChar( CP_ACP, 0, SVERSION_USER, -1, reinterpret_cast<LPWSTR>(aPath + nPos + 1), aPath.getBufSizeInSymbols() - (nPos + 1) );
2403 else
2405 copy_ustr_n(aPath + nPos + 1, strPath, rtl_ustr_getLength(strPath)+1);
2406 dwPathLen = nPos + 1 + rtl_ustr_getLength(strPath);
2409 break;
2414 if ((aPath[dwPathLen - 1] != L'/') && (aPath[dwPathLen - 1] != L'\\'))
2416 aPath[dwPathLen++] = L'\\';
2417 aPath[dwPathLen] = 0;
2420 copy_ustr_n(aPath + dwPathLen, strFile, rtl_ustr_getLength(strFile)+1);
2423 ::osl::LongPathBuffer< sal_Char > aTmpPath( MAX_LONG_PATH );
2425 WideCharToMultiByte(CP_ACP,0, ::osl::mingw_reinterpret_cast<LPCWSTR>(aPath), -1, aTmpPath, aTmpPath.getBufSizeInSymbols(), NULL, NULL);
2427 if ((access(aTmpPath, 0) < 0) && (strlen(Product) > 0))
2429 rtl_uString * strSVFallback = NULL;
2430 rtl_uString * strSVProfile = NULL;
2431 rtl_uString * strSVLocation = NULL;
2432 rtl_uString * strSVName = NULL;
2433 oslProfile hProfile;
2435 rtl_uString_newFromAscii(&strSVFallback, SVERSION_FALLBACK);
2436 rtl_uString_newFromAscii(&strSVLocation, SVERSION_LOCATION);
2437 rtl_uString_newFromAscii(&strSVName, SVERSION_NAME);
2439 /* open sversion.ini in the system directory, and try to locate the entry
2440 with the highest version for StarOffice */
2441 if (osl_getProfileName(strSVLocation, strSVName, &strSVProfile))
2443 hProfile = osl_openProfile(
2444 strSVProfile, osl_Profile_READLOCK);
2445 if (hProfile)
2447 osl_readProfileString(
2448 hProfile, SVERSION_SECTION, Product, Buffer,
2449 sizeof(Buffer), "");
2450 osl_closeProfile(hProfile);
2452 /* if not found, try the fallback */
2453 if ((strlen(Buffer) <= 0)
2454 && (strcmp(SVERSION_LOCATION, SVERSION_FALLBACK)
2455 != 0))
2457 if (osl_getProfileName(
2458 strSVFallback, strSVName, &strSVProfile))
2460 hProfile = osl_openProfile(
2461 strSVProfile, osl_Profile_READLOCK);
2462 if (hProfile)
2464 osl_readProfileString(
2465 hProfile, SVERSION_SECTION, Product,
2466 Buffer, sizeof(Buffer), "");
2470 osl_closeProfile(hProfile);
2473 if (strlen(Buffer) > 0)
2475 dwPathLen = MultiByteToWideChar(
2476 CP_ACP, 0, Buffer, -1, ::osl::mingw_reinterpret_cast<LPWSTR>(aPath), aPath.getBufSizeInSymbols() );
2477 dwPathLen -=1;
2479 /* build full path */
2480 if ((aPath[dwPathLen - 1] != L'/')
2481 && (aPath[dwPathLen - 1] != L'\\'))
2483 copy_ustr_n(aPath + dwPathLen++, L"\\", 2);
2486 if (*strPath)
2488 copy_ustr_n(aPath + dwPathLen, strPath, rtl_ustr_getLength(strPath)+1);
2489 dwPathLen += rtl_ustr_getLength(strPath);
2491 else
2493 ::osl::LongPathBuffer< sal_Char > aTmpPath2( MAX_LONG_PATH );
2494 int n;
2496 if ((n = WideCharToMultiByte(
2497 CP_ACP,0, ::osl::mingw_reinterpret_cast<LPCWSTR>(aPath), -1, aTmpPath2,
2498 aTmpPath2.getBufSizeInSymbols(), NULL, NULL))
2499 > 0)
2501 strcpy(aTmpPath2 + n, SVERSION_USER);
2502 if (access(aTmpPath2, 0) >= 0)
2504 dwPathLen += MultiByteToWideChar(
2505 CP_ACP, 0, SVERSION_USER, -1,
2506 reinterpret_cast<LPWSTR>(aPath + dwPathLen),
2507 aPath.getBufSizeInSymbols() - dwPathLen );
2514 rtl_uString_release(strSVProfile);
2517 rtl_uString_release(strSVFallback);
2518 rtl_uString_release(strSVLocation);
2519 rtl_uString_release(strSVName);
2523 aPath[dwPathLen] = 0;
2526 /* copy filename */
2527 copy_ustr_n(strProfile, aPath, dwPathLen+1);
2529 return sal_True;
2533 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */