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