xref: /trunk/main/sal/osl/w32/profile.cxx (revision ba392698)
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 		/* separate 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