1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: profile.c,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
33 // YD #define min(a,b) (((a) < (b)) ? (a) : (b))
35 #include <osl/security.h>
36 #include <osl/diagnose.h>
37 #include <osl/profile.h>
38 #include <osl/process.h>
39 #include <osl/thread.h>
44 #define SECTIONS_INI 5
45 #define SECTIONS_ADD 3
50 #define STR_INI_EXTENSION ".ini"
51 #define STR_INI_METAHOME "?~"
52 #define STR_INI_METASYS "?$"
53 #define STR_INI_METACFG "?^"
54 #define STR_INI_METAINS "?#"
56 #define STR_INI_BOOLYES "yes"
57 #define STR_INI_BOOLON "on"
58 #define STR_INI_BOOLONE "1"
59 #define STR_INI_BOOLNO "no"
60 #define STR_INI_BOOLOFF "off"
61 #define STR_INI_BOOLZERO "0"
63 #define FLG_USER 0x00FF
64 #define FLG_AUTOOPEN 0x0100
65 #define FLG_MODIFIED 0x0200
67 #define SVERSION_LOCATION STR_INI_METACFG
68 #define SVERSION_FALLBACK STR_INI_METASYS
69 #define SVERSION_NAME "sversion"
70 #define SVERSION_SECTION "Versions"
71 #define SVERSION_SOFFICE "StarOffice"
72 #define SVERSION_PROFILE "soffice.ini"
73 #define SVERSION_OPTION "userid:"
74 #define SVERSION_DIRS { "bin", "program" }
75 #define SVERSION_USER "user"
77 #define _BUILD_STR_(n) # n
78 #define BUILD_STR(n) _BUILD_STR_(n)
80 /* implemented in file.c */
81 extern oslFileError
FileURLToPath( char *, size_t, rtl_uString
* );
83 /*****************************************************************************/
84 /* Data Type Definition */
85 /*****************************************************************************/
87 typedef struct _osl_TStamp
93 typedef enum _osl_TLockMode
95 un_lock
, read_lock
, write_lock
98 typedef struct _osl_TFile
102 sal_Char* m_pReadPtr;
103 sal_Char m_ReadBuf[512];
104 sal_Char* m_pWritePtr;
105 sal_Char m_WriteBuf[512];
107 sal_Char
* m_pReadPtr
;
108 sal_Char m_ReadBuf
[512];
109 /* sal_Char* m_pWritePtr; */
110 /* sal_Char m_WriteBuf[512]; */
111 sal_Char
* m_pWriteBuf
;
112 sal_uInt32 m_nWriteBufLen
;
113 sal_uInt32 m_nWriteBufFree
;
116 typedef struct _osl_TProfileEntry
123 typedef struct _osl_TProfileSection
128 sal_uInt32 m_NoEntries
;
129 sal_uInt32 m_MaxEntries
;
130 osl_TProfileEntry
* m_Entries
;
131 } osl_TProfileSection
;
135 Profile-data structure hidden behind oslProfile:
137 typedef struct _osl_TProfileImpl
142 //sal_Char m_Filename[_MAX_PATH + 1];
143 sal_uInt32 m_NoLines
;
144 sal_uInt32 m_MaxLines
;
145 sal_uInt32 m_NoSections
;
146 sal_uInt32 m_MaxSections
;
148 rtl_uString
*m_strFileName
;
149 osl_TProfileSection
* m_Sections
;
154 /*****************************************************************************/
155 /* Static Module Function Declarations */
156 /*****************************************************************************/
158 //static osl_TFile* openFile(rtl_uString* pszFilename, sal_Bool bWriteable);
159 //static osl_TStamp closeFile(osl_TFile* pFile);
160 static osl_TFile
* openFileImpl(rtl_uString
* strFileName
, oslProfileOption ProfileFlags
);
161 static osl_TStamp
closeFileImpl(osl_TFile
* pFile
);
162 static sal_Bool
lockFile(const osl_TFile
* pFile
, osl_TLockMode eMode
);
163 static sal_Bool
rewindFile(osl_TFile
* pFile
, sal_Bool bTruncate
);
164 static osl_TStamp
getFileStamp(osl_TFile
* pFile
);
166 static sal_Bool
getLine(osl_TFile
* pFile
, const sal_Char
*pszLine
, int MaxLen
);
167 static sal_Bool
putLine(osl_TFile
* pFile
, const sal_Char
*pszLine
);
168 static const sal_Char
* stripBlanks(const sal_Char
* String
, sal_uInt32
* pLen
);
169 static const sal_Char
* addLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
);
170 static const sal_Char
* insertLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
, sal_uInt32 LineNo
);
171 static void removeLine(osl_TProfileImpl
* pProfile
, sal_uInt32 LineNo
);
172 static void setEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
* pSection
,
173 sal_uInt32 NoEntry
, sal_uInt32 Line
,
174 const sal_Char
* Entry
, sal_uInt32 Len
);
175 static sal_Bool
addEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
,
176 int Line
, const sal_Char
* Entry
, sal_uInt32 Len
);
177 static void removeEntry(osl_TProfileSection
*pSection
, sal_uInt32 NoEntry
);
178 static sal_Bool
addSection(osl_TProfileImpl
* pProfile
, int Line
, const sal_Char
* Section
, sal_uInt32 Len
);
179 static void removeSection(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
);
180 static osl_TProfileSection
* findEntry(osl_TProfileImpl
* pProfile
, const sal_Char
* Section
,
181 const sal_Char
* Entry
, sal_uInt32
*pNoEntry
);
182 static sal_Bool
loadProfile(osl_TFile
* pFile
, osl_TProfileImpl
* pProfile
);
183 static sal_Bool
storeProfile(osl_TFile
* pFile
, osl_TProfileImpl
* pProfile
, sal_Bool bCleanup
);
184 static osl_TProfileImpl
* acquireProfile(oslProfile Profile
, sal_Bool bWriteable
);
185 static sal_Bool
releaseProfile(osl_TProfileImpl
* pProfile
);
186 static sal_Bool
lookupProfile(const sal_Char
*pszPath
, const sal_Char
*pszFile
, sal_Char
*pPath
);
189 static sal_Bool SAL_CALL
osl_getProfileName(rtl_uString
* strPath
, rtl_uString
* strName
, rtl_uString
** strProfileName
);
191 sal_Bool SAL_CALL
osl_getFullPath(rtl_uString
* pszFilename
, sal_Char
* pszPath
, sal_uInt32 MaxLen
)
193 return NO_ERROR
== DosQueryPathInfo( (PCSZ
)pszFilename
, FIL_QUERYFULLNAME
, pszPath
, MaxLen
);
198 /*****************************************************************************/
199 /* Exported Module Functions */
200 /*****************************************************************************/
202 oslProfile SAL_CALL
osl_openProfile(rtl_uString
*strProfileName
, sal_uInt32 Flags
)
205 osl_TProfileImpl
* pProfile
;
206 rtl_uString
*FileName
=NULL
;
208 #ifdef TRACE_OSL_PROFILE
209 OSL_TRACE("In osl_openProfile\n");
211 OSL_VERIFY(strProfileName
);
213 /* if (rtl_uString_getLength(strProfileName) == 0 )
215 OSL_VERIFY(osl_getProfileName(NULL, NULL, &FileName));
220 rtl_uString_assign(&FileName
, strProfileName
);
223 osl_getSystemPathFromFileURL(FileName
, &FileName
);
225 #ifdef DEBUG_OSL_PROFILE
226 Flags
=osl_Profile_FLUSHWRITE
;
228 // OSL_TRACE("opening '%s'\n",FileName);
229 if ( Flags
== osl_Profile_DEFAULT
)
231 OSL_TRACE("with osl_Profile_DEFAULT \n");
233 if ( Flags
& osl_Profile_SYSTEM
)
235 OSL_TRACE("with osl_Profile_SYSTEM \n");
237 if ( Flags
& osl_Profile_READLOCK
)
239 OSL_TRACE("with osl_Profile_READLOCK \n");
241 if ( Flags
& osl_Profile_WRITELOCK
)
243 OSL_TRACE("with osl_Profile_WRITELOCK \n");
245 /* if ( Flags & osl_Profile_READWRITE ) */
247 /* OSL_TRACE("with osl_Profile_READWRITE \n"); */
249 if ( Flags
& osl_Profile_FLUSHWRITE
)
251 OSL_TRACE("with osl_Profile_FLUSHWRITE \n");
255 if ((! (Flags
& osl_Profile_SYSTEM
)) &&
256 ((pFile
= openFileImpl(FileName
, (Flags
& osl_Profile_WRITELOCK
) ? sal_True
: sal_False
)) == NULL
))
258 #ifdef TRACE_OSL_PROFILE
259 OSL_TRACE("Out osl_openProfile [not opened]\n");
262 rtl_uString_release( FileName
);
267 pProfile
= (osl_TProfileImpl
*)calloc(1, sizeof(osl_TProfileImpl
));
269 pProfile
->m_Flags
= Flags
& FLG_USER
;
270 osl_getSystemPathFromFileURL(strProfileName
, &pProfile
->m_strFileName
);
271 // rtl_uString_assign(&pProfile->m_strFileName, strProfileName);
273 if (Flags
& (osl_Profile_READLOCK
| osl_Profile_WRITELOCK
))
274 pProfile
->m_pFile
= pFile
;
276 pProfile
->m_Stamp
= getFileStamp(pFile
);
278 loadProfile(pFile
, pProfile
);
280 if (pProfile
->m_pFile
== NULL
)
281 closeFileImpl(pFile
);
283 #ifdef TRACE_OSL_PROFILE
284 OSL_TRACE("Out osl_openProfile [ok]\n");
287 rtl_uString_release( FileName
);
292 sal_Bool SAL_CALL
osl_closeProfile(oslProfile Profile
)
294 osl_TProfileImpl
* pProfile
= (osl_TProfileImpl
*)Profile
;
296 #ifdef TRACE_OSL_PROFILE
297 OSL_TRACE("In osl_closeProfile\n");
302 #ifdef TRACE_OSL_PROFILE
303 OSL_TRACE("Out osl_closeProfile [profile==0]\n");
308 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
310 pProfile
= acquireProfile(Profile
,sal_True
);
314 if ( !( pProfile
->m_Flags
& osl_Profile_READLOCK
) && ( pProfile
->m_Flags
& FLG_MODIFIED
) )
316 /* if (pProfile->m_pFile == NULL) */
317 /* pProfile->m_pFile = openFileImpl(pProfile->m_Filename, sal_True); */
319 storeProfile(pProfile
->m_pFile
, pProfile
, sal_False
);
324 pProfile
= acquireProfile(Profile
,sal_False
);
329 #ifdef TRACE_OSL_PROFILE
330 OSL_TRACE("Out osl_closeProfile [pProfile==0]\n");
335 if (pProfile
->m_pFile
!= NULL
)
336 closeFileImpl(pProfile
->m_pFile
);
339 pProfile
->m_pFile
= NULL
;
340 rtl_uString_release(pProfile
->m_strFileName
);
341 pProfile
->m_strFileName
= NULL
;
343 /* release whole profile data types memory */
344 if ( pProfile
->m_NoLines
> 0)
346 unsigned int index
=0;
347 if ( pProfile
->m_Lines
!= 0 )
349 for ( index
= 0 ; index
< pProfile
->m_NoLines
; ++index
)
351 if ( pProfile
->m_Lines
[index
] != 0 )
353 free(pProfile
->m_Lines
[index
]);
356 free(pProfile
->m_Lines
);
358 if ( pProfile
->m_Sections
!= 0 )
360 /*osl_TProfileSection* pSections=pProfile->m_Sections;*/
361 for ( index
= 0 ; index
< pProfile
->m_NoSections
; ++index
)
363 if ( pProfile
->m_Sections
[index
].m_Entries
!= 0 )
365 free(pProfile
->m_Sections
[index
].m_Entries
);
368 free(pProfile
->m_Sections
);
374 #ifdef TRACE_OSL_PROFILE
375 OSL_TRACE("Out osl_closeProfile [ok]\n");
380 sal_Bool SAL_CALL
osl_flushProfile(oslProfile Profile
)
382 osl_TProfileImpl
* pProfile
= (osl_TProfileImpl
*) Profile
;
384 sal_Bool bRet
= sal_False
;
386 #ifdef TRACE_OSL_PROFILE
387 OSL_TRACE("In osl_flushProfile()\n");
392 #ifdef TRACE_OSL_PROFILE
393 OSL_TRACE("Out osl_flushProfile() [pProfile == 0]\n");
398 pFile
= pProfile
->m_pFile
;
399 if ( !( pFile
!= 0 && pFile
->m_Handle
>= 0 ) )
401 #ifdef TRACE_OSL_PROFILE
402 OSL_TRACE("Out osl_flushProfile() [invalid file]\n");
407 if ( pProfile
->m_Flags
& FLG_MODIFIED
)
409 #ifdef DEBUG_OSL_PROFILE
410 OSL_TRACE("swapping to storeprofile\n");
412 bRet
= storeProfile(pFile
,pProfile
,sal_False
);
415 #ifdef TRACE_OSL_PROFILE
416 OSL_TRACE("Out osl_flushProfile() [ok]\n");
421 sal_Bool SAL_CALL
osl_readProfileString(oslProfile Profile
,
422 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
423 sal_Char
* pszString
, sal_uInt32 MaxLen
,
424 const sal_Char
* pszDefault
)
427 const sal_Char
* pStr
= 0;
428 osl_TProfileSection
* pSec
;
429 osl_TProfileImpl
* pProfile
= 0;
432 #ifdef TRACE_OSL_PROFILE
433 OSL_TRACE("In osl_readProfileString\n");
436 pProfile
= acquireProfile(Profile
, sal_False
);
438 if (pProfile
== NULL
)
440 #ifdef TRACE_OSL_PROFILE
441 OSL_TRACE("Out osl_readProfileString [pProfile==0]\n");
449 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
451 if (((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) != NULL
) &&
452 (NoEntry
< pSec
->m_NoEntries
) &&
453 ((pStr
= strchr(pProfile
->m_Lines
[pSec
->m_Entries
[NoEntry
].m_Line
],
461 pStr
= stripBlanks(pStr
, NULL
);
462 MaxLen
= (MaxLen
- 1 < strlen(pStr
)) ? (MaxLen
- 1) : strlen(pStr
);
463 pStr
= stripBlanks(pStr
, &MaxLen
);
464 strncpy(pszString
, pStr
, MaxLen
);
465 pszString
[MaxLen
] = '\0';
469 PrfQueryProfileString(pProfile
->m_hIni
, (PCSZ
)pszSection
,
470 (PCSZ
)pszEntry
, (PCSZ
)pszDefault
,
473 releaseProfile(pProfile
);
477 #ifdef TRACE_OSL_PROFILE
478 OSL_TRACE("Out osl_readProfileString [pStr==0]\n");
485 #ifdef TRACE_OSL_PROFILE
486 OSL_TRACE("Out osl_readProfileString [ok]\n");
493 sal_Bool SAL_CALL
osl_readProfileBool(oslProfile Profile
,
494 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
499 #ifdef TRACE_OSL_PROFILE
500 OSL_TRACE("In osl_readProfileBool\n");
503 if (osl_readProfileString(Profile
, pszSection
, pszEntry
, Line
, sizeof(Line
), ""))
505 if ((stricmp(Line
, STR_INI_BOOLYES
) == 0) ||
506 (stricmp(Line
, STR_INI_BOOLON
) == 0) ||
507 (stricmp(Line
, STR_INI_BOOLONE
) == 0))
510 if ((stricmp(Line
, STR_INI_BOOLNO
) == 0) ||
511 (stricmp(Line
, STR_INI_BOOLOFF
) == 0) ||
512 (stricmp(Line
, STR_INI_BOOLZERO
) == 0))
516 #ifdef TRACE_OSL_PROFILE
517 OSL_TRACE("Out osl_readProfileBool [ok]\n");
524 sal_uInt32 SAL_CALL
osl_readProfileIdent(oslProfile Profile
,
525 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
526 sal_uInt32 FirstId
, const sal_Char
* Strings
[],
532 #ifdef TRACE_OSL_PROFILE
533 OSL_TRACE("In osl_readProfileIdent\n");
536 if (osl_readProfileString(Profile
, pszSection
, pszEntry
, Line
, sizeof(Line
), ""))
539 while (Strings
[i
] != NULL
)
541 if (stricmp(Line
, Strings
[i
]) == 0)
543 Default
= i
+ FirstId
;
550 #ifdef TRACE_OSL_PROFILE
551 OSL_TRACE("Out osl_readProfileIdent [ok]\n");
557 sal_Bool SAL_CALL
osl_writeProfileString(oslProfile Profile
,
558 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
559 const sal_Char
* pszString
)
562 sal_Bool bRet
= sal_False
;
564 const sal_Char
* pStr
;
566 osl_TProfileSection
* pSec
;
567 osl_TProfileImpl
* pProfile
= 0;
569 #ifdef TRACE_OSL_PROFILE
570 OSL_TRACE("In osl_writeProfileString\n");
573 pProfile
= acquireProfile(Profile
, sal_True
);
575 if (pProfile
== NULL
)
577 #ifdef TRACE_OSL_PROFILE
578 OSL_TRACE("Out osl_writeProfileString [pProfile==0]\n");
584 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
586 if ((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) == NULL
)
589 addLine(pProfile
, Line
);
592 strcpy(&Line
[1], pszSection
);
593 Line
[1 + strlen(pszSection
)] = ']';
594 Line
[2 + strlen(pszSection
)] = '\0';
596 if (((pStr
= addLine(pProfile
, Line
)) == NULL
) ||
597 (! addSection(pProfile
, pProfile
->m_NoLines
- 1, &pStr
[1], strlen(pszSection
))))
599 releaseProfile(pProfile
);
600 #ifdef TRACE_OSL_PROFILE
601 OSL_TRACE("Out osl_writeProfileString [not added]\n");
606 pSec
= &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1];
607 NoEntry
= pSec
->m_NoEntries
;
611 strcpy(&Line
[0], pszEntry
);
612 Line
[0 + strlen(pszEntry
)] = '=';
613 strcpy(&Line
[1 + strlen(pszEntry
)], pszString
);
615 if (NoEntry
>= pSec
->m_NoEntries
)
617 if (pSec
->m_NoEntries
> 0)
618 i
= pSec
->m_Entries
[pSec
->m_NoEntries
- 1].m_Line
+ 1;
620 i
= pSec
->m_Line
+ 1;
622 if (((pStr
= insertLine(pProfile
, Line
, i
)) == NULL
) ||
623 (! addEntry(pProfile
, pSec
, i
, pStr
, strlen(pszEntry
))))
625 releaseProfile(pProfile
);
626 #ifdef TRACE_OSL_PROFILE
627 OSL_TRACE("Out osl_writeProfileString [not inserted]\n");
632 pProfile
->m_Flags
|= FLG_MODIFIED
;
636 i
= pSec
->m_Entries
[NoEntry
].m_Line
;
637 free(pProfile
->m_Lines
[i
]);
638 pProfile
->m_Lines
[i
] = strdup(Line
);
639 setEntry(pProfile
, pSec
, NoEntry
, i
, pProfile
->m_Lines
[i
], strlen(pszEntry
));
641 pProfile
->m_Flags
|= FLG_MODIFIED
;
645 PrfWriteProfileString(pProfile
->m_hIni
, (PCSZ
)pszSection
,
646 (PCSZ
)pszEntry
, (PCSZ
)pszString
);
648 bRet
= releaseProfile(pProfile
);
649 #ifdef TRACE_OSL_PROFILE
650 OSL_TRACE("Out osl_writeProfileString [ok]\n");
656 sal_Bool SAL_CALL
osl_writeProfileBool(oslProfile Profile
,
657 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
660 sal_Bool bRet
= sal_False
;
662 #ifdef TRACE_OSL_PROFILE
663 OSL_TRACE("In osl_writeProfileBool\n");
667 bRet
=osl_writeProfileString(Profile
, pszSection
, pszEntry
, STR_INI_BOOLONE
);
669 bRet
=osl_writeProfileString(Profile
, pszSection
, pszEntry
, STR_INI_BOOLZERO
);
671 #ifdef TRACE_OSL_PROFILE
672 OSL_TRACE("Out osl_writeProfileBool [ok]\n");
679 sal_Bool SAL_CALL
osl_writeProfileIdent(oslProfile Profile
,
680 const sal_Char
* pszSection
, const sal_Char
* pszEntry
,
681 sal_uInt32 FirstId
, const sal_Char
* Strings
[],
685 sal_Bool bRet
= sal_False
;
687 #ifdef TRACE_OSL_PROFILE
688 OSL_TRACE("In osl_writeProfileIdent\n");
691 for (n
= 0; Strings
[n
] != NULL
; n
++);
693 if ((i
= Value
- FirstId
) >= n
)
696 bRet
=osl_writeProfileString(Profile
, pszSection
, pszEntry
, Strings
[i
]);
698 #ifdef TRACE_OSL_PROFILE
699 OSL_TRACE("Out osl_writeProfileIdent\n");
705 sal_Bool SAL_CALL
osl_removeProfileEntry(oslProfile Profile
,
706 const sal_Char
*pszSection
, const sal_Char
*pszEntry
)
709 osl_TProfileSection
* pSec
;
710 osl_TProfileImpl
* pProfile
= 0;
711 sal_Bool bRet
= sal_False
;
713 #ifdef TRACE_OSL_PROFILE
714 OSL_TRACE("In osl_removeProfileEntry\n");
717 pProfile
= acquireProfile(Profile
, sal_True
);
719 if (pProfile
== NULL
)
721 #ifdef TRACE_OSL_PROFILE
722 OSL_TRACE("Out osl_removeProfileEntry [pProfile==0]\n");
730 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
732 if (((pSec
= findEntry(pProfile
, pszSection
, pszEntry
, &NoEntry
)) != NULL
) &&
733 (NoEntry
< pSec
->m_NoEntries
))
735 removeLine(pProfile
, pSec
->m_Entries
[NoEntry
].m_Line
);
736 removeEntry(pSec
, NoEntry
);
737 if (pSec
->m_NoEntries
== 0)
739 removeLine(pProfile
, pSec
->m_Line
);
741 /* remove any empty separation line */
742 if ((pSec
->m_Line
> 0) && (pProfile
->m_Lines
[pSec
->m_Line
- 1][0] == '\0'))
743 removeLine(pProfile
, pSec
->m_Line
- 1);
745 removeSection(pProfile
, pSec
);
748 pProfile
->m_Flags
|= FLG_MODIFIED
;
752 PrfWriteProfileString(pProfile
->m_hIni
, (PCSZ
)pszSection
, (PCSZ
)pszEntry
, NULL
);
754 bRet
= releaseProfile(pProfile
);
755 #ifdef TRACE_OSL_PROFILE
756 OSL_TRACE("Out osl_removeProfileEntry [ok]\n");
762 sal_uInt32 SAL_CALL
osl_getProfileSectionEntries(oslProfile Profile
, const sal_Char
*pszSection
,
763 sal_Char
* pszBuffer
, sal_uInt32 MaxLen
)
767 osl_TProfileSection
* pSec
;
768 osl_TProfileImpl
* pProfile
= 0;
770 #ifdef TRACE_OSL_PROFILE
771 OSL_TRACE("In osl_getProfileSectionEntries\n");
774 pProfile
= acquireProfile(Profile
, sal_False
);
776 if (pProfile
== NULL
)
778 #ifdef TRACE_OSL_PROFILE
779 OSL_TRACE("Out osl_getProfileSectionEntries [pProfile=0]\n");
787 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
789 if ((pSec
= findEntry(pProfile
, pszSection
, "", &NoEntry
)) != NULL
)
793 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
795 if ((n
+ pSec
->m_Entries
[i
].m_Len
+ 1) < MaxLen
)
797 strncpy(&pszBuffer
[n
], &pProfile
->m_Lines
[pSec
->m_Entries
[i
].m_Line
]
798 [pSec
->m_Entries
[i
].m_Offset
], pSec
->m_Entries
[i
].m_Len
);
799 n
+= pSec
->m_Entries
[i
].m_Len
;
800 pszBuffer
[n
++] = '\0';
807 pszBuffer
[n
++] = '\0';
811 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
812 n
+= pSec
->m_Entries
[i
].m_Len
+ 1;
821 n
= PrfQueryProfileString(pProfile
->m_hIni
, (PCSZ
)pszSection
, NULL
, NULL
,
824 releaseProfile(pProfile
);
826 #ifdef TRACE_OSL_PROFILE
827 OSL_TRACE("Out osl_getProfileSectionEntries [ok]\n");
833 sal_uInt32 SAL_CALL
osl_getProfileSections(oslProfile Profile
, sal_Char
* pszBuffer
, sal_uInt32 MaxLen
)
836 osl_TProfileSection
* pSec
;
837 osl_TProfileImpl
* pProfile
= acquireProfile(Profile
, sal_False
);
839 if (pProfile
== NULL
)
842 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
846 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
848 pSec
= &pProfile
->m_Sections
[i
];
850 if ((n
+ pSec
->m_Len
+ 1) < MaxLen
)
852 strncpy(&pszBuffer
[n
], &pProfile
->m_Lines
[pSec
->m_Line
][pSec
->m_Offset
],
855 pszBuffer
[n
++] = '\0';
861 pszBuffer
[n
++] = '\0';
865 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
866 n
+= pProfile
->m_Sections
[i
].m_Len
+ 1;
872 n
= PrfQueryProfileString(pProfile
->m_hIni
, NULL
, NULL
, NULL
,
875 releaseProfile(pProfile
);
881 sal_Bool SAL_CALL
osl_getProfileName(rtl_uString
* strPath
, rtl_uString
* strName
, rtl_uString
** strProfileName
)
884 sal_Char File
[_MAX_PATH
];
885 sal_Char Path
[_MAX_PATH
];
887 sal_uInt32 nPathLen
= 0;
889 rtl_uString
* strTmp
= NULL
;
892 /* build file name */
893 if (strName
&& strName
->length
)
895 if(strName
->length
>= _MAX_PATH
)
898 strcpy(File
, (char*)strName
->buffer
);
899 nFileLen
= strName
->length
;
901 if (rtl_ustr_indexOfChar( File
, L
'.' ) == -1)
903 if (nFileLen
+ strlen(STR_INI_EXTENSION
) >= _MAX_PATH
)
906 /* add default extension */
907 strcpy(File
+ nFileLen
, STR_INI_EXTENSION
);
908 nFileLen
+= strlen(STR_INI_EXTENSION
);
913 rtl_uString
*strProgName
= NULL
;
914 sal_Unicode
*pProgName
;
915 sal_Int32 nOffset
= 0;
919 if (osl_getExecutableFile(&strProgName
) != osl_Process_E_None
)
922 /* remove path and extension from filename */
923 pProgName
= strProgName
->buffer
;
924 nLen
= strProgName
->length
;
926 if ((nPos
= rtl_ustr_lastIndexOfChar( pProgName
, L
'/' )) != -1)
928 else if ((nPos
= rtl_ustr_lastIndexOfChar( pProgName
, L
':' )) != -1)
931 if ((nPos
= rtl_ustr_lastIndexOfChar( pProgName
, L
'.' )) != -1 )
934 if ((nFileLen
= nLen
- nOffset
) >= _MAX_PATH
)
937 strncpy(File
, pProgName
+ nOffset
, nFileLen
);
939 if (nFileLen
+ strlen(STR_INI_EXTENSION
) >= _MAX_PATH
)
942 /* add default extension */
943 strcpy(File
+ nFileLen
, STR_INI_EXTENSION
);
944 nFileLen
+= strlen(STR_INI_EXTENSION
);
946 rtl_uString_release( strProgName
);
952 /* build directory path */
953 if (strPath
&& strPath
->length
)
955 sal_Unicode
*pPath
= rtl_uString_getStr(strPath
);
956 sal_Int32 nLen
= rtl_uString_getLength(strPath
);
958 if ((rtl_ustr_ascii_compare_WithLength(pPath
, RTL_CONSTASCII_LENGTH(STR_INI_METAHOME
) , STR_INI_METAHOME
) == 0) &&
959 ((nLen
== RTL_CONSTASCII_LENGTH(STR_INI_METAHOME
)) || (pPath
[RTL_CONSTASCII_LENGTH(STR_INI_METAHOME
)] == '/')))
961 rtl_uString
* strHome
= NULL
;
962 oslSecurity security
= osl_getCurrentSecurity();
964 bFailed
= ! osl_getHomeDir(security
, &strHome
);
965 osl_freeSecurityHandle(security
);
967 if (bFailed
) return (sal_False
);
969 if (strHome
->length
>= _MAX_PATH
)
972 strcpy( Path
, strHome
->buffer
);
973 nPathLen
= strHome
->length
;
975 if (nLen
> RTL_CONSTASCII_LENGTH(STR_INI_METAHOME
))
977 pPath
+= RTL_CONSTASCII_LENGTH(STR_INI_METAHOME
);
978 nLen
-= RTL_CONSTASCII_LENGTH(STR_INI_METAHOME
);
980 if (nLen
+ nPathLen
>= _MAX_PATH
)
983 strcpy(Path
+ nPathLen
, pPath
);
987 rtl_uString_release(strHome
);
990 else if ((rtl_ustr_ascii_compare_WithLength(pPath
, RTL_CONSTASCII_LENGTH(STR_INI_METACFG
), STR_INI_METACFG
) == 0) &&
991 ((nLen
== RTL_CONSTASCII_LENGTH(STR_INI_METACFG
)) || (pPath
[RTL_CONSTASCII_LENGTH(STR_INI_METACFG
)] == '/')))
993 rtl_uString
* strConfig
= NULL
;
994 oslSecurity security
= osl_getCurrentSecurity();
996 bFailed
= ! osl_getConfigDir(security
, &strConfig
);
997 osl_freeSecurityHandle(security
);
999 if (bFailed
) return (sal_False
);
1001 if (strConfig
->length
>= _MAX_PATH
)
1004 strcpy( Path
, strConfig
->buffer
);
1005 nPathLen
= strConfig
->length
;
1007 if (nLen
> RTL_CONSTASCII_LENGTH(STR_INI_METACFG
))
1009 pPath
+= RTL_CONSTASCII_LENGTH(STR_INI_METACFG
);
1010 nLen
-= RTL_CONSTASCII_LENGTH(STR_INI_METACFG
);
1012 if (nLen
+ nPathLen
>= _MAX_PATH
)
1015 strcpy(Path
+ nPathLen
, pPath
);
1019 rtl_uString_release(strConfig
);
1022 else if ((rtl_ustr_ascii_compare_WithLength(pPath
, RTL_CONSTASCII_LENGTH(STR_INI_METASYS
), STR_INI_METASYS
) == 0) &&
1023 ((nLen
== RTL_CONSTASCII_LENGTH(STR_INI_METASYS
)) || (pPath
[RTL_CONSTASCII_LENGTH(STR_INI_METASYS
)] == '/')))
1025 if (((nPathLen
= GetWindowsDirectoryW(Path
, _MAX_PATH
)) == 0) || (nPathLen
>= _MAX_PATH
))
1028 if (nLen
> RTL_CONSTASCII_LENGTH(STR_INI_METASYS
))
1030 pPath
+= RTL_CONSTASCII_LENGTH(STR_INI_METASYS
);
1031 nLen
-= RTL_CONSTASCII_LENGTH(STR_INI_METASYS
);
1033 if (nLen
+ nPathLen
>= MAX_PATH
)
1036 strcpy(Path
+ nPathLen
, pPath
);
1041 else if ((rtl_ustr_ascii_compare_WithLength(pPath
, RTL_CONSTASCII_LENGTH(STR_INI_METAINS
), STR_INI_METAINS
) == 0) &&
1042 ((nLen
== RTL_CONSTASCII_LENGTH(STR_INI_METAINS
)) || (pPath
[RTL_CONSTASCII_LENGTH(STR_INI_METAINS
)] == '/') ||
1043 (pPath
[RTL_CONSTASCII_LENGTH(STR_INI_METAINS
)] == '"') ) )
1045 if (! lookupProfile(pPath
+ RTL_CONSTASCII_LENGTH(STR_INI_METAINS
), File
, Path
))
1048 nPathLen
= strlen(Path
);
1051 else if(nLen
< MAX_PATH
)
1053 strcpy(Path
, pPath
);
1054 nPathLen
= strlen(Path
);
1061 rtl_uString
* strConfigDir
= NULL
;
1062 oslSecurity security
= osl_getCurrentSecurity();
1064 bFailed
= ! osl_getConfigDir(security
, &strConfigDir
);
1065 osl_freeSecurityHandle(security
);
1067 if (bFailed
) return (sal_False
);
1068 if (strConfigDir
->length
>= MAX_PATH
)
1071 strcpy(Path
, strConfigDir
->buffer
);
1072 nPathLen
= strConfigDir
->length
;
1075 if (nPathLen
&& (Path
[nPathLen
- 1] != L
'/') && (Path
[nPathLen
- 1] != L
'\\'))
1077 Path
[nPathLen
++] = L
'\\';
1081 if (nPathLen
+ nFileLen
>= MAX_PATH
)
1084 /* append file name */
1085 strcpy(Path
+ nPathLen
, File
);
1086 nPathLen
+= nFileLen
;
1089 rtl_uString_newFromStr_WithLength(&strTmp
, Path
, nPathLen
);
1090 nError
= osl_getFileURLFromSystemPath(strTmp
, strProfileName
);
1091 rtl_uString_release(strTmp
);
1093 return nError
== osl_File_E_None
;
1098 /*****************************************************************************/
1099 /* Static Module Functions */
1100 /*****************************************************************************/
1102 static osl_TStamp
getFileStamp(osl_TFile
* pFile
)
1104 osl_TStamp FileTime
;
1105 FILESTATUS3 FileStatus
;
1108 Bytes
= sizeof( FILESTATUS3
);
1109 if ( (!pFile
->m_Handle
) ||
1110 DosQueryFileInfo(pFile
->m_Handle
, FIL_STANDARD
, &FileStatus
, Bytes
))
1111 memset(&FileTime
, 0, sizeof(FileTime
));
1114 FileTime
.m_Date
= FileStatus
.fdateLastWrite
;
1115 FileTime
.m_Time
= FileStatus
.ftimeLastWrite
;
1121 static sal_Bool
lockFile(const osl_TFile
* pFile
, osl_TLockMode eMode
)
1123 sal_uInt32 status
= 1;
1126 if (!pFile
->m_Handle
)
1130 Lock
.lRange
= 0xFFFFFFFF;
1135 status
= DosSetFileLocks(pFile
->m_Handle
, &Lock
, NULL
, 1000, 0);
1139 status
= DosSetFileLocks(pFile
->m_Handle
, NULL
, &Lock
, 1000, 1);
1143 status
= DosSetFileLocks(pFile
->m_Handle
, NULL
, &Lock
, 1000, 0);
1147 return (status
== 0);
1150 //static osl_TFile* openFile(rtl_uString* pszFilename, sal_Bool bWriteable)
1151 static osl_TFile
* openFileImpl(rtl_uString
*ustrFileName
, oslProfileOption ProfileFlags
)
1155 osl_TFile
* pFile
= (osl_TFile
*)calloc(1, sizeof(osl_TFile
));
1160 sal_Bool bWriteable
= sal_False
;
1161 rtl_String
* strFileName
=0;
1162 sal_Char
* pszFileName
=0;
1164 /* check parameters */
1165 OSL_ASSERT( ustrFileName
);
1167 rtl_uString2String( &strFileName
,
1168 rtl_uString_getStr(ustrFileName
),
1169 rtl_uString_getLength(ustrFileName
),
1170 osl_getThreadTextEncoding(),
1171 OUSTRING_TO_OSTRING_CVTFLAGS
);
1172 pszFileName
= rtl_string_getStr(strFileName
);
1174 /* if ( ProfileFlags & ( osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE | osl_Profile_READWRITE ) )*/
1175 if ( ProfileFlags
& ( osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
) )
1177 #ifdef DEBUG_OSL_PROFILE
1178 OSL_TRACE("setting bWriteable to TRUE\n");
1180 bWriteable
=sal_True
;
1185 flags
= FILE_NORMAL
| FILE_ARCHIVED
;
1186 attributes
= OPEN_ACTION_CREATE_IF_NEW
| OPEN_ACTION_OPEN_IF_EXISTS
;
1187 mode
= OPEN_SHARE_DENYNONE
| OPEN_ACCESS_READWRITE
;
1191 flags
= FILE_NORMAL
;
1192 attributes
= OPEN_ACTION_FAIL_IF_NEW
| OPEN_ACTION_OPEN_IF_EXISTS
;
1193 mode
= OPEN_SHARE_DENYNONE
| OPEN_ACCESS_READONLY
;
1196 if (rc
= DosOpen((PCSZ
)pszFileName
, &pFile
->m_Handle
, &action
, 0, flags
, attributes
, mode
, NULL
))
1198 if (rc
== ERROR_TOO_MANY_OPEN_FILES
)
1202 rc
= DosSetRelMaxFH(&fhToAdd
, &fhOld
);
1203 rc
= DosOpen((PCSZ
)pszFileName
, &pFile
->m_Handle
, &action
, 0, flags
, attributes
, mode
, NULL
);
1207 if ( (rc
!= NO_ERROR
) && bWriteable
)
1210 rtl_string_release(strFileName
);
1214 rtl_string_release(strFileName
);
1216 pFile
->m_pWriteBuf
=0;
1217 pFile
->m_nWriteBufFree
=0;
1218 pFile
->m_nWriteBufLen
=0;
1220 if ( ProfileFlags
& (osl_Profile_WRITELOCK
| osl_Profile_READLOCK
) )
1222 #ifdef DEBUG_OSL_PROFILE
1223 OSL_TRACE("locking '%s' file\n",pszFilename
);
1226 lockFile(pFile
, bWriteable
? write_lock
: read_lock
);
1229 /* mfe: new WriteBuf obsolete */
1230 /* pFile->m_pWritePtr = pFile->m_Buf;*/
1231 /* pFile->m_pReadPtr = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);*/
1236 //static osl_TStamp closeFile(osl_TFile* pFile)
1237 static osl_TStamp
closeFileImpl(osl_TFile
* pFile
)
1239 osl_TStamp stamp
= {0, 0};
1246 if (pFile
->m_Handle
)
1248 /* mfe: new WriteBuf obsolete */
1249 /* we just closing the file here, DO NOT write, it has to be handled in higher levels */
1250 //if (pFile->m_pWritePtr > pFile->m_WriteBuf)
1252 // sal_uInt32 Bytes;
1254 // DosWrite(pFile->m_Handle, pFile->m_WriteBuf,
1255 // pFile->m_pWritePtr - pFile->m_WriteBuf,
1259 stamp
= getFileStamp(pFile
);
1261 lockFile(pFile
, un_lock
);
1263 DosClose(pFile
->m_Handle
);
1266 if ( pFile
->m_pWriteBuf
!= 0 )
1268 free(pFile
->m_pWriteBuf
);
1276 static sal_Bool
rewindFile(osl_TFile
* pFile
, sal_Bool bTruncate
)
1278 if (pFile
->m_Handle
)
1280 sal_uInt32 Position
;
1282 /* mfe: new WriteBuf obsolete */
1283 /* we just closing the file here, DO NOT write, it has to be handled in higher levels */
1284 /* if (pFile->m_pWritePtr > pFile->m_WriteBuf)
1288 DosWrite(pFile->m_Handle, pFile->m_WriteBuf,
1289 pFile->m_pWritePtr - pFile->m_WriteBuf,
1292 pFile->m_pWritePtr = pFile->m_WriteBuf;
1295 pFile
->m_pReadPtr
= pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
);
1297 DosSetFilePtr(pFile
->m_Handle
, 0, FILE_BEGIN
, &Position
);
1300 DosSetFileSize(pFile
->m_Handle
, 0);
1306 static sal_Bool
getLine(osl_TFile
* pFile
, const sal_Char
*pszLine
, int MaxLen
)
1310 sal_Char
* pLine
= (sal_Char
*)pszLine
;
1313 if (pFile
->m_Handle
== 0)
1320 Bytes
= sizeof(pFile
->m_ReadBuf
) - (pFile
->m_pReadPtr
- pFile
->m_ReadBuf
);
1325 memcpy(pFile
->m_ReadBuf
, pFile
->m_pReadPtr
, Bytes
);
1326 pFile
->m_pReadPtr
= pFile
->m_ReadBuf
;
1328 Free
= sizeof(pFile
->m_ReadBuf
) - Bytes
;
1330 if (DosRead(pFile
->m_Handle
, &pFile
->m_ReadBuf
[Bytes
], Free
, &Max
))
1338 if ((Max
== 0) && (pLine
== pszLine
))
1344 pFile
->m_ReadBuf
[Bytes
+ Max
] = '\0';
1348 for (pChr
= pFile
->m_pReadPtr
;
1349 (*pChr
!= '\n') && (*pChr
!= '\r') && (*pChr
!= '\0') &&
1350 (pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
) - 1));
1353 Max
= min(pChr
- pFile
->m_pReadPtr
, MaxLen
);
1354 memcpy(pLine
, pFile
->m_pReadPtr
, Max
);
1358 if (pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
) - 1))
1362 if ((pChr
[0] == '\r') && (pChr
[1] == '\n'))
1368 if ((pChr
< (pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
))) &&
1370 pChr
= pFile
->m_ReadBuf
+ sizeof(pFile
->m_ReadBuf
);
1374 /* setting MaxLen to -1 indicates terminating read loop */
1378 pFile
->m_pReadPtr
= pChr
;
1385 static sal_Bool
putLine(osl_TFile
* pFile
, const sal_Char
*pszLine
)
1387 unsigned int Len
= strlen(pszLine
);
1389 #ifdef DEBUG_OSL_PROFILE
1393 if ( pFile
== 0 || pFile
->m_Handle
< 0 )
1398 if ( pFile
->m_pWriteBuf
== 0 )
1400 pFile
->m_pWriteBuf
= (sal_Char
*) malloc(Len
+3);
1401 pFile
->m_nWriteBufLen
= Len
+3;
1402 pFile
->m_nWriteBufFree
= Len
+3;
1406 if ( pFile
->m_nWriteBufFree
<= Len
+ 3 )
1410 pTmp
=(sal_Char
*) realloc(pFile
->m_pWriteBuf
,( ( pFile
->m_nWriteBufLen
+ Len
) * 2) );
1415 pFile
->m_pWriteBuf
= pTmp
;
1416 pFile
->m_nWriteBufFree
= pFile
->m_nWriteBufFree
+ pFile
->m_nWriteBufLen
+ ( 2 * Len
);
1417 pFile
->m_nWriteBufLen
= ( pFile
->m_nWriteBufLen
+ Len
) * 2;
1418 memset( (pFile
->m_pWriteBuf
) + ( pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
), 0, pFile
->m_nWriteBufFree
);
1424 memcpy(pFile
->m_pWriteBuf
+ ( pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
),pszLine
,Len
+1);
1425 #ifdef DEBUG_OSL_PROFILE
1426 strLen
= strlen(pFile
->m_pWriteBuf
);
1428 pFile
->m_pWriteBuf
[pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
+ Len
]='\r';
1429 pFile
->m_pWriteBuf
[pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
+ Len
+ 1]='\n';
1430 pFile
->m_pWriteBuf
[pFile
->m_nWriteBufLen
- pFile
->m_nWriteBufFree
+ Len
+ 2]='\0';
1432 pFile
->m_nWriteBufFree
-=Len
+2;
1434 #ifdef DEBUG_OSL_PROFILE
1435 /* OSL_TRACE("File Buffer in _putLine '%s' '%i'(%i)\n",pFile->m_pWriteBuf,strlen(pFile->m_pWriteBuf),pFile->m_nWriteBufLen - pFile->m_nWriteBufFree);*/
1441 /* platform specific end */
1443 static const sal_Char
* stripBlanks(const sal_Char
* String
, sal_uInt32
* pLen
)
1445 if ( (pLen
!= NULL
) && ( *pLen
!= 0 ) )
1447 while ((String
[*pLen
- 1] == ' ') || (String
[*pLen
- 1] == '\t'))
1450 while ((*String
== ' ') || (*String
== '\t'))
1457 while ((*String
== ' ') || (*String
== '\t'))
1463 static const sal_Char
* addLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
)
1465 if (pProfile
->m_NoLines
>= pProfile
->m_MaxLines
)
1467 if (pProfile
->m_Lines
== NULL
)
1469 pProfile
->m_MaxLines
= LINES_INI
;
1470 pProfile
->m_Lines
= (sal_Char
**)malloc(pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1474 pProfile
->m_MaxLines
+= LINES_ADD
;
1475 pProfile
->m_Lines
= (sal_Char
**)realloc(pProfile
->m_Lines
,
1476 pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1479 if (pProfile
->m_Lines
== NULL
)
1481 pProfile
->m_NoLines
= 0;
1482 pProfile
->m_MaxLines
= 0;
1488 pProfile
->m_Lines
[pProfile
->m_NoLines
++] = strdup(Line
);
1490 return (pProfile
->m_Lines
[pProfile
->m_NoLines
- 1]);
1493 static const sal_Char
* insertLine(osl_TProfileImpl
* pProfile
, const sal_Char
* Line
, sal_uInt32 LineNo
)
1495 if (pProfile
->m_NoLines
>= pProfile
->m_MaxLines
)
1497 if (pProfile
->m_Lines
== NULL
)
1499 pProfile
->m_MaxLines
= LINES_INI
;
1500 pProfile
->m_Lines
= (sal_Char
**)malloc(pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1504 pProfile
->m_MaxLines
+= LINES_ADD
;
1505 pProfile
->m_Lines
= (sal_Char
**)realloc(pProfile
->m_Lines
,
1506 pProfile
->m_MaxLines
* sizeof(sal_Char
*));
1509 if (pProfile
->m_Lines
== NULL
)
1511 pProfile
->m_NoLines
= 0;
1512 pProfile
->m_MaxLines
= 0;
1518 LineNo
= LineNo
> pProfile
->m_NoLines
? pProfile
->m_NoLines
: LineNo
;
1520 if (LineNo
< pProfile
->m_NoLines
)
1523 osl_TProfileSection
* pSec
;
1525 memmove(&pProfile
->m_Lines
[LineNo
+ 1], &pProfile
->m_Lines
[LineNo
],
1526 (pProfile
->m_NoLines
- LineNo
) * sizeof(sal_Char
*));
1528 /* adjust line references */
1529 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1531 pSec
= &pProfile
->m_Sections
[i
];
1533 if (pSec
->m_Line
>= LineNo
)
1536 for (n
= 0; n
< pSec
->m_NoEntries
; n
++)
1537 if (pSec
->m_Entries
[n
].m_Line
>= LineNo
)
1538 pSec
->m_Entries
[n
].m_Line
++;
1542 pProfile
->m_NoLines
++;
1544 pProfile
->m_Lines
[LineNo
] = strdup(Line
);
1546 return (pProfile
->m_Lines
[LineNo
]);
1549 static void removeLine(osl_TProfileImpl
* pProfile
, sal_uInt32 LineNo
)
1551 if (LineNo
< pProfile
->m_NoLines
)
1553 free(pProfile
->m_Lines
[LineNo
]);
1554 if (pProfile
->m_NoLines
- LineNo
> 1)
1557 osl_TProfileSection
* pSec
;
1559 memmove(&pProfile
->m_Lines
[LineNo
], &pProfile
->m_Lines
[LineNo
+ 1],
1560 (pProfile
->m_NoLines
- LineNo
- 1) * sizeof(sal_Char
*));
1562 /* adjust line references */
1563 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1565 pSec
= &pProfile
->m_Sections
[i
];
1567 if (pSec
->m_Line
> LineNo
)
1570 for (n
= 0; n
< pSec
->m_NoEntries
; n
++)
1571 if (pSec
->m_Entries
[n
].m_Line
> LineNo
)
1572 pSec
->m_Entries
[n
].m_Line
--;
1577 pProfile
->m_Lines
[LineNo
] = 0;
1580 pProfile
->m_NoLines
--;
1586 static void setEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
* pSection
,
1587 sal_uInt32 NoEntry
, sal_uInt32 Line
,
1588 const sal_Char
* Entry
, sal_uInt32 Len
)
1590 Entry
= stripBlanks(Entry
, &Len
);
1591 pSection
->m_Entries
[NoEntry
].m_Line
= Line
;
1592 pSection
->m_Entries
[NoEntry
].m_Offset
= Entry
- pProfile
->m_Lines
[Line
];
1593 pSection
->m_Entries
[NoEntry
].m_Len
= Len
;
1598 static sal_Bool
addEntry(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
,
1599 int Line
, const sal_Char
* Entry
, sal_uInt32 Len
)
1601 if (pSection
!= NULL
)
1603 if (pSection
->m_NoEntries
>= pSection
->m_MaxEntries
)
1605 if (pSection
->m_Entries
== NULL
)
1607 pSection
->m_MaxEntries
= ENTRIES_INI
;
1608 pSection
->m_Entries
= (osl_TProfileEntry
*)malloc(
1609 pSection
->m_MaxEntries
* sizeof(osl_TProfileEntry
));
1613 pSection
->m_MaxEntries
+= ENTRIES_ADD
;
1614 pSection
->m_Entries
= (osl_TProfileEntry
*)realloc(pSection
->m_Entries
,
1615 pSection
->m_MaxEntries
* sizeof(osl_TProfileEntry
));
1618 if (pSection
->m_Entries
== NULL
)
1620 pSection
->m_NoEntries
= 0;
1621 pSection
->m_MaxEntries
= 0;
1626 pSection
->m_NoEntries
++;
1628 Entry
= stripBlanks(Entry
, &Len
);
1629 setEntry(pProfile
, pSection
, pSection
->m_NoEntries
- 1, Line
,
1638 static void removeEntry(osl_TProfileSection
*pSection
, sal_uInt32 NoEntry
)
1640 if (NoEntry
< pSection
->m_NoEntries
)
1642 if (pSection
->m_NoEntries
- NoEntry
> 1)
1643 memmove(&pSection
->m_Entries
[NoEntry
],
1644 &pSection
->m_Entries
[NoEntry
+ 1],
1645 (pSection
->m_NoEntries
- NoEntry
- 1) * sizeof(osl_TProfileEntry
));
1646 pSection
->m_NoEntries
--;
1652 static sal_Bool
addSection(osl_TProfileImpl
* pProfile
, int Line
, const sal_Char
* Section
, sal_uInt32 Len
)
1654 if (pProfile
->m_NoSections
>= pProfile
->m_MaxSections
)
1656 if (pProfile
->m_Sections
== NULL
)
1658 pProfile
->m_MaxSections
= SECTIONS_INI
;
1659 pProfile
->m_Sections
= (osl_TProfileSection
*)malloc(pProfile
->m_MaxSections
* sizeof(osl_TProfileSection
));
1663 pProfile
->m_MaxSections
+= SECTIONS_ADD
;
1664 pProfile
->m_Sections
= (osl_TProfileSection
*)realloc(pProfile
->m_Sections
,
1665 pProfile
->m_MaxSections
* sizeof(osl_TProfileSection
));
1668 if (pProfile
->m_Sections
== NULL
)
1670 pProfile
->m_NoSections
= 0;
1671 pProfile
->m_MaxSections
= 0;
1676 pProfile
->m_NoSections
++;
1678 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Entries
= NULL
;
1679 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_NoEntries
= 0;
1680 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_MaxEntries
= 0;
1682 Section
= (sal_Char
*)stripBlanks(Section
, &Len
);
1683 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Line
= Line
;
1684 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Offset
= Section
- pProfile
->m_Lines
[Line
];
1685 pProfile
->m_Sections
[pProfile
->m_NoSections
- 1].m_Len
= Len
;
1690 static void removeSection(osl_TProfileImpl
* pProfile
, osl_TProfileSection
*pSection
)
1694 if ((Section
= pSection
- pProfile
->m_Sections
) < pProfile
->m_NoSections
)
1696 free (pSection
->m_Entries
);
1697 if (pProfile
->m_NoSections
- Section
> 1)
1699 memmove(&pProfile
->m_Sections
[Section
], &pProfile
->m_Sections
[Section
+ 1],
1700 (pProfile
->m_NoSections
- Section
- 1) * sizeof(osl_TProfileSection
));
1704 pSection
->m_Entries
= 0;
1707 pProfile
->m_NoSections
--;
1713 static osl_TProfileSection
* findEntry(osl_TProfileImpl
* pProfile
, const sal_Char
* Section
,
1714 const sal_Char
* Entry
, sal_uInt32
*pNoEntry
)
1716 static sal_uInt32 Sect
= 0;
1719 const sal_Char
* pStr
;
1720 osl_TProfileSection
* pSec
;
1722 Len
= strlen(Section
);
1723 Section
= (sal_Char
*)stripBlanks(Section
, &Len
);
1727 for (i
= 0; i
< pProfile
->m_NoSections
; i
++)
1729 n
%= pProfile
->m_NoSections
;
1730 pSec
= &pProfile
->m_Sections
[n
];
1731 if ((Len
== pSec
->m_Len
) &&
1732 (strnicmp(Section
, &pProfile
->m_Lines
[pSec
->m_Line
][pSec
->m_Offset
], pSec
->m_Len
)
1740 if (i
< pProfile
->m_NoSections
)
1742 Len
= strlen(Entry
);
1743 Entry
= stripBlanks(Entry
, &Len
);
1745 *pNoEntry
= pSec
->m_NoEntries
;
1747 for (i
= 0; i
< pSec
->m_NoEntries
; i
++)
1749 pStr
= &pProfile
->m_Lines
[pSec
->m_Entries
[i
].m_Line
]
1750 [pSec
->m_Entries
[i
].m_Offset
];
1751 if ((Len
== pSec
->m_Entries
[i
].m_Len
) &&
1752 (strnicmp(Entry
, pStr
, pSec
->m_Entries
[i
].m_Len
)
1766 static sal_Bool
loadProfile(osl_TFile
* pFile
, osl_TProfileImpl
* pProfile
)
1771 sal_Char Line
[1024];
1773 pProfile
->m_NoLines
= 0;
1774 pProfile
->m_NoSections
= 0;
1776 OSL_VERIFY(rewindFile(pFile
, sal_False
));
1778 while (getLine(pFile
, Line
, sizeof(Line
)))
1780 if (! addLine(pProfile
, Line
))
1784 for (i
= 0; i
< pProfile
->m_NoLines
; i
++)
1786 pStr
= (sal_Char
*)stripBlanks(pProfile
->m_Lines
[i
], NULL
);
1788 if ((*pStr
== '\0') || (*pStr
== ';'))
1791 if ((*pStr
!= '[') || ((pChar
= strrchr(pStr
, ']')) == NULL
) ||
1792 ((pChar
- pStr
) <= 2))
1796 if (pProfile
->m_NoSections
< 1)
1799 if ((pChar
= strchr(pStr
, '=')) == NULL
)
1800 pChar
= pStr
+ strlen(pStr
);
1802 if (! addEntry(pProfile
, &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1],
1803 i
, pStr
, pChar
- pStr
))
1810 if (! addSection(pProfile
, i
, pStr
+ 1, pChar
- pStr
- 1))
1818 static sal_Bool
storeProfile(osl_TFile
* pFile
, osl_TProfileImpl
* pProfile
, sal_Bool bCleanup
)
1820 if (pProfile
->m_Lines
!= NULL
)
1822 if (pProfile
->m_Flags
& FLG_MODIFIED
)
1826 OSL_VERIFY(rewindFile(pFile
, sal_True
));
1828 for (i
= 0; i
< pProfile
->m_NoLines
; i
++)
1829 OSL_VERIFY(putLine(pFile
, pProfile
->m_Lines
[i
]));
1831 pProfile
->m_Flags
&= ~FLG_MODIFIED
;
1836 while (pProfile
->m_NoLines
> 0)
1837 removeLine(pProfile
, pProfile
->m_NoLines
- 1);
1839 free(pProfile
->m_Lines
);
1840 pProfile
->m_Lines
= NULL
;
1841 pProfile
->m_MaxLines
= 0;
1843 while (pProfile
->m_NoSections
> 0)
1844 removeSection(pProfile
, &pProfile
->m_Sections
[pProfile
->m_NoSections
- 1]);
1846 free(pProfile
->m_Sections
);
1847 pProfile
->m_Sections
= NULL
;
1848 pProfile
->m_MaxSections
= 0;
1855 static osl_TProfileImpl
* acquireProfile(oslProfile Profile
, sal_Bool bWriteable
)
1857 osl_TProfileImpl
* pProfile
= (osl_TProfileImpl
*)Profile
;
1858 oslProfileOption PFlags
=0;
1863 /* PFlags = osl_Profile_DEFAULT | osl_Profile_READWRITE; */
1864 PFlags
= osl_Profile_DEFAULT
| osl_Profile_WRITELOCK
;
1868 PFlags
= osl_Profile_DEFAULT
;
1872 if (pProfile
== NULL
)
1874 #ifdef DEBUG_OSL_PROFILE
1875 OSL_TRACE("AUTOOPEN MODE\n");
1878 if ((pProfile
= (osl_TProfileImpl
*)osl_openProfile(NULL
, PFlags
)) != NULL
)
1880 pProfile
->m_Flags
|= FLG_AUTOOPEN
;
1885 #ifdef DEBUG_OSL_PROFILE
1886 OSL_TRACE("try to acquire\n");
1891 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
1893 if (! (pProfile
->m_Flags
& (osl_Profile_READLOCK
|
1894 osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
)))
1897 #ifdef DEBUG_OSL_PROFILE
1898 OSL_TRACE("DEFAULT MODE\n");
1900 if (! (pProfile
->m_pFile
= openFileImpl(pProfile
->m_strFileName
, pProfile
->m_Flags
| PFlags
)))
1903 Stamp
= getFileStamp(pProfile
->m_pFile
);
1905 if (memcmp(&Stamp
, &(pProfile
->m_Stamp
), sizeof(osl_TStamp
)))
1907 pProfile
->m_Stamp
= Stamp
;
1909 loadProfile(pProfile
->m_pFile
, pProfile
);
1914 #ifdef DEBUG_OSL_PROFILE
1915 OSL_TRACE("READ/WRITELOCK MODE\n");
1919 /* A readlock file could not be written */
1920 if ((pProfile
->m_Flags
& osl_Profile_READLOCK
) && bWriteable
)
1928 sal_Bool bWriteable
= sal_False
;
1929 char pszFilename
[PATH_MAX
] = "";
1931 if ( pProfile
->m_strFileName
!= 0 && pProfile
->m_strFileName
->buffer
[0] != 0 )
1932 FileURLToPath( pszFilename
, PATH_MAX
, pProfile
->m_strFileName
);
1933 /* hack: usualy you have a specific HAB, but NULL works here... */
1934 pProfile
->m_hIni
= PrfOpenProfile(NULL
, (PCSZ
)pszFilename
);
1935 if (! pProfile
->m_hIni
)
1943 static sal_Bool
releaseProfile(osl_TProfileImpl
* pProfile
)
1945 #ifdef TRACE_OSL_PROFILE
1946 OSL_TRACE("In releaseProfile\n");
1949 if ( pProfile
== 0 )
1951 #ifdef TRACE_OSL_PROFILE
1952 OSL_TRACE("Out releaseProfile [profile==0]\n");
1957 if (! (pProfile
->m_Flags
& osl_Profile_SYSTEM
))
1959 if (pProfile
->m_Flags
& FLG_AUTOOPEN
)
1961 #ifdef TRACE_OSL_PROFILE
1962 OSL_TRACE("Out releaseProfile [AUTOOPEN]\n");
1964 return (osl_closeProfile((oslProfile
)pProfile
));
1968 #ifdef DEBUG_OSL_PROFILE
1969 OSL_TRACE("DEFAULT MODE\n");
1971 if (! (pProfile
->m_Flags
& (osl_Profile_READLOCK
|
1972 osl_Profile_WRITELOCK
| osl_Profile_FLUSHWRITE
)))
1974 if (pProfile
->m_Flags
& FLG_MODIFIED
)
1975 storeProfile(pProfile
->m_pFile
, pProfile
, sal_False
);
1977 closeFileImpl(pProfile
->m_pFile
);
1978 pProfile
->m_pFile
= NULL
;
1983 PrfCloseProfile(pProfile
->m_hIni
);
1985 #ifdef TRACE_OSL_PROFILE
1986 OSL_TRACE("Out releaseProfile [ok]\n");
1993 static sal_Bool
lookupProfile(const sal_Char
*pszPath
, const sal_Char
*pszFile
, sal_Char
*pPath
)
1995 sal_Char
*pChr
, *pStr
;
1996 sal_Char Path
[_MAX_PATH
] = "";
1997 sal_Char Product
[132] = "";
1998 sal_Char Buffer
[1024];
2000 if (*pszPath
== '"')
2006 while ((*pszPath
!= '"') && (*pszPath
!= '\0'))
2007 Product
[i
++] = *pszPath
++;
2011 if (*pszPath
== '"')
2014 if ( (*pszPath
== '/') || (*pszPath
== '\\') )
2021 /* if we have not product identfication, do a special handling for soffice.ini */
2022 if (stricmp(SVERSION_PROFILE
, pszFile
) == 0)
2024 sal_Char Profile
[_MAX_PATH
];
2025 sal_Char Dir
[_MAX_PATH
];
2026 oslProfile hProfile
;
2028 /* open sversion.ini in the system directory, and try to locate the entry
2029 with the highest version for StarOffice */
2030 if ((osl_getProfileName(SVERSION_FALLBACK
, SVERSION_NAME
, Profile
, sizeof(Profile
))) &&
2031 (hProfile
= osl_openProfile(Profile
, osl_Profile_READLOCK
)))
2033 osl_getProfileSectionEntries(hProfile
, SVERSION_SECTION
,
2034 Buffer
, sizeof(Buffer
));
2036 for (pChr
= Buffer
; *pChr
!= '\0'; pChr
+= strlen(pChr
) + 1)
2038 if ((strnicmp(pChr
, SVERSION_SOFFICE
, sizeof(SVERSION_SOFFICE
) - 1) == 0) &&
2039 (stricmp(Product
, pChr
) < 0))
2041 osl_readProfileString(hProfile
, SVERSION_SECTION
, pChr
,
2042 Dir
, sizeof(Dir
), "");
2044 /* check for existence of path */
2045 if (access(Dir
, 0) >= 0)
2046 strcpy(Product
, pChr
);
2050 osl_closeProfile(hProfile
);
2053 /* open sversion.ini in the users directory, and try to locate the entry
2054 with the highest version for StarOffice */
2055 if ((strcmp(SVERSION_LOCATION
, SVERSION_FALLBACK
) != 0) &&
2056 (osl_getProfileName(SVERSION_LOCATION
, SVERSION_NAME
, Profile
, sizeof(Profile
))) &&
2057 (hProfile
= osl_openProfile(Profile
, osl_Profile_READLOCK
)))
2059 osl_getProfileSectionEntries(hProfile
, SVERSION_SECTION
,
2060 Buffer
, sizeof(Buffer
));
2062 for (pChr
= Buffer
; *pChr
!= '\0'; pChr
+= strlen(pChr
) + 1)
2064 if ((strnicmp(pChr
, SVERSION_SOFFICE
, sizeof(SVERSION_SOFFICE
) - 1) == 0) &&
2065 (stricmp(Product
, pChr
) < 0))
2067 osl_readProfileString(hProfile
, SVERSION_SECTION
, pChr
,
2068 Dir
, sizeof(Dir
), "");
2070 /* check for existence of path */
2071 if (access(Dir
, 0) >= 0)
2072 strcpy(Product
, pChr
);
2076 osl_closeProfile(hProfile
);
2079 /* remove any trailing build number */
2080 if ((pChr
= strrchr(Product
, '/')) != NULL
)
2086 /* if we have an userid option eg. "-userid:rh[/usr/home/rh/staroffice]",
2087 this will supercede all other locations */
2088 if (osl_getCommandArgs(Buffer
, sizeof(Buffer
)) == osl_Process_E_None
)
2090 sal_Char
*pStart
, *pEnd
;
2092 for (pChr
= Buffer
; *pChr
!= '\0'; pChr
+= strlen(pChr
) + 1)
2093 if (((*pChr
== '-') || (*pChr
== '+')) &&
2094 (strnicmp(pChr
+ 1, SVERSION_OPTION
, sizeof(SVERSION_OPTION
) - 1) == 0))
2096 if (((pStart
= strchr(pChr
+ sizeof(SVERSION_OPTION
), '[')) != NULL
) &&
2097 ((pEnd
= strchr(pStart
+ 1, ']')) != NULL
))
2099 strncpy(Path
, pStart
+ 1, pEnd
- (pStart
+ 1));
2100 Path
[pEnd
- (pStart
+ 1)] = '\0';
2102 /* build full path */
2103 if ((Path
[strlen(Path
) - 1] != '/') && (Path
[strlen(Path
) - 1] != '\\'))
2108 pChr
=&Path
[strlen(Path
)];
2109 if ( strlen(pszPath
) <= 0 )
2111 strcat(Path
,SVERSION_USER
);
2113 if ( access(Path
, 0) < 0 )
2120 strcat(Path
, pszPath
);
2128 if (strlen(Path
) <= 0)
2130 /* try to find the file in the directory of the executbale */
2131 if (osl_getExecutableFile(Path
, sizeof(Path
)) != osl_Process_E_None
)
2134 /* seperate path from filename */
2135 if ((pChr
= strrchr(Path
, '\\')) == NULL
)
2136 if ((pChr
= strrchr(Path
, ':')) == NULL
)
2143 /* if we have no product identification use the executable file name */
2144 if (strlen(Product
) <= 0)
2146 strcpy(Product
, pChr
+ 1);
2148 /* remove extension */
2149 if ((pChr
= strrchr(Product
, '.')) != NULL
)
2153 /* remember last subdir */
2154 pStr
= strrchr(Path
, '\\');
2158 if ( strlen(pszPath
) <= 0 )
2160 strcat(Path
, pszPath
);
2164 strcat(Path
,pszPath
);
2167 /* if file not exists, remove any specified subdirectories
2168 like "bin" or "program" */
2169 if (((access(Path
, 0) < 0) && (pStr
!= NULL
)) || (strlen(pszPath
) <= 0))
2171 static sal_Char
*SubDirs
[] = SVERSION_DIRS
;
2175 for (i
= 0; i
< (sizeof(SubDirs
) / sizeof(SubDirs
[0])); i
++)
2176 if (strnicmp(pStr
+ 1, SubDirs
[i
], strlen(SubDirs
[i
])) == 0)
2178 if ( strlen(pszPath
) <= 0)
2180 strcpy(pStr
+ 1,SVERSION_USER
);
2181 if ( access(Path
, 0) < 0 )
2188 strcpy(pStr
+ 1, pszPath
);
2195 pChr
= &Path
[strlen(Path
)];
2196 if ((Path
[strlen(Path
) - 1] != '/') && (Path
[strlen(Path
) - 1] != '\\'))
2198 strcat(Path
, pszFile
);
2200 if ((access(Path
, 0) < 0) && (strlen(Product
) > 0))
2202 sal_Char Profile
[_MAX_PATH
];
2203 oslProfile hProfile
;
2205 /* remove appended filename */
2208 /* open sversion.ini in the system directory, and try to locate the entry
2209 with the highest version for StarOffice */
2210 if ((osl_getProfileName(SVERSION_LOCATION
, SVERSION_NAME
, Profile
, sizeof(Profile
))) &&
2211 (hProfile
= osl_openProfile(Profile
, osl_Profile_READLOCK
)))
2213 pChr
= &Product
[strlen(Product
)];
2215 /* append build number */
2216 strcat(Product
, "/");
2217 strcat(Product
, BUILD_STR(SUPD
));
2219 osl_readProfileString(hProfile
, SVERSION_SECTION
, Product
,
2220 Buffer
, sizeof(Buffer
), "");
2222 /* if not found, try it without build number */
2223 if (strlen(Buffer
) <= 0)
2227 osl_readProfileString(hProfile
, SVERSION_SECTION
, Product
,
2228 Buffer
, sizeof(Buffer
), "");
2230 osl_closeProfile(hProfile
);
2232 /* if not found, try the fallback */
2233 if ((strlen(Buffer
) <= 0) && (strcmp(SVERSION_LOCATION
, SVERSION_FALLBACK
) != 0))
2235 if ((osl_getProfileName(SVERSION_FALLBACK
, SVERSION_NAME
, Profile
, sizeof(Profile
))) &&
2236 (hProfile
= osl_openProfile(Profile
, osl_Profile_READLOCK
)))
2238 /* prepare build number */
2241 osl_readProfileString(hProfile
, SVERSION_SECTION
, Product
,
2242 Buffer
, sizeof(Buffer
), "");
2244 /* if not found, try it without build number */
2245 if (strlen(Buffer
) <= 0)
2249 osl_readProfileString(hProfile
, SVERSION_SECTION
, Product
,
2250 Buffer
, sizeof(Buffer
), "");
2253 osl_closeProfile(hProfile
);
2258 osl_closeProfile(hProfile
);
2260 if (strlen(Buffer
) > 0)
2262 strcpy(Path
, Buffer
);
2264 /* build full path */
2265 if ((Path
[strlen(Path
) - 1] != '/') && (Path
[strlen(Path
) - 1] != '\\'))
2267 if ((*pszPath
!= '/') && (*pszPath
!= '\\'))
2271 pChr
=&Path
[strlen(pszPath
)];
2272 if ( strlen(pszPath
) > 0 )
2274 strcat(Path
, pszPath
);
2278 strcat(Path
,SVERSION_USER
);
2279 if ( access(Path
, 0) < 0 )
2288 /* remove appended filename */
2292 strcpy(pPath
, Path
);