update dev300-m58
[ooovba.git] / sal / osl / w32 / profile.c
blob0457fbf3c219304faa064fe2ad726ce7bd3d86bf
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: profile.c,v $
10 * $Revision: 1.17 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
32 #include "system.h"
34 #include <osl/diagnose.h>
35 #include <osl/profile.h>
36 #include <osl/process.h>
37 #include <osl/file.h>
38 #include <osl/util.h>
39 #include <rtl/alloc.h>
41 #define LINES_INI 32
42 #define LINES_ADD 10
43 #define SECTIONS_INI 5
44 #define SECTIONS_ADD 3
45 #define ENTRIES_INI 5
46 #define ENTRIES_ADD 3
49 #define STR_INI_EXTENSION L".ini"
50 #define STR_INI_METAHOME "?~"
51 #define STR_INI_METASYS "?$"
52 #define STR_INI_METACFG "?^"
53 #define STR_INI_METAINS "?#"
55 #define STR_INI_BOOLYES "yes"
56 #define STR_INI_BOOLON "on"
57 #define STR_INI_BOOLONE "1"
58 #define STR_INI_BOOLNO "no"
59 #define STR_INI_BOOLOFF "off"
60 #define STR_INI_BOOLZERO "0"
62 #define FLG_USER 0x00FF
63 #define FLG_AUTOOPEN 0x0100
64 #define FLG_MODIFIED 0x0200
66 #define SVERSION_LOCATION STR_INI_METACFG
67 #define SVERSION_FALLBACK STR_INI_METASYS
68 #define SVERSION_NAME "sversion"
69 #define SVERSION_SECTION "Versions"
70 #define SVERSION_SOFFICE "StarOffice"
71 #define SVERSION_PROFILE "soffice.ini"
72 #define SVERSION_OPTION "userid:"
73 #define SVERSION_DIRS { "bin", "program" }
74 #define SVERSION_USER "user"
76 #define DEFAULT_PMODE (_S_IREAD | _S_IWRITE)
78 #define _BUILD_STR_(n) # n
79 #define BUILD_STR(n) _BUILD_STR_(n)
82 /*#define DEBUG_OSL_PROFILE 1*/
83 /*#define TRACE_OSL_PROFILE 1*/
86 /*****************************************************************************/
87 /* Data Type Definition */
88 /*****************************************************************************/
90 typedef FILETIME osl_TStamp;
92 typedef enum _osl_TLockMode
94 un_lock, read_lock, write_lock
95 } osl_TLockMode;
97 typedef struct _osl_TFile
99 HANDLE m_Handle;
100 sal_Char* m_pReadPtr;
101 sal_Char m_ReadBuf[512];
102 /* sal_Char* m_pWritePtr; */
103 /* sal_Char m_WriteBuf[512]; */
104 sal_Char* m_pWriteBuf;
105 sal_uInt32 m_nWriteBufLen;
106 sal_uInt32 m_nWriteBufFree;
107 } osl_TFile;
109 typedef struct _osl_TProfileEntry
111 sal_uInt32 m_Line;
112 sal_uInt32 m_Offset;
113 sal_uInt32 m_Len;
114 } osl_TProfileEntry;
116 typedef struct _osl_TProfileSection
118 sal_uInt32 m_Line;
119 sal_uInt32 m_Offset;
120 sal_uInt32 m_Len;
121 sal_uInt32 m_NoEntries;
122 sal_uInt32 m_MaxEntries;
123 osl_TProfileEntry* m_Entries;
124 } osl_TProfileSection;
128 Profile-data structure hidden behind oslProfile:
130 typedef struct _osl_TProfileImpl
132 sal_uInt32 m_Flags;
133 osl_TFile* m_pFile;
134 osl_TStamp m_Stamp;
135 sal_uInt32 m_NoLines;
136 sal_uInt32 m_MaxLines;
137 sal_uInt32 m_NoSections;
138 sal_uInt32 m_MaxSections;
139 sal_Char** m_Lines;
140 rtl_uString *m_strFileName;
141 osl_TProfileSection* m_Sections;
142 } osl_TProfileImpl;
145 /*****************************************************************************/
146 /* Static Module Function Declarations */
147 /*****************************************************************************/
149 static osl_TFile* openFileImpl(rtl_uString * strFileName, oslProfileOption ProfileFlags );
150 static osl_TStamp closeFileImpl(osl_TFile* pFile);
151 static sal_Bool lockFile(const osl_TFile* pFile, osl_TLockMode eMode);
152 static sal_Bool rewindFile(osl_TFile* pFile, sal_Bool bTruncate);
153 static osl_TStamp getFileStamp(osl_TFile* pFile);
155 static sal_Bool getLine(osl_TFile* pFile, const sal_Char *pszLine, int MaxLen);
156 static sal_Bool putLine(osl_TFile* pFile, const sal_Char *pszLine);
157 static const sal_Char* stripBlanks(const sal_Char* String, sal_uInt32* pLen);
158 static const sal_Char* addLine(osl_TProfileImpl* pProfile, const sal_Char* Line);
159 static const sal_Char* insertLine(osl_TProfileImpl* pProfile, const sal_Char* Line, sal_uInt32 LineNo);
160 static void removeLine(osl_TProfileImpl* pProfile, sal_uInt32 LineNo);
161 static void setEntry(osl_TProfileImpl* pProfile, osl_TProfileSection* pSection,
162 sal_uInt32 NoEntry, sal_uInt32 Line,
163 const sal_Char* Entry, sal_uInt32 Len);
164 static sal_Bool addEntry(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection,
165 int Line, const sal_Char* Entry, sal_uInt32 Len);
166 static void removeEntry(osl_TProfileSection *pSection, sal_uInt32 NoEntry);
167 static sal_Bool addSection(osl_TProfileImpl* pProfile, int Line, const sal_Char* Section, sal_uInt32 Len);
168 static void removeSection(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection);
169 static osl_TProfileSection* findEntry(osl_TProfileImpl* pProfile, const sal_Char* Section,
170 const sal_Char* Entry, sal_uInt32 *pNoEntry);
171 static sal_Bool loadProfile(osl_TFile* pFile, osl_TProfileImpl* pProfile);
172 static sal_Bool storeProfile(osl_TProfileImpl* pProfile, sal_Bool bCleanup);
173 static osl_TProfileImpl* acquireProfile(oslProfile Profile, sal_Bool bWriteable);
174 static sal_Bool releaseProfile(osl_TProfileImpl* pProfile);
175 static sal_Bool lookupProfile(const sal_Unicode *strPath, const sal_Unicode *strFile, sal_Unicode *strProfile);
177 static sal_Bool writeProfileImpl (osl_TFile* pFile);
178 static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl*);
179 static sal_Bool osl_ProfileSwapProfileNames(osl_TProfileImpl*);
180 static rtl_uString* osl_ProfileGenerateExtension(rtl_uString* ustrFileName, rtl_uString* ustrExtension);
182 static sal_Bool SAL_CALL osl_getProfileName(rtl_uString* strPath, rtl_uString* strName, rtl_uString** strProfileName);
184 /*****************************************************************************/
185 /* Exported Module Functions */
186 /*****************************************************************************/
188 oslProfile SAL_CALL osl_openProfile(rtl_uString *strProfileName, sal_uInt32 Flags)
190 osl_TFile* pFile = NULL;
191 osl_TProfileImpl* pProfile;
192 rtl_uString *FileName=NULL;
194 #ifdef TRACE_OSL_PROFILE
195 OSL_TRACE("In osl_openProfile\n");
196 #endif
197 OSL_VERIFY(strProfileName);
199 if (rtl_uString_getLength(strProfileName) == 0 )
201 OSL_VERIFY(osl_getProfileName(NULL, NULL, &FileName));
203 else
205 rtl_uString_assign(&FileName, strProfileName);
209 osl_getSystemPathFromFileURL(FileName, &FileName);
212 #ifdef DEBUG_OSL_PROFILE
213 Flags=osl_Profile_FLUSHWRITE;
215 // OSL_TRACE("opening '%s'\n",FileName);
216 if ( Flags == osl_Profile_DEFAULT )
218 OSL_TRACE("with osl_Profile_DEFAULT \n");
220 if ( Flags & osl_Profile_SYSTEM )
222 OSL_TRACE("with osl_Profile_SYSTEM \n");
224 if ( Flags & osl_Profile_READLOCK )
226 OSL_TRACE("with osl_Profile_READLOCK \n");
228 if ( Flags & osl_Profile_WRITELOCK )
230 OSL_TRACE("with osl_Profile_WRITELOCK \n");
232 /* if ( Flags & osl_Profile_READWRITE ) */
233 /* { */
234 /* OSL_TRACE("with osl_Profile_READWRITE \n"); */
235 /* } */
236 if ( Flags & osl_Profile_FLUSHWRITE )
238 OSL_TRACE("with osl_Profile_FLUSHWRITE \n");
240 #endif
242 if ( (! (Flags & osl_Profile_SYSTEM)) && ( (pFile = openFileImpl(FileName, Flags) ) == NULL ) )
244 #ifdef TRACE_OSL_PROFILE
245 OSL_TRACE("Out osl_openProfile [not opened]\n");
246 #endif
247 if( FileName)
248 rtl_uString_release( FileName);
250 return (NULL);
254 pProfile = (osl_TProfileImpl*)calloc(1, sizeof(osl_TProfileImpl));
257 pProfile->m_Flags = Flags & FLG_USER;
258 osl_getSystemPathFromFileURL(strProfileName, &pProfile->m_strFileName);
259 // rtl_uString_assign(&pProfile->m_strFileName, strProfileName);
261 if (Flags & (osl_Profile_READLOCK | osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE ))
262 pProfile->m_pFile = pFile;
264 pProfile->m_Stamp = getFileStamp(pFile);
266 loadProfile(pFile, pProfile);
268 if (pProfile->m_pFile == NULL)
269 closeFileImpl(pFile);
271 #ifdef TRACE_OSL_PROFILE
272 OSL_TRACE("Out osl_openProfile [ok]\n");
273 #endif
274 if( FileName)
275 rtl_uString_release( FileName);
277 return (pProfile);
280 sal_Bool SAL_CALL osl_closeProfile(oslProfile Profile)
282 osl_TProfileImpl* pProfile = (osl_TProfileImpl*)Profile;
284 #ifdef TRACE_OSL_PROFILE
285 OSL_TRACE("In osl_closeProfile\n");
286 #endif
288 if ( Profile == 0 )
290 #ifdef TRACE_OSL_PROFILE
291 OSL_TRACE("Out osl_closeProfile [profile==0]\n");
292 #endif
293 return sal_False;
296 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
298 pProfile = acquireProfile(Profile,sal_True);
300 if ( pProfile != 0 )
302 if ( !( pProfile->m_Flags & osl_Profile_READLOCK ) && ( pProfile->m_Flags & FLG_MODIFIED ) )
304 /* if (pProfile->m_pFile == NULL) */
305 /* pProfile->m_pFile = openFileImpl(pProfile->m_Filename, sal_True); */
307 storeProfile(pProfile, sal_False);
310 else
312 pProfile = acquireProfile(Profile,sal_False);
315 if ( pProfile == 0 )
317 #ifdef TRACE_OSL_PROFILE
318 OSL_TRACE("Out osl_closeProfile [pProfile==0]\n");
319 #endif
320 return sal_False;
323 if (pProfile->m_pFile != NULL)
324 closeFileImpl(pProfile->m_pFile);
327 pProfile->m_pFile = NULL;
328 rtl_uString_release(pProfile->m_strFileName);
329 pProfile->m_strFileName = NULL;
331 /* release whole profile data types memory */
332 if ( pProfile->m_NoLines > 0)
334 unsigned int index=0;
335 if ( pProfile->m_Lines != 0 )
337 for ( index = 0 ; index < pProfile->m_NoLines ; ++index)
339 if ( pProfile->m_Lines[index] != 0 )
341 free(pProfile->m_Lines[index]);
344 free(pProfile->m_Lines);
346 if ( pProfile->m_Sections != 0 )
348 /*osl_TProfileSection* pSections=pProfile->m_Sections;*/
349 for ( index = 0 ; index < pProfile->m_NoSections ; ++index )
351 if ( pProfile->m_Sections[index].m_Entries != 0 )
353 free(pProfile->m_Sections[index].m_Entries);
356 free(pProfile->m_Sections);
360 free(pProfile);
362 #ifdef TRACE_OSL_PROFILE
363 OSL_TRACE("Out osl_closeProfile [ok]\n");
364 #endif
365 return (sal_True);
369 sal_Bool SAL_CALL osl_flushProfile(oslProfile Profile)
371 osl_TProfileImpl* pProfile = (osl_TProfileImpl*) Profile;
372 osl_TFile* pFile;
373 sal_Bool bRet = sal_False;
375 #ifdef TRACE_OSL_PROFILE
376 OSL_TRACE("In osl_flushProfile()\n");
377 #endif
379 if ( pProfile == 0 )
381 #ifdef TRACE_OSL_PROFILE
382 OSL_TRACE("Out osl_flushProfile() [pProfile == 0]\n");
383 #endif
384 return sal_False;
387 pFile = pProfile->m_pFile;
388 if ( !( pFile != 0 && pFile->m_Handle >= 0 ) )
390 #ifdef TRACE_OSL_PROFILE
391 OSL_TRACE("Out osl_flushProfile() [invalid file]\n");
392 #endif
393 return sal_False;
396 if ( pProfile->m_Flags & FLG_MODIFIED )
398 #ifdef DEBUG_OSL_PROFILE
399 OSL_TRACE("swapping to storeprofile\n");
400 #endif
401 bRet = storeProfile(pProfile,sal_False);
404 #ifdef TRACE_OSL_PROFILE
405 OSL_TRACE("Out osl_flushProfile() [ok]\n");
406 #endif
407 return bRet;
410 static sal_Bool writeProfileImpl(osl_TFile* pFile)
412 DWORD BytesWritten=0;
413 BOOL bRet;
415 #ifdef TRACE_OSL_PROFILE
416 OSL_TRACE("In osl_writeProfileImpl()\n");
417 #endif
419 if ( !( pFile != 0 && pFile->m_Handle != INVALID_HANDLE_VALUE ) || ( pFile->m_pWriteBuf == 0 ) )
421 #ifdef TRACE_OSL_PROFILE
422 OSL_TRACE("Out osl_writeProfileImpl() [invalid args]\n");
423 #endif
424 return sal_False;
427 #ifdef DEBUG_OSL_PROFILE
428 /* OSL_TRACE("File Buffer in writeProfileImpl '%s' size == '%i' '%i'(%i)\n",
429 pFile->m_pWriteBuf,pFile->m_nWriteBufLen,strlen(pFile->m_pWriteBuf),pFile->m_nWriteBufLen - pFile->m_nWriteBufFree);*/
430 #endif
432 bRet=WriteFile(pFile->m_Handle, pFile->m_pWriteBuf, pFile->m_nWriteBufLen - pFile->m_nWriteBufFree,&BytesWritten,NULL);
434 if ( bRet == 0 || BytesWritten <= 0 )
436 OSL_ENSURE(bRet,"WriteFile failed!!!");
438 OSL_TRACE("write failed '%s'\n",strerror(errno));
440 /* OSL_TRACE("Out osl_writeProfileImpl() [write '%s']\n",strerror(errno));*/
441 return (sal_False);
444 free(pFile->m_pWriteBuf);
445 pFile->m_pWriteBuf=0;
446 pFile->m_nWriteBufLen=0;
447 pFile->m_nWriteBufFree=0;
449 #ifdef TRACE_OSL_PROFILE
450 OSL_TRACE("Out osl_writeProfileImpl() [ok]\n");
451 #endif
452 return sal_True;
456 sal_Bool SAL_CALL osl_readProfileString(oslProfile Profile,
457 const sal_Char* pszSection, const sal_Char* pszEntry,
458 sal_Char* pszString, sal_uInt32 MaxLen,
459 const sal_Char* pszDefault)
461 sal_uInt32 NoEntry;
462 const sal_Char* pStr = 0;
463 osl_TProfileSection* pSec;
464 osl_TProfileImpl* pProfile = 0;
467 #ifdef TRACE_OSL_PROFILE
468 OSL_TRACE("In osl_readProfileString\n");
469 #endif
471 pProfile = acquireProfile(Profile, sal_False);
473 if (pProfile == NULL)
475 #ifdef TRACE_OSL_PROFILE
476 OSL_TRACE("Out osl_readProfileString [pProfile==0]\n");
477 #endif
480 return (sal_False);
484 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
486 if (((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) != NULL) &&
487 (NoEntry < pSec->m_NoEntries) &&
488 ((pStr = strchr(pProfile->m_Lines[pSec->m_Entries[NoEntry].m_Line],
489 '=')) != NULL))
490 pStr++;
491 else
492 pStr = pszDefault;
494 if ( pStr != 0 )
496 pStr = stripBlanks(pStr, NULL);
497 MaxLen = (MaxLen - 1 < strlen(pStr)) ? (MaxLen - 1) : strlen(pStr);
498 pStr = stripBlanks(pStr, &MaxLen);
499 strncpy(pszString, pStr, MaxLen);
500 pszString[MaxLen] = '\0';
503 else
505 CHAR szFileName[MAX_PATH];
507 WideCharToMultiByte(CP_ACP,0, pProfile->m_strFileName->buffer, -1, szFileName, MAX_PATH, NULL, NULL);
508 GetPrivateProfileString(pszSection, pszEntry, pszDefault, pszString, MaxLen, szFileName);
511 releaseProfile(pProfile);
513 if ( pStr == 0 )
515 #ifdef TRACE_OSL_PROFILE
516 OSL_TRACE("Out osl_readProfileString [pStr==0]\n");
517 #endif
520 return (sal_False);
523 #ifdef TRACE_OSL_PROFILE
524 OSL_TRACE("Out osl_readProfileString [ok]\n");
525 #endif
530 return (sal_True);
534 sal_Bool SAL_CALL osl_readProfileBool(oslProfile Profile,
535 const sal_Char* pszSection, const sal_Char* pszEntry,
536 sal_Bool Default)
538 sal_Char Line[32];
540 #ifdef TRACE_OSL_PROFILE
541 OSL_TRACE("In osl_readProfileBool\n");
542 #endif
544 if (osl_readProfileString(Profile, pszSection, pszEntry, Line, sizeof(Line), ""))
546 if ((stricmp(Line, STR_INI_BOOLYES) == 0) ||
547 (stricmp(Line, STR_INI_BOOLON) == 0) ||
548 (stricmp(Line, STR_INI_BOOLONE) == 0))
549 Default = sal_True;
550 else
551 if ((stricmp(Line, STR_INI_BOOLNO) == 0) ||
552 (stricmp(Line, STR_INI_BOOLOFF) == 0) ||
553 (stricmp(Line, STR_INI_BOOLZERO) == 0))
554 Default = sal_False;
557 #ifdef TRACE_OSL_PROFILE
558 OSL_TRACE("Out osl_readProfileBool [ok]\n");
559 #endif
561 return (Default);
565 sal_uInt32 SAL_CALL osl_readProfileIdent(oslProfile Profile,
566 const sal_Char* pszSection, const sal_Char* pszEntry,
567 sal_uInt32 FirstId, const sal_Char* Strings[],
568 sal_uInt32 Default)
570 sal_uInt32 i;
571 sal_Char Line[256];
573 #ifdef TRACE_OSL_PROFILE
574 OSL_TRACE("In osl_readProfileIdent\n");
575 #endif
577 if (osl_readProfileString(Profile, pszSection, pszEntry, Line, sizeof(Line), ""))
579 i = 0;
580 while (Strings[i] != NULL)
582 if (stricmp(Line, Strings[i]) == 0)
584 Default = i + FirstId;
585 break;
587 i++;
591 #ifdef TRACE_OSL_PROFILE
592 OSL_TRACE("Out osl_readProfileIdent [ok]\n");
593 #endif
594 return (Default);
597 sal_Bool SAL_CALL osl_writeProfileString(oslProfile Profile,
598 const sal_Char* pszSection, const sal_Char* pszEntry,
599 const sal_Char* pszString)
601 sal_uInt32 i;
602 sal_Bool bRet = sal_False;
603 sal_uInt32 NoEntry;
604 const sal_Char* pStr;
605 sal_Char Line[4096];
606 osl_TProfileSection* pSec;
607 osl_TProfileImpl* pProfile = 0;
609 #ifdef TRACE_OSL_PROFILE
610 OSL_TRACE("In osl_writeProfileString\n");
611 #endif
613 pProfile = acquireProfile(Profile, sal_True);
615 if (pProfile == NULL)
617 #ifdef TRACE_OSL_PROFILE
618 OSL_TRACE("Out osl_writeProfileString [pProfile==0]\n");
619 #endif
620 return (sal_False);
624 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
626 if ((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) == NULL)
628 Line[0] = '\0';
629 addLine(pProfile, Line);
631 Line[0] = '[';
632 strcpy(&Line[1], pszSection);
633 Line[1 + strlen(pszSection)] = ']';
634 Line[2 + strlen(pszSection)] = '\0';
636 if (((pStr = addLine(pProfile, Line)) == NULL) ||
637 (! addSection(pProfile, pProfile->m_NoLines - 1, &pStr[1], strlen(pszSection))))
639 releaseProfile(pProfile);
640 #ifdef TRACE_OSL_PROFILE
641 OSL_TRACE("Out osl_writeProfileString [not added]\n");
642 #endif
643 return (sal_False);
646 pSec = &pProfile->m_Sections[pProfile->m_NoSections - 1];
647 NoEntry = pSec->m_NoEntries;
650 Line[0] = '\0';
651 strcpy(&Line[0], pszEntry);
652 Line[0 + strlen(pszEntry)] = '=';
653 strcpy(&Line[1 + strlen(pszEntry)], pszString);
655 if (NoEntry >= pSec->m_NoEntries)
657 if (pSec->m_NoEntries > 0)
658 i = pSec->m_Entries[pSec->m_NoEntries - 1].m_Line + 1;
659 else
660 i = pSec->m_Line + 1;
662 if (((pStr = insertLine(pProfile, Line, i)) == NULL) ||
663 (! addEntry(pProfile, pSec, i, pStr, strlen(pszEntry))))
665 releaseProfile(pProfile);
666 #ifdef TRACE_OSL_PROFILE
667 OSL_TRACE("Out osl_writeProfileString [not inserted]\n");
668 #endif
669 return (sal_False);
672 pProfile->m_Flags |= FLG_MODIFIED;
674 else
676 i = pSec->m_Entries[NoEntry].m_Line;
677 free(pProfile->m_Lines[i]);
678 pProfile->m_Lines[i] = strdup(Line);
679 setEntry(pProfile, pSec, NoEntry, i, pProfile->m_Lines[i], strlen(pszEntry));
681 pProfile->m_Flags |= FLG_MODIFIED;
684 else
686 CHAR szFileName[MAX_PATH];
688 WideCharToMultiByte(CP_ACP,0, pProfile->m_strFileName->buffer, -1, szFileName, MAX_PATH, NULL, NULL);
689 WritePrivateProfileString(pszSection, pszEntry, pszString, szFileName);
692 bRet = releaseProfile(pProfile);
693 #ifdef TRACE_OSL_PROFILE
694 OSL_TRACE("Out osl_writeProfileString [ok]\n");
695 #endif
696 return bRet;
700 sal_Bool SAL_CALL osl_writeProfileBool(oslProfile Profile,
701 const sal_Char* pszSection, const sal_Char* pszEntry,
702 sal_Bool Value)
704 sal_Bool bRet = sal_False;
706 #ifdef TRACE_OSL_PROFILE
707 OSL_TRACE("In osl_writeProfileBool\n");
708 #endif
710 if (Value)
711 bRet=osl_writeProfileString(Profile, pszSection, pszEntry, STR_INI_BOOLONE);
712 else
713 bRet=osl_writeProfileString(Profile, pszSection, pszEntry, STR_INI_BOOLZERO);
715 #ifdef TRACE_OSL_PROFILE
716 OSL_TRACE("Out osl_writeProfileBool [ok]\n");
717 #endif
719 return bRet;
723 sal_Bool SAL_CALL osl_writeProfileIdent(oslProfile Profile,
724 const sal_Char* pszSection, const sal_Char* pszEntry,
725 sal_uInt32 FirstId, const sal_Char* Strings[],
726 sal_uInt32 Value)
728 int i, n;
729 sal_Bool bRet = sal_False;
731 #ifdef TRACE_OSL_PROFILE
732 OSL_TRACE("In osl_writeProfileIdent\n");
733 #endif
735 for (n = 0; Strings[n] != NULL; n++);
737 if ((i = Value - FirstId) >= n)
738 bRet=sal_False;
739 else
740 bRet=osl_writeProfileString(Profile, pszSection, pszEntry, Strings[i]);
742 #ifdef TRACE_OSL_PROFILE
743 OSL_TRACE("Out osl_writeProfileIdent\n");
744 #endif
745 return bRet;
749 sal_Bool SAL_CALL osl_removeProfileEntry(oslProfile Profile,
750 const sal_Char *pszSection, const sal_Char *pszEntry)
752 sal_uInt32 NoEntry;
753 osl_TProfileSection* pSec;
754 osl_TProfileImpl* pProfile = 0;
755 sal_Bool bRet = sal_False;
757 #ifdef TRACE_OSL_PROFILE
758 OSL_TRACE("In osl_removeProfileEntry\n");
759 #endif
761 pProfile = acquireProfile(Profile, sal_True);
763 if (pProfile == NULL)
765 #ifdef TRACE_OSL_PROFILE
766 OSL_TRACE("Out osl_removeProfileEntry [pProfile==0]\n");
767 #endif
770 return (sal_False);
774 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
776 if (((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) != NULL) &&
777 (NoEntry < pSec->m_NoEntries))
779 removeLine(pProfile, pSec->m_Entries[NoEntry].m_Line);
780 removeEntry(pSec, NoEntry);
781 if (pSec->m_NoEntries == 0)
783 removeLine(pProfile, pSec->m_Line);
785 /* remove any empty separation line */
786 if ((pSec->m_Line > 0) && (pProfile->m_Lines[pSec->m_Line - 1][0] == '\0'))
787 removeLine(pProfile, pSec->m_Line - 1);
789 removeSection(pProfile, pSec);
792 pProfile->m_Flags |= FLG_MODIFIED;
795 else
797 CHAR szFileName[MAX_PATH];
799 WideCharToMultiByte(CP_ACP,0, pProfile->m_strFileName->buffer, -1, szFileName, MAX_PATH, NULL, NULL);
800 WritePrivateProfileString(pszSection, pszEntry, NULL, szFileName);
803 bRet = releaseProfile(pProfile);
804 #ifdef TRACE_OSL_PROFILE
805 OSL_TRACE("Out osl_removeProfileEntry [ok]\n");
806 #endif
807 return bRet;
811 sal_uInt32 SAL_CALL osl_getProfileSectionEntries(oslProfile Profile, const sal_Char *pszSection,
812 sal_Char* pszBuffer, sal_uInt32 MaxLen)
814 sal_uInt32 i, n = 0;
815 sal_uInt32 NoEntry;
816 osl_TProfileSection* pSec;
817 osl_TProfileImpl* pProfile = 0;
819 #ifdef TRACE_OSL_PROFILE
820 OSL_TRACE("In osl_getProfileSectionEntries\n");
821 #endif
823 pProfile = acquireProfile(Profile, sal_False);
825 if (pProfile == NULL)
827 #ifdef TRACE_OSL_PROFILE
828 OSL_TRACE("Out osl_getProfileSectionEntries [pProfile=0]\n");
829 #endif
832 return (0);
836 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
838 if ((pSec = findEntry(pProfile, pszSection, "", &NoEntry)) != NULL)
840 if (MaxLen != 0)
842 for (i = 0; i < pSec->m_NoEntries; i++)
844 if ((n + pSec->m_Entries[i].m_Len + 1) < MaxLen)
846 strncpy(&pszBuffer[n], &pProfile->m_Lines[pSec->m_Entries[i].m_Line]
847 [pSec->m_Entries[i].m_Offset], pSec->m_Entries[i].m_Len);
848 n += pSec->m_Entries[i].m_Len;
849 pszBuffer[n++] = '\0';
851 else
852 break;
856 pszBuffer[n++] = '\0';
858 else
860 for (i = 0; i < pSec->m_NoEntries; i++)
861 n += pSec->m_Entries[i].m_Len + 1;
863 n += 1;
866 else
867 n = 0;
869 else
871 CHAR szFileName[MAX_PATH];
873 WideCharToMultiByte(CP_ACP,0, pProfile->m_strFileName->buffer, -1, szFileName, MAX_PATH, NULL, NULL);
874 n = GetPrivateProfileString(pszSection, NULL, NULL, pszBuffer, MaxLen, szFileName);
877 releaseProfile(pProfile);
879 #ifdef TRACE_OSL_PROFILE
880 OSL_TRACE("Out osl_getProfileSectionEntries [ok]\n");
881 #endif
883 return (n);
887 sal_Bool SAL_CALL osl_getProfileName(rtl_uString* strPath, rtl_uString* strName, rtl_uString** strProfileName)
889 sal_Bool bFailed;
890 sal_Unicode wcsFile[MAX_PATH];
891 sal_Unicode wcsPath[MAX_PATH];
892 sal_uInt32 nFileLen;
893 sal_uInt32 nPathLen = 0;
895 rtl_uString * strTmp = NULL;
896 oslFileError nError;
898 /* build file name */
899 if (strName && strName->length)
901 if(strName->length >= MAX_PATH)
902 return sal_False;
904 wcscpy(wcsFile, strName->buffer);
905 nFileLen = strName->length;
907 if (rtl_ustr_indexOfChar( wcsFile, L'.' ) == -1)
909 if (nFileLen + wcslen(STR_INI_EXTENSION) >= MAX_PATH)
910 return sal_False;
912 /* add default extension */
913 wcscpy(wcsFile + nFileLen, STR_INI_EXTENSION);
914 nFileLen += wcslen(STR_INI_EXTENSION);
917 else
919 rtl_uString *strProgName = NULL;
920 sal_Unicode *pProgName;
921 sal_Int32 nOffset = 0;
922 sal_Int32 nLen;
923 sal_Int32 nPos;
925 if (osl_getExecutableFile(&strProgName) != osl_Process_E_None)
926 return sal_False;
928 /* remove path and extension from filename */
929 pProgName = strProgName->buffer;
930 nLen = strProgName->length ;
932 if ((nPos = rtl_ustr_lastIndexOfChar( pProgName, L'/' )) != -1)
933 nOffset = nPos + 1;
934 else if ((nPos = rtl_ustr_lastIndexOfChar( pProgName, L':' )) != -1)
935 nOffset = nPos + 1;
937 if ((nPos = rtl_ustr_lastIndexOfChar( pProgName, L'.' )) != -1 )
938 nLen -= 4;
940 if ((nFileLen = nLen - nOffset) >= MAX_PATH)
941 return sal_False;
943 wcsncpy(wcsFile, pProgName + nOffset, nFileLen);
945 if (nFileLen + wcslen(STR_INI_EXTENSION) >= MAX_PATH)
946 return sal_False;
948 /* add default extension */
949 wcscpy(wcsFile + nFileLen, STR_INI_EXTENSION);
950 nFileLen += wcslen(STR_INI_EXTENSION);
952 rtl_uString_release( strProgName );
955 if (wcsFile[0] == 0)
956 return sal_False;
958 /* build directory path */
959 if (strPath && strPath->length)
961 sal_Unicode *pPath = rtl_uString_getStr(strPath);
962 sal_Int32 nLen = rtl_uString_getLength(strPath);
964 if ((rtl_ustr_ascii_compare_WithLength(pPath, RTL_CONSTASCII_LENGTH(STR_INI_METAHOME) , STR_INI_METAHOME) == 0) &&
965 ((nLen == RTL_CONSTASCII_LENGTH(STR_INI_METAHOME)) || (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METAHOME)] == '/')))
967 rtl_uString * strHome = NULL;
968 oslSecurity security = osl_getCurrentSecurity();
970 bFailed = ! osl_getHomeDir(security, &strHome);
971 osl_freeSecurityHandle(security);
973 if (bFailed) return (sal_False);
975 if (strHome->length >= MAX_PATH)
976 return sal_False;
978 wcscpy( wcsPath, strHome->buffer);
979 nPathLen = strHome->length;
981 if (nLen > RTL_CONSTASCII_LENGTH(STR_INI_METAHOME))
983 pPath += RTL_CONSTASCII_LENGTH(STR_INI_METAHOME);
984 nLen -= RTL_CONSTASCII_LENGTH(STR_INI_METAHOME);
986 if (nLen + nPathLen >= MAX_PATH)
987 return sal_False;
989 wcscpy(wcsPath + nPathLen, pPath);
990 nPathLen += nLen;
993 rtl_uString_release(strHome);
996 else if ((rtl_ustr_ascii_compare_WithLength(pPath, RTL_CONSTASCII_LENGTH(STR_INI_METACFG), STR_INI_METACFG) == 0) &&
997 ((nLen == RTL_CONSTASCII_LENGTH(STR_INI_METACFG)) || (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METACFG)] == '/')))
999 rtl_uString * strConfig = NULL;
1000 oslSecurity security = osl_getCurrentSecurity();
1002 bFailed = ! osl_getConfigDir(security, &strConfig);
1003 osl_freeSecurityHandle(security);
1005 if (bFailed) return (sal_False);
1007 if (strConfig->length >= MAX_PATH)
1008 return sal_False;
1010 wcscpy( wcsPath, strConfig->buffer);
1011 nPathLen = strConfig->length;
1013 if (nLen > RTL_CONSTASCII_LENGTH(STR_INI_METACFG))
1015 pPath += RTL_CONSTASCII_LENGTH(STR_INI_METACFG);
1016 nLen -= RTL_CONSTASCII_LENGTH(STR_INI_METACFG);
1018 if (nLen + nPathLen >= MAX_PATH)
1019 return sal_False;
1021 wcscpy(wcsPath + nPathLen, pPath);
1022 nPathLen += nLen;
1025 rtl_uString_release(strConfig);
1028 else if ((rtl_ustr_ascii_compare_WithLength(pPath, RTL_CONSTASCII_LENGTH(STR_INI_METASYS), STR_INI_METASYS) == 0) &&
1029 ((nLen == RTL_CONSTASCII_LENGTH(STR_INI_METASYS)) || (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METASYS)] == '/')))
1031 if (((nPathLen = GetWindowsDirectoryW(wcsPath, MAX_PATH)) == 0) || (nPathLen >= MAX_PATH))
1032 return (sal_False);
1034 if (nLen > RTL_CONSTASCII_LENGTH(STR_INI_METASYS))
1036 pPath += RTL_CONSTASCII_LENGTH(STR_INI_METASYS);
1037 nLen -= RTL_CONSTASCII_LENGTH(STR_INI_METASYS);
1039 if (nLen + nPathLen >= MAX_PATH)
1040 return sal_False;
1042 wcscpy(wcsPath + nPathLen, pPath);
1043 nPathLen += nLen;
1047 else if ((rtl_ustr_ascii_compare_WithLength(pPath, RTL_CONSTASCII_LENGTH(STR_INI_METAINS), STR_INI_METAINS) == 0) &&
1048 ((nLen == RTL_CONSTASCII_LENGTH(STR_INI_METAINS)) || (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METAINS)] == '/') ||
1049 (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METAINS)] == '"') ) )
1051 if (! lookupProfile(pPath + RTL_CONSTASCII_LENGTH(STR_INI_METAINS), wcsFile, wcsPath))
1052 return (sal_False);
1054 nPathLen = wcslen(wcsPath);
1057 else if(nLen < MAX_PATH)
1059 wcscpy(wcsPath, pPath);
1060 nPathLen = wcslen(wcsPath);
1062 else
1063 return sal_False;
1065 else
1067 rtl_uString * strConfigDir = NULL;
1068 oslSecurity security = osl_getCurrentSecurity();
1070 bFailed = ! osl_getConfigDir(security, &strConfigDir);
1071 osl_freeSecurityHandle(security);
1073 if (bFailed) return (sal_False);
1074 if (strConfigDir->length >= MAX_PATH)
1075 return sal_False;
1077 wcscpy(wcsPath, strConfigDir->buffer);
1078 nPathLen = strConfigDir->length;
1081 if (nPathLen && (wcsPath[nPathLen - 1] != L'/') && (wcsPath[nPathLen - 1] != L'\\'))
1083 wcsPath[nPathLen++] = L'\\';
1084 wcsPath[nPathLen] = 0;
1087 if (nPathLen + nFileLen >= MAX_PATH)
1088 return sal_False;
1090 /* append file name */
1091 wcscpy(wcsPath + nPathLen, wcsFile);
1092 nPathLen += nFileLen;
1094 /* copy filename */
1095 rtl_uString_newFromStr_WithLength(&strTmp, wcsPath, nPathLen);
1096 nError = osl_getFileURLFromSystemPath(strTmp, strProfileName);
1097 rtl_uString_release(strTmp);
1099 return (sal_Bool) (nError == osl_File_E_None);
1103 sal_uInt32 SAL_CALL osl_getProfileSections(oslProfile Profile, sal_Char* pszBuffer, sal_uInt32 MaxLen)
1105 sal_uInt32 i, n = 0;
1106 osl_TProfileSection* pSec;
1107 osl_TProfileImpl* pProfile = acquireProfile(Profile, sal_False);
1109 if (pProfile == NULL)
1110 return (0);
1112 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
1114 if (MaxLen != 0)
1116 for (i = 0; i < pProfile->m_NoSections; i++)
1118 pSec = &pProfile->m_Sections[i];
1120 if ((n + pSec->m_Len + 1) < MaxLen)
1122 strncpy(&pszBuffer[n], &pProfile->m_Lines[pSec->m_Line][pSec->m_Offset],
1123 pSec->m_Len);
1124 n += pSec->m_Len;
1125 pszBuffer[n++] = '\0';
1127 else
1128 break;
1131 pszBuffer[n++] = '\0';
1133 else
1135 for (i = 0; i < pProfile->m_NoSections; i++)
1136 n += pProfile->m_Sections[i].m_Len + 1;
1138 n += 1;
1141 else
1143 CHAR szFileName[MAX_PATH];
1145 WideCharToMultiByte(CP_ACP,0, pProfile->m_strFileName->buffer, -1, szFileName, MAX_PATH, NULL, NULL);
1146 n = GetPrivateProfileSectionNames(pszBuffer, MaxLen, szFileName);
1149 releaseProfile(pProfile);
1151 return (n);
1186 /*****************************************************************************/
1187 /* Static Module Functions */
1188 /*****************************************************************************/
1190 static osl_TStamp getFileStamp(osl_TFile* pFile)
1192 FILETIME FileTime;
1194 if ((pFile->m_Handle == INVALID_HANDLE_VALUE) ||
1195 (! GetFileTime(pFile->m_Handle, NULL, NULL, &FileTime)))
1196 memset(&FileTime, 0, sizeof(FileTime));
1198 return (FileTime);
1203 static sal_Bool lockFile(const osl_TFile* pFile, osl_TLockMode eMode)
1205 sal_Bool status = sal_False;
1206 OVERLAPPED Overlapped;
1208 if (pFile->m_Handle == INVALID_HANDLE_VALUE)
1209 return (sal_False);
1211 memset(&Overlapped, 0, sizeof(Overlapped));
1213 switch (eMode)
1215 case un_lock:
1216 status = (sal_Bool) UnlockFileEx(
1217 pFile->m_Handle, 0, 0xFFFFFFFF, 0, &Overlapped);
1218 break;
1220 case read_lock:
1221 status = (sal_Bool) LockFileEx(
1222 pFile->m_Handle, 0, 0, 0xFFFFFFFF, 0, &Overlapped);
1223 break;
1225 case write_lock:
1226 status = (sal_Bool) LockFileEx(
1227 pFile->m_Handle, LOCKFILE_EXCLUSIVE_LOCK, 0, 0xFFFFFFFF, 0,
1228 &Overlapped);
1229 break;
1232 return (status);
1288 static osl_TFile* openFileImpl(rtl_uString * strFileName, oslProfileOption ProfileFlags )
1290 osl_TFile* pFile = calloc(1, sizeof(osl_TFile));
1291 sal_Bool bWriteable = sal_False;
1293 /* if ( ProfileFlags & ( osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE | osl_Profile_READWRITE ) )*/
1294 if ( ProfileFlags & ( osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE ) )
1296 #ifdef DEBUG_OSL_PROFILE
1297 OSL_TRACE("setting bWriteable to TRUE\n");
1298 #endif
1299 bWriteable=sal_True;
1302 if (! bWriteable)
1304 #if 0
1305 //#ifdef DEBUG_OSL_PROFILE
1306 OSL_TRACE("opening '%s' read only\n",pszFilename);
1307 #endif
1309 pFile->m_Handle = CreateFileW( rtl_uString_getStr( strFileName ), GENERIC_READ,
1310 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1311 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1313 /* mfe: argghh!!! do not check if the file could be openend */
1314 /* default mode expects it that way!!! */
1316 else
1318 #ifdef DEBUG_OSL_PROFILE
1319 OSL_TRACE("opening '%s' read/write\n",pszFilename);
1320 #endif
1322 if ((pFile->m_Handle = CreateFileW( rtl_uString_getStr( strFileName ), GENERIC_READ | GENERIC_WRITE,
1323 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1324 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL))
1325 == INVALID_HANDLE_VALUE)
1327 free(pFile);
1328 return (NULL);
1332 pFile->m_pWriteBuf=0;
1333 pFile->m_nWriteBufFree=0;
1334 pFile->m_nWriteBufLen=0;
1336 if ( ProfileFlags & (osl_Profile_WRITELOCK | osl_Profile_READLOCK ) )
1338 #ifdef DEBUG_OSL_PROFILE
1339 OSL_TRACE("locking '%s' file\n",pszFilename);
1340 #endif
1342 lockFile(pFile, bWriteable ? write_lock : read_lock);
1345 /* mfe: new WriteBuf obsolete */
1346 /* pFile->m_pWritePtr = pFile->m_Buf;*/
1347 /* pFile->m_pReadPtr = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);*/
1349 return (pFile);
1360 static osl_TStamp closeFileImpl(osl_TFile* pFile)
1362 osl_TStamp stamp = {0, 0};
1364 if ( pFile == 0 )
1366 return stamp;
1369 if (pFile->m_Handle != INVALID_HANDLE_VALUE)
1371 /* mfe: new WriteBuf obsolete */
1372 /* we just closing the file here, DO NOT write, it has to be handled in higher levels */
1373 /* if (pFile->m_pWritePtr > pFile->m_Buf)*/
1374 /* {*/
1375 /* DWORD Bytes;*/
1377 /* WriteFile(pFile->m_Handle, pFile->m_WriteBuf,*/
1378 /* pFile->m_pWritePtr - pFile->m_WriteBuf,*/
1379 /* &Bytes, NULL);*/
1380 /* }*/
1382 stamp = getFileStamp(pFile);
1384 lockFile(pFile, un_lock);
1386 CloseHandle(pFile->m_Handle);
1387 pFile->m_Handle = INVALID_HANDLE_VALUE;
1390 if ( pFile->m_pWriteBuf != 0 )
1392 free(pFile->m_pWriteBuf);
1395 free(pFile);
1397 return(stamp);
1407 static sal_Bool rewindFile(osl_TFile* pFile, sal_Bool bTruncate)
1409 if (pFile->m_Handle != INVALID_HANDLE_VALUE)
1411 /* mfe: new WriteBuf obsolete */
1412 /* we just closing the file here, DO NOT write, it has to be handled in higher levels */
1413 /* if (pFile->m_pWritePtr > pFile->m_WriteBuf)*/
1414 /* {*/
1415 /* DWORD Bytes;*/
1417 /* WriteFile(pFile->m_Handle, pFile->m_WriteBuf,*/
1418 /* pFile->m_pWritePtr - pFile->m_WriteBuf,*/
1419 /* &Bytes, NULL);*/
1421 /* pFile->m_pWritePtr = pFile->m_WriteBuf;*/
1422 /* }*/
1424 pFile->m_pReadPtr = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);
1426 SetFilePointer(pFile->m_Handle, 0, NULL, FILE_BEGIN);
1428 if (bTruncate)
1429 SetEndOfFile(pFile->m_Handle);
1432 return (sal_True);
1444 static sal_Bool getLine(osl_TFile* pFile, const sal_Char *pszLine, int MaxLen)
1446 DWORD Max;
1447 size_t Free, Bytes;
1448 sal_Char* pChr;
1449 sal_Char* pLine = (sal_Char *)pszLine;
1451 if (pFile->m_Handle == INVALID_HANDLE_VALUE)
1452 return (sal_False);
1454 MaxLen -= 1;
1458 Bytes = sizeof(pFile->m_ReadBuf) - (pFile->m_pReadPtr - pFile->m_ReadBuf);
1460 if (Bytes <= 1)
1462 /* refill buffer */
1463 memcpy(pFile->m_ReadBuf, pFile->m_pReadPtr, Bytes);
1464 pFile->m_pReadPtr = pFile->m_ReadBuf;
1466 Free = sizeof(pFile->m_ReadBuf) - Bytes;
1468 if (! ReadFile(pFile->m_Handle, &pFile->m_ReadBuf[Bytes], Free, &Max, NULL))
1470 *pLine = '\0';
1471 return (sal_False);
1474 if (Max < Free)
1476 if ((Max == 0) && (pLine == pszLine))
1478 *pLine = '\0';
1479 return (sal_False);
1482 pFile->m_ReadBuf[Bytes + Max] = '\0';
1486 for (pChr = pFile->m_pReadPtr;
1487 (*pChr != '\n') && (*pChr != '\r') && (*pChr != '\0') &&
1488 (pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf) - 1));
1489 pChr++);
1491 Max = min(pChr - pFile->m_pReadPtr, MaxLen);
1492 memcpy(pLine, pFile->m_pReadPtr, Max);
1493 MaxLen -= Max;
1494 pLine += Max;
1496 if (pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf) - 1))
1498 if (*pChr != '\0')
1500 if ((pChr[0] == '\r') && (pChr[1] == '\n'))
1501 pChr += 2;
1502 else
1503 pChr += 1;
1506 if ((pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf))) &&
1507 (*pChr == '\0'))
1508 pChr = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);
1510 *pLine = '\0';
1512 /* setting MaxLen to -1 indicates terminating read loop */
1513 MaxLen = -1;
1516 pFile->m_pReadPtr = pChr;
1518 while (MaxLen > 0);
1520 return (sal_True);
1532 static sal_Bool putLine(osl_TFile* pFile, const sal_Char *pszLine)
1534 unsigned int Len = strlen(pszLine);
1536 #ifdef DEBUG_OSL_PROFILE
1537 int strLen=0;
1538 #endif
1540 if ( pFile == 0 || pFile->m_Handle < 0 )
1542 return (sal_False);
1545 if ( pFile->m_pWriteBuf == 0 )
1547 pFile->m_pWriteBuf = (sal_Char*) malloc(Len+3);
1548 pFile->m_nWriteBufLen = Len+3;
1549 pFile->m_nWriteBufFree = Len+3;
1551 else
1553 if ( pFile->m_nWriteBufFree <= Len + 3 )
1555 sal_Char* pTmp;
1557 pTmp=(sal_Char*) realloc(pFile->m_pWriteBuf,( ( pFile->m_nWriteBufLen + Len ) * 2) );
1558 if ( pTmp == 0 )
1560 return sal_False;
1562 pFile->m_pWriteBuf = pTmp;
1563 pFile->m_nWriteBufFree = pFile->m_nWriteBufFree + pFile->m_nWriteBufLen + ( 2 * Len );
1564 pFile->m_nWriteBufLen = ( pFile->m_nWriteBufLen + Len ) * 2;
1565 memset( (pFile->m_pWriteBuf) + ( pFile->m_nWriteBufLen - pFile->m_nWriteBufFree ), 0, pFile->m_nWriteBufFree);
1571 memcpy(pFile->m_pWriteBuf + ( pFile->m_nWriteBufLen - pFile->m_nWriteBufFree ),pszLine,Len+1);
1572 #ifdef DEBUG_OSL_PROFILE
1573 strLen = strlen(pFile->m_pWriteBuf);
1574 #endif
1575 pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len]='\r';
1576 pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len + 1]='\n';
1577 pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len + 2]='\0';
1579 pFile->m_nWriteBufFree-=Len+2;
1581 #ifdef DEBUG_OSL_PROFILE
1582 /* OSL_TRACE("File Buffer in _putLine '%s' '%i'(%i)\n",pFile->m_pWriteBuf,strlen(pFile->m_pWriteBuf),pFile->m_nWriteBufLen - pFile->m_nWriteBufFree);*/
1583 #endif
1585 return (sal_True);
1588 /* platform specific end */
1591 static const sal_Char* stripBlanks(const sal_Char* String, sal_uInt32* pLen)
1593 if ( (pLen != NULL) && ( *pLen != 0 ) )
1595 while ((String[*pLen - 1] == ' ') || (String[*pLen - 1] == '\t'))
1596 (*pLen)--;
1598 while ((*String == ' ') || (*String == '\t'))
1600 String++;
1601 (*pLen)--;
1604 else
1605 while ((*String == ' ') || (*String == '\t'))
1606 String++;
1608 return (String);
1611 static const sal_Char* addLine(osl_TProfileImpl* pProfile, const sal_Char* Line)
1613 if (pProfile->m_NoLines >= pProfile->m_MaxLines)
1615 if (pProfile->m_Lines == NULL)
1617 pProfile->m_MaxLines = LINES_INI;
1618 pProfile->m_Lines = (sal_Char **)malloc(pProfile->m_MaxLines * sizeof(sal_Char *));
1619 memset(pProfile->m_Lines,0,pProfile->m_MaxLines * sizeof(sal_Char *));
1621 else
1623 unsigned int index=0;
1624 unsigned int oldmax=pProfile->m_MaxLines;
1626 pProfile->m_MaxLines += LINES_ADD;
1627 pProfile->m_Lines = (sal_Char **)realloc(pProfile->m_Lines, pProfile->m_MaxLines * sizeof(sal_Char *));
1629 for ( index = oldmax ; index < pProfile->m_MaxLines ; ++index )
1631 pProfile->m_Lines[index]=0;
1635 if (pProfile->m_Lines == NULL)
1637 pProfile->m_NoLines = 0;
1638 pProfile->m_MaxLines = 0;
1639 return (NULL);
1644 if ( pProfile->m_Lines != 0 && pProfile->m_Lines[pProfile->m_NoLines] != 0 )
1646 free(pProfile->m_Lines[pProfile->m_NoLines]);
1648 pProfile->m_Lines[pProfile->m_NoLines++] = strdup(Line);
1650 return (pProfile->m_Lines[pProfile->m_NoLines - 1]);
1653 static const sal_Char* insertLine(osl_TProfileImpl* pProfile, const sal_Char* Line, sal_uInt32 LineNo)
1655 if (pProfile->m_NoLines >= pProfile->m_MaxLines)
1657 if (pProfile->m_Lines == NULL)
1659 pProfile->m_MaxLines = LINES_INI;
1660 pProfile->m_Lines = (sal_Char **)malloc(pProfile->m_MaxLines * sizeof(sal_Char *));
1661 memset(pProfile->m_Lines,0,pProfile->m_MaxLines * sizeof(sal_Char *));
1663 else
1665 pProfile->m_MaxLines += LINES_ADD;
1666 pProfile->m_Lines = (sal_Char **)realloc(pProfile->m_Lines,
1667 pProfile->m_MaxLines * sizeof(sal_Char *));
1669 memset(&pProfile->m_Lines[pProfile->m_NoLines],
1671 (pProfile->m_MaxLines - pProfile->m_NoLines - 1) * sizeof(sal_Char*));
1674 if (pProfile->m_Lines == NULL)
1676 pProfile->m_NoLines = 0;
1677 pProfile->m_MaxLines = 0;
1678 return (NULL);
1682 LineNo = LineNo > pProfile->m_NoLines ? pProfile->m_NoLines : LineNo;
1684 if (LineNo < pProfile->m_NoLines)
1686 sal_uInt32 i, n;
1687 osl_TProfileSection* pSec;
1689 memmove(&pProfile->m_Lines[LineNo + 1], &pProfile->m_Lines[LineNo],
1690 (pProfile->m_NoLines - LineNo) * sizeof(sal_Char *));
1693 /* adjust line references */
1694 for (i = 0; i < pProfile->m_NoSections; i++)
1696 pSec = &pProfile->m_Sections[i];
1698 if (pSec->m_Line >= LineNo)
1699 pSec->m_Line++;
1701 for (n = 0; n < pSec->m_NoEntries; n++)
1702 if (pSec->m_Entries[n].m_Line >= LineNo)
1703 pSec->m_Entries[n].m_Line++;
1707 pProfile->m_NoLines++;
1709 pProfile->m_Lines[LineNo] = strdup(Line);
1711 return (pProfile->m_Lines[LineNo]);
1714 static void removeLine(osl_TProfileImpl* pProfile, sal_uInt32 LineNo)
1716 if (LineNo < pProfile->m_NoLines)
1718 free(pProfile->m_Lines[LineNo]);
1719 pProfile->m_Lines[LineNo]=0;
1720 if (pProfile->m_NoLines - LineNo > 1)
1722 sal_uInt32 i, n;
1723 osl_TProfileSection* pSec;
1725 memmove(&pProfile->m_Lines[LineNo], &pProfile->m_Lines[LineNo + 1],
1726 (pProfile->m_NoLines - LineNo - 1) * sizeof(sal_Char *));
1728 memset(&pProfile->m_Lines[pProfile->m_NoLines - 1],
1730 (pProfile->m_MaxLines - pProfile->m_NoLines) * sizeof(sal_Char*));
1732 /* adjust line references */
1733 for (i = 0; i < pProfile->m_NoSections; i++)
1735 pSec = &pProfile->m_Sections[i];
1737 if (pSec->m_Line > LineNo)
1738 pSec->m_Line--;
1740 for (n = 0; n < pSec->m_NoEntries; n++)
1741 if (pSec->m_Entries[n].m_Line > LineNo)
1742 pSec->m_Entries[n].m_Line--;
1745 else
1747 pProfile->m_Lines[LineNo] = 0;
1750 pProfile->m_NoLines--;
1753 return;
1756 static void setEntry(osl_TProfileImpl* pProfile, osl_TProfileSection* pSection,
1757 sal_uInt32 NoEntry, sal_uInt32 Line,
1758 const sal_Char* Entry, sal_uInt32 Len)
1760 Entry = stripBlanks(Entry, &Len);
1761 pSection->m_Entries[NoEntry].m_Line = Line;
1762 pSection->m_Entries[NoEntry].m_Offset = Entry - pProfile->m_Lines[Line];
1763 pSection->m_Entries[NoEntry].m_Len = Len;
1765 return;
1768 static sal_Bool addEntry(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection,
1769 int Line, const sal_Char* Entry, sal_uInt32 Len)
1771 if (pSection != NULL)
1773 if (pSection->m_NoEntries >= pSection->m_MaxEntries)
1775 if (pSection->m_Entries == NULL)
1777 pSection->m_MaxEntries = ENTRIES_INI;
1778 pSection->m_Entries = (osl_TProfileEntry *)malloc(
1779 pSection->m_MaxEntries * sizeof(osl_TProfileEntry));
1781 else
1783 pSection->m_MaxEntries += ENTRIES_ADD;
1784 pSection->m_Entries = (osl_TProfileEntry *)realloc(pSection->m_Entries,
1785 pSection->m_MaxEntries * sizeof(osl_TProfileEntry));
1788 if (pSection->m_Entries == NULL)
1790 pSection->m_NoEntries = 0;
1791 pSection->m_MaxEntries = 0;
1792 return (sal_False);
1796 pSection->m_NoEntries++;
1798 Entry = stripBlanks(Entry, &Len);
1799 setEntry(pProfile, pSection, pSection->m_NoEntries - 1, Line,
1800 Entry, Len);
1802 return (sal_True);
1805 return (sal_False);
1808 static void removeEntry(osl_TProfileSection *pSection, sal_uInt32 NoEntry)
1810 if (NoEntry < pSection->m_NoEntries)
1812 if (pSection->m_NoEntries - NoEntry > 1)
1814 memmove(&pSection->m_Entries[NoEntry],
1815 &pSection->m_Entries[NoEntry + 1],
1816 (pSection->m_NoEntries - NoEntry - 1) * sizeof(osl_TProfileEntry));
1817 pSection->m_Entries[pSection->m_NoEntries - 1].m_Line=0;
1818 pSection->m_Entries[pSection->m_NoEntries - 1].m_Offset=0;
1819 pSection->m_Entries[pSection->m_NoEntries - 1].m_Len=0;
1822 pSection->m_NoEntries--;
1825 return;
1828 static sal_Bool addSection(osl_TProfileImpl* pProfile, int Line, const sal_Char* Section, sal_uInt32 Len)
1830 if (pProfile->m_NoSections >= pProfile->m_MaxSections)
1832 if (pProfile->m_Sections == NULL)
1834 pProfile->m_MaxSections = SECTIONS_INI;
1835 pProfile->m_Sections = (osl_TProfileSection *)malloc(pProfile->m_MaxSections * sizeof(osl_TProfileSection));
1836 memset(pProfile->m_Sections,0,pProfile->m_MaxSections * sizeof(osl_TProfileSection));
1838 else
1840 unsigned int index=0;
1841 unsigned int oldmax=pProfile->m_MaxSections;
1843 pProfile->m_MaxSections += SECTIONS_ADD;
1844 pProfile->m_Sections = (osl_TProfileSection *)realloc(pProfile->m_Sections,
1845 pProfile->m_MaxSections * sizeof(osl_TProfileSection));
1846 for ( index = oldmax ; index < pProfile->m_MaxSections ; ++index )
1848 pProfile->m_Sections[index].m_Entries=0;
1852 if (pProfile->m_Sections == NULL)
1854 pProfile->m_NoSections = 0;
1855 pProfile->m_MaxSections = 0;
1856 return (sal_False);
1860 pProfile->m_NoSections++;
1862 if ( pProfile->m_Sections[(pProfile->m_NoSections) - 1].m_Entries != 0 )
1864 free(pProfile->m_Sections[(pProfile->m_NoSections) - 1].m_Entries);
1866 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Entries = NULL;
1867 pProfile->m_Sections[pProfile->m_NoSections - 1].m_NoEntries = 0;
1868 pProfile->m_Sections[pProfile->m_NoSections - 1].m_MaxEntries = 0;
1870 Section = (sal_Char *)stripBlanks(Section, &Len);
1871 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Line = Line;
1872 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Offset = Section - pProfile->m_Lines[Line];
1873 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Len = Len;
1875 return (sal_True);
1878 static void removeSection(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection)
1880 sal_uInt32 Section;
1882 if ((Section = pSection - pProfile->m_Sections) < pProfile->m_NoSections)
1884 free (pSection->m_Entries);
1885 pSection->m_Entries=0;
1886 if (pProfile->m_NoSections - Section > 1)
1888 memmove(&pProfile->m_Sections[Section], &pProfile->m_Sections[Section + 1],
1889 (pProfile->m_NoSections - Section - 1) * sizeof(osl_TProfileSection));
1891 memset(&pProfile->m_Sections[pProfile->m_NoSections - 1],
1893 (pProfile->m_MaxSections - pProfile->m_NoSections) * sizeof(osl_TProfileSection));
1894 pProfile->m_Sections[pProfile->m_NoSections - 1].m_Entries = 0;
1896 else
1898 pSection->m_Entries = 0;
1901 pProfile->m_NoSections--;
1904 return;
1907 static osl_TProfileSection* findEntry(osl_TProfileImpl* pProfile, const sal_Char* Section,
1908 const sal_Char* Entry, sal_uInt32 *pNoEntry)
1910 static sal_uInt32 Sect = 0;
1911 sal_uInt32 i, n;
1912 sal_uInt32 Len;
1913 const sal_Char* pStr;
1914 osl_TProfileSection* pSec = NULL;
1916 Len = strlen(Section);
1917 Section = (sal_Char *)stripBlanks(Section, &Len);
1919 n = Sect;
1921 for (i = 0; i < pProfile->m_NoSections; i++)
1923 n %= pProfile->m_NoSections;
1924 pSec = &pProfile->m_Sections[n];
1925 if ((Len == pSec->m_Len) &&
1926 (strnicmp(Section, &pProfile->m_Lines[pSec->m_Line][pSec->m_Offset], pSec->m_Len)
1927 == 0))
1928 break;
1929 n++;
1932 Sect = n;
1934 if (i < pProfile->m_NoSections)
1936 Len = strlen(Entry);
1937 Entry = stripBlanks(Entry, &Len);
1939 *pNoEntry = pSec->m_NoEntries;
1941 for (i = 0; i < pSec->m_NoEntries; i++)
1943 pStr = &pProfile->m_Lines[pSec->m_Entries[i].m_Line]
1944 [pSec->m_Entries[i].m_Offset];
1945 if ((Len == pSec->m_Entries[i].m_Len) &&
1946 (strnicmp(Entry, pStr, pSec->m_Entries[i].m_Len)
1947 == 0))
1949 *pNoEntry = i;
1950 break;
1954 else
1955 pSec = NULL;
1957 return (pSec);
1960 static sal_Bool loadProfile(osl_TFile* pFile, osl_TProfileImpl* pProfile)
1962 sal_uInt32 i;
1963 sal_Char* pStr;
1964 sal_Char* pChar;
1965 sal_Char Line[4096];
1967 pProfile->m_NoLines = 0;
1968 pProfile->m_NoSections = 0;
1970 OSL_VERIFY(rewindFile(pFile, sal_False));
1972 while (getLine(pFile, Line, sizeof(Line)))
1974 if (! addLine(pProfile, Line))
1975 return (sal_False);
1978 for (i = 0; i < pProfile->m_NoLines; i++)
1980 pStr = (sal_Char *)stripBlanks(pProfile->m_Lines[i], NULL);
1982 if ((*pStr == '\0') || (*pStr == ';'))
1983 continue;
1985 if ((*pStr != '[') || ((pChar = strrchr(pStr, ']')) == NULL) ||
1986 ((pChar - pStr) <= 2))
1988 /* insert entry */
1990 if (pProfile->m_NoSections < 1)
1991 continue;
1993 if ((pChar = strchr(pStr, '=')) == NULL)
1994 pChar = pStr + strlen(pStr);
1996 if (! addEntry(pProfile, &pProfile->m_Sections[pProfile->m_NoSections - 1],
1997 i, pStr, pChar - pStr))
1998 return (sal_False);
2000 else
2002 /* new section */
2004 if (! addSection(pProfile, i, pStr + 1, pChar - pStr - 1))
2005 return (sal_False);
2009 return (sal_True);
2016 static sal_Bool storeProfile(osl_TProfileImpl* pProfile, sal_Bool bCleanup)
2018 #ifdef TRACE_OSL_PROFILE
2019 OSL_TRACE("In storeProfile\n");
2020 #endif
2022 if (pProfile->m_Lines != NULL)
2024 if (pProfile->m_Flags & FLG_MODIFIED)
2026 sal_uInt32 i;
2028 osl_TFile* pTmpFile = osl_openTmpProfileImpl(pProfile);
2030 if ( pTmpFile == 0 )
2032 return sal_False;
2035 OSL_VERIFY(rewindFile(pTmpFile, sal_True));
2037 for (i = 0; i < pProfile->m_NoLines; i++)
2039 OSL_VERIFY(putLine(pTmpFile, pProfile->m_Lines[i]));
2042 if ( ! writeProfileImpl(pTmpFile) )
2044 if ( pTmpFile->m_pWriteBuf != 0 )
2046 free(pTmpFile->m_pWriteBuf);
2049 pTmpFile->m_pWriteBuf=0;
2050 pTmpFile->m_nWriteBufLen=0;
2051 pTmpFile->m_nWriteBufFree=0;
2053 #ifdef TRACE_OSL_PROFILE
2054 OSL_TRACE("Out storeProfile [not flushed]\n");
2055 #endif
2056 closeFileImpl(pTmpFile);
2058 return sal_False;
2061 pProfile->m_Flags &= ~FLG_MODIFIED;
2063 closeFileImpl(pProfile->m_pFile);
2064 closeFileImpl(pTmpFile);
2066 osl_ProfileSwapProfileNames(pProfile);
2068 /* free(pProfile->m_pFile);*/
2069 /* free(pTmpFile);*/
2071 pProfile->m_pFile = openFileImpl(pProfile->m_strFileName,pProfile->m_Flags);
2075 if (bCleanup)
2077 while (pProfile->m_NoLines > 0)
2078 removeLine(pProfile, pProfile->m_NoLines - 1);
2080 free(pProfile->m_Lines);
2081 pProfile->m_Lines = NULL;
2082 pProfile->m_MaxLines = 0;
2084 while (pProfile->m_NoSections > 0)
2085 removeSection(pProfile, &pProfile->m_Sections[pProfile->m_NoSections - 1]);
2087 free(pProfile->m_Sections);
2088 pProfile->m_Sections = NULL;
2089 pProfile->m_MaxSections = 0;
2093 #ifdef TRACE_OSL_PROFILE
2094 OSL_TRACE("Out storeProfile [ok]\n");
2095 #endif
2096 return (sal_True);
2100 static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl* pProfile)
2102 osl_TFile* pFile=0;
2103 rtl_uString* ustrExtension=0;
2104 rtl_uString* ustrTmpName=0;
2105 oslProfileOption PFlags=0;
2107 rtl_uString_newFromAscii(&ustrExtension,"tmp");
2110 /* generate tmp profilename */
2111 ustrTmpName=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
2112 rtl_uString_release(ustrExtension);
2114 if ( ustrTmpName == 0 )
2116 return 0;
2120 if ( ! ( pProfile->m_Flags & osl_Profile_READLOCK ) )
2122 PFlags |= osl_Profile_WRITELOCK;
2125 /* open this file */
2126 pFile = openFileImpl(ustrTmpName,pProfile->m_Flags | PFlags);
2129 /* return new pFile */
2130 return pFile;
2134 static sal_Bool osl_ProfileSwapProfileNames(osl_TProfileImpl* pProfile)
2136 sal_Bool bRet = sal_False;
2138 rtl_uString* ustrBakFile=0;
2139 rtl_uString* ustrTmpFile=0;
2140 rtl_uString* ustrIniFile=0;
2141 rtl_uString* ustrExtension=0;
2144 rtl_uString_newFromAscii(&ustrExtension,"bak");
2146 ustrBakFile=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
2147 rtl_uString_release(ustrExtension);
2148 ustrExtension=0;
2151 rtl_uString_newFromAscii(&ustrExtension,"ini");
2153 ustrIniFile=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
2154 rtl_uString_release(ustrExtension);
2155 ustrExtension=0;
2158 rtl_uString_newFromAscii(&ustrExtension,"tmp");
2160 ustrTmpFile=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
2161 rtl_uString_release(ustrExtension);
2162 ustrExtension=0;
2165 /* unlink bak */
2166 DeleteFileW( rtl_uString_getStr( ustrBakFile ) );
2168 /* rename ini bak */
2169 MoveFileExW( rtl_uString_getStr( ustrIniFile ), rtl_uString_getStr( ustrBakFile ), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH );
2171 /* rename tmp ini */
2172 MoveFileExW( rtl_uString_getStr( ustrTmpFile ), rtl_uString_getStr( ustrIniFile ), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH );
2174 return bRet;
2178 static rtl_uString* osl_ProfileGenerateExtension(rtl_uString* ustrFileName, rtl_uString* ustrExtension)
2180 rtl_uString* ustrNewFileName=0;
2181 rtl_uString* ustrOldExtension = 0;
2182 sal_Unicode* pExtensionBuf = 0;
2183 sal_Unicode* pFileNameBuf = 0;
2184 sal_Int32 nIndex = -1;
2186 pFileNameBuf = rtl_uString_getStr(ustrFileName);
2188 rtl_uString_newFromAscii(&ustrOldExtension,".");
2190 pExtensionBuf = rtl_uString_getStr(ustrOldExtension);
2192 nIndex = rtl_ustr_lastIndexOfChar(pFileNameBuf,*pExtensionBuf);
2194 rtl_uString_newReplaceStrAt(&ustrNewFileName,
2195 ustrFileName,
2196 nIndex+1,
2198 ustrExtension);
2200 return ustrNewFileName;
2204 static osl_TProfileImpl* acquireProfile(oslProfile Profile, sal_Bool bWriteable)
2206 osl_TProfileImpl* pProfile = (osl_TProfileImpl*)Profile;
2207 oslProfileOption PFlags=0;
2210 if ( bWriteable )
2212 /* PFlags = osl_Profile_DEFAULT | osl_Profile_READWRITE; */
2213 PFlags = osl_Profile_DEFAULT | osl_Profile_WRITELOCK;
2215 else
2217 PFlags = osl_Profile_DEFAULT;
2221 if (pProfile == NULL)
2223 #ifdef DEBUG_OSL_PROFILE
2224 OSL_TRACE("AUTOOPEN MODE\n");
2225 #endif
2229 if ((pProfile = osl_openProfile(NULL, PFlags)) != NULL )
2231 pProfile->m_Flags |= FLG_AUTOOPEN;
2234 else
2236 #ifdef DEBUG_OSL_PROFILE
2237 OSL_TRACE("try to acquire\n");
2238 #endif
2242 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
2244 if (! (pProfile->m_Flags & (osl_Profile_READLOCK |
2245 osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE)))
2247 osl_TStamp Stamp;
2248 #ifdef DEBUG_OSL_PROFILE
2249 OSL_TRACE("DEFAULT MODE\n");
2250 #endif
2251 pProfile->m_pFile = openFileImpl(
2252 pProfile->m_strFileName, pProfile->m_Flags | PFlags);
2253 if (!pProfile->m_pFile)
2254 return NULL;
2256 Stamp = getFileStamp(pProfile->m_pFile);
2258 if (memcmp(&Stamp, &(pProfile->m_Stamp), sizeof(osl_TStamp)))
2260 pProfile->m_Stamp = Stamp;
2262 loadProfile(pProfile->m_pFile, pProfile);
2265 else
2267 #ifdef DEBUG_OSL_PROFILE
2268 OSL_TRACE("READ/WRITELOCK MODE\n");
2269 #endif
2272 /* A readlock file could not be written */
2273 if ((pProfile->m_Flags & osl_Profile_READLOCK) && bWriteable)
2275 return (NULL);
2281 return (pProfile);
2284 static sal_Bool releaseProfile(osl_TProfileImpl* pProfile)
2286 #ifdef TRACE_OSL_PROFILE
2287 OSL_TRACE("In releaseProfile\n");
2288 #endif
2290 if ( pProfile == 0 )
2292 #ifdef TRACE_OSL_PROFILE
2293 OSL_TRACE("Out releaseProfile [profile==0]\n");
2294 #endif
2295 return sal_False;
2298 if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
2300 if (pProfile->m_Flags & FLG_AUTOOPEN)
2302 #ifdef TRACE_OSL_PROFILE
2303 OSL_TRACE("Out releaseProfile [AUTOOPEN]\n");
2304 #endif
2305 return (osl_closeProfile((oslProfile)pProfile));
2307 else
2309 #ifdef DEBUG_OSL_PROFILE
2310 OSL_TRACE("DEFAULT MODE\n");
2311 #endif
2312 if (! (pProfile->m_Flags & (osl_Profile_READLOCK |
2313 osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE)))
2315 if (pProfile->m_Flags & FLG_MODIFIED)
2316 storeProfile(pProfile, sal_False);
2318 closeFileImpl(pProfile->m_pFile);
2319 pProfile->m_pFile = NULL;
2324 #ifdef TRACE_OSL_PROFILE
2325 OSL_TRACE("Out releaseProfile [ok]\n");
2326 #endif
2327 return (sal_True);
2330 static sal_Bool lookupProfile(const sal_Unicode *strPath, const sal_Unicode *strFile, sal_Unicode *strProfile)
2332 sal_Char *pChr, *pStr;
2333 sal_Char Buffer[4096] = "";
2334 sal_Char Product[132] = "";
2336 WCHAR wcsPath[MAX_PATH] = L"";
2337 DWORD dwPathLen = 0;
2339 if (*strPath == L'"')
2341 int i = 0;
2343 strPath++;
2345 while ((strPath[i] != L'"') && (strPath[i] != L'\0'))
2346 i++;
2348 WideCharToMultiByte(CP_ACP,0, strPath, i, Product, sizeof(Product), NULL, NULL);
2349 Product[i] = '\0';
2350 strPath += i;
2352 if (*strPath == L'"')
2353 strPath++;
2355 if ( (*strPath == L'/') || (*strPath == L'\\') )
2357 strPath++;
2361 else
2363 /* if we have not product identfication, do a special handling for soffice.ini */
2364 if (rtl_ustr_ascii_compare(strFile, SVERSION_PROFILE) == 0)
2366 rtl_uString * strSVProfile = NULL;
2367 rtl_uString * strSVFallback = NULL;
2368 rtl_uString * strSVLocation = NULL;
2369 rtl_uString * strSVName = NULL;
2370 sal_Char Dir[MAX_PATH];
2371 oslProfile hProfile;
2373 rtl_uString_newFromAscii(&strSVFallback, SVERSION_FALLBACK);
2374 rtl_uString_newFromAscii(&strSVLocation, SVERSION_LOCATION);
2375 rtl_uString_newFromAscii(&strSVName, SVERSION_NAME);
2377 /* open sversion.ini in the system directory, and try to locate the entry
2378 with the highest version for StarOffice */
2379 if (osl_getProfileName( strSVFallback, strSVName, &strSVProfile))
2381 hProfile = osl_openProfile(strSVProfile, osl_Profile_READLOCK);
2382 if (hProfile)
2384 osl_getProfileSectionEntries(
2385 hProfile, SVERSION_SECTION, Buffer, sizeof(Buffer));
2387 for (pChr = Buffer; *pChr != '\0'; pChr += strlen(pChr) + 1)
2389 if ((strnicmp(
2390 pChr, SVERSION_SOFFICE,
2391 sizeof(SVERSION_SOFFICE) - 1)
2392 == 0)
2393 && (stricmp(Product, pChr) < 0))
2395 osl_readProfileString(
2396 hProfile, SVERSION_SECTION, pChr, Dir,
2397 sizeof(Dir), "");
2399 /* check for existence of path */
2400 if (access(Dir, 0) >= 0)
2401 strcpy(Product, pChr);
2405 osl_closeProfile(hProfile);
2407 rtl_uString_release(strSVProfile);
2408 strSVProfile = NULL;
2411 /* open sversion.ini in the users directory, and try to locate the entry
2412 with the highest version for StarOffice */
2413 if ((strcmp(SVERSION_LOCATION, SVERSION_FALLBACK) != 0) &&
2414 (osl_getProfileName(strSVLocation, strSVName, &strSVProfile)))
2416 hProfile = osl_openProfile(strSVProfile, osl_Profile_READLOCK);
2417 if (hProfile)
2419 osl_getProfileSectionEntries(
2420 hProfile, SVERSION_SECTION, Buffer, sizeof(Buffer));
2422 for (pChr = Buffer; *pChr != '\0'; pChr += strlen(pChr) + 1)
2424 if ((strnicmp(
2425 pChr, SVERSION_SOFFICE,
2426 sizeof(SVERSION_SOFFICE) - 1)
2427 == 0)
2428 && (stricmp(Product, pChr) < 0))
2430 osl_readProfileString(
2431 hProfile, SVERSION_SECTION, pChr, Dir,
2432 sizeof(Dir), "");
2434 /* check for existence of path */
2435 if (access(Dir, 0) >= 0)
2436 strcpy(Product, pChr);
2440 osl_closeProfile(hProfile);
2442 rtl_uString_release(strSVProfile);
2445 rtl_uString_release(strSVFallback);
2446 rtl_uString_release(strSVLocation);
2447 rtl_uString_release(strSVName);
2449 /* remove any trailing build number */
2450 if ((pChr = strrchr(Product, '/')) != NULL)
2451 *pChr = '\0';
2455 /* if we have an userid option eg. "-userid:rh[/usr/home/rh/staroffice]",
2456 this will supercede all other locations */
2458 sal_uInt32 n, nArgs = osl_getCommandArgCount();
2460 for (n = 0; n < nArgs; n++)
2462 rtl_uString * strCommandArg = NULL;
2464 if ((osl_getCommandArg( n, &strCommandArg ) == osl_Process_E_None) &&
2465 ((strCommandArg->buffer[0] == L'-') || (strCommandArg->buffer[0] == L'+')) &&
2466 (rtl_ustr_ascii_compare_WithLength(strCommandArg->buffer, RTL_CONSTASCII_LENGTH(SVERSION_OPTION), SVERSION_OPTION)))
2468 sal_Unicode *pCommandArg = strCommandArg->buffer + RTL_CONSTASCII_LENGTH(SVERSION_OPTION);
2469 sal_Int32 nStart, nEnd;
2471 if (((nStart = rtl_ustr_indexOfChar(pCommandArg, L'[')) != -1) &&
2472 ((nEnd = rtl_ustr_indexOfChar(pCommandArg + nStart + 1, L']')) != -1))
2474 dwPathLen = nEnd;
2475 wcsncpy(wcsPath, pCommandArg + nStart + 1, dwPathLen );
2476 wcsPath[dwPathLen] = 0;
2478 /* build full path */
2479 if ((wcsPath[dwPathLen - 1] != L'/') && (wcsPath[dwPathLen - 1] != L'\\'))
2481 wcscpy(wcsPath + dwPathLen++, L"/");
2484 if (*strPath)
2486 wcscpy(wcsPath + dwPathLen, strPath);
2487 dwPathLen += wcslen(strPath);
2489 else
2491 CHAR szPath[MAX_PATH];
2492 int n;
2494 if ((n = WideCharToMultiByte(CP_ACP,0, wcsPath, -1, szPath, MAX_PATH, NULL, NULL)) > 0)
2496 strcpy(szPath + n, SVERSION_USER);
2497 if (access(szPath, 0) >= 0)
2499 dwPathLen += MultiByteToWideChar( CP_ACP, 0, SVERSION_USER, -1, wcsPath + dwPathLen, MAX_PATH - dwPathLen );
2504 break;
2511 if (dwPathLen == 0)
2513 rtl_uString * strExecutable = NULL;
2514 rtl_uString * strTmp = NULL;
2515 sal_Int32 nPos;
2517 /* try to find the file in the directory of the executbale */
2518 if (osl_getExecutableFile(&strTmp) != osl_Process_E_None)
2519 return (sal_False);
2521 /* convert to native path */
2522 if (osl_getSystemPathFromFileURL(strTmp, &strExecutable) != osl_File_E_None)
2524 rtl_uString_release(strTmp);
2525 return sal_False;
2528 rtl_uString_release(strTmp);
2530 /* seperate path from filename */
2531 if ((nPos = rtl_ustr_lastIndexOfChar(strExecutable->buffer, L'\\')) == -1)
2533 if ((nPos = rtl_ustr_lastIndexOfChar(strExecutable->buffer, L':')) == -1)
2535 return sal_False;
2537 else
2539 wcsncpy(wcsPath, strExecutable->buffer, nPos );
2540 wcsPath[nPos] = 0;
2541 dwPathLen = nPos;
2544 else
2546 wcsncpy(wcsPath, strExecutable->buffer, nPos );
2547 dwPathLen = nPos;
2548 wcsPath[dwPathLen] = 0;
2551 /* if we have no product identification use the executable file name */
2552 if (*Product == 0)
2554 WideCharToMultiByte(CP_ACP,0, strExecutable->buffer + nPos + 1, -1, Product, sizeof(Product), NULL, NULL);
2556 /* remove extension */
2557 if ((pChr = strrchr(Product, '.')) != NULL)
2558 *pChr = '\0';
2561 rtl_uString_release(strExecutable);
2563 /* remember last subdir */
2564 nPos = rtl_ustr_lastIndexOfChar(wcsPath, L'\\');
2566 wcscpy(wcsPath + dwPathLen++, L"\\");
2568 if (*strPath)
2570 wcscpy(wcsPath + dwPathLen, strPath);
2571 dwPathLen += wcslen(strPath);
2575 CHAR szPath[MAX_PATH];
2577 WideCharToMultiByte(CP_ACP,0, wcsPath, -1, szPath, MAX_PATH, NULL, NULL);
2579 /* if file not exists, remove any specified subdirectories
2580 like "bin" or "program" */
2582 if (((access(szPath, 0) < 0) && (nPos != -1)) || (*strPath == 0))
2584 static sal_Char *SubDirs[] = SVERSION_DIRS;
2586 int i = 0;
2587 pStr = szPath + nPos;
2589 for (i = 0; i < (sizeof(SubDirs) / sizeof(SubDirs[0])); i++)
2590 if (strnicmp(pStr + 1, SubDirs[i], strlen(SubDirs[i])) == 0)
2592 if ( *strPath == 0)
2594 strcpy(pStr + 1,SVERSION_USER);
2595 if ( access(szPath, 0) < 0 )
2597 *(pStr+1)='\0';
2599 else
2601 dwPathLen = nPos + MultiByteToWideChar( CP_ACP, 0, SVERSION_USER, -1, wcsPath + nPos + 1, MAX_PATH - (nPos + 1) );
2604 else
2606 wcscpy(wcsPath + nPos + 1, strPath);
2607 dwPathLen = nPos + 1 + wcslen(strPath);
2610 break;
2615 if ((wcsPath[dwPathLen - 1] != L'/') && (wcsPath[dwPathLen - 1] != L'\\'))
2617 wcsPath[dwPathLen++] = L'\\';
2618 wcsPath[dwPathLen] = 0;
2621 wcscpy(wcsPath + dwPathLen, strFile);
2624 CHAR szPath[MAX_PATH];
2626 WideCharToMultiByte(CP_ACP,0, wcsPath, -1, szPath, MAX_PATH, NULL, NULL);
2628 if ((access(szPath, 0) < 0) && (strlen(Product) > 0))
2630 rtl_uString * strSVFallback = NULL;
2631 rtl_uString * strSVProfile = NULL;
2632 rtl_uString * strSVLocation = NULL;
2633 rtl_uString * strSVName = NULL;
2634 oslProfile hProfile;
2636 rtl_uString_newFromAscii(&strSVFallback, SVERSION_FALLBACK);
2637 rtl_uString_newFromAscii(&strSVLocation, SVERSION_LOCATION);
2638 rtl_uString_newFromAscii(&strSVName, SVERSION_NAME);
2640 /* open sversion.ini in the system directory, and try to locate the entry
2641 with the highest version for StarOffice */
2642 if (osl_getProfileName(strSVLocation, strSVName, &strSVProfile))
2644 hProfile = osl_openProfile(
2645 strSVProfile, osl_Profile_READLOCK);
2646 if (hProfile)
2648 osl_readProfileString(
2649 hProfile, SVERSION_SECTION, Product, Buffer,
2650 sizeof(Buffer), "");
2651 osl_closeProfile(hProfile);
2653 /* if not found, try the fallback */
2654 if ((strlen(Buffer) <= 0)
2655 && (strcmp(SVERSION_LOCATION, SVERSION_FALLBACK)
2656 != 0))
2658 if (osl_getProfileName(
2659 strSVFallback, strSVName, &strSVProfile))
2661 hProfile = osl_openProfile(
2662 strSVProfile, osl_Profile_READLOCK);
2663 if (hProfile)
2665 osl_readProfileString(
2666 hProfile, SVERSION_SECTION, Product,
2667 Buffer, sizeof(Buffer), "");
2671 osl_closeProfile(hProfile);
2674 if (strlen(Buffer) > 0)
2676 dwPathLen = MultiByteToWideChar(
2677 CP_ACP, 0, Buffer, -1, wcsPath, MAX_PATH );
2678 dwPathLen -=1;
2680 /* build full path */
2681 if ((wcsPath[dwPathLen - 1] != L'/')
2682 && (wcsPath[dwPathLen - 1] != L'\\'))
2684 wcscpy(wcsPath + dwPathLen++, L"\\");
2687 if (*strPath)
2689 wcscpy(wcsPath + dwPathLen, strPath);
2690 dwPathLen += wcslen(strPath);
2692 else
2694 CHAR szPath[MAX_PATH];
2695 int n;
2697 if ((n = WideCharToMultiByte(
2698 CP_ACP,0, wcsPath, -1, szPath,
2699 MAX_PATH, NULL, NULL))
2700 > 0)
2702 strcpy(szPath + n, SVERSION_USER);
2703 if (access(szPath, 0) >= 0)
2705 dwPathLen += MultiByteToWideChar(
2706 CP_ACP, 0, SVERSION_USER, -1,
2707 wcsPath + dwPathLen,
2708 MAX_PATH - dwPathLen );
2715 rtl_uString_release(strSVProfile);
2718 rtl_uString_release(strSVFallback);
2719 rtl_uString_release(strSVLocation);
2720 rtl_uString_release(strSVName);
2724 wcsPath[dwPathLen] = 0;
2727 /* copy filename */
2728 wcscpy(strProfile, wcsPath);
2730 return sal_True;