xref: /AOO41X/main/sal/osl/w32/profile.cxx (revision 8809db7a87f97847b57a57f4cd2b0104b2b83182)
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 
1206 
1207 
1208 
1209 
1210 
1211 
1212 
1213 
1214 
1215 
1216 
1217 
1218 
1219 
1220 
1221 
1222 
1223 
1224 
1225 
1226 
1227 
1228 
1229 
1230 
1231 
1232 
1233 
1234 
1235 
1236 
1237 
1238 
1239 
1240 
1241 
1242 
1243 
1244 
1245 
1246 
1247 
1248 
1249 
1250 
1251 
1252 
1253 
1254 
1255 
1256 
1257 static osl_TFile* openFileImpl(rtl_uString * strFileName, oslProfileOption ProfileFlags )
1258 {
1259     osl_TFile* pFile = reinterpret_cast< osl_TFile*>( calloc( 1, sizeof(osl_TFile) ) );
1260     sal_Bool bWriteable = sal_False;
1261 
1262 /*    if ( ProfileFlags & ( osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE | osl_Profile_READWRITE ) )*/
1263     if ( ProfileFlags & ( osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE ) )
1264     {
1265 #ifdef DEBUG_OSL_PROFILE
1266         OSL_TRACE("setting bWriteable to TRUE\n");
1267 #endif
1268         bWriteable=sal_True;
1269     }
1270 
1271     if (! bWriteable)
1272     {
1273 #if 0
1274 //#ifdef DEBUG_OSL_PROFILE
1275         OSL_TRACE("opening '%s' read only\n",pszFilename);
1276 #endif
1277 
1278         pFile->m_Handle = CreateFileW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( strFileName )), GENERIC_READ,
1279                                           FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1280                                           OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1281 
1282         /* mfe: argghh!!! do not check if the file could be openend */
1283         /*      default mode expects it that way!!!                 */
1284     }
1285     else
1286     {
1287 #ifdef DEBUG_OSL_PROFILE
1288         OSL_TRACE("opening '%s' read/write\n",pszFilename);
1289 #endif
1290 
1291         if ((pFile->m_Handle = CreateFileW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( strFileName )), GENERIC_READ | GENERIC_WRITE,
1292                                                FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1293                                                OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL))
1294             == INVALID_HANDLE_VALUE)
1295         {
1296             free(pFile);
1297             return (NULL);
1298         }
1299     }
1300 
1301     pFile->m_pWriteBuf=0;
1302     pFile->m_nWriteBufFree=0;
1303     pFile->m_nWriteBufLen=0;
1304 
1305     if ( ProfileFlags & (osl_Profile_WRITELOCK | osl_Profile_READLOCK ) )
1306     {
1307 #ifdef DEBUG_OSL_PROFILE
1308         OSL_TRACE("locking '%s' file\n",pszFilename);
1309 #endif
1310 
1311         lockFile(pFile, bWriteable ? write_lock : read_lock);
1312     }
1313 
1314     /* mfe: new WriteBuf obsolete */
1315 /*  pFile->m_pWritePtr = pFile->m_Buf;*/
1316 /*  pFile->m_pReadPtr  = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);*/
1317 
1318     return (pFile);
1319 }
1320 
1321 
1322 
1323 
1324 
1325 
1326 
1327 
1328 
1329 static osl_TStamp closeFileImpl(osl_TFile* pFile)
1330 {
1331     osl_TStamp stamp = {0, 0};
1332 
1333     if ( pFile == 0 )
1334     {
1335         return stamp;
1336     }
1337 
1338     if (pFile->m_Handle != INVALID_HANDLE_VALUE)
1339     {
1340        /* mfe: new WriteBuf obsolete */
1341         /* we just closing the file here, DO NOT write, it has to be handled in higher levels */
1342 /*      if (pFile->m_pWritePtr > pFile->m_Buf)*/
1343 /*      {*/
1344 /*          DWORD Bytes;*/
1345 
1346 /*          WriteFile(pFile->m_Handle, pFile->m_WriteBuf,*/
1347 /*                    pFile->m_pWritePtr - pFile->m_WriteBuf,*/
1348 /*                    &Bytes, NULL);*/
1349 /*      }*/
1350 
1351         stamp = getFileStamp(pFile);
1352 
1353         lockFile(pFile, un_lock);
1354 
1355         CloseHandle(pFile->m_Handle);
1356         pFile->m_Handle = INVALID_HANDLE_VALUE;
1357     }
1358 
1359     if ( pFile->m_pWriteBuf != 0 )
1360     {
1361         free(pFile->m_pWriteBuf);
1362     }
1363 
1364     free(pFile);
1365 
1366     return(stamp);
1367 }
1368 
1369 
1370 
1371 
1372 
1373 
1374 
1375 
1376 static sal_Bool rewindFile(osl_TFile* pFile, sal_Bool bTruncate)
1377 {
1378     if (pFile->m_Handle != INVALID_HANDLE_VALUE)
1379     {
1380         /* mfe: new WriteBuf obsolete */
1381         /* we just closing the file here, DO NOT write, it has to be handled in higher levels */
1382 /*      if (pFile->m_pWritePtr > pFile->m_WriteBuf)*/
1383 /*      {*/
1384 /*          DWORD Bytes;*/
1385 
1386 /*          WriteFile(pFile->m_Handle, pFile->m_WriteBuf,*/
1387 /*                    pFile->m_pWritePtr - pFile->m_WriteBuf,*/
1388 /*                    &Bytes, NULL);*/
1389 
1390 /*          pFile->m_pWritePtr = pFile->m_WriteBuf;*/
1391 /*      }*/
1392 
1393         pFile->m_pReadPtr = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);
1394 
1395         SetFilePointer(pFile->m_Handle, 0, NULL, FILE_BEGIN);
1396 
1397         if (bTruncate)
1398             SetEndOfFile(pFile->m_Handle);
1399     }
1400 
1401     return (sal_True);
1402 }
1403 
1404 
1405 
1406 
1407 
1408 
1409 
1410 
1411 
1412 
1413 static sal_Bool getLine(osl_TFile* pFile, const sal_Char *pszLine, int MaxLen)
1414 {
1415     DWORD Max;
1416     size_t Free, Bytes;
1417     sal_Char* pChr;
1418     sal_Char* pLine = (sal_Char *)pszLine;
1419 
1420     if (pFile->m_Handle == INVALID_HANDLE_VALUE)
1421         return (sal_False);
1422 
1423     MaxLen -= 1;
1424 
1425     do
1426     {
1427         Bytes = sizeof(pFile->m_ReadBuf) - (pFile->m_pReadPtr - pFile->m_ReadBuf);
1428 
1429         if (Bytes <= 1)
1430         {
1431             /* refill buffer */
1432             memcpy(pFile->m_ReadBuf, pFile->m_pReadPtr, Bytes);
1433             pFile->m_pReadPtr = pFile->m_ReadBuf;
1434 
1435             Free = sizeof(pFile->m_ReadBuf) - Bytes;
1436 
1437             if (! ReadFile(pFile->m_Handle, &pFile->m_ReadBuf[Bytes], Free, &Max, NULL))
1438             {
1439                 *pLine = '\0';
1440                 return (sal_False);
1441             }
1442 
1443             if (Max < Free)
1444             {
1445                 if ((Max == 0) && (pLine == pszLine))
1446                 {
1447                     *pLine = '\0';
1448                     return (sal_False);
1449                 }
1450 
1451                 pFile->m_ReadBuf[Bytes + Max] = '\0';
1452             }
1453         }
1454 
1455         for (pChr = pFile->m_pReadPtr;
1456              (*pChr != '\n') && (*pChr != '\r') && (*pChr != '\0') &&
1457              (pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf) - 1));
1458              pChr++);
1459 
1460         Max = min(pChr - pFile->m_pReadPtr, MaxLen);
1461         memcpy(pLine, pFile->m_pReadPtr, Max);
1462         MaxLen -= Max;
1463         pLine  += Max;
1464 
1465         if (pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf) - 1))
1466         {
1467             if (*pChr != '\0')
1468             {
1469                 if ((pChr[0] == '\r') && (pChr[1] == '\n'))
1470                     pChr += 2;
1471                 else
1472                     pChr += 1;
1473             }
1474 
1475             if ((pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf))) &&
1476                 (*pChr == '\0'))
1477                 pChr = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);
1478 
1479             *pLine = '\0';
1480 
1481             /* setting MaxLen to -1 indicates terminating read loop */
1482             MaxLen = -1;
1483         }
1484 
1485         pFile->m_pReadPtr = pChr;
1486     }
1487     while (MaxLen > 0);
1488 
1489     return (sal_True);
1490 }
1491 
1492 
1493 
1494 
1495 
1496 
1497 
1498 
1499 
1500 
1501 static sal_Bool putLine(osl_TFile* pFile, const sal_Char *pszLine)
1502 {
1503     unsigned int Len = strlen(pszLine);
1504 
1505 #ifdef DEBUG_OSL_PROFILE
1506     int strLen=0;
1507 #endif
1508 
1509     if ( pFile == 0 || pFile->m_Handle < 0 )
1510     {
1511         return (sal_False);
1512     }
1513 
1514     if ( pFile->m_pWriteBuf == 0 )
1515     {
1516         pFile->m_pWriteBuf = (sal_Char*) malloc(Len+3);
1517         pFile->m_nWriteBufLen = Len+3;
1518         pFile->m_nWriteBufFree = Len+3;
1519     }
1520     else
1521     {
1522         if ( pFile->m_nWriteBufFree <= Len + 3 )
1523         {
1524             sal_Char* pTmp;
1525 
1526             pTmp=(sal_Char*) realloc(pFile->m_pWriteBuf,( ( pFile->m_nWriteBufLen + Len ) * 2) );
1527             if ( pTmp == 0 )
1528             {
1529                 return sal_False;
1530             }
1531             pFile->m_pWriteBuf = pTmp;
1532             pFile->m_nWriteBufFree = pFile->m_nWriteBufFree + pFile->m_nWriteBufLen + ( 2 * Len );
1533             pFile->m_nWriteBufLen = ( pFile->m_nWriteBufLen + Len ) * 2;
1534             memset( (pFile->m_pWriteBuf) + ( pFile->m_nWriteBufLen - pFile->m_nWriteBufFree ), 0, pFile->m_nWriteBufFree);
1535         }
1536     }
1537 
1538 
1539 
1540     memcpy(pFile->m_pWriteBuf + ( pFile->m_nWriteBufLen - pFile->m_nWriteBufFree ),pszLine,Len+1);
1541 #ifdef DEBUG_OSL_PROFILE
1542     strLen = strlen(pFile->m_pWriteBuf);
1543 #endif
1544     pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len]='\r';
1545     pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len + 1]='\n';
1546     pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len + 2]='\0';
1547 
1548     pFile->m_nWriteBufFree-=Len+2;
1549 
1550 #ifdef DEBUG_OSL_PROFILE
1551 /*    OSL_TRACE("File Buffer in _putLine '%s' '%i'(%i)\n",pFile->m_pWriteBuf,strlen(pFile->m_pWriteBuf),pFile->m_nWriteBufLen - pFile->m_nWriteBufFree);*/
1552 #endif
1553 
1554     return (sal_True);
1555 }
1556 
1557 /* platform specific end */
1558 
1559 
1560 static const sal_Char* stripBlanks(const sal_Char* String, sal_uInt32* pLen)
1561 {
1562     if ( (pLen != NULL) && ( *pLen != 0 ) )
1563     {
1564         while ((String[*pLen - 1] == ' ') || (String[*pLen - 1] == '\t'))
1565             (*pLen)--;
1566 
1567         while ((*String == ' ') || (*String == '\t'))
1568         {
1569             String++;
1570             (*pLen)--;
1571         }
1572     }
1573     else
1574         while ((*String == ' ') || (*String == '\t'))
1575             String++;
1576 
1577     return (String);
1578 }
1579 
1580 static const sal_Char* addLine(osl_TProfileImpl* pProfile, const sal_Char* Line)
1581 {
1582     if (pProfile->m_NoLines >= pProfile->m_MaxLines)
1583     {
1584         if (pProfile->m_Lines == NULL)
1585         {
1586             pProfile->m_MaxLines = LINES_INI;
1587             pProfile->m_Lines = (sal_Char **)malloc(pProfile->m_MaxLines * sizeof(sal_Char *));
1588             memset(pProfile->m_Lines,0,pProfile->m_MaxLines * sizeof(sal_Char *));
1589         }
1590         else
1591         {
1592             unsigned int index=0;
1593             unsigned int oldmax=pProfile->m_MaxLines;
1594 
1595             pProfile->m_MaxLines += LINES_ADD;
1596             pProfile->m_Lines = (sal_Char **)realloc(pProfile->m_Lines, pProfile->m_MaxLines * sizeof(sal_Char *));
1597 
1598             for ( index = oldmax ; index < pProfile->m_MaxLines ; ++index )
1599             {
1600                 pProfile->m_Lines[index]=0;
1601             }
1602         }
1603 
1604         if (pProfile->m_Lines == NULL)
1605         {
1606             pProfile->m_NoLines  = 0;
1607             pProfile->m_MaxLines = 0;
1608             return (NULL);
1609         }
1610 
1611     }
1612 
1613     if ( pProfile->m_Lines != 0 && pProfile->m_Lines[pProfile->m_NoLines] != 0 )
1614     {
1615             free(pProfile->m_Lines[pProfile->m_NoLines]);
1616     }
1617     pProfile->m_Lines[pProfile->m_NoLines++] = strdup(Line);
1618 
1619     return (pProfile->m_Lines[pProfile->m_NoLines - 1]);
1620 }
1621 
1622 static const sal_Char* insertLine(osl_TProfileImpl* pProfile, const sal_Char* Line, sal_uInt32 LineNo)
1623 {
1624     if (pProfile->m_NoLines >= pProfile->m_MaxLines)
1625     {
1626         if (pProfile->m_Lines == NULL)
1627         {
1628             pProfile->m_MaxLines = LINES_INI;
1629             pProfile->m_Lines = (sal_Char **)malloc(pProfile->m_MaxLines * sizeof(sal_Char *));
1630             memset(pProfile->m_Lines,0,pProfile->m_MaxLines * sizeof(sal_Char *));
1631         }
1632         else
1633         {
1634             pProfile->m_MaxLines += LINES_ADD;
1635             pProfile->m_Lines = (sal_Char **)realloc(pProfile->m_Lines,
1636                                                  pProfile->m_MaxLines * sizeof(sal_Char *));
1637 
1638             memset(&pProfile->m_Lines[pProfile->m_NoLines],
1639                 0,
1640                 (pProfile->m_MaxLines - pProfile->m_NoLines - 1) * sizeof(sal_Char*));
1641         }
1642 
1643         if (pProfile->m_Lines == NULL)
1644         {
1645             pProfile->m_NoLines  = 0;
1646             pProfile->m_MaxLines = 0;
1647             return (NULL);
1648         }
1649     }
1650 
1651     LineNo = LineNo > pProfile->m_NoLines ? pProfile->m_NoLines : LineNo;
1652 
1653     if (LineNo < pProfile->m_NoLines)
1654     {
1655         sal_uInt32 i, n;
1656         osl_TProfileSection* pSec;
1657 
1658         memmove(&pProfile->m_Lines[LineNo + 1], &pProfile->m_Lines[LineNo],
1659                 (pProfile->m_NoLines - LineNo) * sizeof(sal_Char *));
1660 
1661 
1662         /* adjust line references */
1663         for (i = 0; i < pProfile->m_NoSections; i++)
1664         {
1665             pSec = &pProfile->m_Sections[i];
1666 
1667             if (pSec->m_Line >= LineNo)
1668                 pSec->m_Line++;
1669 
1670             for (n = 0; n < pSec->m_NoEntries; n++)
1671                 if (pSec->m_Entries[n].m_Line >= LineNo)
1672                     pSec->m_Entries[n].m_Line++;
1673         }
1674     }
1675 
1676     pProfile->m_NoLines++;
1677 
1678     pProfile->m_Lines[LineNo] = strdup(Line);
1679 
1680     return (pProfile->m_Lines[LineNo]);
1681 }
1682 
1683 static void removeLine(osl_TProfileImpl* pProfile, sal_uInt32 LineNo)
1684 {
1685     if (LineNo < pProfile->m_NoLines)
1686     {
1687         free(pProfile->m_Lines[LineNo]);
1688         pProfile->m_Lines[LineNo]=0;
1689         if (pProfile->m_NoLines - LineNo > 1)
1690         {
1691             sal_uInt32 i, n;
1692             osl_TProfileSection* pSec;
1693 
1694             memmove(&pProfile->m_Lines[LineNo], &pProfile->m_Lines[LineNo + 1],
1695                     (pProfile->m_NoLines - LineNo - 1) * sizeof(sal_Char *));
1696 
1697             memset(&pProfile->m_Lines[pProfile->m_NoLines - 1],
1698                 0,
1699                 (pProfile->m_MaxLines - pProfile->m_NoLines) * sizeof(sal_Char*));
1700 
1701             /* adjust line references */
1702             for (i = 0; i < pProfile->m_NoSections; i++)
1703             {
1704                 pSec = &pProfile->m_Sections[i];
1705 
1706                 if (pSec->m_Line > LineNo)
1707                     pSec->m_Line--;
1708 
1709                 for (n = 0; n < pSec->m_NoEntries; n++)
1710                     if (pSec->m_Entries[n].m_Line > LineNo)
1711                         pSec->m_Entries[n].m_Line--;
1712             }
1713         }
1714         else
1715         {
1716             pProfile->m_Lines[LineNo] = 0;
1717         }
1718 
1719         pProfile->m_NoLines--;
1720     }
1721 
1722     return;
1723 }
1724 
1725 static void setEntry(osl_TProfileImpl* pProfile, osl_TProfileSection* pSection,
1726                      sal_uInt32 NoEntry, sal_uInt32 Line,
1727                      const sal_Char* Entry, sal_uInt32 Len)
1728 {
1729     Entry = stripBlanks(Entry, &Len);
1730     pSection->m_Entries[NoEntry].m_Line   = Line;
1731     pSection->m_Entries[NoEntry].m_Offset = Entry - pProfile->m_Lines[Line];
1732     pSection->m_Entries[NoEntry].m_Len    = Len;
1733 
1734     return;
1735 }
1736 
1737 static sal_Bool addEntry(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection,
1738                         int Line, const sal_Char* Entry, sal_uInt32 Len)
1739 {
1740     if (pSection != NULL)
1741     {
1742         if (pSection->m_NoEntries >= pSection->m_MaxEntries)
1743         {
1744             if (pSection->m_Entries == NULL)
1745             {
1746                 pSection->m_MaxEntries = ENTRIES_INI;
1747                 pSection->m_Entries = (osl_TProfileEntry *)malloc(
1748                                 pSection->m_MaxEntries * sizeof(osl_TProfileEntry));
1749             }
1750             else
1751             {
1752                 pSection->m_MaxEntries += ENTRIES_ADD;
1753                 pSection->m_Entries = (osl_TProfileEntry *)realloc(pSection->m_Entries,
1754                                 pSection->m_MaxEntries * sizeof(osl_TProfileEntry));
1755             }
1756 
1757             if (pSection->m_Entries == NULL)
1758             {
1759                 pSection->m_NoEntries  = 0;
1760                 pSection->m_MaxEntries = 0;
1761                 return (sal_False);
1762             }
1763         }
1764 
1765         pSection->m_NoEntries++;
1766 
1767         Entry = stripBlanks(Entry, &Len);
1768         setEntry(pProfile, pSection, pSection->m_NoEntries - 1, Line,
1769                  Entry, Len);
1770 
1771         return (sal_True);
1772     }
1773 
1774     return (sal_False);
1775 }
1776 
1777 static void removeEntry(osl_TProfileSection *pSection, sal_uInt32 NoEntry)
1778 {
1779     if (NoEntry < pSection->m_NoEntries)
1780     {
1781         if (pSection->m_NoEntries - NoEntry > 1)
1782         {
1783             memmove(&pSection->m_Entries[NoEntry],
1784                     &pSection->m_Entries[NoEntry + 1],
1785                     (pSection->m_NoEntries - NoEntry - 1) * sizeof(osl_TProfileEntry));
1786             pSection->m_Entries[pSection->m_NoEntries - 1].m_Line=0;
1787             pSection->m_Entries[pSection->m_NoEntries - 1].m_Offset=0;
1788             pSection->m_Entries[pSection->m_NoEntries - 1].m_Len=0;
1789         }
1790 
1791         pSection->m_NoEntries--;
1792     }
1793 
1794     return;
1795 }
1796 
1797 static sal_Bool addSection(osl_TProfileImpl* pProfile, int Line, const sal_Char* Section, sal_uInt32 Len)
1798 {
1799     if (pProfile->m_NoSections >= pProfile->m_MaxSections)
1800     {
1801         if (pProfile->m_Sections == NULL)
1802         {
1803             pProfile->m_MaxSections = SECTIONS_INI;
1804             pProfile->m_Sections = (osl_TProfileSection *)malloc(pProfile->m_MaxSections * sizeof(osl_TProfileSection));
1805             memset(pProfile->m_Sections,0,pProfile->m_MaxSections * sizeof(osl_TProfileSection));
1806         }
1807         else
1808         {
1809             unsigned int index=0;
1810             unsigned int oldmax=pProfile->m_MaxSections;
1811 
1812             pProfile->m_MaxSections += SECTIONS_ADD;
1813             pProfile->m_Sections = (osl_TProfileSection *)realloc(pProfile->m_Sections,
1814                                           pProfile->m_MaxSections * sizeof(osl_TProfileSection));
1815             for ( index = oldmax ; index < pProfile->m_MaxSections ; ++index )
1816             {
1817                 pProfile->m_Sections[index].m_Entries=0;
1818             }
1819         }
1820 
1821         if (pProfile->m_Sections == NULL)
1822         {
1823             pProfile->m_NoSections = 0;
1824             pProfile->m_MaxSections = 0;
1825             return (sal_False);
1826         }
1827     }
1828 
1829     pProfile->m_NoSections++;
1830 
1831     if ( pProfile->m_Sections[(pProfile->m_NoSections) - 1].m_Entries != 0 )
1832     {
1833         free(pProfile->m_Sections[(pProfile->m_NoSections) - 1].m_Entries);
1834     }
1835     pProfile->m_Sections[pProfile->m_NoSections - 1].m_Entries    = NULL;
1836     pProfile->m_Sections[pProfile->m_NoSections - 1].m_NoEntries  = 0;
1837     pProfile->m_Sections[pProfile->m_NoSections - 1].m_MaxEntries = 0;
1838 
1839     Section = (sal_Char *)stripBlanks(Section, &Len);
1840     pProfile->m_Sections[pProfile->m_NoSections - 1].m_Line = Line;
1841     pProfile->m_Sections[pProfile->m_NoSections - 1].m_Offset = Section - pProfile->m_Lines[Line];
1842     pProfile->m_Sections[pProfile->m_NoSections - 1].m_Len = Len;
1843 
1844     return (sal_True);
1845 }
1846 
1847 static void removeSection(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection)
1848 {
1849     sal_uInt32 Section;
1850 
1851     if ((Section = pSection - pProfile->m_Sections) < pProfile->m_NoSections)
1852     {
1853         free (pSection->m_Entries);
1854         pSection->m_Entries=0;
1855         if (pProfile->m_NoSections - Section > 1)
1856         {
1857             memmove(&pProfile->m_Sections[Section], &pProfile->m_Sections[Section + 1],
1858                     (pProfile->m_NoSections - Section - 1) * sizeof(osl_TProfileSection));
1859 
1860             memset(&pProfile->m_Sections[pProfile->m_NoSections - 1],
1861                 0,
1862                 (pProfile->m_MaxSections - pProfile->m_NoSections) * sizeof(osl_TProfileSection));
1863             pProfile->m_Sections[pProfile->m_NoSections - 1].m_Entries = 0;
1864         }
1865         else
1866         {
1867             pSection->m_Entries = 0;
1868         }
1869 
1870         pProfile->m_NoSections--;
1871     }
1872 
1873     return;
1874 }
1875 
1876 static osl_TProfileSection* findEntry(osl_TProfileImpl* pProfile, const sal_Char* Section,
1877                                       const sal_Char* Entry, sal_uInt32 *pNoEntry)
1878 {
1879 static  sal_uInt32    Sect = 0;
1880         sal_uInt32    i, n;
1881         sal_uInt32    Len;
1882         const sal_Char* pStr;
1883         osl_TProfileSection* pSec = NULL;
1884 
1885     Len = strlen(Section);
1886     Section = (sal_Char *)stripBlanks(Section, &Len);
1887 
1888     n = Sect;
1889 
1890     for (i = 0; i < pProfile->m_NoSections; i++)
1891     {
1892         n %= pProfile->m_NoSections;
1893         pSec = &pProfile->m_Sections[n];
1894         if ((Len == pSec->m_Len) &&
1895             (strnicmp(Section, &pProfile->m_Lines[pSec->m_Line][pSec->m_Offset], pSec->m_Len)
1896              == 0))
1897             break;
1898         n++;
1899     }
1900 
1901     Sect = n;
1902 
1903     if (i < pProfile->m_NoSections)
1904     {
1905         Len = strlen(Entry);
1906         Entry = stripBlanks(Entry, &Len);
1907 
1908         *pNoEntry = pSec->m_NoEntries;
1909 
1910         for (i = 0; i < pSec->m_NoEntries; i++)
1911         {
1912             pStr = &pProfile->m_Lines[pSec->m_Entries[i].m_Line]
1913                                      [pSec->m_Entries[i].m_Offset];
1914             if ((Len == pSec->m_Entries[i].m_Len) &&
1915                 (strnicmp(Entry, pStr, pSec->m_Entries[i].m_Len)
1916                  == 0))
1917             {
1918                 *pNoEntry = i;
1919                 break;
1920             }
1921         }
1922     }
1923     else
1924         pSec = NULL;
1925 
1926     return (pSec);
1927 }
1928 
1929 static sal_Bool loadProfile(osl_TFile* pFile, osl_TProfileImpl* pProfile)
1930 {
1931     sal_uInt32    i;
1932     sal_Char*       pStr;
1933     sal_Char*       pChar;
1934     sal_Char        Line[4096];
1935 
1936     pProfile->m_NoLines    = 0;
1937     pProfile->m_NoSections = 0;
1938 
1939     OSL_VERIFY(rewindFile(pFile, sal_False));
1940 
1941     while (getLine(pFile, Line, sizeof(Line)))
1942     {
1943         if (! addLine(pProfile, Line))
1944             return (sal_False);
1945     }
1946 
1947     for (i = 0; i < pProfile->m_NoLines; i++)
1948     {
1949         pStr = (sal_Char *)stripBlanks(pProfile->m_Lines[i], NULL);
1950 
1951         if ((*pStr == '\0') || (*pStr == ';'))
1952             continue;
1953 
1954         if ((*pStr != '[') || ((pChar = strrchr(pStr, ']')) == NULL) ||
1955             ((pChar - pStr) <= 2))
1956         {
1957             /* insert entry */
1958 
1959             if (pProfile->m_NoSections < 1)
1960                 continue;
1961 
1962             if ((pChar = strchr(pStr, '=')) == NULL)
1963                 pChar = pStr + strlen(pStr);
1964 
1965             if (! addEntry(pProfile, &pProfile->m_Sections[pProfile->m_NoSections - 1],
1966                            i, pStr, pChar - pStr))
1967                 return (sal_False);
1968         }
1969         else
1970         {
1971             /* new section */
1972 
1973             if (! addSection(pProfile, i, pStr + 1, pChar - pStr - 1))
1974                 return (sal_False);
1975         }
1976     }
1977 
1978     return (sal_True);
1979 }
1980 
1981 
1982 
1983 
1984 
1985 static sal_Bool storeProfile(osl_TProfileImpl* pProfile, sal_Bool bCleanup)
1986 {
1987 #ifdef TRACE_OSL_PROFILE
1988     OSL_TRACE("In  storeProfile\n");
1989 #endif
1990 
1991     if (pProfile->m_Lines != NULL)
1992     {
1993         if (pProfile->m_Flags & FLG_MODIFIED)
1994         {
1995             sal_uInt32 i;
1996 
1997             osl_TFile* pTmpFile = osl_openTmpProfileImpl(pProfile);
1998 
1999             if ( pTmpFile == 0 )
2000             {
2001                 return sal_False;
2002             }
2003 
2004             OSL_VERIFY(rewindFile(pTmpFile, sal_True));
2005 
2006             for (i = 0; i < pProfile->m_NoLines; i++)
2007             {
2008                 OSL_VERIFY(putLine(pTmpFile, pProfile->m_Lines[i]));
2009             }
2010 
2011             if ( ! writeProfileImpl(pTmpFile) )
2012             {
2013                 if ( pTmpFile->m_pWriteBuf != 0 )
2014                 {
2015                     free(pTmpFile->m_pWriteBuf);
2016                 }
2017 
2018                 pTmpFile->m_pWriteBuf=0;
2019                 pTmpFile->m_nWriteBufLen=0;
2020                 pTmpFile->m_nWriteBufFree=0;
2021 
2022 #ifdef TRACE_OSL_PROFILE
2023                 OSL_TRACE("Out storeProfile [not flushed]\n");
2024 #endif
2025                 closeFileImpl(pTmpFile);
2026 
2027                 return sal_False;
2028             }
2029 
2030             pProfile->m_Flags &= ~FLG_MODIFIED;
2031 
2032             closeFileImpl(pProfile->m_pFile);
2033             closeFileImpl(pTmpFile);
2034 
2035             osl_ProfileSwapProfileNames(pProfile);
2036 
2037 /*          free(pProfile->m_pFile);*/
2038 /*          free(pTmpFile);*/
2039 
2040             pProfile->m_pFile = openFileImpl(pProfile->m_strFileName,pProfile->m_Flags);
2041 
2042         }
2043 
2044         if (bCleanup)
2045         {
2046             while (pProfile->m_NoLines > 0)
2047                 removeLine(pProfile, pProfile->m_NoLines - 1);
2048 
2049             free(pProfile->m_Lines);
2050             pProfile->m_Lines = NULL;
2051             pProfile->m_MaxLines = 0;
2052 
2053             while (pProfile->m_NoSections > 0)
2054                 removeSection(pProfile, &pProfile->m_Sections[pProfile->m_NoSections - 1]);
2055 
2056             free(pProfile->m_Sections);
2057             pProfile->m_Sections = NULL;
2058             pProfile->m_MaxSections = 0;
2059         }
2060     }
2061 
2062 #ifdef TRACE_OSL_PROFILE
2063     OSL_TRACE("Out storeProfile [ok]\n");
2064 #endif
2065     return (sal_True);
2066 }
2067 
2068 
2069 static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl* pProfile)
2070 {
2071     osl_TFile* pFile=0;
2072     rtl_uString* ustrExtension=0;
2073     rtl_uString* ustrTmpName=0;
2074     oslProfileOption PFlags=0;
2075 
2076     rtl_uString_newFromAscii(&ustrExtension,"tmp");
2077 
2078 
2079     /* generate tmp profilename */
2080     ustrTmpName=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
2081     rtl_uString_release(ustrExtension);
2082 
2083     if ( ustrTmpName == 0 )
2084     {
2085         return 0;
2086     }
2087 
2088 
2089     if ( ! ( pProfile->m_Flags & osl_Profile_READLOCK ) )
2090     {
2091         PFlags |= osl_Profile_WRITELOCK;
2092     }
2093 
2094     /* open this file */
2095     pFile = openFileImpl(ustrTmpName,pProfile->m_Flags | PFlags);
2096 
2097 
2098     /* return new pFile */
2099     return pFile;
2100 }
2101 
2102 
2103 static sal_Bool osl_ProfileSwapProfileNames(osl_TProfileImpl* pProfile)
2104 {
2105     sal_Bool bRet = sal_False;
2106 
2107     rtl_uString* ustrBakFile=0;
2108     rtl_uString* ustrTmpFile=0;
2109     rtl_uString* ustrIniFile=0;
2110     rtl_uString* ustrExtension=0;
2111 
2112 
2113     rtl_uString_newFromAscii(&ustrExtension,"bak");
2114 
2115     ustrBakFile=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
2116     rtl_uString_release(ustrExtension);
2117     ustrExtension=0;
2118 
2119 
2120     rtl_uString_newFromAscii(&ustrExtension,"ini");
2121 
2122     ustrIniFile=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
2123     rtl_uString_release(ustrExtension);
2124     ustrExtension=0;
2125 
2126 
2127     rtl_uString_newFromAscii(&ustrExtension,"tmp");
2128 
2129     ustrTmpFile=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
2130     rtl_uString_release(ustrExtension);
2131     ustrExtension=0;
2132 
2133 
2134     /* unlink bak */
2135     DeleteFileW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrBakFile )) );
2136 
2137     /* rename ini bak */
2138     MoveFileExW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrIniFile )), reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrBakFile )), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH );
2139 
2140     /* rename tmp ini */
2141     MoveFileExW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrTmpFile )), reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrIniFile )), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH );
2142 
2143     return bRet;
2144 }
2145 
2146 
2147 static rtl_uString* osl_ProfileGenerateExtension(rtl_uString* ustrFileName, rtl_uString* ustrExtension)
2148 {
2149     rtl_uString* ustrNewFileName=0;
2150     rtl_uString* ustrOldExtension = 0;
2151     sal_Unicode* pExtensionBuf = 0;
2152     sal_Unicode* pFileNameBuf  = 0;
2153     sal_Int32 nIndex = -1;
2154 
2155     pFileNameBuf = rtl_uString_getStr(ustrFileName);
2156 
2157     rtl_uString_newFromAscii(&ustrOldExtension,".");
2158 
2159     pExtensionBuf = rtl_uString_getStr(ustrOldExtension);
2160 
2161     nIndex = rtl_ustr_lastIndexOfChar(pFileNameBuf,*pExtensionBuf);
2162 
2163     rtl_uString_newReplaceStrAt(&ustrNewFileName,
2164                                 ustrFileName,
2165                                 nIndex+1,
2166                                 3,
2167                                 ustrExtension);
2168 
2169     return ustrNewFileName;
2170 }
2171 
2172 
2173 static osl_TProfileImpl* acquireProfile(oslProfile Profile, sal_Bool bWriteable)
2174 {
2175     osl_TProfileImpl* pProfile = (osl_TProfileImpl*)Profile;
2176     oslProfileOption PFlags=0;
2177 
2178 
2179     if ( bWriteable )
2180     {
2181 /*          PFlags = osl_Profile_DEFAULT | osl_Profile_READWRITE; */
2182         PFlags = osl_Profile_DEFAULT | osl_Profile_WRITELOCK;
2183     }
2184     else
2185     {
2186         PFlags = osl_Profile_DEFAULT;
2187     }
2188 
2189 
2190     if (pProfile == NULL)
2191     {
2192 #ifdef DEBUG_OSL_PROFILE
2193         OSL_TRACE("AUTOOPEN MODE\n");
2194 #endif
2195 
2196 
2197 
2198         if ( ( pProfile = (osl_TProfileImpl*)osl_openProfile( NULL, PFlags ) ) != NULL )
2199         {
2200             pProfile->m_Flags |= FLG_AUTOOPEN;
2201         }
2202     }
2203     else
2204     {
2205 #ifdef DEBUG_OSL_PROFILE
2206         OSL_TRACE("try to acquire\n");
2207 #endif
2208 
2209 
2210 
2211         if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
2212         {
2213             if (! (pProfile->m_Flags & (osl_Profile_READLOCK |
2214                                         osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE)))
2215             {
2216                 osl_TStamp Stamp;
2217 #ifdef DEBUG_OSL_PROFILE
2218                 OSL_TRACE("DEFAULT MODE\n");
2219 #endif
2220                 pProfile->m_pFile = openFileImpl(
2221                     pProfile->m_strFileName, pProfile->m_Flags | PFlags);
2222                 if (!pProfile->m_pFile)
2223                     return NULL;
2224 
2225                 Stamp = getFileStamp(pProfile->m_pFile);
2226 
2227                 if (memcmp(&Stamp, &(pProfile->m_Stamp), sizeof(osl_TStamp)))
2228                 {
2229                     pProfile->m_Stamp = Stamp;
2230 
2231                     loadProfile(pProfile->m_pFile, pProfile);
2232                 }
2233             }
2234             else
2235             {
2236 #ifdef DEBUG_OSL_PROFILE
2237                 OSL_TRACE("READ/WRITELOCK MODE\n");
2238 #endif
2239 
2240 
2241                 /* A readlock file could not be written */
2242                 if ((pProfile->m_Flags & osl_Profile_READLOCK) && bWriteable)
2243                 {
2244                     return (NULL);
2245                 }
2246             }
2247         }
2248     }
2249 
2250     return (pProfile);
2251 }
2252 
2253 static sal_Bool releaseProfile(osl_TProfileImpl* pProfile)
2254 {
2255 #ifdef TRACE_OSL_PROFILE
2256     OSL_TRACE("In  releaseProfile\n");
2257 #endif
2258 
2259     if ( pProfile == 0 )
2260     {
2261 #ifdef TRACE_OSL_PROFILE
2262         OSL_TRACE("Out releaseProfile [profile==0]\n");
2263 #endif
2264         return sal_False;
2265     }
2266 
2267     if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
2268     {
2269         if (pProfile->m_Flags & FLG_AUTOOPEN)
2270         {
2271 #ifdef TRACE_OSL_PROFILE
2272         OSL_TRACE("Out releaseProfile [AUTOOPEN]\n");
2273 #endif
2274             return (osl_closeProfile((oslProfile)pProfile));
2275         }
2276         else
2277         {
2278 #ifdef DEBUG_OSL_PROFILE
2279         OSL_TRACE("DEFAULT MODE\n");
2280 #endif
2281         if (! (pProfile->m_Flags & (osl_Profile_READLOCK |
2282                                     osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE)))
2283             {
2284                 if (pProfile->m_Flags & FLG_MODIFIED)
2285                     storeProfile(pProfile, sal_False);
2286 
2287                 closeFileImpl(pProfile->m_pFile);
2288                 pProfile->m_pFile = NULL;
2289             }
2290         }
2291     }
2292 
2293 #ifdef TRACE_OSL_PROFILE
2294     OSL_TRACE("Out releaseProfile [ok]\n");
2295 #endif
2296     return (sal_True);
2297 }
2298 
2299 static sal_Bool lookupProfile(const sal_Unicode *strPath, const sal_Unicode *strFile, sal_Unicode *strProfile)
2300 {
2301     sal_Char *pChr, *pStr;
2302     sal_Char Buffer[4096] = "";
2303     sal_Char Product[132] = "";
2304 
2305     ::osl::LongPathBuffer< sal_Unicode > aPath( MAX_LONG_PATH );
2306     aPath[0] = 0;
2307     DWORD dwPathLen = 0;
2308 
2309     if (*strPath == L'"')
2310     {
2311         int i = 0;
2312 
2313         strPath++;
2314 
2315         while ((strPath[i] != L'"') && (strPath[i] != L'\0'))
2316             i++;
2317 
2318         WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(strPath), i, Product, sizeof(Product), NULL, NULL);
2319         Product[i] = '\0';
2320         strPath += i;
2321 
2322         if (*strPath == L'"')
2323             strPath++;
2324 
2325         if ( (*strPath == L'/') || (*strPath == L'\\') )
2326         {
2327             strPath++;
2328         }
2329     }
2330 
2331     else
2332     {
2333         /* if we have not product identfication, do a special handling for soffice.ini */
2334         if (rtl_ustr_ascii_compare(strFile, SVERSION_PROFILE) == 0)
2335         {
2336             rtl_uString * strSVProfile  = NULL;
2337             rtl_uString * strSVFallback = NULL;
2338             rtl_uString * strSVLocation = NULL;
2339             rtl_uString * strSVName     = NULL;
2340             ::osl::LongPathBuffer< sal_Char > aDir( MAX_LONG_PATH );
2341             oslProfile hProfile;
2342 
2343             rtl_uString_newFromAscii(&strSVFallback, SVERSION_FALLBACK);
2344             rtl_uString_newFromAscii(&strSVLocation, SVERSION_LOCATION);
2345             rtl_uString_newFromAscii(&strSVName, SVERSION_NAME);
2346 
2347             /* open sversion.ini in the system directory, and try to locate the entry
2348                with the highest version for StarOffice */
2349             if (osl_getProfileName( strSVFallback, strSVName, &strSVProfile))
2350             {
2351                 hProfile = osl_openProfile(strSVProfile, osl_Profile_READLOCK);
2352                 if (hProfile)
2353                 {
2354                     osl_getProfileSectionEntries(
2355                         hProfile, SVERSION_SECTION, Buffer, sizeof(Buffer));
2356 
2357                     for (pChr = Buffer; *pChr != '\0'; pChr += strlen(pChr) + 1)
2358                     {
2359                         if ((strnicmp(
2360                                  pChr, SVERSION_SOFFICE,
2361                                  sizeof(SVERSION_SOFFICE) - 1)
2362                              == 0)
2363                             && (stricmp(Product, pChr) < 0))
2364                         {
2365                             osl_readProfileString(
2366                                 hProfile, SVERSION_SECTION, pChr, aDir,
2367                                 aDir.getBufSizeInSymbols(), "");
2368 
2369                             /* check for existence of path */
2370                             if (access(aDir, 0) >= 0)
2371                                 strcpy(Product, pChr);
2372                         }
2373                     }
2374 
2375                     osl_closeProfile(hProfile);
2376                 }
2377                 rtl_uString_release(strSVProfile);
2378                 strSVProfile = NULL;
2379             }
2380 
2381             /* open sversion.ini in the users directory, and try to locate the entry
2382                with the highest version for StarOffice */
2383             if ((strcmp(SVERSION_LOCATION, SVERSION_FALLBACK) != 0) &&
2384                 (osl_getProfileName(strSVLocation, strSVName, &strSVProfile)))
2385             {
2386                 hProfile = osl_openProfile(strSVProfile, osl_Profile_READLOCK);
2387                 if (hProfile)
2388                 {
2389                     osl_getProfileSectionEntries(
2390                         hProfile, SVERSION_SECTION, Buffer, sizeof(Buffer));
2391 
2392                     for (pChr = Buffer; *pChr != '\0'; pChr += strlen(pChr) + 1)
2393                     {
2394                         if ((strnicmp(
2395                                  pChr, SVERSION_SOFFICE,
2396                                  sizeof(SVERSION_SOFFICE) - 1)
2397                              == 0)
2398                             && (stricmp(Product, pChr) < 0))
2399                         {
2400                             osl_readProfileString(
2401                                 hProfile, SVERSION_SECTION, pChr, aDir,
2402                                 aDir.getBufSizeInSymbols(), "");
2403 
2404                             /* check for existence of path */
2405                             if (access(aDir, 0) >= 0)
2406                                 strcpy(Product, pChr);
2407                         }
2408                     }
2409 
2410                     osl_closeProfile(hProfile);
2411                 }
2412                 rtl_uString_release(strSVProfile);
2413             }
2414 
2415             rtl_uString_release(strSVFallback);
2416             rtl_uString_release(strSVLocation);
2417             rtl_uString_release(strSVName);
2418 
2419             /* remove any trailing build number */
2420             if ((pChr = strrchr(Product, '/')) != NULL)
2421                 *pChr = '\0';
2422         }
2423     }
2424 
2425     /* if we have an userid option eg. "-userid:rh[/usr/home/rh/staroffice]",
2426        this will supercede all other locations */
2427     {
2428         sal_uInt32 n, nArgs = osl_getCommandArgCount();
2429 
2430         for (n = 0; n < nArgs; n++)
2431         {
2432             rtl_uString * strCommandArg = NULL;
2433 
2434             if ((osl_getCommandArg( n, &strCommandArg ) == osl_Process_E_None) &&
2435                 ((strCommandArg->buffer[0] == L'-') || (strCommandArg->buffer[0] == L'+')) &&
2436                 (rtl_ustr_ascii_compare_WithLength(strCommandArg->buffer, RTL_CONSTASCII_LENGTH(SVERSION_OPTION), SVERSION_OPTION)))
2437             {
2438                 sal_Unicode *pCommandArg = strCommandArg->buffer + RTL_CONSTASCII_LENGTH(SVERSION_OPTION);
2439                 sal_Int32 nStart, nEnd;
2440 
2441                 if (((nStart = rtl_ustr_indexOfChar(pCommandArg, L'[')) != -1) &&
2442                     ((nEnd = rtl_ustr_indexOfChar(pCommandArg + nStart + 1, L']')) != -1))
2443                 {
2444                     dwPathLen = nEnd;
2445                     copy_ustr_n(aPath, pCommandArg + nStart + 1, dwPathLen);
2446                     aPath[dwPathLen] = 0;
2447 
2448                     /* build full path */
2449                     if ((aPath[dwPathLen - 1] != L'/') && (aPath[dwPathLen - 1] != L'\\'))
2450                     {
2451                         copy_ustr_n(aPath + dwPathLen++, L"/", 2);
2452                     }
2453 
2454                     if (*strPath)
2455                     {
2456                         copy_ustr_n(aPath + dwPathLen, strPath, rtl_ustr_getLength(strPath)+1);
2457                         dwPathLen += rtl_ustr_getLength(strPath);
2458                     }
2459                     else
2460                     {
2461                         ::osl::LongPathBuffer< sal_Char > aTmpPath( MAX_LONG_PATH );
2462                         int n;
2463 
2464                         if ((n = WideCharToMultiByte(CP_ACP,0, ::osl::mingw_reinterpret_cast<LPCWSTR>(aPath), -1, aTmpPath, aTmpPath.getBufSizeInSymbols(), NULL, NULL)) > 0)
2465                         {
2466                             strcpy(aTmpPath + n, SVERSION_USER);
2467                             if (access(aTmpPath, 0) >= 0)
2468                             {
2469                                 dwPathLen += MultiByteToWideChar( CP_ACP, 0, SVERSION_USER, -1, reinterpret_cast<LPWSTR>(aPath + dwPathLen), aPath.getBufSizeInSymbols() - dwPathLen );
2470                             }
2471                         }
2472                     }
2473 
2474                     break;
2475                 }
2476             }
2477         }
2478     }
2479 
2480 
2481     if (dwPathLen == 0)
2482     {
2483         rtl_uString * strExecutable = NULL;
2484         rtl_uString * strTmp = NULL;
2485         sal_Int32 nPos;
2486 
2487         /* try to find the file in the directory of the executbale */
2488         if (osl_getExecutableFile(&strTmp) != osl_Process_E_None)
2489             return (sal_False);
2490 
2491         /* convert to native path */
2492         if (osl_getSystemPathFromFileURL(strTmp, &strExecutable) != osl_File_E_None)
2493         {
2494             rtl_uString_release(strTmp);
2495             return sal_False;
2496         }
2497 
2498         rtl_uString_release(strTmp);
2499 
2500         /* seperate path from filename */
2501         if ((nPos = rtl_ustr_lastIndexOfChar(strExecutable->buffer, L'\\')) == -1)
2502         {
2503             if ((nPos = rtl_ustr_lastIndexOfChar(strExecutable->buffer, L':')) == -1)
2504             {
2505                 return sal_False;
2506             }
2507             else
2508             {
2509                 copy_ustr_n(aPath, strExecutable->buffer, nPos);
2510                 aPath[nPos] = 0;
2511                 dwPathLen = nPos;
2512             }
2513         }
2514         else
2515         {
2516             copy_ustr_n(aPath, strExecutable->buffer, nPos);
2517             dwPathLen = nPos;
2518             aPath[dwPathLen] = 0;
2519         }
2520 
2521         /* if we have no product identification use the executable file name */
2522         if (*Product == 0)
2523         {
2524             WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(strExecutable->buffer + nPos + 1), -1, Product, sizeof(Product), NULL, NULL);
2525 
2526             /* remove extension */
2527             if ((pChr = strrchr(Product, '.')) != NULL)
2528                 *pChr = '\0';
2529         }
2530 
2531         rtl_uString_release(strExecutable);
2532 
2533         /* remember last subdir */
2534         nPos = rtl_ustr_lastIndexOfChar(aPath, L'\\');
2535 
2536         copy_ustr_n(aPath + dwPathLen++, L"\\", 2);
2537 
2538         if (*strPath)
2539         {
2540             copy_ustr_n(aPath + dwPathLen, strPath, rtl_ustr_getLength(strPath)+1);
2541             dwPathLen += rtl_ustr_getLength(strPath);
2542         }
2543 
2544         {
2545             ::osl::LongPathBuffer< sal_Char > aTmpPath( MAX_LONG_PATH );
2546 
2547             WideCharToMultiByte(CP_ACP,0, ::osl::mingw_reinterpret_cast<LPCWSTR>(aPath), -1, aTmpPath, aTmpPath.getBufSizeInSymbols(), NULL, NULL);
2548 
2549             /* if file not exists, remove any specified subdirectories
2550                like "bin" or "program" */
2551 
2552             if (((access(aTmpPath, 0) < 0) && (nPos != -1)) || (*strPath == 0))
2553             {
2554                 static sal_Char *SubDirs[] = SVERSION_DIRS;
2555 
2556                 int i = 0;
2557                 pStr = aTmpPath + nPos;
2558 
2559                 for (i = 0; i < (sizeof(SubDirs) / sizeof(SubDirs[0])); i++)
2560                     if (strnicmp(pStr + 1, SubDirs[i], strlen(SubDirs[i])) == 0)
2561                     {
2562                         if ( *strPath == 0)
2563                         {
2564                             strcpy(pStr + 1,SVERSION_USER);
2565                             if ( access(aTmpPath, 0) < 0 )
2566                             {
2567                                 *(pStr+1)='\0';
2568                             }
2569                             else
2570                             {
2571                                 dwPathLen = nPos + MultiByteToWideChar( CP_ACP, 0, SVERSION_USER, -1, reinterpret_cast<LPWSTR>(aPath + nPos + 1), aPath.getBufSizeInSymbols() - (nPos + 1) );
2572                             }
2573                         }
2574                         else
2575                         {
2576                             copy_ustr_n(aPath + nPos + 1, strPath, rtl_ustr_getLength(strPath)+1);
2577                             dwPathLen = nPos + 1 + rtl_ustr_getLength(strPath);
2578                         }
2579 
2580                         break;
2581                     }
2582             }
2583         }
2584 
2585         if ((aPath[dwPathLen - 1] != L'/') && (aPath[dwPathLen - 1] != L'\\'))
2586         {
2587             aPath[dwPathLen++] = L'\\';
2588             aPath[dwPathLen] = 0;
2589         }
2590 
2591         copy_ustr_n(aPath + dwPathLen, strFile, rtl_ustr_getLength(strFile)+1);
2592 
2593         {
2594             ::osl::LongPathBuffer< sal_Char > aTmpPath( MAX_LONG_PATH );
2595 
2596             WideCharToMultiByte(CP_ACP,0, ::osl::mingw_reinterpret_cast<LPCWSTR>(aPath), -1, aTmpPath, aTmpPath.getBufSizeInSymbols(), NULL, NULL);
2597 
2598             if ((access(aTmpPath, 0) < 0) && (strlen(Product) > 0))
2599             {
2600                 rtl_uString * strSVFallback = NULL;
2601                 rtl_uString * strSVProfile  = NULL;
2602                 rtl_uString * strSVLocation = NULL;
2603                 rtl_uString * strSVName     = NULL;
2604                 oslProfile hProfile;
2605 
2606                 rtl_uString_newFromAscii(&strSVFallback, SVERSION_FALLBACK);
2607                 rtl_uString_newFromAscii(&strSVLocation, SVERSION_LOCATION);
2608                 rtl_uString_newFromAscii(&strSVName, SVERSION_NAME);
2609 
2610                 /* open sversion.ini in the system directory, and try to locate the entry
2611                    with the highest version for StarOffice */
2612                 if (osl_getProfileName(strSVLocation, strSVName, &strSVProfile))
2613                 {
2614                     hProfile = osl_openProfile(
2615                         strSVProfile, osl_Profile_READLOCK);
2616                     if (hProfile)
2617                     {
2618                         osl_readProfileString(
2619                             hProfile, SVERSION_SECTION, Product, Buffer,
2620                             sizeof(Buffer), "");
2621                         osl_closeProfile(hProfile);
2622 
2623                         /* if not found, try the fallback */
2624                         if ((strlen(Buffer) <= 0)
2625                             && (strcmp(SVERSION_LOCATION, SVERSION_FALLBACK)
2626                                 != 0))
2627                         {
2628                             if (osl_getProfileName(
2629                                     strSVFallback, strSVName, &strSVProfile))
2630                             {
2631                                 hProfile = osl_openProfile(
2632                                     strSVProfile, osl_Profile_READLOCK);
2633                                 if (hProfile)
2634                                 {
2635                                     osl_readProfileString(
2636                                         hProfile, SVERSION_SECTION, Product,
2637                                         Buffer, sizeof(Buffer), "");
2638                                 }
2639                             }
2640 
2641                             osl_closeProfile(hProfile);
2642                         }
2643 
2644                         if (strlen(Buffer) > 0)
2645                         {
2646                             dwPathLen = MultiByteToWideChar(
2647                                 CP_ACP, 0, Buffer, -1, ::osl::mingw_reinterpret_cast<LPWSTR>(aPath), aPath.getBufSizeInSymbols() );
2648                             dwPathLen -=1;
2649 
2650                             /* build full path */
2651                             if ((aPath[dwPathLen - 1] != L'/')
2652                                 && (aPath[dwPathLen - 1] != L'\\'))
2653                             {
2654                                 copy_ustr_n(aPath + dwPathLen++, L"\\", 2);
2655                             }
2656 
2657                             if (*strPath)
2658                             {
2659                                 copy_ustr_n(aPath + dwPathLen, strPath, rtl_ustr_getLength(strPath)+1);
2660                                 dwPathLen += rtl_ustr_getLength(strPath);
2661                             }
2662                             else
2663                             {
2664                                 ::osl::LongPathBuffer< sal_Char > aTmpPath( MAX_LONG_PATH );
2665                                 int n;
2666 
2667                                 if ((n = WideCharToMultiByte(
2668                                          CP_ACP,0, ::osl::mingw_reinterpret_cast<LPCWSTR>(aPath), -1, aTmpPath,
2669                                          aTmpPath.getBufSizeInSymbols(), NULL, NULL))
2670                                     > 0)
2671                                 {
2672                                     strcpy(aTmpPath + n, SVERSION_USER);
2673                                     if (access(aTmpPath, 0) >= 0)
2674                                     {
2675                                         dwPathLen += MultiByteToWideChar(
2676                                             CP_ACP, 0, SVERSION_USER, -1,
2677                                             reinterpret_cast<LPWSTR>(aPath + dwPathLen),
2678                                             aPath.getBufSizeInSymbols() - dwPathLen );
2679                                     }
2680                                 }
2681                             }
2682                         }
2683                     }
2684 
2685                     rtl_uString_release(strSVProfile);
2686                 }
2687 
2688                 rtl_uString_release(strSVFallback);
2689                 rtl_uString_release(strSVLocation);
2690                 rtl_uString_release(strSVName);
2691             }
2692         }
2693 
2694         aPath[dwPathLen] = 0;
2695     }
2696 
2697     /* copy filename */
2698     copy_ustr_n(strProfile, aPath, dwPathLen+1);
2699 
2700     return sal_True;
2701 }
2702 
2703 
2704