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