xref: /AOO41X/main/sal/osl/w32/profile.cxx (revision 979d5488e290108d398b3cd7ba1be4e5c63442e0)
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;
copy_ustr_n(void * dest,const void * source,size_t length)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 
osl_openProfile(rtl_uString * strProfileName,sal_uInt32 Flags)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 
osl_closeProfile(oslProfile Profile)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 
osl_flushProfile(oslProfile Profile)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 
writeProfileImpl(osl_TFile * pFile)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 
osl_readProfileString(oslProfile Profile,const sal_Char * pszSection,const sal_Char * pszEntry,sal_Char * pszString,sal_uInt32 MaxLen,const sal_Char * pszDefault)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 
osl_readProfileBool(oslProfile Profile,const sal_Char * pszSection,const sal_Char * pszEntry,sal_Bool Default)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 
osl_readProfileIdent(oslProfile Profile,const sal_Char * pszSection,const sal_Char * pszEntry,sal_uInt32 FirstId,const sal_Char * Strings[],sal_uInt32 Default)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 
osl_writeProfileString(oslProfile Profile,const sal_Char * pszSection,const sal_Char * pszEntry,const sal_Char * pszString)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 
osl_writeProfileBool(oslProfile Profile,const sal_Char * pszSection,const sal_Char * pszEntry,sal_Bool Value)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 
osl_writeProfileIdent(oslProfile Profile,const sal_Char * pszSection,const sal_Char * pszEntry,sal_uInt32 FirstId,const sal_Char * Strings[],sal_uInt32 Value)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 
osl_removeProfileEntry(oslProfile Profile,const sal_Char * pszSection,const sal_Char * pszEntry)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 
osl_getProfileSectionEntries(oslProfile Profile,const sal_Char * pszSection,sal_Char * pszBuffer,sal_uInt32 MaxLen)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 
osl_getProfileName(rtl_uString * strPath,rtl_uString * strName,rtl_uString ** strProfileName)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 
osl_getProfileSections(oslProfile Profile,sal_Char * pszBuffer,sal_uInt32 MaxLen)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 
getFileStamp(osl_TFile * pFile)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 
lockFile(const osl_TFile * pFile,osl_TLockMode eMode)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 
openFileImpl(rtl_uString * strFileName,oslProfileOption ProfileFlags)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 
closeFileImpl(osl_TFile * pFile)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 
rewindFile(osl_TFile * pFile,sal_Bool bTruncate)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 
getLine(osl_TFile * pFile,const sal_Char * pszLine,int MaxLen)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 
putLine(osl_TFile * pFile,const sal_Char * pszLine)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 
stripBlanks(const sal_Char * String,sal_uInt32 * pLen)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 
addLine(osl_TProfileImpl * pProfile,const sal_Char * Line)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 **)calloc(pProfile->m_MaxLines, sizeof(sal_Char *));
1588         }
1589         else
1590         {
1591             unsigned int index=0;
1592             unsigned int oldmax=pProfile->m_MaxLines;
1593 
1594             pProfile->m_MaxLines += LINES_ADD;
1595             pProfile->m_Lines = (sal_Char **)realloc(pProfile->m_Lines, pProfile->m_MaxLines * sizeof(sal_Char *));
1596 
1597             for ( index = oldmax ; index < pProfile->m_MaxLines ; ++index )
1598             {
1599                 pProfile->m_Lines[index]=0;
1600             }
1601         }
1602 
1603         if (pProfile->m_Lines == NULL)
1604         {
1605             pProfile->m_NoLines  = 0;
1606             pProfile->m_MaxLines = 0;
1607             return (NULL);
1608         }
1609 
1610     }
1611 
1612     if ( pProfile->m_Lines != 0 && pProfile->m_Lines[pProfile->m_NoLines] != 0 )
1613     {
1614             free(pProfile->m_Lines[pProfile->m_NoLines]);
1615     }
1616     pProfile->m_Lines[pProfile->m_NoLines++] = strdup(Line);
1617 
1618     return (pProfile->m_Lines[pProfile->m_NoLines - 1]);
1619 }
1620 
insertLine(osl_TProfileImpl * pProfile,const sal_Char * Line,sal_uInt32 LineNo)1621 static const sal_Char* insertLine(osl_TProfileImpl* pProfile, const sal_Char* Line, sal_uInt32 LineNo)
1622 {
1623     if (pProfile->m_NoLines >= pProfile->m_MaxLines)
1624     {
1625         if (pProfile->m_Lines == NULL)
1626         {
1627             pProfile->m_MaxLines = LINES_INI;
1628             pProfile->m_Lines = (sal_Char **)calloc(pProfile->m_MaxLines, sizeof(sal_Char *));
1629         }
1630         else
1631         {
1632             pProfile->m_MaxLines += LINES_ADD;
1633             pProfile->m_Lines = (sal_Char **)realloc(pProfile->m_Lines,
1634                                                  pProfile->m_MaxLines * sizeof(sal_Char *));
1635 
1636             memset(&pProfile->m_Lines[pProfile->m_NoLines],
1637                 0,
1638                 (pProfile->m_MaxLines - pProfile->m_NoLines - 1) * sizeof(sal_Char*));
1639         }
1640 
1641         if (pProfile->m_Lines == NULL)
1642         {
1643             pProfile->m_NoLines  = 0;
1644             pProfile->m_MaxLines = 0;
1645             return (NULL);
1646         }
1647     }
1648 
1649     LineNo = LineNo > pProfile->m_NoLines ? pProfile->m_NoLines : LineNo;
1650 
1651     if (LineNo < pProfile->m_NoLines)
1652     {
1653         sal_uInt32 i, n;
1654         osl_TProfileSection* pSec;
1655 
1656         memmove(&pProfile->m_Lines[LineNo + 1], &pProfile->m_Lines[LineNo],
1657                 (pProfile->m_NoLines - LineNo) * sizeof(sal_Char *));
1658 
1659 
1660         /* adjust line references */
1661         for (i = 0; i < pProfile->m_NoSections; i++)
1662         {
1663             pSec = &pProfile->m_Sections[i];
1664 
1665             if (pSec->m_Line >= LineNo)
1666                 pSec->m_Line++;
1667 
1668             for (n = 0; n < pSec->m_NoEntries; n++)
1669                 if (pSec->m_Entries[n].m_Line >= LineNo)
1670                     pSec->m_Entries[n].m_Line++;
1671         }
1672     }
1673 
1674     pProfile->m_NoLines++;
1675 
1676     pProfile->m_Lines[LineNo] = strdup(Line);
1677 
1678     return (pProfile->m_Lines[LineNo]);
1679 }
1680 
removeLine(osl_TProfileImpl * pProfile,sal_uInt32 LineNo)1681 static void removeLine(osl_TProfileImpl* pProfile, sal_uInt32 LineNo)
1682 {
1683     if (LineNo < pProfile->m_NoLines)
1684     {
1685         free(pProfile->m_Lines[LineNo]);
1686         pProfile->m_Lines[LineNo]=0;
1687         if (pProfile->m_NoLines - LineNo > 1)
1688         {
1689             sal_uInt32 i, n;
1690             osl_TProfileSection* pSec;
1691 
1692             memmove(&pProfile->m_Lines[LineNo], &pProfile->m_Lines[LineNo + 1],
1693                     (pProfile->m_NoLines - LineNo - 1) * sizeof(sal_Char *));
1694 
1695             memset(&pProfile->m_Lines[pProfile->m_NoLines - 1],
1696                 0,
1697                 (pProfile->m_MaxLines - pProfile->m_NoLines) * sizeof(sal_Char*));
1698 
1699             /* adjust line references */
1700             for (i = 0; i < pProfile->m_NoSections; i++)
1701             {
1702                 pSec = &pProfile->m_Sections[i];
1703 
1704                 if (pSec->m_Line > LineNo)
1705                     pSec->m_Line--;
1706 
1707                 for (n = 0; n < pSec->m_NoEntries; n++)
1708                     if (pSec->m_Entries[n].m_Line > LineNo)
1709                         pSec->m_Entries[n].m_Line--;
1710             }
1711         }
1712         else
1713         {
1714             pProfile->m_Lines[LineNo] = 0;
1715         }
1716 
1717         pProfile->m_NoLines--;
1718     }
1719 
1720     return;
1721 }
1722 
setEntry(osl_TProfileImpl * pProfile,osl_TProfileSection * pSection,sal_uInt32 NoEntry,sal_uInt32 Line,const sal_Char * Entry,sal_uInt32 Len)1723 static void setEntry(osl_TProfileImpl* pProfile, osl_TProfileSection* pSection,
1724                      sal_uInt32 NoEntry, sal_uInt32 Line,
1725                      const sal_Char* Entry, sal_uInt32 Len)
1726 {
1727     Entry = stripBlanks(Entry, &Len);
1728     pSection->m_Entries[NoEntry].m_Line   = Line;
1729     pSection->m_Entries[NoEntry].m_Offset = Entry - pProfile->m_Lines[Line];
1730     pSection->m_Entries[NoEntry].m_Len    = Len;
1731 
1732     return;
1733 }
1734 
addEntry(osl_TProfileImpl * pProfile,osl_TProfileSection * pSection,int Line,const sal_Char * Entry,sal_uInt32 Len)1735 static sal_Bool addEntry(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection,
1736                         int Line, const sal_Char* Entry, sal_uInt32 Len)
1737 {
1738     if (pSection != NULL)
1739     {
1740         if (pSection->m_NoEntries >= pSection->m_MaxEntries)
1741         {
1742             if (pSection->m_Entries == NULL)
1743             {
1744                 pSection->m_MaxEntries = ENTRIES_INI;
1745                 pSection->m_Entries = (osl_TProfileEntry *)malloc(
1746                                 pSection->m_MaxEntries * sizeof(osl_TProfileEntry));
1747             }
1748             else
1749             {
1750                 pSection->m_MaxEntries += ENTRIES_ADD;
1751                 pSection->m_Entries = (osl_TProfileEntry *)realloc(pSection->m_Entries,
1752                                 pSection->m_MaxEntries * sizeof(osl_TProfileEntry));
1753             }
1754 
1755             if (pSection->m_Entries == NULL)
1756             {
1757                 pSection->m_NoEntries  = 0;
1758                 pSection->m_MaxEntries = 0;
1759                 return (sal_False);
1760             }
1761         }
1762 
1763         pSection->m_NoEntries++;
1764 
1765         Entry = stripBlanks(Entry, &Len);
1766         setEntry(pProfile, pSection, pSection->m_NoEntries - 1, Line,
1767                  Entry, Len);
1768 
1769         return (sal_True);
1770     }
1771 
1772     return (sal_False);
1773 }
1774 
removeEntry(osl_TProfileSection * pSection,sal_uInt32 NoEntry)1775 static void removeEntry(osl_TProfileSection *pSection, sal_uInt32 NoEntry)
1776 {
1777     if (NoEntry < pSection->m_NoEntries)
1778     {
1779         if (pSection->m_NoEntries - NoEntry > 1)
1780         {
1781             memmove(&pSection->m_Entries[NoEntry],
1782                     &pSection->m_Entries[NoEntry + 1],
1783                     (pSection->m_NoEntries - NoEntry - 1) * sizeof(osl_TProfileEntry));
1784             pSection->m_Entries[pSection->m_NoEntries - 1].m_Line=0;
1785             pSection->m_Entries[pSection->m_NoEntries - 1].m_Offset=0;
1786             pSection->m_Entries[pSection->m_NoEntries - 1].m_Len=0;
1787         }
1788 
1789         pSection->m_NoEntries--;
1790     }
1791 
1792     return;
1793 }
1794 
addSection(osl_TProfileImpl * pProfile,int Line,const sal_Char * Section,sal_uInt32 Len)1795 static sal_Bool addSection(osl_TProfileImpl* pProfile, int Line, const sal_Char* Section, sal_uInt32 Len)
1796 {
1797     if (pProfile->m_NoSections >= pProfile->m_MaxSections)
1798     {
1799         if (pProfile->m_Sections == NULL)
1800         {
1801             pProfile->m_MaxSections = SECTIONS_INI;
1802             pProfile->m_Sections = (osl_TProfileSection *)calloc(pProfile->m_MaxSections, sizeof(osl_TProfileSection));
1803         }
1804         else
1805         {
1806             unsigned int index=0;
1807             unsigned int oldmax=pProfile->m_MaxSections;
1808 
1809             pProfile->m_MaxSections += SECTIONS_ADD;
1810             pProfile->m_Sections = (osl_TProfileSection *)realloc(pProfile->m_Sections,
1811                                           pProfile->m_MaxSections * sizeof(osl_TProfileSection));
1812             for ( index = oldmax ; index < pProfile->m_MaxSections ; ++index )
1813             {
1814                 pProfile->m_Sections[index].m_Entries=0;
1815             }
1816         }
1817 
1818         if (pProfile->m_Sections == NULL)
1819         {
1820             pProfile->m_NoSections = 0;
1821             pProfile->m_MaxSections = 0;
1822             return (sal_False);
1823         }
1824     }
1825 
1826     pProfile->m_NoSections++;
1827 
1828     if ( pProfile->m_Sections[(pProfile->m_NoSections) - 1].m_Entries != 0 )
1829     {
1830         free(pProfile->m_Sections[(pProfile->m_NoSections) - 1].m_Entries);
1831     }
1832     pProfile->m_Sections[pProfile->m_NoSections - 1].m_Entries    = NULL;
1833     pProfile->m_Sections[pProfile->m_NoSections - 1].m_NoEntries  = 0;
1834     pProfile->m_Sections[pProfile->m_NoSections - 1].m_MaxEntries = 0;
1835 
1836     Section = (sal_Char *)stripBlanks(Section, &Len);
1837     pProfile->m_Sections[pProfile->m_NoSections - 1].m_Line = Line;
1838     pProfile->m_Sections[pProfile->m_NoSections - 1].m_Offset = Section - pProfile->m_Lines[Line];
1839     pProfile->m_Sections[pProfile->m_NoSections - 1].m_Len = Len;
1840 
1841     return (sal_True);
1842 }
1843 
removeSection(osl_TProfileImpl * pProfile,osl_TProfileSection * pSection)1844 static void removeSection(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection)
1845 {
1846     sal_uInt32 Section;
1847 
1848     if ((Section = pSection - pProfile->m_Sections) < pProfile->m_NoSections)
1849     {
1850         free (pSection->m_Entries);
1851         pSection->m_Entries=0;
1852         if (pProfile->m_NoSections - Section > 1)
1853         {
1854             memmove(&pProfile->m_Sections[Section], &pProfile->m_Sections[Section + 1],
1855                     (pProfile->m_NoSections - Section - 1) * sizeof(osl_TProfileSection));
1856 
1857             memset(&pProfile->m_Sections[pProfile->m_NoSections - 1],
1858                 0,
1859                 (pProfile->m_MaxSections - pProfile->m_NoSections) * sizeof(osl_TProfileSection));
1860             pProfile->m_Sections[pProfile->m_NoSections - 1].m_Entries = 0;
1861         }
1862         else
1863         {
1864             pSection->m_Entries = 0;
1865         }
1866 
1867         pProfile->m_NoSections--;
1868     }
1869 
1870     return;
1871 }
1872 
findEntry(osl_TProfileImpl * pProfile,const sal_Char * Section,const sal_Char * Entry,sal_uInt32 * pNoEntry)1873 static osl_TProfileSection* findEntry(osl_TProfileImpl* pProfile, const sal_Char* Section,
1874                                       const sal_Char* Entry, sal_uInt32 *pNoEntry)
1875 {
1876 static  sal_uInt32    Sect = 0;
1877         sal_uInt32    i, n;
1878         sal_uInt32    Len;
1879         const sal_Char* pStr;
1880         osl_TProfileSection* pSec = NULL;
1881 
1882     Len = strlen(Section);
1883     Section = (sal_Char *)stripBlanks(Section, &Len);
1884 
1885     n = Sect;
1886 
1887     for (i = 0; i < pProfile->m_NoSections; i++)
1888     {
1889         n %= pProfile->m_NoSections;
1890         pSec = &pProfile->m_Sections[n];
1891         if ((Len == pSec->m_Len) &&
1892             (strnicmp(Section, &pProfile->m_Lines[pSec->m_Line][pSec->m_Offset], pSec->m_Len)
1893              == 0))
1894             break;
1895         n++;
1896     }
1897 
1898     Sect = n;
1899 
1900     if (i < pProfile->m_NoSections)
1901     {
1902         Len = strlen(Entry);
1903         Entry = stripBlanks(Entry, &Len);
1904 
1905         *pNoEntry = pSec->m_NoEntries;
1906 
1907         for (i = 0; i < pSec->m_NoEntries; i++)
1908         {
1909             pStr = &pProfile->m_Lines[pSec->m_Entries[i].m_Line]
1910                                      [pSec->m_Entries[i].m_Offset];
1911             if ((Len == pSec->m_Entries[i].m_Len) &&
1912                 (strnicmp(Entry, pStr, pSec->m_Entries[i].m_Len)
1913                  == 0))
1914             {
1915                 *pNoEntry = i;
1916                 break;
1917             }
1918         }
1919     }
1920     else
1921         pSec = NULL;
1922 
1923     return (pSec);
1924 }
1925 
loadProfile(osl_TFile * pFile,osl_TProfileImpl * pProfile)1926 static sal_Bool loadProfile(osl_TFile* pFile, osl_TProfileImpl* pProfile)
1927 {
1928     sal_uInt32    i;
1929     sal_Char*       pStr;
1930     sal_Char*       pChar;
1931     sal_Char        Line[4096];
1932 
1933     pProfile->m_NoLines    = 0;
1934     pProfile->m_NoSections = 0;
1935 
1936     OSL_VERIFY(rewindFile(pFile, sal_False));
1937 
1938     while (getLine(pFile, Line, sizeof(Line)))
1939     {
1940         if (! addLine(pProfile, Line))
1941             return (sal_False);
1942     }
1943 
1944     for (i = 0; i < pProfile->m_NoLines; i++)
1945     {
1946         pStr = (sal_Char *)stripBlanks(pProfile->m_Lines[i], NULL);
1947 
1948         if ((*pStr == '\0') || (*pStr == ';'))
1949             continue;
1950 
1951         if ((*pStr != '[') || ((pChar = strrchr(pStr, ']')) == NULL) ||
1952             ((pChar - pStr) <= 2))
1953         {
1954             /* insert entry */
1955 
1956             if (pProfile->m_NoSections < 1)
1957                 continue;
1958 
1959             if ((pChar = strchr(pStr, '=')) == NULL)
1960                 pChar = pStr + strlen(pStr);
1961 
1962             if (! addEntry(pProfile, &pProfile->m_Sections[pProfile->m_NoSections - 1],
1963                            i, pStr, pChar - pStr))
1964                 return (sal_False);
1965         }
1966         else
1967         {
1968             /* new section */
1969 
1970             if (! addSection(pProfile, i, pStr + 1, pChar - pStr - 1))
1971                 return (sal_False);
1972         }
1973     }
1974 
1975     return (sal_True);
1976 }
1977 
1978 
1979 
1980 
1981 
storeProfile(osl_TProfileImpl * pProfile,sal_Bool bCleanup)1982 static sal_Bool storeProfile(osl_TProfileImpl* pProfile, sal_Bool bCleanup)
1983 {
1984 #ifdef TRACE_OSL_PROFILE
1985     OSL_TRACE("In  storeProfile\n");
1986 #endif
1987 
1988     if (pProfile->m_Lines != NULL)
1989     {
1990         if (pProfile->m_Flags & FLG_MODIFIED)
1991         {
1992             sal_uInt32 i;
1993 
1994             osl_TFile* pTmpFile = osl_openTmpProfileImpl(pProfile);
1995 
1996             if ( pTmpFile == 0 )
1997             {
1998                 return sal_False;
1999             }
2000 
2001             OSL_VERIFY(rewindFile(pTmpFile, sal_True));
2002 
2003             for (i = 0; i < pProfile->m_NoLines; i++)
2004             {
2005                 OSL_VERIFY(putLine(pTmpFile, pProfile->m_Lines[i]));
2006             }
2007 
2008             if ( ! writeProfileImpl(pTmpFile) )
2009             {
2010                 if ( pTmpFile->m_pWriteBuf != 0 )
2011                 {
2012                     free(pTmpFile->m_pWriteBuf);
2013                 }
2014 
2015                 pTmpFile->m_pWriteBuf=0;
2016                 pTmpFile->m_nWriteBufLen=0;
2017                 pTmpFile->m_nWriteBufFree=0;
2018 
2019 #ifdef TRACE_OSL_PROFILE
2020                 OSL_TRACE("Out storeProfile [not flushed]\n");
2021 #endif
2022                 closeFileImpl(pTmpFile);
2023 
2024                 return sal_False;
2025             }
2026 
2027             pProfile->m_Flags &= ~FLG_MODIFIED;
2028 
2029             closeFileImpl(pProfile->m_pFile);
2030             closeFileImpl(pTmpFile);
2031 
2032             osl_ProfileSwapProfileNames(pProfile);
2033 
2034 /*          free(pProfile->m_pFile);*/
2035 /*          free(pTmpFile);*/
2036 
2037             pProfile->m_pFile = openFileImpl(pProfile->m_strFileName,pProfile->m_Flags);
2038 
2039         }
2040 
2041         if (bCleanup)
2042         {
2043             while (pProfile->m_NoLines > 0)
2044                 removeLine(pProfile, pProfile->m_NoLines - 1);
2045 
2046             free(pProfile->m_Lines);
2047             pProfile->m_Lines = NULL;
2048             pProfile->m_MaxLines = 0;
2049 
2050             while (pProfile->m_NoSections > 0)
2051                 removeSection(pProfile, &pProfile->m_Sections[pProfile->m_NoSections - 1]);
2052 
2053             free(pProfile->m_Sections);
2054             pProfile->m_Sections = NULL;
2055             pProfile->m_MaxSections = 0;
2056         }
2057     }
2058 
2059 #ifdef TRACE_OSL_PROFILE
2060     OSL_TRACE("Out storeProfile [ok]\n");
2061 #endif
2062     return (sal_True);
2063 }
2064 
2065 
osl_openTmpProfileImpl(osl_TProfileImpl * pProfile)2066 static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl* pProfile)
2067 {
2068     osl_TFile* pFile=0;
2069     rtl_uString* ustrExtension=0;
2070     rtl_uString* ustrTmpName=0;
2071     oslProfileOption PFlags=0;
2072 
2073     rtl_uString_newFromAscii(&ustrExtension,"tmp");
2074 
2075 
2076     /* generate tmp profilename */
2077     ustrTmpName=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
2078     rtl_uString_release(ustrExtension);
2079 
2080     if ( ustrTmpName == 0 )
2081     {
2082         return 0;
2083     }
2084 
2085 
2086     if ( ! ( pProfile->m_Flags & osl_Profile_READLOCK ) )
2087     {
2088         PFlags |= osl_Profile_WRITELOCK;
2089     }
2090 
2091     /* open this file */
2092     pFile = openFileImpl(ustrTmpName,pProfile->m_Flags | PFlags);
2093 
2094 
2095     /* return new pFile */
2096     return pFile;
2097 }
2098 
2099 
osl_ProfileSwapProfileNames(osl_TProfileImpl * pProfile)2100 static sal_Bool osl_ProfileSwapProfileNames(osl_TProfileImpl* pProfile)
2101 {
2102     sal_Bool bRet = sal_False;
2103 
2104     rtl_uString* ustrBakFile=0;
2105     rtl_uString* ustrTmpFile=0;
2106     rtl_uString* ustrIniFile=0;
2107     rtl_uString* ustrExtension=0;
2108 
2109 
2110     rtl_uString_newFromAscii(&ustrExtension,"bak");
2111 
2112     ustrBakFile=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
2113     rtl_uString_release(ustrExtension);
2114     ustrExtension=0;
2115 
2116 
2117     rtl_uString_newFromAscii(&ustrExtension,"ini");
2118 
2119     ustrIniFile=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
2120     rtl_uString_release(ustrExtension);
2121     ustrExtension=0;
2122 
2123 
2124     rtl_uString_newFromAscii(&ustrExtension,"tmp");
2125 
2126     ustrTmpFile=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
2127     rtl_uString_release(ustrExtension);
2128     ustrExtension=0;
2129 
2130 
2131     /* unlink bak */
2132     DeleteFileW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrBakFile )) );
2133 
2134     /* rename ini bak */
2135     MoveFileExW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrIniFile )), reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrBakFile )), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH );
2136 
2137     /* rename tmp ini */
2138     MoveFileExW( reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrTmpFile )), reinterpret_cast<LPCWSTR>(rtl_uString_getStr( ustrIniFile )), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH );
2139 
2140     return bRet;
2141 }
2142 
2143 
osl_ProfileGenerateExtension(rtl_uString * ustrFileName,rtl_uString * ustrExtension)2144 static rtl_uString* osl_ProfileGenerateExtension(rtl_uString* ustrFileName, rtl_uString* ustrExtension)
2145 {
2146     rtl_uString* ustrNewFileName=0;
2147     rtl_uString* ustrOldExtension = 0;
2148     sal_Unicode* pExtensionBuf = 0;
2149     sal_Unicode* pFileNameBuf  = 0;
2150     sal_Int32 nIndex = -1;
2151 
2152     pFileNameBuf = rtl_uString_getStr(ustrFileName);
2153 
2154     rtl_uString_newFromAscii(&ustrOldExtension,".");
2155 
2156     pExtensionBuf = rtl_uString_getStr(ustrOldExtension);
2157 
2158     nIndex = rtl_ustr_lastIndexOfChar(pFileNameBuf,*pExtensionBuf);
2159 
2160     rtl_uString_newReplaceStrAt(&ustrNewFileName,
2161                                 ustrFileName,
2162                                 nIndex+1,
2163                                 3,
2164                                 ustrExtension);
2165 
2166     return ustrNewFileName;
2167 }
2168 
2169 
acquireProfile(oslProfile Profile,sal_Bool bWriteable)2170 static osl_TProfileImpl* acquireProfile(oslProfile Profile, sal_Bool bWriteable)
2171 {
2172     osl_TProfileImpl* pProfile = (osl_TProfileImpl*)Profile;
2173     oslProfileOption PFlags=0;
2174 
2175 
2176     if ( bWriteable )
2177     {
2178 /*          PFlags = osl_Profile_DEFAULT | osl_Profile_READWRITE; */
2179         PFlags = osl_Profile_DEFAULT | osl_Profile_WRITELOCK;
2180     }
2181     else
2182     {
2183         PFlags = osl_Profile_DEFAULT;
2184     }
2185 
2186 
2187     if (pProfile == NULL)
2188     {
2189 #ifdef DEBUG_OSL_PROFILE
2190         OSL_TRACE("AUTOOPEN MODE\n");
2191 #endif
2192 
2193 
2194 
2195         if ( ( pProfile = (osl_TProfileImpl*)osl_openProfile( NULL, PFlags ) ) != NULL )
2196         {
2197             pProfile->m_Flags |= FLG_AUTOOPEN;
2198         }
2199     }
2200     else
2201     {
2202 #ifdef DEBUG_OSL_PROFILE
2203         OSL_TRACE("try to acquire\n");
2204 #endif
2205 
2206 
2207 
2208         if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
2209         {
2210             if (! (pProfile->m_Flags & (osl_Profile_READLOCK |
2211                                         osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE)))
2212             {
2213                 osl_TStamp Stamp;
2214 #ifdef DEBUG_OSL_PROFILE
2215                 OSL_TRACE("DEFAULT MODE\n");
2216 #endif
2217                 pProfile->m_pFile = openFileImpl(
2218                     pProfile->m_strFileName, pProfile->m_Flags | PFlags);
2219                 if (!pProfile->m_pFile)
2220                     return NULL;
2221 
2222                 Stamp = getFileStamp(pProfile->m_pFile);
2223 
2224                 if (memcmp(&Stamp, &(pProfile->m_Stamp), sizeof(osl_TStamp)))
2225                 {
2226                     pProfile->m_Stamp = Stamp;
2227 
2228                     loadProfile(pProfile->m_pFile, pProfile);
2229                 }
2230             }
2231             else
2232             {
2233 #ifdef DEBUG_OSL_PROFILE
2234                 OSL_TRACE("READ/WRITELOCK MODE\n");
2235 #endif
2236 
2237 
2238                 /* A readlock file could not be written */
2239                 if ((pProfile->m_Flags & osl_Profile_READLOCK) && bWriteable)
2240                 {
2241                     return (NULL);
2242                 }
2243             }
2244         }
2245     }
2246 
2247     return (pProfile);
2248 }
2249 
releaseProfile(osl_TProfileImpl * pProfile)2250 static sal_Bool releaseProfile(osl_TProfileImpl* pProfile)
2251 {
2252 #ifdef TRACE_OSL_PROFILE
2253     OSL_TRACE("In  releaseProfile\n");
2254 #endif
2255 
2256     if ( pProfile == 0 )
2257     {
2258 #ifdef TRACE_OSL_PROFILE
2259         OSL_TRACE("Out releaseProfile [profile==0]\n");
2260 #endif
2261         return sal_False;
2262     }
2263 
2264     if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
2265     {
2266         if (pProfile->m_Flags & FLG_AUTOOPEN)
2267         {
2268 #ifdef TRACE_OSL_PROFILE
2269         OSL_TRACE("Out releaseProfile [AUTOOPEN]\n");
2270 #endif
2271             return (osl_closeProfile((oslProfile)pProfile));
2272         }
2273         else
2274         {
2275 #ifdef DEBUG_OSL_PROFILE
2276         OSL_TRACE("DEFAULT MODE\n");
2277 #endif
2278         if (! (pProfile->m_Flags & (osl_Profile_READLOCK |
2279                                     osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE)))
2280             {
2281                 if (pProfile->m_Flags & FLG_MODIFIED)
2282                     storeProfile(pProfile, sal_False);
2283 
2284                 closeFileImpl(pProfile->m_pFile);
2285                 pProfile->m_pFile = NULL;
2286             }
2287         }
2288     }
2289 
2290 #ifdef TRACE_OSL_PROFILE
2291     OSL_TRACE("Out releaseProfile [ok]\n");
2292 #endif
2293     return (sal_True);
2294 }
2295 
lookupProfile(const sal_Unicode * strPath,const sal_Unicode * strFile,sal_Unicode * strProfile)2296 static sal_Bool lookupProfile(const sal_Unicode *strPath, const sal_Unicode *strFile, sal_Unicode *strProfile)
2297 {
2298     sal_Char *pChr, *pStr;
2299     sal_Char Buffer[4096] = "";
2300     sal_Char Product[132] = "";
2301 
2302     ::osl::LongPathBuffer< sal_Unicode > aPath( MAX_LONG_PATH );
2303     aPath[0] = 0;
2304     DWORD dwPathLen = 0;
2305 
2306     if (*strPath == L'"')
2307     {
2308         int i = 0;
2309 
2310         strPath++;
2311 
2312         while ((strPath[i] != L'"') && (strPath[i] != L'\0'))
2313             i++;
2314 
2315         WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(strPath), i, Product, sizeof(Product), NULL, NULL);
2316         Product[i] = '\0';
2317         strPath += i;
2318 
2319         if (*strPath == L'"')
2320             strPath++;
2321 
2322         if ( (*strPath == L'/') || (*strPath == L'\\') )
2323         {
2324             strPath++;
2325         }
2326     }
2327 
2328     else
2329     {
2330         /* if we have not product identfication, do a special handling for soffice.ini */
2331         if (rtl_ustr_ascii_compare(strFile, SVERSION_PROFILE) == 0)
2332         {
2333             rtl_uString * strSVProfile  = NULL;
2334             rtl_uString * strSVFallback = NULL;
2335             rtl_uString * strSVLocation = NULL;
2336             rtl_uString * strSVName     = NULL;
2337             ::osl::LongPathBuffer< sal_Char > aDir( MAX_LONG_PATH );
2338             oslProfile hProfile;
2339 
2340             rtl_uString_newFromAscii(&strSVFallback, SVERSION_FALLBACK);
2341             rtl_uString_newFromAscii(&strSVLocation, SVERSION_LOCATION);
2342             rtl_uString_newFromAscii(&strSVName, SVERSION_NAME);
2343 
2344             /* open sversion.ini in the system directory, and try to locate the entry
2345                with the highest version for StarOffice */
2346             if (osl_getProfileName( strSVFallback, strSVName, &strSVProfile))
2347             {
2348                 hProfile = osl_openProfile(strSVProfile, osl_Profile_READLOCK);
2349                 if (hProfile)
2350                 {
2351                     osl_getProfileSectionEntries(
2352                         hProfile, SVERSION_SECTION, Buffer, sizeof(Buffer));
2353 
2354                     for (pChr = Buffer; *pChr != '\0'; pChr += strlen(pChr) + 1)
2355                     {
2356                         if ((strnicmp(
2357                                  pChr, SVERSION_SOFFICE,
2358                                  sizeof(SVERSION_SOFFICE) - 1)
2359                              == 0)
2360                             && (stricmp(Product, pChr) < 0))
2361                         {
2362                             osl_readProfileString(
2363                                 hProfile, SVERSION_SECTION, pChr, aDir,
2364                                 aDir.getBufSizeInSymbols(), "");
2365 
2366                             /* check for existence of path */
2367                             if (access(aDir, 0) >= 0)
2368                                 strcpy(Product, pChr);
2369                         }
2370                     }
2371 
2372                     osl_closeProfile(hProfile);
2373                 }
2374                 rtl_uString_release(strSVProfile);
2375                 strSVProfile = NULL;
2376             }
2377 
2378             /* open sversion.ini in the users directory, and try to locate the entry
2379                with the highest version for StarOffice */
2380             if ((strcmp(SVERSION_LOCATION, SVERSION_FALLBACK) != 0) &&
2381                 (osl_getProfileName(strSVLocation, strSVName, &strSVProfile)))
2382             {
2383                 hProfile = osl_openProfile(strSVProfile, osl_Profile_READLOCK);
2384                 if (hProfile)
2385                 {
2386                     osl_getProfileSectionEntries(
2387                         hProfile, SVERSION_SECTION, Buffer, sizeof(Buffer));
2388 
2389                     for (pChr = Buffer; *pChr != '\0'; pChr += strlen(pChr) + 1)
2390                     {
2391                         if ((strnicmp(
2392                                  pChr, SVERSION_SOFFICE,
2393                                  sizeof(SVERSION_SOFFICE) - 1)
2394                              == 0)
2395                             && (stricmp(Product, pChr) < 0))
2396                         {
2397                             osl_readProfileString(
2398                                 hProfile, SVERSION_SECTION, pChr, aDir,
2399                                 aDir.getBufSizeInSymbols(), "");
2400 
2401                             /* check for existence of path */
2402                             if (access(aDir, 0) >= 0)
2403                                 strcpy(Product, pChr);
2404                         }
2405                     }
2406 
2407                     osl_closeProfile(hProfile);
2408                 }
2409                 rtl_uString_release(strSVProfile);
2410             }
2411 
2412             rtl_uString_release(strSVFallback);
2413             rtl_uString_release(strSVLocation);
2414             rtl_uString_release(strSVName);
2415 
2416             /* remove any trailing build number */
2417             if ((pChr = strrchr(Product, '/')) != NULL)
2418                 *pChr = '\0';
2419         }
2420     }
2421 
2422     /* if we have an userid option eg. "-userid:rh[/usr/home/rh/staroffice]",
2423        this will supercede all other locations */
2424     {
2425         sal_uInt32 n, nArgs = osl_getCommandArgCount();
2426 
2427         for (n = 0; n < nArgs; n++)
2428         {
2429             rtl_uString * strCommandArg = NULL;
2430 
2431             if ((osl_getCommandArg( n, &strCommandArg ) == osl_Process_E_None) &&
2432                 ((strCommandArg->buffer[0] == L'-') || (strCommandArg->buffer[0] == L'+')) &&
2433                 (rtl_ustr_ascii_compare_WithLength(strCommandArg->buffer, RTL_CONSTASCII_LENGTH(SVERSION_OPTION), SVERSION_OPTION)))
2434             {
2435                 sal_Unicode *pCommandArg = strCommandArg->buffer + RTL_CONSTASCII_LENGTH(SVERSION_OPTION);
2436                 sal_Int32 nStart, nEnd;
2437 
2438                 if (((nStart = rtl_ustr_indexOfChar(pCommandArg, L'[')) != -1) &&
2439                     ((nEnd = rtl_ustr_indexOfChar(pCommandArg + nStart + 1, L']')) != -1))
2440                 {
2441                     dwPathLen = nEnd;
2442                     copy_ustr_n(aPath, pCommandArg + nStart + 1, dwPathLen);
2443                     aPath[dwPathLen] = 0;
2444 
2445                     /* build full path */
2446                     if ((aPath[dwPathLen - 1] != L'/') && (aPath[dwPathLen - 1] != L'\\'))
2447                     {
2448                         copy_ustr_n(aPath + dwPathLen++, L"/", 2);
2449                     }
2450 
2451                     if (*strPath)
2452                     {
2453                         copy_ustr_n(aPath + dwPathLen, strPath, rtl_ustr_getLength(strPath)+1);
2454                         dwPathLen += rtl_ustr_getLength(strPath);
2455                     }
2456                     else
2457                     {
2458                         ::osl::LongPathBuffer< sal_Char > aTmpPath( MAX_LONG_PATH );
2459                         int n;
2460 
2461                         if ((n = WideCharToMultiByte(CP_ACP,0, ::osl::mingw_reinterpret_cast<LPCWSTR>(aPath), -1, aTmpPath, aTmpPath.getBufSizeInSymbols(), NULL, NULL)) > 0)
2462                         {
2463                             strcpy(aTmpPath + n, SVERSION_USER);
2464                             if (access(aTmpPath, 0) >= 0)
2465                             {
2466                                 dwPathLen += MultiByteToWideChar( CP_ACP, 0, SVERSION_USER, -1, reinterpret_cast<LPWSTR>(aPath + dwPathLen), aPath.getBufSizeInSymbols() - dwPathLen );
2467                             }
2468                         }
2469                     }
2470 
2471                     break;
2472                 }
2473             }
2474         }
2475     }
2476 
2477 
2478     if (dwPathLen == 0)
2479     {
2480         rtl_uString * strExecutable = NULL;
2481         rtl_uString * strTmp = NULL;
2482         sal_Int32 nPos;
2483 
2484         /* try to find the file in the directory of the executbale */
2485         if (osl_getExecutableFile(&strTmp) != osl_Process_E_None)
2486             return (sal_False);
2487 
2488         /* convert to native path */
2489         if (osl_getSystemPathFromFileURL(strTmp, &strExecutable) != osl_File_E_None)
2490         {
2491             rtl_uString_release(strTmp);
2492             return sal_False;
2493         }
2494 
2495         rtl_uString_release(strTmp);
2496 
2497         /* seperate path from filename */
2498         if ((nPos = rtl_ustr_lastIndexOfChar(strExecutable->buffer, L'\\')) == -1)
2499         {
2500             if ((nPos = rtl_ustr_lastIndexOfChar(strExecutable->buffer, L':')) == -1)
2501             {
2502                 return sal_False;
2503             }
2504             else
2505             {
2506                 copy_ustr_n(aPath, strExecutable->buffer, nPos);
2507                 aPath[nPos] = 0;
2508                 dwPathLen = nPos;
2509             }
2510         }
2511         else
2512         {
2513             copy_ustr_n(aPath, strExecutable->buffer, nPos);
2514             dwPathLen = nPos;
2515             aPath[dwPathLen] = 0;
2516         }
2517 
2518         /* if we have no product identification use the executable file name */
2519         if (*Product == 0)
2520         {
2521             WideCharToMultiByte(CP_ACP,0, reinterpret_cast<LPCWSTR>(strExecutable->buffer + nPos + 1), -1, Product, sizeof(Product), NULL, NULL);
2522 
2523             /* remove extension */
2524             if ((pChr = strrchr(Product, '.')) != NULL)
2525                 *pChr = '\0';
2526         }
2527 
2528         rtl_uString_release(strExecutable);
2529 
2530         /* remember last subdir */
2531         nPos = rtl_ustr_lastIndexOfChar(aPath, L'\\');
2532 
2533         copy_ustr_n(aPath + dwPathLen++, L"\\", 2);
2534 
2535         if (*strPath)
2536         {
2537             copy_ustr_n(aPath + dwPathLen, strPath, rtl_ustr_getLength(strPath)+1);
2538             dwPathLen += rtl_ustr_getLength(strPath);
2539         }
2540 
2541         {
2542             ::osl::LongPathBuffer< sal_Char > aTmpPath( MAX_LONG_PATH );
2543 
2544             WideCharToMultiByte(CP_ACP,0, ::osl::mingw_reinterpret_cast<LPCWSTR>(aPath), -1, aTmpPath, aTmpPath.getBufSizeInSymbols(), NULL, NULL);
2545 
2546             /* if file not exists, remove any specified subdirectories
2547                like "bin" or "program" */
2548 
2549             if (((access(aTmpPath, 0) < 0) && (nPos != -1)) || (*strPath == 0))
2550             {
2551                 static sal_Char *SubDirs[] = SVERSION_DIRS;
2552 
2553                 int i = 0;
2554                 pStr = aTmpPath + nPos;
2555 
2556                 for (i = 0; i < (sizeof(SubDirs) / sizeof(SubDirs[0])); i++)
2557                     if (strnicmp(pStr + 1, SubDirs[i], strlen(SubDirs[i])) == 0)
2558                     {
2559                         if ( *strPath == 0)
2560                         {
2561                             strcpy(pStr + 1,SVERSION_USER);
2562                             if ( access(aTmpPath, 0) < 0 )
2563                             {
2564                                 *(pStr+1)='\0';
2565                             }
2566                             else
2567                             {
2568                                 dwPathLen = nPos + MultiByteToWideChar( CP_ACP, 0, SVERSION_USER, -1, reinterpret_cast<LPWSTR>(aPath + nPos + 1), aPath.getBufSizeInSymbols() - (nPos + 1) );
2569                             }
2570                         }
2571                         else
2572                         {
2573                             copy_ustr_n(aPath + nPos + 1, strPath, rtl_ustr_getLength(strPath)+1);
2574                             dwPathLen = nPos + 1 + rtl_ustr_getLength(strPath);
2575                         }
2576 
2577                         break;
2578                     }
2579             }
2580         }
2581 
2582         if ((aPath[dwPathLen - 1] != L'/') && (aPath[dwPathLen - 1] != L'\\'))
2583         {
2584             aPath[dwPathLen++] = L'\\';
2585             aPath[dwPathLen] = 0;
2586         }
2587 
2588         copy_ustr_n(aPath + dwPathLen, strFile, rtl_ustr_getLength(strFile)+1);
2589 
2590         {
2591             ::osl::LongPathBuffer< sal_Char > aTmpPath( MAX_LONG_PATH );
2592 
2593             WideCharToMultiByte(CP_ACP,0, ::osl::mingw_reinterpret_cast<LPCWSTR>(aPath), -1, aTmpPath, aTmpPath.getBufSizeInSymbols(), NULL, NULL);
2594 
2595             if ((access(aTmpPath, 0) < 0) && (strlen(Product) > 0))
2596             {
2597                 rtl_uString * strSVFallback = NULL;
2598                 rtl_uString * strSVProfile  = NULL;
2599                 rtl_uString * strSVLocation = NULL;
2600                 rtl_uString * strSVName     = NULL;
2601                 oslProfile hProfile;
2602 
2603                 rtl_uString_newFromAscii(&strSVFallback, SVERSION_FALLBACK);
2604                 rtl_uString_newFromAscii(&strSVLocation, SVERSION_LOCATION);
2605                 rtl_uString_newFromAscii(&strSVName, SVERSION_NAME);
2606 
2607                 /* open sversion.ini in the system directory, and try to locate the entry
2608                    with the highest version for StarOffice */
2609                 if (osl_getProfileName(strSVLocation, strSVName, &strSVProfile))
2610                 {
2611                     hProfile = osl_openProfile(
2612                         strSVProfile, osl_Profile_READLOCK);
2613                     if (hProfile)
2614                     {
2615                         osl_readProfileString(
2616                             hProfile, SVERSION_SECTION, Product, Buffer,
2617                             sizeof(Buffer), "");
2618                         osl_closeProfile(hProfile);
2619 
2620                         /* if not found, try the fallback */
2621                         if ((strlen(Buffer) <= 0)
2622                             && (strcmp(SVERSION_LOCATION, SVERSION_FALLBACK)
2623                                 != 0))
2624                         {
2625                             if (osl_getProfileName(
2626                                     strSVFallback, strSVName, &strSVProfile))
2627                             {
2628                                 hProfile = osl_openProfile(
2629                                     strSVProfile, osl_Profile_READLOCK);
2630                                 if (hProfile)
2631                                 {
2632                                     osl_readProfileString(
2633                                         hProfile, SVERSION_SECTION, Product,
2634                                         Buffer, sizeof(Buffer), "");
2635                                 }
2636                             }
2637 
2638                             osl_closeProfile(hProfile);
2639                         }
2640 
2641                         if (strlen(Buffer) > 0)
2642                         {
2643                             dwPathLen = MultiByteToWideChar(
2644                                 CP_ACP, 0, Buffer, -1, ::osl::mingw_reinterpret_cast<LPWSTR>(aPath), aPath.getBufSizeInSymbols() );
2645                             dwPathLen -=1;
2646 
2647                             /* build full path */
2648                             if ((aPath[dwPathLen - 1] != L'/')
2649                                 && (aPath[dwPathLen - 1] != L'\\'))
2650                             {
2651                                 copy_ustr_n(aPath + dwPathLen++, L"\\", 2);
2652                             }
2653 
2654                             if (*strPath)
2655                             {
2656                                 copy_ustr_n(aPath + dwPathLen, strPath, rtl_ustr_getLength(strPath)+1);
2657                                 dwPathLen += rtl_ustr_getLength(strPath);
2658                             }
2659                             else
2660                             {
2661                                 ::osl::LongPathBuffer< sal_Char > aTmpPath( MAX_LONG_PATH );
2662                                 int n;
2663 
2664                                 if ((n = WideCharToMultiByte(
2665                                          CP_ACP,0, ::osl::mingw_reinterpret_cast<LPCWSTR>(aPath), -1, aTmpPath,
2666                                          aTmpPath.getBufSizeInSymbols(), NULL, NULL))
2667                                     > 0)
2668                                 {
2669                                     strcpy(aTmpPath + n, SVERSION_USER);
2670                                     if (access(aTmpPath, 0) >= 0)
2671                                     {
2672                                         dwPathLen += MultiByteToWideChar(
2673                                             CP_ACP, 0, SVERSION_USER, -1,
2674                                             reinterpret_cast<LPWSTR>(aPath + dwPathLen),
2675                                             aPath.getBufSizeInSymbols() - dwPathLen );
2676                                     }
2677                                 }
2678                             }
2679                         }
2680                     }
2681 
2682                     rtl_uString_release(strSVProfile);
2683                 }
2684 
2685                 rtl_uString_release(strSVFallback);
2686                 rtl_uString_release(strSVLocation);
2687                 rtl_uString_release(strSVName);
2688             }
2689         }
2690 
2691         aPath[dwPathLen] = 0;
2692     }
2693 
2694     /* copy filename */
2695     copy_ustr_n(strProfile, aPath, dwPathLen+1);
2696 
2697     return sal_True;
2698 }
2699 
2700 
2701