xref: /trunk/main/sal/osl/w32/profile.cxx (revision 16e045db78ee048bd87aedeef7086dd5fa9f221d)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "system.h"
25 
26 #include "file_url.h"
27 #include "path_helper.hxx"
28 
29 #include <osl/diagnose.h>
30 #include <osl/profile.h>
31 #include <osl/process.h>
32 #include <osl/file.h>
33 #include <osl/util.h>
34 #include <rtl/alloc.h>
35 #include <algorithm>
36 using std::min;
37 static inline void copy_ustr_n( void *dest, const void *source, size_t length ) { rtl_copyMemory(dest, source, length*sizeof(sal_Unicode)); }
38 
39 #define LINES_INI       32
40 #define LINES_ADD       10
41 #define SECTIONS_INI    5
42 #define SECTIONS_ADD    3
43 #define ENTRIES_INI     5
44 #define ENTRIES_ADD     3
45 
46 
47 #define STR_INI_EXTENSION   L".ini"
48 #define STR_INI_METAHOME    "?~"
49 #define STR_INI_METASYS     "?$"
50 #define STR_INI_METACFG     "?^"
51 #define STR_INI_METAINS     "?#"
52 
53 #define STR_INI_BOOLYES     "yes"
54 #define STR_INI_BOOLON      "on"
55 #define STR_INI_BOOLONE     "1"
56 #define STR_INI_BOOLNO      "no"
57 #define STR_INI_BOOLOFF     "off"
58 #define STR_INI_BOOLZERO    "0"
59 
60 #define FLG_USER            0x00FF
61 #define FLG_AUTOOPEN        0x0100
62 #define FLG_MODIFIED        0x0200
63 
64 #define SVERSION_LOCATION   STR_INI_METACFG
65 #define SVERSION_FALLBACK   STR_INI_METASYS
66 #define SVERSION_NAME       "sversion"
67 #define SVERSION_SECTION    "Versions"
68 #define SVERSION_SOFFICE    "StarOffice"
69 #define SVERSION_PROFILE    "soffice.ini"
70 #define SVERSION_OPTION     "userid:"
71 #define SVERSION_DIRS       { "bin", "program" }
72 #define SVERSION_USER       "user"
73 
74 #define DEFAULT_PMODE   (_S_IREAD | _S_IWRITE)
75 
76 #define _BUILD_STR_(n)  # n
77 #define BUILD_STR(n)    _BUILD_STR_(n)
78 
79 
80 /*#define DEBUG_OSL_PROFILE 1*/
81 /*#define TRACE_OSL_PROFILE 1*/
82 
83 
84 /*****************************************************************************/
85 /* Data Type Definition */
86 /*****************************************************************************/
87 
88 typedef FILETIME osl_TStamp;
89 
90 typedef enum _osl_TLockMode
91 {
92     un_lock, read_lock, write_lock
93 } osl_TLockMode;
94 
95 typedef struct _osl_TFile
96 {
97     HANDLE  m_Handle;
98     sal_Char*   m_pReadPtr;
99     sal_Char    m_ReadBuf[512];
100 /*      sal_Char*   m_pWritePtr; */
101 /*      sal_Char    m_WriteBuf[512]; */
102     sal_Char*   m_pWriteBuf;
103     sal_uInt32  m_nWriteBufLen;
104     sal_uInt32  m_nWriteBufFree;
105 } osl_TFile;
106 
107 typedef struct _osl_TProfileEntry
108 {
109     sal_uInt32      m_Line;
110     sal_uInt32      m_Offset;
111     sal_uInt32      m_Len;
112 } osl_TProfileEntry;
113 
114 typedef struct _osl_TProfileSection
115 {
116     sal_uInt32          m_Line;
117     sal_uInt32          m_Offset;
118     sal_uInt32          m_Len;
119     sal_uInt32          m_NoEntries;
120     sal_uInt32          m_MaxEntries;
121     osl_TProfileEntry*  m_Entries;
122 } osl_TProfileSection;
123 
124 
125 /*
126     Profile-data structure hidden behind oslProfile:
127 */
128 typedef struct _osl_TProfileImpl
129 {
130     sal_uInt32  m_Flags;
131     osl_TFile*  m_pFile;
132     osl_TStamp  m_Stamp;
133     sal_uInt32  m_NoLines;
134     sal_uInt32  m_MaxLines;
135     sal_uInt32  m_NoSections;
136     sal_uInt32  m_MaxSections;
137     sal_Char**  m_Lines;
138     rtl_uString *m_strFileName;
139     osl_TProfileSection* m_Sections;
140 } osl_TProfileImpl;
141 
142 
143 /*****************************************************************************/
144 /* Static Module Function Declarations */
145 /*****************************************************************************/
146 
147 static osl_TFile*           openFileImpl(rtl_uString * strFileName, oslProfileOption ProfileFlags  );
148 static osl_TStamp           closeFileImpl(osl_TFile* pFile);
149 static sal_Bool             lockFile(const osl_TFile* pFile, osl_TLockMode eMode);
150 static sal_Bool             rewindFile(osl_TFile* pFile, sal_Bool bTruncate);
151 static osl_TStamp           getFileStamp(osl_TFile* pFile);
152 
153 static sal_Bool             getLine(osl_TFile* pFile, const sal_Char *pszLine, int MaxLen);
154 static sal_Bool             putLine(osl_TFile* pFile, const sal_Char *pszLine);
155 static const sal_Char*      stripBlanks(const sal_Char* String, sal_uInt32* pLen);
156 static const sal_Char*      addLine(osl_TProfileImpl* pProfile, const sal_Char* Line);
157 static const sal_Char*      insertLine(osl_TProfileImpl* pProfile, const sal_Char* Line, sal_uInt32 LineNo);
158 static void                 removeLine(osl_TProfileImpl* pProfile, sal_uInt32 LineNo);
159 static void                 setEntry(osl_TProfileImpl* pProfile, osl_TProfileSection* pSection,
160                                      sal_uInt32 NoEntry, sal_uInt32 Line,
161                                      const sal_Char* Entry, sal_uInt32 Len);
162 static sal_Bool             addEntry(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection,
163                                      int Line, const sal_Char* Entry, sal_uInt32 Len);
164 static void                 removeEntry(osl_TProfileSection *pSection, sal_uInt32 NoEntry);
165 static sal_Bool             addSection(osl_TProfileImpl* pProfile, int Line, const sal_Char* Section, sal_uInt32 Len);
166 static void                 removeSection(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection);
167 static osl_TProfileSection* findEntry(osl_TProfileImpl* pProfile, const sal_Char* Section,
168                                       const sal_Char* Entry, sal_uInt32 *pNoEntry);
169 static sal_Bool             loadProfile(osl_TFile* pFile, osl_TProfileImpl* pProfile);
170 static sal_Bool             storeProfile(osl_TProfileImpl* pProfile, sal_Bool bCleanup);
171 static osl_TProfileImpl*    acquireProfile(oslProfile Profile, sal_Bool bWriteable);
172 static sal_Bool             releaseProfile(osl_TProfileImpl* pProfile);
173 static sal_Bool             lookupProfile(const sal_Unicode *strPath, const sal_Unicode *strFile, sal_Unicode *strProfile);
174 
175 static sal_Bool writeProfileImpl (osl_TFile* pFile);
176 static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl*);
177 static sal_Bool osl_ProfileSwapProfileNames(osl_TProfileImpl*);
178 static rtl_uString* osl_ProfileGenerateExtension(rtl_uString* ustrFileName, rtl_uString* ustrExtension);
179 
180 static sal_Bool SAL_CALL osl_getProfileName(rtl_uString* strPath, rtl_uString* strName, rtl_uString** strProfileName);
181 
182 /*****************************************************************************/
183 /* Exported Module Functions */
184 /*****************************************************************************/
185 
186 oslProfile SAL_CALL osl_openProfile(rtl_uString *strProfileName, sal_uInt32 Flags)
187 {
188     osl_TFile*        pFile = NULL;
189     osl_TProfileImpl* pProfile;
190     rtl_uString       *FileName=NULL;
191 
192 #ifdef TRACE_OSL_PROFILE
193     OSL_TRACE("In  osl_openProfile\n");
194 #endif
195     OSL_VERIFY(strProfileName);
196 
197     if (rtl_uString_getLength(strProfileName) == 0 )
198     {
199         OSL_VERIFY(osl_getProfileName(NULL, NULL, &FileName));
200     }
201     else
202     {
203         rtl_uString_assign(&FileName, strProfileName);
204     }
205 
206 
207     osl_getSystemPathFromFileURL(FileName, &FileName);
208 
209 
210 #ifdef DEBUG_OSL_PROFILE
211     Flags=osl_Profile_FLUSHWRITE;
212 
213     // OSL_TRACE("opening '%s'\n",FileName);
214     if ( Flags == osl_Profile_DEFAULT )
215     {
216         OSL_TRACE("with osl_Profile_DEFAULT \n");
217     }
218     if ( Flags & osl_Profile_SYSTEM )
219     {
220         OSL_TRACE("with osl_Profile_SYSTEM \n");
221     }
222     if ( Flags & osl_Profile_READLOCK )
223     {
224         OSL_TRACE("with osl_Profile_READLOCK \n");
225     }
226     if ( Flags & osl_Profile_WRITELOCK )
227     {
228         OSL_TRACE("with osl_Profile_WRITELOCK \n");
229     }
230 /*      if ( Flags & osl_Profile_READWRITE ) */
231 /*      { */
232 /*          OSL_TRACE("with osl_Profile_READWRITE \n"); */
233 /*      } */
234     if ( Flags & osl_Profile_FLUSHWRITE )
235     {
236         OSL_TRACE("with osl_Profile_FLUSHWRITE \n");
237     }
238 #endif
239 
240     if ( (! (Flags & osl_Profile_SYSTEM)) && ( (pFile = openFileImpl(FileName, Flags) ) == NULL ) )
241     {
242 #ifdef TRACE_OSL_PROFILE
243         OSL_TRACE("Out osl_openProfile [not opened]\n");
244 #endif
245         if( FileName)
246             rtl_uString_release( FileName);
247 
248         return (NULL);
249     }
250 
251 
252     pProfile = (osl_TProfileImpl*)calloc(1, sizeof(osl_TProfileImpl));
253 
254 
255     pProfile->m_Flags = Flags & FLG_USER;
256     osl_getSystemPathFromFileURL(strProfileName, &pProfile->m_strFileName);
257 //  rtl_uString_assign(&pProfile->m_strFileName, strProfileName);
258 
259     if (Flags & (osl_Profile_READLOCK | osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE ))
260         pProfile->m_pFile = pFile;
261 
262     pProfile->m_Stamp = getFileStamp(pFile);
263 
264     loadProfile(pFile, pProfile);
265 
266     if (pProfile->m_pFile == NULL)
267         closeFileImpl(pFile);
268 
269 #ifdef TRACE_OSL_PROFILE
270     OSL_TRACE("Out osl_openProfile [ok]\n");
271 #endif
272     if( FileName)
273         rtl_uString_release( FileName);
274 
275     return (pProfile);
276 }
277 
278 sal_Bool SAL_CALL osl_closeProfile(oslProfile Profile)
279 {
280     osl_TProfileImpl* pProfile = (osl_TProfileImpl*)Profile;
281 
282 #ifdef TRACE_OSL_PROFILE
283     OSL_TRACE("In  osl_closeProfile\n");
284 #endif
285 
286     if ( Profile == 0 )
287     {
288 #ifdef TRACE_OSL_PROFILE
289         OSL_TRACE("Out osl_closeProfile [profile==0]\n");
290 #endif
291         return sal_False;
292     }
293 
294     if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
295     {
296         pProfile = acquireProfile(Profile,sal_True);
297 
298         if ( pProfile != 0 )
299         {
300             if ( !( pProfile->m_Flags & osl_Profile_READLOCK )  && ( pProfile->m_Flags & FLG_MODIFIED ) )
301             {
302 /*                  if (pProfile->m_pFile == NULL) */
303 /*                      pProfile->m_pFile = openFileImpl(pProfile->m_Filename, sal_True); */
304 
305                 storeProfile(pProfile, sal_False);
306             }
307         }
308         else
309         {
310             pProfile = acquireProfile(Profile,sal_False);
311         }
312 
313         if ( pProfile == 0 )
314         {
315 #ifdef TRACE_OSL_PROFILE
316             OSL_TRACE("Out osl_closeProfile [pProfile==0]\n");
317 #endif
318             return sal_False;
319         }
320 
321         if (pProfile->m_pFile != NULL)
322             closeFileImpl(pProfile->m_pFile);
323     }
324 
325     pProfile->m_pFile = NULL;
326     rtl_uString_release(pProfile->m_strFileName);
327     pProfile->m_strFileName = NULL;
328 
329     /* release whole profile data types memory */
330     if ( pProfile->m_NoLines > 0)
331     {
332         unsigned int index=0;
333         if ( pProfile->m_Lines != 0 )
334         {
335             for ( index = 0 ; index < pProfile->m_NoLines ; ++index)
336             {
337                 if ( pProfile->m_Lines[index] != 0 )
338                 {
339                     free(pProfile->m_Lines[index]);
340                 }
341             }
342             free(pProfile->m_Lines);
343         }
344         if ( pProfile->m_Sections != 0 )
345         {
346             /*osl_TProfileSection* pSections=pProfile->m_Sections;*/
347             for ( index = 0 ; index < pProfile->m_NoSections ; ++index )
348             {
349                 if ( pProfile->m_Sections[index].m_Entries != 0 )
350                 {
351                     free(pProfile->m_Sections[index].m_Entries);
352                 }
353             }
354             free(pProfile->m_Sections);
355         }
356 
357     }
358     free(pProfile);
359 
360 #ifdef TRACE_OSL_PROFILE
361     OSL_TRACE("Out osl_closeProfile [ok]\n");
362 #endif
363     return (sal_True);
364 }
365 
366 
367 sal_Bool SAL_CALL osl_flushProfile(oslProfile Profile)
368 {
369     osl_TProfileImpl* pProfile = (osl_TProfileImpl*) Profile;
370     osl_TFile* pFile;
371     sal_Bool bRet = sal_False;
372 
373 #ifdef TRACE_OSL_PROFILE
374     OSL_TRACE("In  osl_flushProfile()\n");
375 #endif
376 
377     if ( pProfile == 0 )
378     {
379 #ifdef TRACE_OSL_PROFILE
380         OSL_TRACE("Out osl_flushProfile() [pProfile == 0]\n");
381 #endif
382         return sal_False;
383     }
384 
385     pFile = pProfile->m_pFile;
386     if ( !( pFile != 0 && pFile->m_Handle >= 0 ) )
387     {
388 #ifdef TRACE_OSL_PROFILE
389         OSL_TRACE("Out osl_flushProfile() [invalid file]\n");
390 #endif
391         return sal_False;
392     }
393 
394     if ( pProfile->m_Flags & FLG_MODIFIED )
395     {
396 #ifdef DEBUG_OSL_PROFILE
397         OSL_TRACE("swapping to storeprofile\n");
398 #endif
399         bRet = storeProfile(pProfile,sal_False);
400     }
401 
402 #ifdef TRACE_OSL_PROFILE
403     OSL_TRACE("Out osl_flushProfile() [ok]\n");
404 #endif
405     return bRet;
406 }
407 
408 static sal_Bool writeProfileImpl(osl_TFile* pFile)
409 {
410     DWORD BytesWritten=0;
411     BOOL bRet;
412 
413 #ifdef TRACE_OSL_PROFILE
414     OSL_TRACE("In  osl_writeProfileImpl()\n");
415 #endif
416 
417     if ( !( pFile != 0 && pFile->m_Handle != INVALID_HANDLE_VALUE ) || ( pFile->m_pWriteBuf == 0 ) )
418     {
419 #ifdef TRACE_OSL_PROFILE
420         OSL_TRACE("Out osl_writeProfileImpl() [invalid args]\n");
421 #endif
422         return sal_False;
423     }
424 
425 #ifdef DEBUG_OSL_PROFILE
426 /*    OSL_TRACE("File Buffer in writeProfileImpl '%s' size == '%i' '%i'(%i)\n",
427       pFile->m_pWriteBuf,pFile->m_nWriteBufLen,strlen(pFile->m_pWriteBuf),pFile->m_nWriteBufLen - pFile->m_nWriteBufFree);*/
428 #endif
429 
430     bRet=WriteFile(pFile->m_Handle, pFile->m_pWriteBuf, pFile->m_nWriteBufLen - pFile->m_nWriteBufFree,&BytesWritten,NULL);
431 
432     if ( bRet == 0 || BytesWritten <= 0 )
433     {
434         OSL_ENSURE(bRet,"WriteFile failed!!!");
435 
436         OSL_TRACE("write failed '%s'\n",strerror(errno));
437 
438 /*        OSL_TRACE("Out osl_writeProfileImpl() [write '%s']\n",strerror(errno));*/
439         return (sal_False);
440     }
441 
442     free(pFile->m_pWriteBuf);
443     pFile->m_pWriteBuf=0;
444     pFile->m_nWriteBufLen=0;
445     pFile->m_nWriteBufFree=0;
446 
447 #ifdef TRACE_OSL_PROFILE
448     OSL_TRACE("Out osl_writeProfileImpl() [ok]\n");
449 #endif
450     return sal_True;
451 }
452 
453 
454 sal_Bool SAL_CALL osl_readProfileString(oslProfile Profile,
455                               const sal_Char* pszSection, const sal_Char* pszEntry,
456                               sal_Char* pszString, sal_uInt32 MaxLen,
457                               const sal_Char* pszDefault)
458 {
459     sal_uInt32    NoEntry;
460     const sal_Char* pStr = 0;
461     osl_TProfileSection* pSec;
462     osl_TProfileImpl*    pProfile = 0;
463 
464 
465 #ifdef TRACE_OSL_PROFILE
466     OSL_TRACE("In  osl_readProfileString\n");
467 #endif
468 
469     pProfile = acquireProfile(Profile, sal_False);
470 
471     if (pProfile == NULL)
472     {
473 #ifdef TRACE_OSL_PROFILE
474         OSL_TRACE("Out osl_readProfileString [pProfile==0]\n");
475 #endif
476 
477 
478         return (sal_False);
479     }
480 
481 
482     if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
483     {
484         if (((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) != NULL) &&
485             (NoEntry < pSec->m_NoEntries) &&
486             ((pStr = strchr(pProfile->m_Lines[pSec->m_Entries[NoEntry].m_Line],
487                             '=')) != NULL))
488             pStr++;
489         else
490             pStr = pszDefault;
491 
492         if ( pStr != 0 )
493         {
494             pStr = stripBlanks(pStr, NULL);
495             MaxLen = (MaxLen - 1 < strlen(pStr)) ? (MaxLen - 1) : strlen(pStr);
496             pStr = stripBlanks(pStr, &MaxLen);
497             strncpy(pszString, pStr, MaxLen);
498             pszString[MaxLen] = '\0';
499         }
500     }
501     else
502     {
503         ::osl::LongPathBuffer< sal_Char > aFileName( MAX_LONG_PATH );
504 
505         WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(pProfile->m_strFileName->buffer), -1, aFileName, aFileName.getBufSizeInSymbols(), NULL, NULL);
506         GetPrivateProfileString(pszSection, pszEntry, pszDefault, pszString, MaxLen, aFileName);
507     }
508 
509     releaseProfile(pProfile);
510 
511     if ( pStr == 0 )
512     {
513 #ifdef TRACE_OSL_PROFILE
514         OSL_TRACE("Out osl_readProfileString [pStr==0]\n");
515 #endif
516 
517 
518         return (sal_False);
519     }
520 
521 #ifdef TRACE_OSL_PROFILE
522     OSL_TRACE("Out osl_readProfileString [ok]\n");
523 #endif
524 
525 
526 
527 
528     return (sal_True);
529 }
530 
531 
532 sal_Bool SAL_CALL osl_readProfileBool(oslProfile Profile,
533                             const sal_Char* pszSection, const sal_Char* pszEntry,
534                             sal_Bool Default)
535 {
536     sal_Char Line[32];
537 
538 #ifdef TRACE_OSL_PROFILE
539     OSL_TRACE("In  osl_readProfileBool\n");
540 #endif
541 
542     if (osl_readProfileString(Profile, pszSection, pszEntry, Line, sizeof(Line), ""))
543     {
544         if ((stricmp(Line, STR_INI_BOOLYES) == 0) ||
545             (stricmp(Line, STR_INI_BOOLON)  == 0) ||
546             (stricmp(Line, STR_INI_BOOLONE) == 0))
547             Default = sal_True;
548         else
549             if ((stricmp(Line, STR_INI_BOOLNO)   == 0) ||
550                 (stricmp(Line, STR_INI_BOOLOFF)  == 0) ||
551                 (stricmp(Line, STR_INI_BOOLZERO) == 0))
552                 Default = sal_False;
553     }
554 
555 #ifdef TRACE_OSL_PROFILE
556     OSL_TRACE("Out osl_readProfileBool [ok]\n");
557 #endif
558 
559     return (Default);
560 }
561 
562 
563 sal_uInt32 SAL_CALL osl_readProfileIdent(oslProfile Profile,
564                               const sal_Char* pszSection, const sal_Char* pszEntry,
565                               sal_uInt32 FirstId, const sal_Char* Strings[],
566                               sal_uInt32 Default)
567 {
568     sal_uInt32    i;
569     sal_Char        Line[256];
570 
571 #ifdef TRACE_OSL_PROFILE
572     OSL_TRACE("In  osl_readProfileIdent\n");
573 #endif
574 
575     if (osl_readProfileString(Profile, pszSection, pszEntry, Line, sizeof(Line), ""))
576     {
577         i = 0;
578         while (Strings[i] != NULL)
579         {
580             if (stricmp(Line, Strings[i]) == 0)
581             {
582                 Default = i + FirstId;
583                 break;
584             }
585             i++;
586         }
587     }
588 
589 #ifdef TRACE_OSL_PROFILE
590     OSL_TRACE("Out osl_readProfileIdent [ok]\n");
591 #endif
592     return (Default);
593 }
594 
595 sal_Bool SAL_CALL osl_writeProfileString(oslProfile Profile,
596                                const sal_Char* pszSection, const sal_Char* pszEntry,
597                                const sal_Char* pszString)
598 {
599     sal_uInt32    i;
600     sal_Bool bRet = sal_False;
601     sal_uInt32    NoEntry;
602     const sal_Char* pStr;
603     sal_Char        Line[4096];
604     osl_TProfileSection* pSec;
605     osl_TProfileImpl*    pProfile = 0;
606 
607 #ifdef TRACE_OSL_PROFILE
608     OSL_TRACE("In  osl_writeProfileString\n");
609 #endif
610 
611     pProfile = acquireProfile(Profile, sal_True);
612 
613     if (pProfile == NULL)
614     {
615 #ifdef TRACE_OSL_PROFILE
616         OSL_TRACE("Out osl_writeProfileString [pProfile==0]\n");
617 #endif
618         return (sal_False);
619     }
620 
621 
622     if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
623     {
624         if ((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) == NULL)
625         {
626             Line[0] = '\0';
627             addLine(pProfile, Line);
628 
629             Line[0] = '[';
630             strcpy(&Line[1], pszSection);
631             Line[1 + strlen(pszSection)] = ']';
632             Line[2 + strlen(pszSection)] = '\0';
633 
634             if (((pStr = addLine(pProfile, Line)) == NULL) ||
635                 (! addSection(pProfile, pProfile->m_NoLines - 1, &pStr[1], strlen(pszSection))))
636             {
637                 releaseProfile(pProfile);
638 #ifdef TRACE_OSL_PROFILE
639                 OSL_TRACE("Out osl_writeProfileString [not added]\n");
640 #endif
641                 return (sal_False);
642             }
643 
644             pSec = &pProfile->m_Sections[pProfile->m_NoSections - 1];
645             NoEntry = pSec->m_NoEntries;
646         }
647 
648         Line[0] = '\0';
649         strcpy(&Line[0], pszEntry);
650         Line[0 + strlen(pszEntry)] = '=';
651         strcpy(&Line[1 + strlen(pszEntry)], pszString);
652 
653         if (NoEntry >= pSec->m_NoEntries)
654         {
655             if (pSec->m_NoEntries > 0)
656                 i = pSec->m_Entries[pSec->m_NoEntries - 1].m_Line + 1;
657             else
658                 i = pSec->m_Line + 1;
659 
660             if (((pStr = insertLine(pProfile, Line, i)) == NULL) ||
661                 (! addEntry(pProfile, pSec, i, pStr, strlen(pszEntry))))
662             {
663                 releaseProfile(pProfile);
664 #ifdef TRACE_OSL_PROFILE
665                 OSL_TRACE("Out osl_writeProfileString [not inserted]\n");
666 #endif
667                 return (sal_False);
668             }
669 
670             pProfile->m_Flags |= FLG_MODIFIED;
671         }
672         else
673         {
674             i = pSec->m_Entries[NoEntry].m_Line;
675             free(pProfile->m_Lines[i]);
676             pProfile->m_Lines[i] = strdup(Line);
677             setEntry(pProfile, pSec, NoEntry, i, pProfile->m_Lines[i], strlen(pszEntry));
678 
679             pProfile->m_Flags |= FLG_MODIFIED;
680         }
681     }
682     else
683     {
684         ::osl::LongPathBuffer< sal_Char > aFileName( MAX_LONG_PATH );
685 
686         WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(pProfile->m_strFileName->buffer), -1, aFileName, aFileName.getBufSizeInSymbols(), NULL, NULL);
687         WritePrivateProfileString(pszSection, pszEntry, pszString, aFileName);
688     }
689 
690     bRet = releaseProfile(pProfile);
691 #ifdef TRACE_OSL_PROFILE
692     OSL_TRACE("Out osl_writeProfileString [ok]\n");
693 #endif
694     return bRet;
695 }
696 
697 
698 sal_Bool SAL_CALL osl_writeProfileBool(oslProfile Profile,
699                              const sal_Char* pszSection, const sal_Char* pszEntry,
700                              sal_Bool Value)
701 {
702     sal_Bool bRet = sal_False;
703 
704 #ifdef TRACE_OSL_PROFILE
705     OSL_TRACE("In  osl_writeProfileBool\n");
706 #endif
707 
708     if (Value)
709         bRet=osl_writeProfileString(Profile, pszSection, pszEntry, STR_INI_BOOLONE);
710     else
711         bRet=osl_writeProfileString(Profile, pszSection, pszEntry, STR_INI_BOOLZERO);
712 
713 #ifdef TRACE_OSL_PROFILE
714     OSL_TRACE("Out osl_writeProfileBool [ok]\n");
715 #endif
716 
717     return bRet;
718 }
719 
720 
721 sal_Bool SAL_CALL osl_writeProfileIdent(oslProfile Profile,
722                               const sal_Char* pszSection, const sal_Char* pszEntry,
723                               sal_uInt32 FirstId, const sal_Char* Strings[],
724                               sal_uInt32 Value)
725 {
726     int i, n;
727     sal_Bool bRet = sal_False;
728 
729 #ifdef TRACE_OSL_PROFILE
730     OSL_TRACE("In  osl_writeProfileIdent\n");
731 #endif
732 
733     for (n = 0; Strings[n] != NULL; n++);
734 
735     if ((i = Value - FirstId) >= n)
736         bRet=sal_False;
737     else
738         bRet=osl_writeProfileString(Profile, pszSection, pszEntry, Strings[i]);
739 
740 #ifdef TRACE_OSL_PROFILE
741     OSL_TRACE("Out osl_writeProfileIdent\n");
742 #endif
743     return bRet;
744 }
745 
746 
747 sal_Bool SAL_CALL osl_removeProfileEntry(oslProfile Profile,
748                                const sal_Char *pszSection, const sal_Char *pszEntry)
749 {
750     sal_uInt32    NoEntry;
751     osl_TProfileSection* pSec;
752     osl_TProfileImpl*    pProfile = 0;
753     sal_Bool bRet = sal_False;
754 
755 #ifdef TRACE_OSL_PROFILE
756     OSL_TRACE("In  osl_removeProfileEntry\n");
757 #endif
758 
759     pProfile = acquireProfile(Profile, sal_True);
760 
761     if (pProfile == NULL)
762     {
763 #ifdef TRACE_OSL_PROFILE
764         OSL_TRACE("Out osl_removeProfileEntry [pProfile==0]\n");
765 #endif
766 
767 
768         return (sal_False);
769     }
770 
771 
772     if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
773     {
774         if (((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) != NULL) &&
775             (NoEntry < pSec->m_NoEntries))
776         {
777             removeLine(pProfile, pSec->m_Entries[NoEntry].m_Line);
778             removeEntry(pSec, NoEntry);
779             if (pSec->m_NoEntries == 0)
780             {
781                 removeLine(pProfile, pSec->m_Line);
782 
783                 /* remove any empty separation line */
784                 if ((pSec->m_Line > 0) && (pProfile->m_Lines[pSec->m_Line - 1][0] == '\0'))
785                     removeLine(pProfile, pSec->m_Line - 1);
786 
787                 removeSection(pProfile, pSec);
788             }
789 
790             pProfile->m_Flags |= FLG_MODIFIED;
791         }
792     }
793     else
794     {
795         ::osl::LongPathBuffer< sal_Char > aFileName( MAX_LONG_PATH );
796 
797         WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(pProfile->m_strFileName->buffer), -1, aFileName, aFileName.getBufSizeInSymbols(), NULL, NULL);
798         WritePrivateProfileString(pszSection, pszEntry, NULL, aFileName);
799     }
800 
801     bRet = releaseProfile(pProfile);
802 #ifdef TRACE_OSL_PROFILE
803     OSL_TRACE("Out osl_removeProfileEntry [ok]\n");
804 #endif
805     return bRet;
806 }
807 
808 
809 sal_uInt32 SAL_CALL osl_getProfileSectionEntries(oslProfile Profile, const sal_Char *pszSection,
810                                     sal_Char* pszBuffer, sal_uInt32 MaxLen)
811 {
812     sal_uInt32    i, n = 0;
813     sal_uInt32    NoEntry;
814     osl_TProfileSection* pSec;
815     osl_TProfileImpl*    pProfile = 0;
816 
817 #ifdef TRACE_OSL_PROFILE
818     OSL_TRACE("In  osl_getProfileSectionEntries\n");
819 #endif
820 
821     pProfile = acquireProfile(Profile, sal_False);
822 
823     if (pProfile == NULL)
824     {
825 #ifdef TRACE_OSL_PROFILE
826         OSL_TRACE("Out osl_getProfileSectionEntries [pProfile=0]\n");
827 #endif
828 
829 
830         return (0);
831     }
832 
833 
834     if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
835     {
836         if ((pSec = findEntry(pProfile, pszSection, "", &NoEntry)) != NULL)
837         {
838             if (MaxLen != 0)
839             {
840                 for (i = 0; i < pSec->m_NoEntries; i++)
841                 {
842                     if ((n + pSec->m_Entries[i].m_Len + 1) < MaxLen)
843                     {
844                         strncpy(&pszBuffer[n], &pProfile->m_Lines[pSec->m_Entries[i].m_Line]
845                                 [pSec->m_Entries[i].m_Offset], pSec->m_Entries[i].m_Len);
846                         n += pSec->m_Entries[i].m_Len;
847                         pszBuffer[n++] = '\0';
848                     }
849                     else
850                         break;
851 
852                 }
853 
854                 pszBuffer[n++] = '\0';
855             }
856             else
857             {
858                 for (i = 0; i < pSec->m_NoEntries; i++)
859                     n += pSec->m_Entries[i].m_Len + 1;
860 
861                 n += 1;
862             }
863         }
864         else
865             n = 0;
866     }
867     else
868     {
869         ::osl::LongPathBuffer< sal_Char > aFileName( MAX_LONG_PATH );
870 
871         WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(pProfile->m_strFileName->buffer), -1, aFileName, aFileName.getBufSizeInSymbols(), NULL, NULL);
872         n = GetPrivateProfileString(pszSection, NULL, NULL, pszBuffer, MaxLen, aFileName);
873     }
874 
875     releaseProfile(pProfile);
876 
877 #ifdef TRACE_OSL_PROFILE
878     OSL_TRACE("Out osl_getProfileSectionEntries [ok]\n");
879 #endif
880 
881     return (n);
882 }
883 
884 
885 sal_Bool SAL_CALL osl_getProfileName(rtl_uString* strPath, rtl_uString* strName, rtl_uString** strProfileName)
886 {
887     sal_Bool bFailed;
888     ::osl::LongPathBuffer< sal_Unicode > aFile( MAX_LONG_PATH );
889     ::osl::LongPathBuffer< sal_Unicode > aPath( MAX_LONG_PATH );
890     sal_uInt32  nFileLen = 0;
891     sal_uInt32  nPathLen = 0;
892 
893     rtl_uString * strTmp = NULL;
894     oslFileError nError;
895 
896     /* build file name */
897     if (strName && strName->length)
898     {
899         if( ::sal::static_int_cast< sal_uInt32 >( strName->length ) >= aFile.getBufSizeInSymbols() )
900             return sal_False;
901 
902         copy_ustr_n( aFile, strName->buffer, strName->length+1);
903         nFileLen = strName->length;
904 
905         if (rtl_ustr_indexOfChar( aFile, L'.' ) == -1)
906         {
907             if (nFileLen + wcslen(STR_INI_EXTENSION) >= aFile.getBufSizeInSymbols())
908                 return sal_False;
909 
910             /* add default extension */
911             copy_ustr_n( aFile + nFileLen, STR_INI_EXTENSION, wcslen(STR_INI_EXTENSION)+1 );
912             nFileLen += wcslen(STR_INI_EXTENSION);
913         }
914     }
915     else
916     {
917         rtl_uString *strProgName = NULL;
918         sal_Unicode *pProgName;
919         sal_Int32 nOffset = 0;
920         sal_Int32 nLen;
921         sal_Int32 nPos;
922 
923         if (osl_getExecutableFile(&strProgName) != osl_Process_E_None)
924             return sal_False;
925 
926         /* remove path and extension from filename */
927         pProgName = strProgName->buffer;
928         nLen = strProgName->length ;
929 
930         if ((nPos = rtl_ustr_lastIndexOfChar( pProgName, L'/' )) != -1)
931             nOffset = nPos + 1;
932         else if ((nPos = rtl_ustr_lastIndexOfChar( pProgName, L':' )) != -1)
933             nOffset = nPos + 1;
934 
935         if ((nPos = rtl_ustr_lastIndexOfChar( pProgName, L'.' )) != -1 )
936             nLen -= 4;
937 
938         if ((nFileLen = nLen - nOffset) >= aFile.getBufSizeInSymbols())
939             return sal_False;
940 
941         copy_ustr_n(aFile, pProgName + nOffset, nFileLen);
942 
943         if (nFileLen + wcslen(STR_INI_EXTENSION) >= aFile.getBufSizeInSymbols())
944             return sal_False;
945 
946         /* add default extension */
947         copy_ustr_n(aFile + nFileLen, STR_INI_EXTENSION, wcslen(STR_INI_EXTENSION)+1);
948         nFileLen += wcslen(STR_INI_EXTENSION);
949 
950         rtl_uString_release( strProgName );
951     }
952 
953     if (aFile[0] == 0)
954         return sal_False;
955 
956     /* build directory path */
957     if (strPath && strPath->length)
958     {
959         sal_Unicode *pPath = rtl_uString_getStr(strPath);
960         sal_Int32 nLen = rtl_uString_getLength(strPath);
961 
962         if ((rtl_ustr_ascii_compare_WithLength(pPath, RTL_CONSTASCII_LENGTH(STR_INI_METAHOME) , STR_INI_METAHOME) == 0) &&
963             ((nLen == RTL_CONSTASCII_LENGTH(STR_INI_METAHOME)) || (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METAHOME)] == '/')))
964         {
965             rtl_uString * strHome = NULL;
966             oslSecurity security = osl_getCurrentSecurity();
967 
968             bFailed = ! osl_getHomeDir(security, &strHome);
969             osl_freeSecurityHandle(security);
970 
971             if (bFailed) return (sal_False);
972 
973             if ( ::sal::static_int_cast< sal_uInt32 >( strHome->length ) >= aPath.getBufSizeInSymbols())
974                 return sal_False;
975 
976             copy_ustr_n( aPath, strHome->buffer, strHome->length+1);
977             nPathLen = strHome->length;
978 
979             if (nLen > RTL_CONSTASCII_LENGTH(STR_INI_METAHOME))
980             {
981                 pPath += RTL_CONSTASCII_LENGTH(STR_INI_METAHOME);
982                 nLen -= RTL_CONSTASCII_LENGTH(STR_INI_METAHOME);
983 
984                 if (nLen + nPathLen >= aPath.getBufSizeInSymbols())
985                     return sal_False;
986 
987                 copy_ustr_n(aPath + nPathLen, pPath, nLen+1);
988                 nPathLen += nLen;
989             }
990 
991             rtl_uString_release(strHome);
992         }
993 
994         else if ((rtl_ustr_ascii_compare_WithLength(pPath, RTL_CONSTASCII_LENGTH(STR_INI_METACFG), STR_INI_METACFG) == 0) &&
995             ((nLen == RTL_CONSTASCII_LENGTH(STR_INI_METACFG)) || (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METACFG)] == '/')))
996         {
997             rtl_uString * strConfig = NULL;
998             oslSecurity security = osl_getCurrentSecurity();
999 
1000             bFailed = ! osl_getConfigDir(security, &strConfig);
1001             osl_freeSecurityHandle(security);
1002 
1003             if (bFailed) return (sal_False);
1004 
1005             if ( ::sal::static_int_cast< sal_uInt32 >( strConfig->length ) >= aPath.getBufSizeInSymbols())
1006                 return sal_False;
1007 
1008             copy_ustr_n( aPath, strConfig->buffer, strConfig->length+1 );
1009             nPathLen = strConfig->length;
1010 
1011             if (nLen > RTL_CONSTASCII_LENGTH(STR_INI_METACFG))
1012             {
1013                 pPath += RTL_CONSTASCII_LENGTH(STR_INI_METACFG);
1014                 nLen -= RTL_CONSTASCII_LENGTH(STR_INI_METACFG);
1015 
1016                 if (nLen + nPathLen >= aPath.getBufSizeInSymbols())
1017                     return sal_False;
1018 
1019                 copy_ustr_n(aPath + nPathLen, pPath, nLen+1);
1020                 nPathLen += nLen;
1021             }
1022 
1023             rtl_uString_release(strConfig);
1024         }
1025 
1026         else if ((rtl_ustr_ascii_compare_WithLength(pPath, RTL_CONSTASCII_LENGTH(STR_INI_METASYS), STR_INI_METASYS) == 0) &&
1027             ((nLen == RTL_CONSTASCII_LENGTH(STR_INI_METASYS)) || (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METASYS)] == '/')))
1028         {
1029             if (((nPathLen = GetWindowsDirectoryW(::osl::mingw_reinterpret_cast<LPWSTR>(aPath), aPath.getBufSizeInSymbols())) == 0) || (nPathLen >= aPath.getBufSizeInSymbols()))
1030                 return (sal_False);
1031 
1032             if (nLen > RTL_CONSTASCII_LENGTH(STR_INI_METASYS))
1033             {
1034                 pPath += RTL_CONSTASCII_LENGTH(STR_INI_METASYS);
1035                 nLen -= RTL_CONSTASCII_LENGTH(STR_INI_METASYS);
1036 
1037                 if (nLen + nPathLen >= aPath.getBufSizeInSymbols())
1038                     return sal_False;
1039 
1040                 copy_ustr_n(aPath + nPathLen, pPath, nLen+1);
1041                 nPathLen += nLen;
1042             }
1043         }
1044 
1045         else if ((rtl_ustr_ascii_compare_WithLength(pPath, RTL_CONSTASCII_LENGTH(STR_INI_METAINS), STR_INI_METAINS) == 0) &&
1046             ((nLen == RTL_CONSTASCII_LENGTH(STR_INI_METAINS)) || (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METAINS)] == '/') ||
1047                 (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METAINS)] == '"') ) )
1048         {
1049             if (! lookupProfile(pPath + RTL_CONSTASCII_LENGTH(STR_INI_METAINS), aFile, aPath))
1050                 return (sal_False);
1051 
1052             nPathLen = rtl_ustr_getLength(aPath);
1053         }
1054 
1055         else if( ::sal::static_int_cast< sal_uInt32 >( nLen ) < aPath.getBufSizeInSymbols())
1056         {
1057             copy_ustr_n(aPath, pPath, nLen+1);
1058             nPathLen = rtl_ustr_getLength(aPath);
1059         }
1060         else
1061             return sal_False;
1062     }
1063     else
1064     {
1065         rtl_uString * strConfigDir = NULL;
1066         oslSecurity security = osl_getCurrentSecurity();
1067 
1068         bFailed = ! osl_getConfigDir(security, &strConfigDir);
1069         osl_freeSecurityHandle(security);
1070 
1071         if (bFailed) return (sal_False);
1072         if ( ::sal::static_int_cast< sal_uInt32 >( strConfigDir->length ) >= aPath.getBufSizeInSymbols() )
1073             return sal_False;
1074 
1075         copy_ustr_n(aPath, strConfigDir->buffer, strConfigDir->length+1);
1076         nPathLen = strConfigDir->length;
1077     }
1078 
1079     if (nPathLen && (aPath[nPathLen - 1] != L'/') && (aPath[nPathLen - 1] != L'\\'))
1080     {
1081         aPath[nPathLen++] = L'\\';
1082         aPath[nPathLen] = 0;
1083     }
1084 
1085     if (nPathLen + nFileLen >= aPath.getBufSizeInSymbols())
1086         return sal_False;
1087 
1088     /* append file name */
1089     copy_ustr_n(aPath + nPathLen, aFile, nFileLen+1);
1090     nPathLen += nFileLen;
1091 
1092     /* copy filename */
1093     rtl_uString_newFromStr_WithLength(&strTmp, aPath, nPathLen);
1094     nError = osl_getFileURLFromSystemPath(strTmp, strProfileName);
1095     rtl_uString_release(strTmp);
1096 
1097     return (sal_Bool) (nError == osl_File_E_None);
1098 }
1099 
1100 
1101 sal_uInt32 SAL_CALL osl_getProfileSections(oslProfile Profile, sal_Char* pszBuffer, sal_uInt32 MaxLen)
1102 {
1103     sal_uInt32    i, n = 0;
1104     osl_TProfileSection* pSec;
1105     osl_TProfileImpl*    pProfile = acquireProfile(Profile, sal_False);
1106 
1107     if (pProfile == NULL)
1108         return (0);
1109 
1110     if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
1111     {
1112         if (MaxLen != 0)
1113         {
1114             for (i = 0; i < pProfile->m_NoSections; i++)
1115             {
1116                 pSec = &pProfile->m_Sections[i];
1117 
1118                 if ((n + pSec->m_Len + 1) < MaxLen)
1119                 {
1120                     strncpy(&pszBuffer[n], &pProfile->m_Lines[pSec->m_Line][pSec->m_Offset],
1121                             pSec->m_Len);
1122                     n += pSec->m_Len;
1123                     pszBuffer[n++] = '\0';
1124                 }
1125                 else
1126                     break;
1127             }
1128 
1129             pszBuffer[n++] = '\0';
1130         }
1131         else
1132         {
1133             for (i = 0; i < pProfile->m_NoSections; i++)
1134                 n += pProfile->m_Sections[i].m_Len + 1;
1135 
1136             n += 1;
1137         }
1138     }
1139     else
1140     {
1141         ::osl::LongPathBuffer< sal_Char > aFileName( MAX_LONG_PATH );
1142 
1143         WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(pProfile->m_strFileName->buffer), -1, aFileName, aFileName.getBufSizeInSymbols(), NULL, NULL);
1144         n = GetPrivateProfileSectionNames(pszBuffer, MaxLen, aFileName);
1145     }
1146 
1147     releaseProfile(pProfile);
1148 
1149     return (n);
1150 }
1151 
1152 
1153 
1154 
1155 /*****************************************************************************/
1156 /* Static Module Functions */
1157 /*****************************************************************************/
1158 
1159 static osl_TStamp getFileStamp(osl_TFile* pFile)
1160 {
1161     FILETIME FileTime;
1162 
1163     if ((pFile->m_Handle == INVALID_HANDLE_VALUE) ||
1164         (! GetFileTime(pFile->m_Handle, NULL, NULL, &FileTime)))
1165         memset(&FileTime, 0, sizeof(FileTime));
1166 
1167     return (FileTime);
1168 }
1169 
1170 
1171 
1172 static sal_Bool lockFile(const osl_TFile* pFile, osl_TLockMode eMode)
1173 {
1174     sal_Bool     status = sal_False;
1175     OVERLAPPED  Overlapped;
1176 
1177     if (pFile->m_Handle == INVALID_HANDLE_VALUE)
1178         return (sal_False);
1179 
1180     memset(&Overlapped, 0, sizeof(Overlapped));
1181 
1182     switch (eMode)
1183     {
1184         case un_lock:
1185             status = (sal_Bool) UnlockFileEx(
1186                 pFile->m_Handle, 0, 0xFFFFFFFF, 0, &Overlapped);
1187             break;
1188 
1189         case read_lock:
1190             status = (sal_Bool) LockFileEx(
1191                 pFile->m_Handle, 0, 0, 0xFFFFFFFF, 0, &Overlapped);
1192             break;
1193 
1194         case write_lock:
1195             status = (sal_Bool) LockFileEx(
1196                 pFile->m_Handle, LOCKFILE_EXCLUSIVE_LOCK, 0, 0xFFFFFFFF, 0,
1197                 &Overlapped);
1198             break;
1199     }
1200 
1201     return (status);
1202 }
1203 
1204 
1205 static osl_TFile* openFileImpl(rtl_uString * strFileName, oslProfileOption ProfileFlags )
1206 {
1207     osl_TFile* pFile = reinterpret_cast< osl_TFile*>( calloc( 1, sizeof(osl_TFile) ) );
1208     sal_Bool bWriteable = sal_False;
1209 
1210 /*    if ( ProfileFlags & ( osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE | osl_Profile_READWRITE ) )*/
1211     if ( ProfileFlags & ( osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE ) )
1212     {
1213 #ifdef DEBUG_OSL_PROFILE
1214         OSL_TRACE("setting bWriteable to TRUE\n");
1215 #endif
1216         bWriteable=sal_True;
1217     }
1218 
1219     if (! bWriteable)
1220     {
1221 #if 0
1222 //#ifdef DEBUG_OSL_PROFILE
1223         OSL_TRACE("opening '%s' read only\n",pszFilename);
1224 #endif
1225 
1226         pFile->m_Handle = CreateFileW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( strFileName )), GENERIC_READ,
1227                                           FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1228                                           OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1229 
1230         /* mfe: argghh!!! do not check if the file could be openend */
1231         /*      default mode expects it that way!!!                 */
1232     }
1233     else
1234     {
1235 #ifdef DEBUG_OSL_PROFILE
1236         OSL_TRACE("opening '%s' read/write\n",pszFilename);
1237 #endif
1238 
1239         if ((pFile->m_Handle = CreateFileW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( strFileName )), GENERIC_READ | GENERIC_WRITE,
1240                                                FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1241                                                OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL))
1242             == INVALID_HANDLE_VALUE)
1243         {
1244             free(pFile);
1245             return (NULL);
1246         }
1247     }
1248 
1249     pFile->m_pWriteBuf=0;
1250     pFile->m_nWriteBufFree=0;
1251     pFile->m_nWriteBufLen=0;
1252 
1253     if ( ProfileFlags & (osl_Profile_WRITELOCK | osl_Profile_READLOCK ) )
1254     {
1255 #ifdef DEBUG_OSL_PROFILE
1256         OSL_TRACE("locking '%s' file\n",pszFilename);
1257 #endif
1258 
1259         lockFile(pFile, bWriteable ? write_lock : read_lock);
1260     }
1261 
1262     /* mfe: new WriteBuf obsolete */
1263 /*  pFile->m_pWritePtr = pFile->m_Buf;*/
1264 /*  pFile->m_pReadPtr  = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);*/
1265 
1266     return (pFile);
1267 }
1268 
1269 
1270 
1271 
1272 
1273 
1274 
1275 
1276 
1277 static osl_TStamp closeFileImpl(osl_TFile* pFile)
1278 {
1279     osl_TStamp stamp = {0, 0};
1280 
1281     if ( pFile == 0 )
1282     {
1283         return stamp;
1284     }
1285 
1286     if (pFile->m_Handle != INVALID_HANDLE_VALUE)
1287     {
1288        /* mfe: new WriteBuf obsolete */
1289         /* we just closing the file here, DO NOT write, it has to be handled in higher levels */
1290 /*      if (pFile->m_pWritePtr > pFile->m_Buf)*/
1291 /*      {*/
1292 /*          DWORD Bytes;*/
1293 
1294 /*          WriteFile(pFile->m_Handle, pFile->m_WriteBuf,*/
1295 /*                    pFile->m_pWritePtr - pFile->m_WriteBuf,*/
1296 /*                    &Bytes, NULL);*/
1297 /*      }*/
1298 
1299         stamp = getFileStamp(pFile);
1300 
1301         lockFile(pFile, un_lock);
1302 
1303         CloseHandle(pFile->m_Handle);
1304         pFile->m_Handle = INVALID_HANDLE_VALUE;
1305     }
1306 
1307     if ( pFile->m_pWriteBuf != 0 )
1308     {
1309         free(pFile->m_pWriteBuf);
1310     }
1311 
1312     free(pFile);
1313 
1314     return(stamp);
1315 }
1316 
1317 
1318 
1319 
1320 
1321 
1322 
1323 
1324 static sal_Bool rewindFile(osl_TFile* pFile, sal_Bool bTruncate)
1325 {
1326     if (pFile->m_Handle != INVALID_HANDLE_VALUE)
1327     {
1328         /* mfe: new WriteBuf obsolete */
1329         /* we just closing the file here, DO NOT write, it has to be handled in higher levels */
1330 /*      if (pFile->m_pWritePtr > pFile->m_WriteBuf)*/
1331 /*      {*/
1332 /*          DWORD Bytes;*/
1333 
1334 /*          WriteFile(pFile->m_Handle, pFile->m_WriteBuf,*/
1335 /*                    pFile->m_pWritePtr - pFile->m_WriteBuf,*/
1336 /*                    &Bytes, NULL);*/
1337 
1338 /*          pFile->m_pWritePtr = pFile->m_WriteBuf;*/
1339 /*      }*/
1340 
1341         pFile->m_pReadPtr = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);
1342 
1343         SetFilePointer(pFile->m_Handle, 0, NULL, FILE_BEGIN);
1344 
1345         if (bTruncate)
1346             SetEndOfFile(pFile->m_Handle);
1347     }
1348 
1349     return (sal_True);
1350 }
1351 
1352 
1353 
1354 
1355 
1356 
1357 
1358 
1359 
1360 
1361 static sal_Bool getLine(osl_TFile* pFile, const sal_Char *pszLine, int MaxLen)
1362 {
1363     DWORD Max;
1364     size_t Free, Bytes;
1365     sal_Char* pChr;
1366     sal_Char* pLine = (sal_Char *)pszLine;
1367 
1368     if (pFile->m_Handle == INVALID_HANDLE_VALUE)
1369         return (sal_False);
1370 
1371     MaxLen -= 1;
1372 
1373     do
1374     {
1375         Bytes = sizeof(pFile->m_ReadBuf) - (pFile->m_pReadPtr - pFile->m_ReadBuf);
1376 
1377         if (Bytes <= 1)
1378         {
1379             /* refill buffer */
1380             memcpy(pFile->m_ReadBuf, pFile->m_pReadPtr, Bytes);
1381             pFile->m_pReadPtr = pFile->m_ReadBuf;
1382 
1383             Free = sizeof(pFile->m_ReadBuf) - Bytes;
1384 
1385             if (! ReadFile(pFile->m_Handle, &pFile->m_ReadBuf[Bytes], Free, &Max, NULL))
1386             {
1387                 *pLine = '\0';
1388                 return (sal_False);
1389             }
1390 
1391             if (Max < Free)
1392             {
1393                 if ((Max == 0) && (pLine == pszLine))
1394                 {
1395                     *pLine = '\0';
1396                     return (sal_False);
1397                 }
1398 
1399                 pFile->m_ReadBuf[Bytes + Max] = '\0';
1400             }
1401         }
1402 
1403         for (pChr = pFile->m_pReadPtr;
1404              (*pChr != '\n') && (*pChr != '\r') && (*pChr != '\0') &&
1405              (pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf) - 1));
1406              pChr++);
1407 
1408         Max = min(pChr - pFile->m_pReadPtr, MaxLen);
1409         memcpy(pLine, pFile->m_pReadPtr, Max);
1410         MaxLen -= Max;
1411         pLine  += Max;
1412 
1413         if (pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf) - 1))
1414         {
1415             if (*pChr != '\0')
1416             {
1417                 if ((pChr[0] == '\r') && (pChr[1] == '\n'))
1418                     pChr += 2;
1419                 else
1420                     pChr += 1;
1421             }
1422 
1423             if ((pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf))) &&
1424                 (*pChr == '\0'))
1425                 pChr = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);
1426 
1427             *pLine = '\0';
1428 
1429             /* setting MaxLen to -1 indicates terminating read loop */
1430             MaxLen = -1;
1431         }
1432 
1433         pFile->m_pReadPtr = pChr;
1434     }
1435     while (MaxLen > 0);
1436 
1437     return (sal_True);
1438 }
1439 
1440 
1441 
1442 
1443 
1444 
1445 
1446 
1447 
1448 
1449 static sal_Bool putLine(osl_TFile* pFile, const sal_Char *pszLine)
1450 {
1451     unsigned int Len = strlen(pszLine);
1452 
1453 #ifdef DEBUG_OSL_PROFILE
1454     int strLen=0;
1455 #endif
1456 
1457     if ( pFile == 0 || pFile->m_Handle < 0 )
1458     {
1459         return (sal_False);
1460     }
1461 
1462     if ( pFile->m_pWriteBuf == 0 )
1463     {
1464         pFile->m_pWriteBuf = (sal_Char*) malloc(Len+3);
1465         pFile->m_nWriteBufLen = Len+3;
1466         pFile->m_nWriteBufFree = Len+3;
1467     }
1468     else
1469     {
1470         if ( pFile->m_nWriteBufFree <= Len + 3 )
1471         {
1472             sal_Char* pTmp;
1473 
1474             pTmp=(sal_Char*) realloc(pFile->m_pWriteBuf,( ( pFile->m_nWriteBufLen + Len ) * 2) );
1475             if ( pTmp == 0 )
1476             {
1477                 return sal_False;
1478             }
1479             pFile->m_pWriteBuf = pTmp;
1480             pFile->m_nWriteBufFree = pFile->m_nWriteBufFree + pFile->m_nWriteBufLen + ( 2 * Len );
1481             pFile->m_nWriteBufLen = ( pFile->m_nWriteBufLen + Len ) * 2;
1482             memset( (pFile->m_pWriteBuf) + ( pFile->m_nWriteBufLen - pFile->m_nWriteBufFree ), 0, pFile->m_nWriteBufFree);
1483         }
1484     }
1485 
1486 
1487 
1488     memcpy(pFile->m_pWriteBuf + ( pFile->m_nWriteBufLen - pFile->m_nWriteBufFree ),pszLine,Len+1);
1489 #ifdef DEBUG_OSL_PROFILE
1490     strLen = strlen(pFile->m_pWriteBuf);
1491 #endif
1492     pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len]='\r';
1493     pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len + 1]='\n';
1494     pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len + 2]='\0';
1495 
1496     pFile->m_nWriteBufFree-=Len+2;
1497 
1498 #ifdef DEBUG_OSL_PROFILE
1499 /*    OSL_TRACE("File Buffer in _putLine '%s' '%i'(%i)\n",pFile->m_pWriteBuf,strlen(pFile->m_pWriteBuf),pFile->m_nWriteBufLen - pFile->m_nWriteBufFree);*/
1500 #endif
1501 
1502     return (sal_True);
1503 }
1504 
1505 /* platform specific end */
1506 
1507 
1508 static const sal_Char* stripBlanks(const sal_Char* String, sal_uInt32* pLen)
1509 {
1510     if ( (pLen != NULL) && ( *pLen != 0 ) )
1511     {
1512         while ((String[*pLen - 1] == ' ') || (String[*pLen - 1] == '\t'))
1513             (*pLen)--;
1514 
1515         while ((*String == ' ') || (*String == '\t'))
1516         {
1517             String++;
1518             (*pLen)--;
1519         }
1520     }
1521     else
1522         while ((*String == ' ') || (*String == '\t'))
1523             String++;
1524 
1525     return (String);
1526 }
1527 
1528 static const sal_Char* addLine(osl_TProfileImpl* pProfile, const sal_Char* Line)
1529 {
1530     if (pProfile->m_NoLines >= pProfile->m_MaxLines)
1531     {
1532         if (pProfile->m_Lines == NULL)
1533         {
1534             pProfile->m_MaxLines = LINES_INI;
1535             pProfile->m_Lines = (sal_Char **)calloc(pProfile->m_MaxLines, sizeof(sal_Char *));
1536         }
1537         else
1538         {
1539             unsigned int index=0;
1540             unsigned int oldmax=pProfile->m_MaxLines;
1541 
1542             pProfile->m_MaxLines += LINES_ADD;
1543             pProfile->m_Lines = (sal_Char **)realloc(pProfile->m_Lines, pProfile->m_MaxLines * sizeof(sal_Char *));
1544 
1545             for ( index = oldmax ; index < pProfile->m_MaxLines ; ++index )
1546             {
1547                 pProfile->m_Lines[index]=0;
1548             }
1549         }
1550 
1551         if (pProfile->m_Lines == NULL)
1552         {
1553             pProfile->m_NoLines  = 0;
1554             pProfile->m_MaxLines = 0;
1555             return (NULL);
1556         }
1557 
1558     }
1559 
1560     if ( pProfile->m_Lines != 0 && pProfile->m_Lines[pProfile->m_NoLines] != 0 )
1561     {
1562             free(pProfile->m_Lines[pProfile->m_NoLines]);
1563     }
1564     pProfile->m_Lines[pProfile->m_NoLines++] = strdup(Line);
1565 
1566     return (pProfile->m_Lines[pProfile->m_NoLines - 1]);
1567 }
1568 
1569 static const sal_Char* insertLine(osl_TProfileImpl* pProfile, const sal_Char* Line, sal_uInt32 LineNo)
1570 {
1571     if (pProfile->m_NoLines >= pProfile->m_MaxLines)
1572     {
1573         if (pProfile->m_Lines == NULL)
1574         {
1575             pProfile->m_MaxLines = LINES_INI;
1576             pProfile->m_Lines = (sal_Char **)calloc(pProfile->m_MaxLines, sizeof(sal_Char *));
1577         }
1578         else
1579         {
1580             pProfile->m_MaxLines += LINES_ADD;
1581             pProfile->m_Lines = (sal_Char **)realloc(pProfile->m_Lines,
1582                                                  pProfile->m_MaxLines * sizeof(sal_Char *));
1583 
1584             memset(&pProfile->m_Lines[pProfile->m_NoLines],
1585                 0,
1586                 (pProfile->m_MaxLines - pProfile->m_NoLines - 1) * sizeof(sal_Char*));
1587         }
1588 
1589         if (pProfile->m_Lines == NULL)
1590         {
1591             pProfile->m_NoLines  = 0;
1592             pProfile->m_MaxLines = 0;
1593             return (NULL);
1594         }
1595     }
1596 
1597     LineNo = LineNo > pProfile->m_NoLines ? pProfile->m_NoLines : LineNo;
1598 
1599     if (LineNo < pProfile->m_NoLines)
1600     {
1601         sal_uInt32 i, n;
1602         osl_TProfileSection* pSec;
1603 
1604         memmove(&pProfile->m_Lines[LineNo + 1], &pProfile->m_Lines[LineNo],
1605                 (pProfile->m_NoLines - LineNo) * sizeof(sal_Char *));
1606 
1607 
1608         /* adjust line references */
1609         for (i = 0; i < pProfile->m_NoSections; i++)
1610         {
1611             pSec = &pProfile->m_Sections[i];
1612 
1613             if (pSec->m_Line >= LineNo)
1614                 pSec->m_Line++;
1615 
1616             for (n = 0; n < pSec->m_NoEntries; n++)
1617                 if (pSec->m_Entries[n].m_Line >= LineNo)
1618                     pSec->m_Entries[n].m_Line++;
1619         }
1620     }
1621 
1622     pProfile->m_NoLines++;
1623 
1624     pProfile->m_Lines[LineNo] = strdup(Line);
1625 
1626     return (pProfile->m_Lines[LineNo]);
1627 }
1628 
1629 static void removeLine(osl_TProfileImpl* pProfile, sal_uInt32 LineNo)
1630 {
1631     if (LineNo < pProfile->m_NoLines)
1632     {
1633         free(pProfile->m_Lines[LineNo]);
1634         pProfile->m_Lines[LineNo]=0;
1635         if (pProfile->m_NoLines - LineNo > 1)
1636         {
1637             sal_uInt32 i, n;
1638             osl_TProfileSection* pSec;
1639 
1640             memmove(&pProfile->m_Lines[LineNo], &pProfile->m_Lines[LineNo + 1],
1641                     (pProfile->m_NoLines - LineNo - 1) * sizeof(sal_Char *));
1642 
1643             memset(&pProfile->m_Lines[pProfile->m_NoLines - 1],
1644                 0,
1645                 (pProfile->m_MaxLines - pProfile->m_NoLines) * sizeof(sal_Char*));
1646 
1647             /* adjust line references */
1648             for (i = 0; i < pProfile->m_NoSections; i++)
1649             {
1650                 pSec = &pProfile->m_Sections[i];
1651 
1652                 if (pSec->m_Line > LineNo)
1653                     pSec->m_Line--;
1654 
1655                 for (n = 0; n < pSec->m_NoEntries; n++)
1656                     if (pSec->m_Entries[n].m_Line > LineNo)
1657                         pSec->m_Entries[n].m_Line--;
1658             }
1659         }
1660         else
1661         {
1662             pProfile->m_Lines[LineNo] = 0;
1663         }
1664 
1665         pProfile->m_NoLines--;
1666     }
1667 
1668     return;
1669 }
1670 
1671 static void setEntry(osl_TProfileImpl* pProfile, osl_TProfileSection* pSection,
1672                      sal_uInt32 NoEntry, sal_uInt32 Line,
1673                      const sal_Char* Entry, sal_uInt32 Len)
1674 {
1675     Entry = stripBlanks(Entry, &Len);
1676     pSection->m_Entries[NoEntry].m_Line   = Line;
1677     pSection->m_Entries[NoEntry].m_Offset = Entry - pProfile->m_Lines[Line];
1678     pSection->m_Entries[NoEntry].m_Len    = Len;
1679 
1680     return;
1681 }
1682 
1683 static sal_Bool addEntry(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection,
1684                         int Line, const sal_Char* Entry, sal_uInt32 Len)
1685 {
1686     if (pSection != NULL)
1687     {
1688         if (pSection->m_NoEntries >= pSection->m_MaxEntries)
1689         {
1690             if (pSection->m_Entries == NULL)
1691             {
1692                 pSection->m_MaxEntries = ENTRIES_INI;
1693                 pSection->m_Entries = (osl_TProfileEntry *)malloc(
1694                                 pSection->m_MaxEntries * sizeof(osl_TProfileEntry));
1695             }
1696             else
1697             {
1698                 pSection->m_MaxEntries += ENTRIES_ADD;
1699                 pSection->m_Entries = (osl_TProfileEntry *)realloc(pSection->m_Entries,
1700                                 pSection->m_MaxEntries * sizeof(osl_TProfileEntry));
1701             }
1702 
1703             if (pSection->m_Entries == NULL)
1704             {
1705                 pSection->m_NoEntries  = 0;
1706                 pSection->m_MaxEntries = 0;
1707                 return (sal_False);
1708             }
1709         }
1710 
1711         pSection->m_NoEntries++;
1712 
1713         Entry = stripBlanks(Entry, &Len);
1714         setEntry(pProfile, pSection, pSection->m_NoEntries - 1, Line,
1715                  Entry, Len);
1716 
1717         return (sal_True);
1718     }
1719 
1720     return (sal_False);
1721 }
1722 
1723 static void removeEntry(osl_TProfileSection *pSection, sal_uInt32 NoEntry)
1724 {
1725     if (NoEntry < pSection->m_NoEntries)
1726     {
1727         if (pSection->m_NoEntries - NoEntry > 1)
1728         {
1729             memmove(&pSection->m_Entries[NoEntry],
1730                     &pSection->m_Entries[NoEntry + 1],
1731                     (pSection->m_NoEntries - NoEntry - 1) * sizeof(osl_TProfileEntry));
1732             pSection->m_Entries[pSection->m_NoEntries - 1].m_Line=0;
1733             pSection->m_Entries[pSection->m_NoEntries - 1].m_Offset=0;
1734             pSection->m_Entries[pSection->m_NoEntries - 1].m_Len=0;
1735         }
1736 
1737         pSection->m_NoEntries--;
1738     }
1739 
1740     return;
1741 }
1742 
1743 static sal_Bool addSection(osl_TProfileImpl* pProfile, int Line, const sal_Char* Section, sal_uInt32 Len)
1744 {
1745     if (pProfile->m_NoSections >= pProfile->m_MaxSections)
1746     {
1747         if (pProfile->m_Sections == NULL)
1748         {
1749             pProfile->m_MaxSections = SECTIONS_INI;
1750             pProfile->m_Sections = (osl_TProfileSection *)calloc(pProfile->m_MaxSections, sizeof(osl_TProfileSection));
1751         }
1752         else
1753         {
1754             unsigned int index=0;
1755             unsigned int oldmax=pProfile->m_MaxSections;
1756 
1757             pProfile->m_MaxSections += SECTIONS_ADD;
1758             pProfile->m_Sections = (osl_TProfileSection *)realloc(pProfile->m_Sections,
1759                                           pProfile->m_MaxSections * sizeof(osl_TProfileSection));
1760             for ( index = oldmax ; index < pProfile->m_MaxSections ; ++index )
1761             {
1762                 pProfile->m_Sections[index].m_Entries=0;
1763             }
1764         }
1765 
1766         if (pProfile->m_Sections == NULL)
1767         {
1768             pProfile->m_NoSections = 0;
1769             pProfile->m_MaxSections = 0;
1770             return (sal_False);
1771         }
1772     }
1773 
1774     pProfile->m_NoSections++;
1775 
1776     if ( pProfile->m_Sections[(pProfile->m_NoSections) - 1].m_Entries != 0 )
1777     {
1778         free(pProfile->m_Sections[(pProfile->m_NoSections) - 1].m_Entries);
1779     }
1780     pProfile->m_Sections[pProfile->m_NoSections - 1].m_Entries    = NULL;
1781     pProfile->m_Sections[pProfile->m_NoSections - 1].m_NoEntries  = 0;
1782     pProfile->m_Sections[pProfile->m_NoSections - 1].m_MaxEntries = 0;
1783 
1784     Section = (sal_Char *)stripBlanks(Section, &Len);
1785     pProfile->m_Sections[pProfile->m_NoSections - 1].m_Line = Line;
1786     pProfile->m_Sections[pProfile->m_NoSections - 1].m_Offset = Section - pProfile->m_Lines[Line];
1787     pProfile->m_Sections[pProfile->m_NoSections - 1].m_Len = Len;
1788 
1789     return (sal_True);
1790 }
1791 
1792 static void removeSection(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection)
1793 {
1794     sal_uInt32 Section;
1795 
1796     if ((Section = pSection - pProfile->m_Sections) < pProfile->m_NoSections)
1797     {
1798         free (pSection->m_Entries);
1799         pSection->m_Entries=0;
1800         if (pProfile->m_NoSections - Section > 1)
1801         {
1802             memmove(&pProfile->m_Sections[Section], &pProfile->m_Sections[Section + 1],
1803                     (pProfile->m_NoSections - Section - 1) * sizeof(osl_TProfileSection));
1804 
1805             memset(&pProfile->m_Sections[pProfile->m_NoSections - 1],
1806                 0,
1807                 (pProfile->m_MaxSections - pProfile->m_NoSections) * sizeof(osl_TProfileSection));
1808             pProfile->m_Sections[pProfile->m_NoSections - 1].m_Entries = 0;
1809         }
1810         else
1811         {
1812             pSection->m_Entries = 0;
1813         }
1814 
1815         pProfile->m_NoSections--;
1816     }
1817 
1818     return;
1819 }
1820 
1821 static osl_TProfileSection* findEntry(osl_TProfileImpl* pProfile, const sal_Char* Section,
1822                                       const sal_Char* Entry, sal_uInt32 *pNoEntry)
1823 {
1824 static  sal_uInt32    Sect = 0;
1825         sal_uInt32    i, n;
1826         sal_uInt32    Len;
1827         const sal_Char* pStr;
1828         osl_TProfileSection* pSec = NULL;
1829 
1830     Len = strlen(Section);
1831     Section = (sal_Char *)stripBlanks(Section, &Len);
1832 
1833     n = Sect;
1834 
1835     for (i = 0; i < pProfile->m_NoSections; i++)
1836     {
1837         n %= pProfile->m_NoSections;
1838         pSec = &pProfile->m_Sections[n];
1839         if ((Len == pSec->m_Len) &&
1840             (strnicmp(Section, &pProfile->m_Lines[pSec->m_Line][pSec->m_Offset], pSec->m_Len)
1841              == 0))
1842             break;
1843         n++;
1844     }
1845 
1846     Sect = n;
1847 
1848     if (i < pProfile->m_NoSections)
1849     {
1850         Len = strlen(Entry);
1851         Entry = stripBlanks(Entry, &Len);
1852 
1853         *pNoEntry = pSec->m_NoEntries;
1854 
1855         for (i = 0; i < pSec->m_NoEntries; i++)
1856         {
1857             pStr = &pProfile->m_Lines[pSec->m_Entries[i].m_Line]
1858                                      [pSec->m_Entries[i].m_Offset];
1859             if ((Len == pSec->m_Entries[i].m_Len) &&
1860                 (strnicmp(Entry, pStr, pSec->m_Entries[i].m_Len)
1861                  == 0))
1862             {
1863                 *pNoEntry = i;
1864                 break;
1865             }
1866         }
1867     }
1868     else
1869         pSec = NULL;
1870 
1871     return (pSec);
1872 }
1873 
1874 static sal_Bool loadProfile(osl_TFile* pFile, osl_TProfileImpl* pProfile)
1875 {
1876     sal_uInt32    i;
1877     sal_Char*       pStr;
1878     sal_Char*       pChar;
1879     sal_Char        Line[4096];
1880 
1881     pProfile->m_NoLines    = 0;
1882     pProfile->m_NoSections = 0;
1883 
1884     OSL_VERIFY(rewindFile(pFile, sal_False));
1885 
1886     while (getLine(pFile, Line, sizeof(Line)))
1887     {
1888         if (! addLine(pProfile, Line))
1889             return (sal_False);
1890     }
1891 
1892     for (i = 0; i < pProfile->m_NoLines; i++)
1893     {
1894         pStr = (sal_Char *)stripBlanks(pProfile->m_Lines[i], NULL);
1895 
1896         if ((*pStr == '\0') || (*pStr == ';'))
1897             continue;
1898 
1899         if ((*pStr != '[') || ((pChar = strrchr(pStr, ']')) == NULL) ||
1900             ((pChar - pStr) <= 2))
1901         {
1902             /* insert entry */
1903 
1904             if (pProfile->m_NoSections < 1)
1905                 continue;
1906 
1907             if ((pChar = strchr(pStr, '=')) == NULL)
1908                 pChar = pStr + strlen(pStr);
1909 
1910             if (! addEntry(pProfile, &pProfile->m_Sections[pProfile->m_NoSections - 1],
1911                            i, pStr, pChar - pStr))
1912                 return (sal_False);
1913         }
1914         else
1915         {
1916             /* new section */
1917 
1918             if (! addSection(pProfile, i, pStr + 1, pChar - pStr - 1))
1919                 return (sal_False);
1920         }
1921     }
1922 
1923     return (sal_True);
1924 }
1925 
1926 
1927 
1928 
1929 
1930 static sal_Bool storeProfile(osl_TProfileImpl* pProfile, sal_Bool bCleanup)
1931 {
1932 #ifdef TRACE_OSL_PROFILE
1933     OSL_TRACE("In  storeProfile\n");
1934 #endif
1935 
1936     if (pProfile->m_Lines != NULL)
1937     {
1938         if (pProfile->m_Flags & FLG_MODIFIED)
1939         {
1940             sal_uInt32 i;
1941 
1942             osl_TFile* pTmpFile = osl_openTmpProfileImpl(pProfile);
1943 
1944             if ( pTmpFile == 0 )
1945             {
1946                 return sal_False;
1947             }
1948 
1949             OSL_VERIFY(rewindFile(pTmpFile, sal_True));
1950 
1951             for (i = 0; i < pProfile->m_NoLines; i++)
1952             {
1953                 OSL_VERIFY(putLine(pTmpFile, pProfile->m_Lines[i]));
1954             }
1955 
1956             if ( ! writeProfileImpl(pTmpFile) )
1957             {
1958                 if ( pTmpFile->m_pWriteBuf != 0 )
1959                 {
1960                     free(pTmpFile->m_pWriteBuf);
1961                 }
1962 
1963                 pTmpFile->m_pWriteBuf=0;
1964                 pTmpFile->m_nWriteBufLen=0;
1965                 pTmpFile->m_nWriteBufFree=0;
1966 
1967 #ifdef TRACE_OSL_PROFILE
1968                 OSL_TRACE("Out storeProfile [not flushed]\n");
1969 #endif
1970                 closeFileImpl(pTmpFile);
1971 
1972                 return sal_False;
1973             }
1974 
1975             pProfile->m_Flags &= ~FLG_MODIFIED;
1976 
1977             closeFileImpl(pProfile->m_pFile);
1978             closeFileImpl(pTmpFile);
1979 
1980             osl_ProfileSwapProfileNames(pProfile);
1981 
1982 /*          free(pProfile->m_pFile);*/
1983 /*          free(pTmpFile);*/
1984 
1985             pProfile->m_pFile = openFileImpl(pProfile->m_strFileName,pProfile->m_Flags);
1986 
1987         }
1988 
1989         if (bCleanup)
1990         {
1991             while (pProfile->m_NoLines > 0)
1992                 removeLine(pProfile, pProfile->m_NoLines - 1);
1993 
1994             free(pProfile->m_Lines);
1995             pProfile->m_Lines = NULL;
1996             pProfile->m_MaxLines = 0;
1997 
1998             while (pProfile->m_NoSections > 0)
1999                 removeSection(pProfile, &pProfile->m_Sections[pProfile->m_NoSections - 1]);
2000 
2001             free(pProfile->m_Sections);
2002             pProfile->m_Sections = NULL;
2003             pProfile->m_MaxSections = 0;
2004         }
2005     }
2006 
2007 #ifdef TRACE_OSL_PROFILE
2008     OSL_TRACE("Out storeProfile [ok]\n");
2009 #endif
2010     return (sal_True);
2011 }
2012 
2013 
2014 static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl* pProfile)
2015 {
2016     osl_TFile* pFile=0;
2017     rtl_uString* ustrExtension=0;
2018     rtl_uString* ustrTmpName=0;
2019     oslProfileOption PFlags=0;
2020 
2021     rtl_uString_newFromAscii(&ustrExtension,"tmp");
2022 
2023 
2024     /* generate tmp profilename */
2025     ustrTmpName=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
2026     rtl_uString_release(ustrExtension);
2027 
2028     if ( ustrTmpName == 0 )
2029     {
2030         return 0;
2031     }
2032 
2033 
2034     if ( ! ( pProfile->m_Flags & osl_Profile_READLOCK ) )
2035     {
2036         PFlags |= osl_Profile_WRITELOCK;
2037     }
2038 
2039     /* open this file */
2040     pFile = openFileImpl(ustrTmpName,pProfile->m_Flags | PFlags);
2041 
2042 
2043     /* return new pFile */
2044     return pFile;
2045 }
2046 
2047 
2048 static sal_Bool osl_ProfileSwapProfileNames(osl_TProfileImpl* pProfile)
2049 {
2050     sal_Bool bRet = sal_False;
2051 
2052     rtl_uString* ustrBakFile=0;
2053     rtl_uString* ustrTmpFile=0;
2054     rtl_uString* ustrIniFile=0;
2055     rtl_uString* ustrExtension=0;
2056 
2057 
2058     rtl_uString_newFromAscii(&ustrExtension,"bak");
2059 
2060     ustrBakFile=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
2061     rtl_uString_release(ustrExtension);
2062     ustrExtension=0;
2063 
2064 
2065     rtl_uString_newFromAscii(&ustrExtension,"ini");
2066 
2067     ustrIniFile=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
2068     rtl_uString_release(ustrExtension);
2069     ustrExtension=0;
2070 
2071 
2072     rtl_uString_newFromAscii(&ustrExtension,"tmp");
2073 
2074     ustrTmpFile=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
2075     rtl_uString_release(ustrExtension);
2076     ustrExtension=0;
2077 
2078 
2079     /* unlink bak */
2080     DeleteFileW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrBakFile )) );
2081 
2082     /* rename ini bak */
2083     MoveFileExW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrIniFile )), reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrBakFile )), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH );
2084 
2085     /* rename tmp ini */
2086     MoveFileExW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrTmpFile )), reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrIniFile )), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH );
2087 
2088     return bRet;
2089 }
2090 
2091 
2092 static rtl_uString* osl_ProfileGenerateExtension(rtl_uString* ustrFileName, rtl_uString* ustrExtension)
2093 {
2094     rtl_uString* ustrNewFileName=0;
2095     rtl_uString* ustrOldExtension = 0;
2096     sal_Unicode* pExtensionBuf = 0;
2097     sal_Unicode* pFileNameBuf  = 0;
2098     sal_Int32 nIndex = -1;
2099 
2100     pFileNameBuf = rtl_uString_getStr(ustrFileName);
2101 
2102     rtl_uString_newFromAscii(&ustrOldExtension,".");
2103 
2104     pExtensionBuf = rtl_uString_getStr(ustrOldExtension);
2105 
2106     nIndex = rtl_ustr_lastIndexOfChar(pFileNameBuf,*pExtensionBuf);
2107 
2108     rtl_uString_newReplaceStrAt(&ustrNewFileName,
2109                                 ustrFileName,
2110                                 nIndex+1,
2111                                 3,
2112                                 ustrExtension);
2113 
2114     return ustrNewFileName;
2115 }
2116 
2117 
2118 static osl_TProfileImpl* acquireProfile(oslProfile Profile, sal_Bool bWriteable)
2119 {
2120     osl_TProfileImpl* pProfile = (osl_TProfileImpl*)Profile;
2121     oslProfileOption PFlags=0;
2122 
2123 
2124     if ( bWriteable )
2125     {
2126 /*          PFlags = osl_Profile_DEFAULT | osl_Profile_READWRITE; */
2127         PFlags = osl_Profile_DEFAULT | osl_Profile_WRITELOCK;
2128     }
2129     else
2130     {
2131         PFlags = osl_Profile_DEFAULT;
2132     }
2133 
2134 
2135     if (pProfile == NULL)
2136     {
2137 #ifdef DEBUG_OSL_PROFILE
2138         OSL_TRACE("AUTOOPEN MODE\n");
2139 #endif
2140 
2141 
2142 
2143         if ( ( pProfile = (osl_TProfileImpl*)osl_openProfile( NULL, PFlags ) ) != NULL )
2144         {
2145             pProfile->m_Flags |= FLG_AUTOOPEN;
2146         }
2147     }
2148     else
2149     {
2150 #ifdef DEBUG_OSL_PROFILE
2151         OSL_TRACE("try to acquire\n");
2152 #endif
2153 
2154 
2155 
2156         if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
2157         {
2158             if (! (pProfile->m_Flags & (osl_Profile_READLOCK |
2159                                         osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE)))
2160             {
2161                 osl_TStamp Stamp;
2162 #ifdef DEBUG_OSL_PROFILE
2163                 OSL_TRACE("DEFAULT MODE\n");
2164 #endif
2165                 pProfile->m_pFile = openFileImpl(
2166                     pProfile->m_strFileName, pProfile->m_Flags | PFlags);
2167                 if (!pProfile->m_pFile)
2168                     return NULL;
2169 
2170                 Stamp = getFileStamp(pProfile->m_pFile);
2171 
2172                 if (memcmp(&Stamp, &(pProfile->m_Stamp), sizeof(osl_TStamp)))
2173                 {
2174                     pProfile->m_Stamp = Stamp;
2175 
2176                     loadProfile(pProfile->m_pFile, pProfile);
2177                 }
2178             }
2179             else
2180             {
2181 #ifdef DEBUG_OSL_PROFILE
2182                 OSL_TRACE("READ/WRITELOCK MODE\n");
2183 #endif
2184 
2185 
2186                 /* A readlock file could not be written */
2187                 if ((pProfile->m_Flags & osl_Profile_READLOCK) && bWriteable)
2188                 {
2189                     return (NULL);
2190                 }
2191             }
2192         }
2193     }
2194 
2195     return (pProfile);
2196 }
2197 
2198 static sal_Bool releaseProfile(osl_TProfileImpl* pProfile)
2199 {
2200 #ifdef TRACE_OSL_PROFILE
2201     OSL_TRACE("In  releaseProfile\n");
2202 #endif
2203 
2204     if ( pProfile == 0 )
2205     {
2206 #ifdef TRACE_OSL_PROFILE
2207         OSL_TRACE("Out releaseProfile [profile==0]\n");
2208 #endif
2209         return sal_False;
2210     }
2211 
2212     if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
2213     {
2214         if (pProfile->m_Flags & FLG_AUTOOPEN)
2215         {
2216 #ifdef TRACE_OSL_PROFILE
2217         OSL_TRACE("Out releaseProfile [AUTOOPEN]\n");
2218 #endif
2219             return (osl_closeProfile((oslProfile)pProfile));
2220         }
2221         else
2222         {
2223 #ifdef DEBUG_OSL_PROFILE
2224         OSL_TRACE("DEFAULT MODE\n");
2225 #endif
2226         if (! (pProfile->m_Flags & (osl_Profile_READLOCK |
2227                                     osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE)))
2228             {
2229                 if (pProfile->m_Flags & FLG_MODIFIED)
2230                     storeProfile(pProfile, sal_False);
2231 
2232                 closeFileImpl(pProfile->m_pFile);
2233                 pProfile->m_pFile = NULL;
2234             }
2235         }
2236     }
2237 
2238 #ifdef TRACE_OSL_PROFILE
2239     OSL_TRACE("Out releaseProfile [ok]\n");
2240 #endif
2241     return (sal_True);
2242 }
2243 
2244 static sal_Bool lookupProfile(const sal_Unicode *strPath, const sal_Unicode *strFile, sal_Unicode *strProfile)
2245 {
2246     sal_Char *pChr, *pStr;
2247     sal_Char Buffer[4096] = "";
2248     sal_Char Product[132] = "";
2249 
2250     ::osl::LongPathBuffer< sal_Unicode > aPath( MAX_LONG_PATH );
2251     aPath[0] = 0;
2252     DWORD dwPathLen = 0;
2253 
2254     if (*strPath == L'"')
2255     {
2256         int i = 0;
2257 
2258         strPath++;
2259 
2260         while ((strPath[i] != L'"') && (strPath[i] != L'\0'))
2261             i++;
2262 
2263         WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(strPath), i, Product, sizeof(Product), NULL, NULL);
2264         Product[i] = '\0';
2265         strPath += i;
2266 
2267         if (*strPath == L'"')
2268             strPath++;
2269 
2270         if ( (*strPath == L'/') || (*strPath == L'\\') )
2271         {
2272             strPath++;
2273         }
2274     }
2275 
2276     else
2277     {
2278         /* if we have not product identfication, do a special handling for soffice.ini */
2279         if (rtl_ustr_ascii_compare(strFile, SVERSION_PROFILE) == 0)
2280         {
2281             rtl_uString * strSVProfile  = NULL;
2282             rtl_uString * strSVFallback = NULL;
2283             rtl_uString * strSVLocation = NULL;
2284             rtl_uString * strSVName     = NULL;
2285             ::osl::LongPathBuffer< sal_Char > aDir( MAX_LONG_PATH );
2286             oslProfile hProfile;
2287 
2288             rtl_uString_newFromAscii(&strSVFallback, SVERSION_FALLBACK);
2289             rtl_uString_newFromAscii(&strSVLocation, SVERSION_LOCATION);
2290             rtl_uString_newFromAscii(&strSVName, SVERSION_NAME);
2291 
2292             /* open sversion.ini in the system directory, and try to locate the entry
2293                with the highest version for StarOffice */
2294             if (osl_getProfileName( strSVFallback, strSVName, &strSVProfile))
2295             {
2296                 hProfile = osl_openProfile(strSVProfile, osl_Profile_READLOCK);
2297                 if (hProfile)
2298                 {
2299                     osl_getProfileSectionEntries(
2300                         hProfile, SVERSION_SECTION, Buffer, sizeof(Buffer));
2301 
2302                     for (pChr = Buffer; *pChr != '\0'; pChr += strlen(pChr) + 1)
2303                     {
2304                         if ((strnicmp(
2305                                  pChr, SVERSION_SOFFICE,
2306                                  sizeof(SVERSION_SOFFICE) - 1)
2307                              == 0)
2308                             && (stricmp(Product, pChr) < 0))
2309                         {
2310                             osl_readProfileString(
2311                                 hProfile, SVERSION_SECTION, pChr, aDir,
2312                                 aDir.getBufSizeInSymbols(), "");
2313 
2314                             /* check for existence of path */
2315                             if (access(aDir, 0) >= 0)
2316                                 strcpy(Product, pChr);
2317                         }
2318                     }
2319 
2320                     osl_closeProfile(hProfile);
2321                 }
2322                 rtl_uString_release(strSVProfile);
2323                 strSVProfile = NULL;
2324             }
2325 
2326             /* open sversion.ini in the users directory, and try to locate the entry
2327                with the highest version for StarOffice */
2328             if ((strcmp(SVERSION_LOCATION, SVERSION_FALLBACK) != 0) &&
2329                 (osl_getProfileName(strSVLocation, strSVName, &strSVProfile)))
2330             {
2331                 hProfile = osl_openProfile(strSVProfile, osl_Profile_READLOCK);
2332                 if (hProfile)
2333                 {
2334                     osl_getProfileSectionEntries(
2335                         hProfile, SVERSION_SECTION, Buffer, sizeof(Buffer));
2336 
2337                     for (pChr = Buffer; *pChr != '\0'; pChr += strlen(pChr) + 1)
2338                     {
2339                         if ((strnicmp(
2340                                  pChr, SVERSION_SOFFICE,
2341                                  sizeof(SVERSION_SOFFICE) - 1)
2342                              == 0)
2343                             && (stricmp(Product, pChr) < 0))
2344                         {
2345                             osl_readProfileString(
2346                                 hProfile, SVERSION_SECTION, pChr, aDir,
2347                                 aDir.getBufSizeInSymbols(), "");
2348 
2349                             /* check for existence of path */
2350                             if (access(aDir, 0) >= 0)
2351                                 strcpy(Product, pChr);
2352                         }
2353                     }
2354 
2355                     osl_closeProfile(hProfile);
2356                 }
2357                 rtl_uString_release(strSVProfile);
2358             }
2359 
2360             rtl_uString_release(strSVFallback);
2361             rtl_uString_release(strSVLocation);
2362             rtl_uString_release(strSVName);
2363 
2364             /* remove any trailing build number */
2365             if ((pChr = strrchr(Product, '/')) != NULL)
2366                 *pChr = '\0';
2367         }
2368     }
2369 
2370     /* if we have an userid option eg. "-userid:rh[/usr/home/rh/staroffice]",
2371        this will supercede all other locations */
2372     {
2373         sal_uInt32 n, nArgs = osl_getCommandArgCount();
2374 
2375         for (n = 0; n < nArgs; n++)
2376         {
2377             rtl_uString * strCommandArg = NULL;
2378 
2379             if ((osl_getCommandArg( n, &strCommandArg ) == osl_Process_E_None) &&
2380                 ((strCommandArg->buffer[0] == L'-') || (strCommandArg->buffer[0] == L'+')) &&
2381                 (rtl_ustr_ascii_compare_WithLength(strCommandArg->buffer, RTL_CONSTASCII_LENGTH(SVERSION_OPTION), SVERSION_OPTION)))
2382             {
2383                 sal_Unicode *pCommandArg = strCommandArg->buffer + RTL_CONSTASCII_LENGTH(SVERSION_OPTION);
2384                 sal_Int32 nStart, nEnd;
2385 
2386                 if (((nStart = rtl_ustr_indexOfChar(pCommandArg, L'[')) != -1) &&
2387                     ((nEnd = rtl_ustr_indexOfChar(pCommandArg + nStart + 1, L']')) != -1))
2388                 {
2389                     dwPathLen = nEnd;
2390                     copy_ustr_n(aPath, pCommandArg + nStart + 1, dwPathLen);
2391                     aPath[dwPathLen] = 0;
2392 
2393                     /* build full path */
2394                     if ((aPath[dwPathLen - 1] != L'/') && (aPath[dwPathLen - 1] != L'\\'))
2395                     {
2396                         copy_ustr_n(aPath + dwPathLen++, L"/", 2);
2397                     }
2398 
2399                     if (*strPath)
2400                     {
2401                         copy_ustr_n(aPath + dwPathLen, strPath, rtl_ustr_getLength(strPath)+1);
2402                         dwPathLen += rtl_ustr_getLength(strPath);
2403                     }
2404                     else
2405                     {
2406                         ::osl::LongPathBuffer< sal_Char > aTmpPath( MAX_LONG_PATH );
2407                         int n;
2408 
2409                         if ((n = WideCharToMultiByte(CP_ACP,0, ::osl::mingw_reinterpret_cast<LPCWSTR>(aPath), -1, aTmpPath, aTmpPath.getBufSizeInSymbols(), NULL, NULL)) > 0)
2410                         {
2411                             strcpy(aTmpPath + n, SVERSION_USER);
2412                             if (access(aTmpPath, 0) >= 0)
2413                             {
2414                                 dwPathLen += MultiByteToWideChar( CP_ACP, 0, SVERSION_USER, -1, reinterpret_cast<LPWSTR>(aPath + dwPathLen), aPath.getBufSizeInSymbols() - dwPathLen );
2415                             }
2416                         }
2417                     }
2418 
2419                     break;
2420                 }
2421             }
2422         }
2423     }
2424 
2425 
2426     if (dwPathLen == 0)
2427     {
2428         rtl_uString * strExecutable = NULL;
2429         rtl_uString * strTmp = NULL;
2430         sal_Int32 nPos;
2431 
2432         /* try to find the file in the directory of the executbale */
2433         if (osl_getExecutableFile(&strTmp) != osl_Process_E_None)
2434             return (sal_False);
2435 
2436         /* convert to native path */
2437         if (osl_getSystemPathFromFileURL(strTmp, &strExecutable) != osl_File_E_None)
2438         {
2439             rtl_uString_release(strTmp);
2440             return sal_False;
2441         }
2442 
2443         rtl_uString_release(strTmp);
2444 
2445         /* separate path from filename */
2446         if ((nPos = rtl_ustr_lastIndexOfChar(strExecutable->buffer, L'\\')) == -1)
2447         {
2448             if ((nPos = rtl_ustr_lastIndexOfChar(strExecutable->buffer, L':')) == -1)
2449             {
2450                 return sal_False;
2451             }
2452             else
2453             {
2454                 copy_ustr_n(aPath, strExecutable->buffer, nPos);
2455                 aPath[nPos] = 0;
2456                 dwPathLen = nPos;
2457             }
2458         }
2459         else
2460         {
2461             copy_ustr_n(aPath, strExecutable->buffer, nPos);
2462             dwPathLen = nPos;
2463             aPath[dwPathLen] = 0;
2464         }
2465 
2466         /* if we have no product identification use the executable file name */
2467         if (*Product == 0)
2468         {
2469             WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(strExecutable->buffer + nPos + 1), -1, Product, sizeof(Product), NULL, NULL);
2470 
2471             /* remove extension */
2472             if ((pChr = strrchr(Product, '.')) != NULL)
2473                 *pChr = '\0';
2474         }
2475 
2476         rtl_uString_release(strExecutable);
2477 
2478         /* remember last subdir */
2479         nPos = rtl_ustr_lastIndexOfChar(aPath, L'\\');
2480 
2481         copy_ustr_n(aPath + dwPathLen++, L"\\", 2);
2482 
2483         if (*strPath)
2484         {
2485             copy_ustr_n(aPath + dwPathLen, strPath, rtl_ustr_getLength(strPath)+1);
2486             dwPathLen += rtl_ustr_getLength(strPath);
2487         }
2488 
2489         {
2490             ::osl::LongPathBuffer< sal_Char > aTmpPath( MAX_LONG_PATH );
2491 
2492             WideCharToMultiByte(CP_ACP,0, ::osl::mingw_reinterpret_cast<LPCWSTR>(aPath), -1, aTmpPath, aTmpPath.getBufSizeInSymbols(), NULL, NULL);
2493 
2494             /* if file not exists, remove any specified subdirectories
2495                like "bin" or "program" */
2496 
2497             if (((access(aTmpPath, 0) < 0) && (nPos != -1)) || (*strPath == 0))
2498             {
2499                 static sal_Char *SubDirs[] = SVERSION_DIRS;
2500 
2501                 int i = 0;
2502                 pStr = aTmpPath + nPos;
2503 
2504                 for (i = 0; i < (sizeof(SubDirs) / sizeof(SubDirs[0])); i++)
2505                     if (strnicmp(pStr + 1, SubDirs[i], strlen(SubDirs[i])) == 0)
2506                     {
2507                         if ( *strPath == 0)
2508                         {
2509                             strcpy(pStr + 1,SVERSION_USER);
2510                             if ( access(aTmpPath, 0) < 0 )
2511                             {
2512                                 *(pStr+1)='\0';
2513                             }
2514                             else
2515                             {
2516                                 dwPathLen = nPos + MultiByteToWideChar( CP_ACP, 0, SVERSION_USER, -1, reinterpret_cast<LPWSTR>(aPath + nPos + 1), aPath.getBufSizeInSymbols() - (nPos + 1) );
2517                             }
2518                         }
2519                         else
2520                         {
2521                             copy_ustr_n(aPath + nPos + 1, strPath, rtl_ustr_getLength(strPath)+1);
2522                             dwPathLen = nPos + 1 + rtl_ustr_getLength(strPath);
2523                         }
2524 
2525                         break;
2526                     }
2527             }
2528         }
2529 
2530         if ((aPath[dwPathLen - 1] != L'/') && (aPath[dwPathLen - 1] != L'\\'))
2531         {
2532             aPath[dwPathLen++] = L'\\';
2533             aPath[dwPathLen] = 0;
2534         }
2535 
2536         copy_ustr_n(aPath + dwPathLen, strFile, rtl_ustr_getLength(strFile)+1);
2537 
2538         {
2539             ::osl::LongPathBuffer< sal_Char > aTmpPath( MAX_LONG_PATH );
2540 
2541             WideCharToMultiByte(CP_ACP,0, ::osl::mingw_reinterpret_cast<LPCWSTR>(aPath), -1, aTmpPath, aTmpPath.getBufSizeInSymbols(), NULL, NULL);
2542 
2543             if ((access(aTmpPath, 0) < 0) && (strlen(Product) > 0))
2544             {
2545                 rtl_uString * strSVFallback = NULL;
2546                 rtl_uString * strSVProfile  = NULL;
2547                 rtl_uString * strSVLocation = NULL;
2548                 rtl_uString * strSVName     = NULL;
2549                 oslProfile hProfile;
2550 
2551                 rtl_uString_newFromAscii(&strSVFallback, SVERSION_FALLBACK);
2552                 rtl_uString_newFromAscii(&strSVLocation, SVERSION_LOCATION);
2553                 rtl_uString_newFromAscii(&strSVName, SVERSION_NAME);
2554 
2555                 /* open sversion.ini in the system directory, and try to locate the entry
2556                    with the highest version for StarOffice */
2557                 if (osl_getProfileName(strSVLocation, strSVName, &strSVProfile))
2558                 {
2559                     hProfile = osl_openProfile(
2560                         strSVProfile, osl_Profile_READLOCK);
2561                     if (hProfile)
2562                     {
2563                         osl_readProfileString(
2564                             hProfile, SVERSION_SECTION, Product, Buffer,
2565                             sizeof(Buffer), "");
2566                         osl_closeProfile(hProfile);
2567 
2568                         /* if not found, try the fallback */
2569                         if ((strlen(Buffer) <= 0)
2570                             && (strcmp(SVERSION_LOCATION, SVERSION_FALLBACK)
2571                                 != 0))
2572                         {
2573                             if (osl_getProfileName(
2574                                     strSVFallback, strSVName, &strSVProfile))
2575                             {
2576                                 hProfile = osl_openProfile(
2577                                     strSVProfile, osl_Profile_READLOCK);
2578                                 if (hProfile)
2579                                 {
2580                                     osl_readProfileString(
2581                                         hProfile, SVERSION_SECTION, Product,
2582                                         Buffer, sizeof(Buffer), "");
2583                                 }
2584                             }
2585 
2586                             osl_closeProfile(hProfile);
2587                         }
2588 
2589                         if (strlen(Buffer) > 0)
2590                         {
2591                             dwPathLen = MultiByteToWideChar(
2592                                 CP_ACP, 0, Buffer, -1, ::osl::mingw_reinterpret_cast<LPWSTR>(aPath), aPath.getBufSizeInSymbols() );
2593                             dwPathLen -=1;
2594 
2595                             /* build full path */
2596                             if ((aPath[dwPathLen - 1] != L'/')
2597                                 && (aPath[dwPathLen - 1] != L'\\'))
2598                             {
2599                                 copy_ustr_n(aPath + dwPathLen++, L"\\", 2);
2600                             }
2601 
2602                             if (*strPath)
2603                             {
2604                                 copy_ustr_n(aPath + dwPathLen, strPath, rtl_ustr_getLength(strPath)+1);
2605                                 dwPathLen += rtl_ustr_getLength(strPath);
2606                             }
2607                             else
2608                             {
2609                                 ::osl::LongPathBuffer< sal_Char > aTmpPath( MAX_LONG_PATH );
2610                                 int n;
2611 
2612                                 if ((n = WideCharToMultiByte(
2613                                          CP_ACP,0, ::osl::mingw_reinterpret_cast<LPCWSTR>(aPath), -1, aTmpPath,
2614                                          aTmpPath.getBufSizeInSymbols(), NULL, NULL))
2615                                     > 0)
2616                                 {
2617                                     strcpy(aTmpPath + n, SVERSION_USER);
2618                                     if (access(aTmpPath, 0) >= 0)
2619                                     {
2620                                         dwPathLen += MultiByteToWideChar(
2621                                             CP_ACP, 0, SVERSION_USER, -1,
2622                                             reinterpret_cast<LPWSTR>(aPath + dwPathLen),
2623                                             aPath.getBufSizeInSymbols() - dwPathLen );
2624                                     }
2625                                 }
2626                             }
2627                         }
2628                     }
2629 
2630                     rtl_uString_release(strSVProfile);
2631                 }
2632 
2633                 rtl_uString_release(strSVFallback);
2634                 rtl_uString_release(strSVLocation);
2635                 rtl_uString_release(strSVName);
2636             }
2637         }
2638 
2639         aPath[dwPathLen] = 0;
2640     }
2641 
2642     /* copy filename */
2643     copy_ustr_n(strProfile, aPath, dwPathLen+1);
2644 
2645     return sal_True;
2646 }
2647 
2648 
2649