/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include "system.h"
#include "file_url.hxx"
#include "path_helper.hxx"
#include <string.h>
#include <osl/diagnose.h>
#include <osl/profile.h>
#include <osl/process.h>
#include <osl/thread.h>
#include <osl/file.h>
#include <rtl/alloc.h>
#include <sal/macros.h>
#include <sal/log.hxx>
#include <o3tl/char16_t2wchar_t.hxx>
#include <algorithm>
#include <vector>
using std::min;
static inline void copy_ustr_n( void *dest, const void *source, size_t length ) { memcpy(dest, source, length*sizeof(sal_Unicode)); }
#define LINES_INI 32
#define LINES_ADD 10
#define SECTIONS_INI 5
#define SECTIONS_ADD 3
#define ENTRIES_INI 5
#define ENTRIES_ADD 3
#define STR_INI_EXTENSION L".ini"
#define STR_INI_METAHOME "?~"
#define STR_INI_METASYS "?$"
#define STR_INI_METACFG "?^"
#define STR_INI_METAINS "?#"
#define STR_INI_BOOLYES "yes"
#define STR_INI_BOOLON "on"
#define STR_INI_BOOLONE "1"
#define STR_INI_BOOLNO "no"
#define STR_INI_BOOLOFF "off"
#define STR_INI_BOOLZERO "0"
#define FLG_USER 0x00FF
#define FLG_AUTOOPEN 0x0100
#define FLG_MODIFIED 0x0200
#define SVERSION_LOCATION STR_INI_METACFG
#define SVERSION_FALLBACK STR_INI_METASYS
#define SVERSION_NAME "sversion"
#define SVERSION_SECTION "Versions"
#define SVERSION_SOFFICE "StarOffice"
#define SVERSION_PROFILE "soffice.ini"
#define SVERSION_DIRS { "bin", "program" }
#define SVERSION_USER "user"
/*#define DEBUG_OSL_PROFILE 1*/
typedef FILETIME osl_TStamp;
enum osl_TLockMode
{
un_lock, read_lock, write_lock
};
struct osl_TFile
{
HANDLE m_Handle;
sal_Char* m_pReadPtr;
sal_Char m_ReadBuf[512];
sal_Char* m_pWriteBuf;
sal_uInt32 m_nWriteBufLen;
sal_uInt32 m_nWriteBufFree;
};
struct osl_TProfileEntry
{
sal_uInt32 m_Line;
sal_uInt32 m_Offset;
sal_uInt32 m_Len;
};
struct osl_TProfileSection
{
sal_uInt32 m_Line;
sal_uInt32 m_Offset;
sal_uInt32 m_Len;
sal_uInt32 m_NoEntries;
sal_uInt32 m_MaxEntries;
osl_TProfileEntry* m_Entries;
};
/*
Profile-data structure hidden behind oslProfile:
*/
struct osl_TProfileImpl
{
sal_uInt32 m_Flags;
osl_TFile* m_pFile;
osl_TStamp m_Stamp;
sal_uInt32 m_NoLines;
sal_uInt32 m_MaxLines;
sal_uInt32 m_NoSections;
sal_uInt32 m_MaxSections;
sal_Char** m_Lines;
rtl_uString *m_strFileName;
osl_TProfileSection* m_Sections;
};
static osl_TFile* openFileImpl(rtl_uString * strFileName, oslProfileOption ProfileFlags );
static osl_TStamp closeFileImpl(osl_TFile* pFile);
static bool lockFile(const osl_TFile* pFile, osl_TLockMode eMode);
static bool rewindFile(osl_TFile* pFile, bool bTruncate);
static osl_TStamp getFileStamp(osl_TFile* pFile);
static bool getLine(osl_TFile* pFile, sal_Char *pszLine, int MaxLen);
static bool putLine(osl_TFile* pFile, const sal_Char *pszLine);
static const sal_Char* stripBlanks(const sal_Char* String, sal_uInt32* pLen);
static const sal_Char* addLine(osl_TProfileImpl* pProfile, const sal_Char* Line);
static const sal_Char* insertLine(osl_TProfileImpl* pProfile, const sal_Char* Line, sal_uInt32 LineNo);
static void removeLine(osl_TProfileImpl* pProfile, sal_uInt32 LineNo);
static void setEntry(osl_TProfileImpl* pProfile, osl_TProfileSection* pSection,
sal_uInt32 NoEntry, sal_uInt32 Line,
const sal_Char* Entry, sal_uInt32 Len);
static bool addEntry(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection,
int Line, const sal_Char* Entry, sal_uInt32 Len);
static void removeEntry(osl_TProfileSection *pSection, sal_uInt32 NoEntry);
static bool addSection(osl_TProfileImpl* pProfile, int Line, const sal_Char* Section, sal_uInt32 Len);
static void removeSection(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection);
static osl_TProfileSection* findEntry(osl_TProfileImpl* pProfile, const sal_Char* Section,
const sal_Char* Entry, sal_uInt32 *pNoEntry);
static bool loadProfile(osl_TFile* pFile, osl_TProfileImpl* pProfile);
static bool storeProfile(osl_TProfileImpl* pProfile, bool bCleanup);
static osl_TProfileImpl* acquireProfile(oslProfile Profile, bool bWriteable);
static bool releaseProfile(osl_TProfileImpl* pProfile);
static bool lookupProfile(const sal_Unicode *strPath, const sal_Unicode *strFile, sal_Unicode *strProfile);
static bool writeProfileImpl (osl_TFile* pFile);
static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl*);
static bool osl_ProfileSwapProfileNames(osl_TProfileImpl*);
static rtl_uString* osl_ProfileGenerateExtension(rtl_uString* ustrFileName, rtl_uString* ustrExtension);
static bool osl_getProfileName(rtl_uString* strPath, rtl_uString* strName, rtl_uString** strProfileName);
oslProfile SAL_CALL osl_openProfile(rtl_uString *strProfileName, sal_uInt32 Flags)
{
osl_TFile* pFile = nullptr;
osl_TProfileImpl* pProfile;
rtl_uString *FileName=nullptr;
OSL_VERIFY(strProfileName);
if (rtl_uString_getLength(strProfileName) == 0 )
{
OSL_VERIFY(osl_getProfileName(nullptr, nullptr, &FileName));
}
else
{
rtl_uString_assign(&FileName, strProfileName);
}
osl_getSystemPathFromFileURL(FileName, &FileName);
#ifdef DEBUG_OSL_PROFILE
Flags=osl_Profile_FLUSHWRITE;
if ( Flags == osl_Profile_DEFAULT )
{
SAL_INFO("sal.osl", "with osl_Profile_DEFAULT");
}
if ( Flags & osl_Profile_SYSTEM )
{
SAL_INFO("sal.osl", "with osl_Profile_SYSTEM");
}
if ( Flags & osl_Profile_READLOCK )
{
SAL_INFO("sal.osl", "with osl_Profile_READLOCK");
}
if ( Flags & osl_Profile_WRITELOCK )
{
SAL_INFO("sal.osl", "with osl_Profile_WRITELOCK");
}
if ( Flags & osl_Profile_FLUSHWRITE )
{
SAL_INFO("sal.osl", "with osl_Profile_FLUSHWRITE");
}
#endif
if ( (! (Flags & osl_Profile_SYSTEM)) && ( (pFile = openFileImpl(FileName, Flags) ) == nullptr ) )
{
if( FileName)
rtl_uString_release( FileName);
return nullptr;
}
pProfile = static_cast<osl_TProfileImpl*>(calloc(1, sizeof(osl_TProfileImpl)));
pProfile->m_Flags = Flags & FLG_USER;
osl_getSystemPathFromFileURL(strProfileName, &pProfile->m_strFileName);
if (Flags & (osl_Profile_READLOCK | osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE ))
pProfile->m_pFile = pFile;
pProfile->m_Stamp = getFileStamp(pFile);
loadProfile(pFile, pProfile);
if (pProfile->m_pFile == nullptr)
closeFileImpl(pFile);
if( FileName)
rtl_uString_release( FileName);
return pProfile;
}
sal_Bool SAL_CALL osl_closeProfile(oslProfile Profile)
{
osl_TProfileImpl* pProfile = static_cast<osl_TProfileImpl*>(Profile);
if ( Profile == nullptr )
{
return false;
}
if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
{
pProfile = acquireProfile(Profile,true);
if ( pProfile != nullptr )
{
if ( !( pProfile->m_Flags & osl_Profile_READLOCK ) && ( pProfile->m_Flags & FLG_MODIFIED ) )
{
storeProfile(pProfile, false);
}
}
else
{
pProfile = acquireProfile(Profile,false);
}
if ( pProfile == nullptr )
{
return false;
}
if (pProfile->m_pFile != nullptr)
closeFileImpl(pProfile->m_pFile);
}
pProfile->m_pFile = nullptr;
rtl_uString_release(pProfile->m_strFileName);
pProfile->m_strFileName = nullptr;
/* release whole profile data types memory */
if ( pProfile->m_NoLines > 0)
{
unsigned int index=0;
if ( pProfile->m_Lines != nullptr )
{
for ( index = 0 ; index < pProfile->m_NoLines ; ++index)
{
if ( pProfile->m_Lines[index] != nullptr )
{
free(pProfile->m_Lines[index]);
}
}
free(pProfile->m_Lines);
}
if ( pProfile->m_Sections != nullptr )
{
for ( index = 0 ; index < pProfile->m_NoSections ; ++index )
{
if ( pProfile->m_Sections[index].m_Entries != nullptr )
free(pProfile->m_Sections[index].m_Entries);
}
free(pProfile->m_Sections);
}
}
free(pProfile);
return true;
}
sal_Bool SAL_CALL osl_flushProfile(oslProfile Profile)
{
osl_TProfileImpl* pProfile = static_cast<osl_TProfileImpl*>(Profile);
osl_TFile* pFile;
bool bRet = false;
if ( pProfile == nullptr )
{
return false;
}
pFile = pProfile->m_pFile;
if ( pFile == nullptr || pFile->m_Handle == INVALID_HANDLE_VALUE )
{
return false;
}
if ( pProfile->m_Flags & FLG_MODIFIED )
{
#ifdef DEBUG_OSL_PROFILE
SAL_INFO("sal.osl", "swapping to storeprofile");
#endif
bRet = storeProfile(pProfile,false);
}
return bRet;
}
static bool writeProfileImpl(osl_TFile* pFile)
{
DWORD BytesWritten=0;
BOOL bRet;
if ( !( pFile != nullptr && pFile->m_Handle != INVALID_HANDLE_VALUE ) || ( pFile->m_pWriteBuf == nullptr ) )
{
return false;
}
bRet=WriteFile(pFile->m_Handle, pFile->m_pWriteBuf, pFile->m_nWriteBufLen - pFile->m_nWriteBufFree,&BytesWritten,nullptr);
if ( bRet == 0 || BytesWritten == 0 )
{
OSL_ENSURE(bRet,"WriteFile failed!!!");
SAL_WARN("sal.osl", "write failed " << strerror(errno));
return false;
}
free(pFile->m_pWriteBuf);
pFile->m_pWriteBuf=nullptr;
pFile->m_nWriteBufLen=0;
pFile->m_nWriteBufFree=0;
return true;
}
namespace {
// Use Unicode version of GetPrivateProfileString, to work with Multi-language paths
DWORD GetPrivateProfileStringWrapper(const osl_TProfileImpl* pProfile,
const sal_Char* pszSection, const sal_Char* pszEntry,
sal_Char* pszString, sal_uInt32 MaxLen,
const sal_Char* pszDefault)
{
OSL_ASSERT(pProfile && (!MaxLen || pszString));
rtl_uString *pSection = nullptr, *pEntry = nullptr, *pDefault = nullptr;
if (pszSection)
{
rtl_string2UString(&pSection, pszSection, strlen(pszSection), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS);
OSL_ASSERT(pSection);
}
if (pszEntry)
{
rtl_string2UString(&pEntry, pszEntry, strlen(pszEntry), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS);
OSL_ASSERT(pEntry);
}
if (pszDefault)
{
rtl_string2UString(&pDefault, pszDefault, strlen(pszDefault), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS);
OSL_ASSERT(pDefault);
}
LPCWSTR pWSection = (pSection ? o3tl::toW(rtl_uString_getStr(pSection)) : nullptr),
pWEntry = (pEntry ? o3tl::toW(rtl_uString_getStr(pEntry)) : nullptr),
pWDefault = (pDefault ? o3tl::toW(rtl_uString_getStr(pDefault)) : nullptr);
std::vector<wchar_t> aBuf(MaxLen + 1);
GetPrivateProfileStringW(pWSection, pWEntry, pWDefault, &aBuf[0], MaxLen, o3tl::toW(rtl_uString_getStr(pProfile->m_strFileName)));
if (pDefault)
rtl_uString_release(pDefault);
if (pEntry)
rtl_uString_release(pEntry);
if (pSection)
rtl_uString_release(pSection);
return WideCharToMultiByte(CP_ACP, 0, &aBuf[0], -1, pszString, MaxLen, nullptr, nullptr);
}
// Use Unicode version of WritePrivateProfileString, to work with Multi-language paths
BOOL WritePrivateProfileStringWrapper(const osl_TProfileImpl* pProfile,
const sal_Char* pszSection, const sal_Char* pszEntry,
const sal_Char* pszString)
{
OSL_ASSERT(pProfile && pszSection);
rtl_uString *pSection, *pEntry = nullptr, *pString = nullptr;
rtl_string2UString(&pSection, pszSection, strlen(pszSection), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS);
OSL_ASSERT(pSection);
if (pszEntry)
{
rtl_string2UString(&pEntry, pszEntry, strlen(pszEntry), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS);
OSL_ASSERT(pEntry);
}
if (pszString)
{
rtl_string2UString(&pString, pszString, strlen(pszString), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS);
OSL_ASSERT(pString);
}
LPCWSTR pWSection = o3tl::toW(pSection->buffer),
pWEntry = (pEntry ? o3tl::toW(rtl_uString_getStr(pEntry)) : nullptr),
pWString = (pString ? o3tl::toW(rtl_uString_getStr(pString)) : nullptr);
BOOL bResult = WritePrivateProfileStringW(pWSection, pWEntry, pWString, o3tl::toW(rtl_uString_getStr(pProfile->m_strFileName)));
if (pString)
rtl_uString_release(pString);
if (pEntry)
rtl_uString_release(pEntry);
rtl_uString_release(pSection);
return bResult;
}
}
sal_Bool SAL_CALL osl_readProfileString(oslProfile Profile,
const sal_Char* pszSection, const sal_Char* pszEntry,
sal_Char* pszString, sal_uInt32 MaxLen,
const sal_Char* pszDefault)
{
sal_uInt32 NoEntry;
const sal_Char* pStr = nullptr;
osl_TProfileImpl* pProfile = nullptr;
pProfile = acquireProfile(Profile, false);
if (pProfile == nullptr)
{
return false;
}
if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
{
osl_TProfileSection* pSec;
if (((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) != nullptr) &&
(NoEntry < pSec->m_NoEntries) &&
((pStr = strchr(pProfile->m_Lines[pSec->m_Entries[NoEntry].m_Line],
'=')) != nullptr))
pStr++;
else
pStr = pszDefault;
if ( pStr != nullptr )
{
pStr = stripBlanks(pStr, nullptr);
MaxLen = (MaxLen - 1 < strlen(pStr)) ? (MaxLen - 1) : strlen(pStr);
pStr = stripBlanks(pStr, &MaxLen);
strncpy(pszString, pStr, MaxLen);
pszString[MaxLen] = '\0';
}
}
else
{
if (GetPrivateProfileStringWrapper(pProfile, pszSection, pszEntry, pszString, MaxLen, pszDefault) > 0)
pStr = pszString; // required to return true below
}
releaseProfile(pProfile);
if ( pStr == nullptr )
{
return false;
}
return true;
}
sal_Bool SAL_CALL osl_readProfileBool(oslProfile Profile,
const sal_Char* pszSection, const sal_Char* pszEntry,
sal_Bool Default)
{
sal_Char Line[32];
if (osl_readProfileString(Profile, pszSection, pszEntry, Line, sizeof(Line), ""))
{
if ((stricmp(Line, STR_INI_BOOLYES) == 0) ||
(stricmp(Line, STR_INI_BOOLON) == 0) ||
(stricmp(Line, STR_INI_BOOLONE) == 0))
Default = true;
else
if ((stricmp(Line, STR_INI_BOOLNO) == 0) ||
(stricmp(Line, STR_INI_BOOLOFF) == 0) ||
(stricmp(Line, STR_INI_BOOLZERO) == 0))
Default = false;
}
return Default;
}
sal_uInt32 SAL_CALL osl_readProfileIdent(oslProfile Profile,
const sal_Char* pszSection, const sal_Char* pszEntry,
sal_uInt32 FirstId, const sal_Char* Strings[],
sal_uInt32 Default)
{
sal_uInt32 i;
sal_Char Line[256];
if (osl_readProfileString(Profile, pszSection, pszEntry, Line, sizeof(Line), ""))
{
i = 0;
while (Strings[i] != nullptr)
{
if (stricmp(Line, Strings[i]) == 0)
{
Default = i + FirstId;
break;
}
i++;
}
}
return Default;
}
sal_Bool SAL_CALL osl_writeProfileString(oslProfile Profile,
const sal_Char* pszSection, const sal_Char* pszEntry,
const sal_Char* pszString)
{
sal_uInt32 i;
bool bRet = false;
sal_uInt32 NoEntry;
const sal_Char* pStr;
sal_Char Line[4096];
osl_TProfileSection* pSec;
osl_TProfileImpl* pProfile = nullptr;
pProfile = acquireProfile(Profile, true);
if (pProfile == nullptr)
{
return false;
}
if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
{
if ((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) == nullptr)
{
Line[0] = '\0';
addLine(pProfile, Line);
Line[0] = '[';
strcpy(&Line[1], pszSection);
Line[1 + strlen(pszSection)] = ']';
Line[2 + strlen(pszSection)] = '\0';
if (((pStr = addLine(pProfile, Line)) == nullptr) ||
(! addSection(pProfile, pProfile->m_NoLines - 1, &pStr[1], strlen(pszSection))))
{
releaseProfile(pProfile);
return false;
}
pSec = &pProfile->m_Sections[pProfile->m_NoSections - 1];
NoEntry = pSec->m_NoEntries;
}
Line[0] = '\0';
strcpy(&Line[0], pszEntry);
Line[0 + strlen(pszEntry)] = '=';
strcpy(&Line[1 + strlen(pszEntry)], pszString);
if (NoEntry >= pSec->m_NoEntries)
{
if (pSec->m_NoEntries > 0)
i = pSec->m_Entries[pSec->m_NoEntries - 1].m_Line + 1;
else
i = pSec->m_Line + 1;
if (((pStr = insertLine(pProfile, Line, i)) == nullptr) ||
(! addEntry(pProfile, pSec, i, pStr, strlen(pszEntry))))
{
releaseProfile(pProfile);
return false;
}
pProfile->m_Flags |= FLG_MODIFIED;
}
else
{
i = pSec->m_Entries[NoEntry].m_Line;
free(pProfile->m_Lines[i]);
pProfile->m_Lines[i] = strdup(Line);
setEntry(pProfile, pSec, NoEntry, i, pProfile->m_Lines[i], strlen(pszEntry));
pProfile->m_Flags |= FLG_MODIFIED;
}
}
else
{
WritePrivateProfileStringWrapper(pProfile, pszSection, pszEntry, pszString);
}
bRet = releaseProfile(pProfile);
return bRet;
}
sal_Bool SAL_CALL osl_writeProfileBool(oslProfile Profile,
const sal_Char* pszSection, const sal_Char* pszEntry,
sal_Bool Value)
{
bool bRet = false;
if (Value)
bRet=osl_writeProfileString(Profile, pszSection, pszEntry, STR_INI_BOOLONE);
else
bRet=osl_writeProfileString(Profile, pszSection, pszEntry, STR_INI_BOOLZERO);
return bRet;
}
sal_Bool SAL_CALL osl_writeProfileIdent(oslProfile Profile,
const sal_Char* pszSection, const sal_Char* pszEntry,
sal_uInt32 FirstId, const sal_Char* Strings[],
sal_uInt32 Value)
{
int i, n;
bool bRet = false;
for (n = 0; Strings[n] != nullptr; n++);
if ((i = Value - FirstId) >= n)
bRet=false;
else
bRet=osl_writeProfileString(Profile, pszSection, pszEntry, Strings[i]);
return bRet;
}
sal_Bool SAL_CALL osl_removeProfileEntry(oslProfile Profile,
const sal_Char *pszSection, const sal_Char *pszEntry)
{
sal_uInt32 NoEntry;
osl_TProfileImpl* pProfile = nullptr;
bool bRet = false;
pProfile = acquireProfile(Profile, true);
if (pProfile == nullptr)
return false;
if (!(pProfile->m_Flags & osl_Profile_SYSTEM))
{
osl_TProfileSection* pSec;
if (((pSec = findEntry(pProfile, pszSection, pszEntry, &NoEntry)) != nullptr) &&
(NoEntry < pSec->m_NoEntries))
{
removeLine(pProfile, pSec->m_Entries[NoEntry].m_Line);
removeEntry(pSec, NoEntry);
if (pSec->m_NoEntries == 0)
{
removeLine(pProfile, pSec->m_Line);
/* remove any empty separation line */
if ((pSec->m_Line > 0) && (pProfile->m_Lines[pSec->m_Line - 1][0] == '\0'))
removeLine(pProfile, pSec->m_Line - 1);
removeSection(pProfile, pSec);
}
pProfile->m_Flags |= FLG_MODIFIED;
}
}
else
{
WritePrivateProfileStringWrapper(pProfile, pszSection, pszEntry, nullptr);
}
bRet = releaseProfile(pProfile);
return bRet;
}
sal_uInt32 SAL_CALL osl_getProfileSectionEntries(oslProfile Profile, const sal_Char *pszSection,
sal_Char* pszBuffer, sal_uInt32 MaxLen)
{
sal_uInt32 i, n = 0;
sal_uInt32 NoEntry;
osl_TProfileImpl* pProfile = nullptr;
pProfile = acquireProfile(Profile, false);
if (pProfile == nullptr)
return 0;
if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
{
osl_TProfileSection* pSec;
if ((pSec = findEntry(pProfile, pszSection, "", &NoEntry)) != nullptr)
{
if (MaxLen != 0)
{
for (i = 0; i < pSec->m_NoEntries; i++)
{
if ((n + pSec->m_Entries[i].m_Len + 1) < MaxLen)
{
strncpy(&pszBuffer[n], &pProfile->m_Lines[pSec->m_Entries[i].m_Line]
[pSec->m_Entries[i].m_Offset], pSec->m_Entries[i].m_Len);
n += pSec->m_Entries[i].m_Len;
pszBuffer[n++] = '\0';
}
else
{
break;
}
}
pszBuffer[n++] = '\0';
}
else
{
for (i = 0; i < pSec->m_NoEntries; i++)
{
n += pSec->m_Entries[i].m_Len + 1;
}
n += 1;
}
}
else
{
n = 0;
}
}
else
{
n = GetPrivateProfileStringWrapper(pProfile, pszSection, nullptr, pszBuffer, MaxLen, nullptr);
}
releaseProfile(pProfile);
return n;
}
bool osl_getProfileName(rtl_uString* strPath, rtl_uString* strName, rtl_uString** strProfileName)
{
bool bFailed;
::osl::LongPathBuffer< sal_Unicode > aFile( MAX_LONG_PATH );
::osl::LongPathBuffer< sal_Unicode > aPath( MAX_LONG_PATH );
sal_uInt32 nFileLen = 0;
sal_uInt32 nPathLen = 0;
rtl_uString * strTmp = nullptr;
oslFileError nError;
/* build file name */
if (strName && strName->length)
{
if( ::sal::static_int_cast< sal_uInt32 >( strName->length ) >= aFile.getBufSizeInSymbols() )
return false;
copy_ustr_n( aFile, strName->buffer, strName->length+1);
nFileLen = strName->length;
if (rtl_ustr_indexOfChar( aFile, L'.' ) == -1)
{
if (nFileLen + wcslen(STR_INI_EXTENSION) >= aFile.getBufSizeInSymbols())
return false;
/* add default extension */
copy_ustr_n( aFile + nFileLen, STR_INI_EXTENSION, wcslen(STR_INI_EXTENSION)+1 );
nFileLen += wcslen(STR_INI_EXTENSION);
}
}
else
{
rtl_uString *strProgName = nullptr;
sal_Unicode *pProgName;
sal_Int32 nOffset = 0;
sal_Int32 nLen;
sal_Int32 nPos;
if (osl_getExecutableFile(&strProgName) != osl_Process_E_None)
return false;
/* remove path and extension from filename */
pProgName = strProgName->buffer;
nLen = strProgName->length ;
if ((nPos = rtl_ustr_lastIndexOfChar( pProgName, L'/' )) != -1)
nOffset = nPos + 1;
else if ((nPos = rtl_ustr_lastIndexOfChar( pProgName, L':' )) != -1)
nOffset = nPos + 1;
if ((nPos = rtl_ustr_lastIndexOfChar( pProgName, L'.' )) != -1 )
nLen -= 4;
if ((nFileLen = nLen - nOffset) >= aFile.getBufSizeInSymbols())
return false;
copy_ustr_n(aFile, pProgName + nOffset, nFileLen);
if (nFileLen + wcslen(STR_INI_EXTENSION) >= aFile.getBufSizeInSymbols())
return false;
/* add default extension */
copy_ustr_n(aFile + nFileLen, STR_INI_EXTENSION, wcslen(STR_INI_EXTENSION)+1);
nFileLen += wcslen(STR_INI_EXTENSION);
rtl_uString_release( strProgName );
}
if (aFile[0] == 0)
return false;
/* build directory path */
if (strPath && strPath->length)
{
sal_Unicode *pPath = rtl_uString_getStr(strPath);
sal_Int32 nLen = rtl_uString_getLength(strPath);
if ((rtl_ustr_ascii_compare_WithLength(pPath, RTL_CONSTASCII_LENGTH(STR_INI_METAHOME) , STR_INI_METAHOME) == 0) &&
((nLen == RTL_CONSTASCII_LENGTH(STR_INI_METAHOME)) || (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METAHOME)] == '/')))
{
rtl_uString * strHome = nullptr;
oslSecurity security = osl_getCurrentSecurity();
bFailed = ! osl_getHomeDir(security, &strHome);
osl_freeSecurityHandle(security);
if (bFailed) return false;
if ( ::sal::static_int_cast< sal_uInt32 >( strHome->length ) >= aPath.getBufSizeInSymbols())
return false;
copy_ustr_n( aPath, strHome->buffer, strHome->length+1);
nPathLen = strHome->length;
if (nLen > RTL_CONSTASCII_LENGTH(STR_INI_METAHOME))
{
pPath += RTL_CONSTASCII_LENGTH(STR_INI_METAHOME);
nLen -= RTL_CONSTASCII_LENGTH(STR_INI_METAHOME);
if (nLen + nPathLen >= aPath.getBufSizeInSymbols())
return false;
copy_ustr_n(aPath + nPathLen, pPath, nLen+1);
nPathLen += nLen;
}
rtl_uString_release(strHome);
}
else if ((rtl_ustr_ascii_compare_WithLength(pPath, RTL_CONSTASCII_LENGTH(STR_INI_METACFG), STR_INI_METACFG) == 0) &&
((nLen == RTL_CONSTASCII_LENGTH(STR_INI_METACFG)) || (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METACFG)] == '/')))
{
rtl_uString * strConfig = nullptr;
oslSecurity security = osl_getCurrentSecurity();
bFailed = ! osl_getConfigDir(security, &strConfig);
osl_freeSecurityHandle(security);
if (bFailed) return false;
if ( ::sal::static_int_cast< sal_uInt32 >( strConfig->length ) >= aPath.getBufSizeInSymbols())
return false;
copy_ustr_n( aPath, strConfig->buffer, strConfig->length+1 );
nPathLen = strConfig->length;
if (nLen > RTL_CONSTASCII_LENGTH(STR_INI_METACFG))
{
pPath += RTL_CONSTASCII_LENGTH(STR_INI_METACFG);
nLen -= RTL_CONSTASCII_LENGTH(STR_INI_METACFG);
if (nLen + nPathLen >= aPath.getBufSizeInSymbols())
return false;
copy_ustr_n(aPath + nPathLen, pPath, nLen+1);
nPathLen += nLen;
}
rtl_uString_release(strConfig);
}
else if ((rtl_ustr_ascii_compare_WithLength(pPath, RTL_CONSTASCII_LENGTH(STR_INI_METASYS), STR_INI_METASYS) == 0) &&
((nLen == RTL_CONSTASCII_LENGTH(STR_INI_METASYS)) || (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METASYS)] == '/')))
{
if (((nPathLen = GetWindowsDirectoryW(o3tl::toW(aPath), aPath.getBufSizeInSymbols())) == 0) || (nPathLen >= aPath.getBufSizeInSymbols()))
return false;
if (nLen > RTL_CONSTASCII_LENGTH(STR_INI_METASYS))
{
pPath += RTL_CONSTASCII_LENGTH(STR_INI_METASYS);
nLen -= RTL_CONSTASCII_LENGTH(STR_INI_METASYS);
if (nLen + nPathLen >= aPath.getBufSizeInSymbols())
return false;
copy_ustr_n(aPath + nPathLen, pPath, nLen+1);
nPathLen += nLen;
}
}
else if ((rtl_ustr_ascii_compare_WithLength(pPath, RTL_CONSTASCII_LENGTH(STR_INI_METAINS), STR_INI_METAINS) == 0) &&
((nLen == RTL_CONSTASCII_LENGTH(STR_INI_METAINS)) || (pPath[RTL_CONSTASCII_LENGTH(STR_INI_METAINS)] == '/') ||
(pPath[RTL_CONSTASCII_LENGTH(STR_INI_METAINS)] == '"') ) )
{
if (! lookupProfile(pPath + RTL_CONSTASCII_LENGTH(STR_INI_METAINS), aFile, aPath))
return false;
nPathLen = rtl_ustr_getLength(aPath);
}
else if( ::sal::static_int_cast< sal_uInt32 >( nLen ) < aPath.getBufSizeInSymbols())
{
copy_ustr_n(aPath, pPath, nLen+1);
nPathLen = rtl_ustr_getLength(aPath);
}
else
return false;
}
else
{
rtl_uString * strConfigDir = nullptr;
oslSecurity security = osl_getCurrentSecurity();
bFailed = ! osl_getConfigDir(security, &strConfigDir);
osl_freeSecurityHandle(security);
if (bFailed) return false;
if ( ::sal::static_int_cast< sal_uInt32 >( strConfigDir->length ) >= aPath.getBufSizeInSymbols() )
return false;
copy_ustr_n(aPath, strConfigDir->buffer, strConfigDir->length+1);
nPathLen = strConfigDir->length;
}
if (nPathLen && (aPath[nPathLen - 1] != L'/') && (aPath[nPathLen - 1] != L'\\'))
{
aPath[nPathLen++] = L'\\';
aPath[nPathLen] = 0;
}
if (nPathLen + nFileLen >= aPath.getBufSizeInSymbols())
return false;
/* append file name */
copy_ustr_n(aPath + nPathLen, aFile, nFileLen+1);
nPathLen += nFileLen;
/* copy filename */
rtl_uString_newFromStr_WithLength(&strTmp, aPath, nPathLen);
nError = osl_getFileURLFromSystemPath(strTmp, strProfileName);
rtl_uString_release(strTmp);
return nError == osl_File_E_None;
}
sal_uInt32 SAL_CALL osl_getProfileSections(oslProfile Profile, sal_Char* pszBuffer, sal_uInt32 MaxLen)
{
sal_uInt32 i, n = 0;
osl_TProfileImpl* pProfile = acquireProfile(Profile, false);
if (pProfile == nullptr)
return 0;
if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
{
if (MaxLen != 0)
{
for (i = 0; i < pProfile->m_NoSections; i++)
{
osl_TProfileSection* pSec = &pProfile->m_Sections[i];
if ((n + pSec->m_Len + 1) < MaxLen)
{
strncpy(&pszBuffer[n], &pProfile->m_Lines[pSec->m_Line][pSec->m_Offset],
pSec->m_Len);
n += pSec->m_Len;
pszBuffer[n++] = '\0';
}
else
break;
}
pszBuffer[n++] = '\0';
}
else
{
for (i = 0; i < pProfile->m_NoSections; i++)
n += pProfile->m_Sections[i].m_Len + 1;
n += 1;
}
}
else
{
std::vector<wchar_t> aBuf(MaxLen + 1);
GetPrivateProfileSectionNamesW(&aBuf[0], MaxLen, o3tl::toW(rtl_uString_getStr(pProfile->m_strFileName)));
n = WideCharToMultiByte(CP_ACP, 0, &aBuf[0], -1, pszBuffer, MaxLen, nullptr, nullptr);
}
releaseProfile(pProfile);
return n;
}
static osl_TStamp getFileStamp(osl_TFile* pFile)
{
FILETIME FileTime;
if ((pFile->m_Handle == INVALID_HANDLE_VALUE) ||
(! GetFileTime(pFile->m_Handle, nullptr, nullptr, &FileTime)))
memset(&FileTime, 0, sizeof(FileTime));
return FileTime;
}
static bool lockFile(const osl_TFile* pFile, osl_TLockMode eMode)
{
bool status = false;
OVERLAPPED Overlapped;
if (pFile->m_Handle == INVALID_HANDLE_VALUE)
return false;
memset(&Overlapped, 0, sizeof(Overlapped));
switch (eMode)
{
case un_lock:
status = UnlockFileEx(
pFile->m_Handle, 0, 0xFFFFFFFF, 0, &Overlapped);
break;
case read_lock:
status = LockFileEx(
pFile->m_Handle, 0, 0, 0xFFFFFFFF, 0, &Overlapped);
break;
case write_lock:
status = LockFileEx(
pFile->m_Handle, LOCKFILE_EXCLUSIVE_LOCK, 0, 0xFFFFFFFF, 0,
&Overlapped);
break;
}
return status;
}
static osl_TFile* openFileImpl(rtl_uString * strFileName, oslProfileOption ProfileFlags )
{
osl_TFile* pFile = static_cast< osl_TFile*>( calloc( 1, sizeof(osl_TFile) ) );
bool bWriteable = false;
if ( ProfileFlags & ( osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE ) )
{
#ifdef DEBUG_OSL_PROFILE
SAL_INFO("sal.osl", "setting bWriteable to TRUE");
#endif
bWriteable=true;
}
if (! bWriteable)
{
pFile->m_Handle = CreateFileW( o3tl::toW(rtl_uString_getStr( strFileName )), GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
/* mfe: argghh!!! do not check if the file could be opened */
/* default mode expects it that way!!! */
}
else
{
#ifdef DEBUG_OSL_PROFILE
SAL_INFO("sal.osl", "opening read/write " << pszFilename);
#endif
if ((pFile->m_Handle = CreateFileW( o3tl::toW(rtl_uString_getStr( strFileName )), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr))
== INVALID_HANDLE_VALUE)
{
free(pFile);
return nullptr;
}
}
pFile->m_pWriteBuf=nullptr;
pFile->m_nWriteBufFree=0;
pFile->m_nWriteBufLen=0;
if ( ProfileFlags & (osl_Profile_WRITELOCK | osl_Profile_READLOCK ) )
{
#ifdef DEBUG_OSL_PROFILE
SAL_INFO("sal.osl", "locking file " << pszFilename);
#endif
lockFile(pFile, bWriteable ? write_lock : read_lock);
}
return pFile;
}
static osl_TStamp closeFileImpl(osl_TFile* pFile)
{
osl_TStamp stamp = {0, 0};
if ( pFile == nullptr )
{
return stamp;
}
if (pFile->m_Handle != INVALID_HANDLE_VALUE)
{
stamp = getFileStamp(pFile);
lockFile(pFile, un_lock);
CloseHandle(pFile->m_Handle);
pFile->m_Handle = INVALID_HANDLE_VALUE;
}
if ( pFile->m_pWriteBuf != nullptr )
{
free(pFile->m_pWriteBuf);
}
free(pFile);
return stamp;
}
static bool rewindFile(osl_TFile* pFile, bool bTruncate)
{
if (pFile->m_Handle != INVALID_HANDLE_VALUE)
{
pFile->m_pReadPtr = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);
SetFilePointer(pFile->m_Handle, 0, nullptr, FILE_BEGIN);
if (bTruncate)
SetEndOfFile(pFile->m_Handle);
}
return true;
}
static bool getLine(osl_TFile* pFile, sal_Char *pszLine, int MaxLen)
{
DWORD Max;
size_t Free;
sal_Char* pChr;
sal_Char* pLine = pszLine;
if (pFile->m_Handle == INVALID_HANDLE_VALUE)
return false;
MaxLen -= 1;
do
{
size_t Bytes = sizeof(pFile->m_ReadBuf) - (pFile->m_pReadPtr - pFile->m_ReadBuf);
if (Bytes <= 1)
{
/* refill buffer */
memcpy(pFile->m_ReadBuf, pFile->m_pReadPtr, Bytes);
pFile->m_pReadPtr = pFile->m_ReadBuf;
Free = sizeof(pFile->m_ReadBuf) - Bytes;
if (! ReadFile(pFile->m_Handle, &pFile->m_ReadBuf[Bytes], Free, &Max, nullptr))
{
*pLine = '\0';
return false;
}
if (Max < Free)
{
if ((Max == 0) && (pLine == pszLine))
{
*pLine = '\0';
return false;
}
pFile->m_ReadBuf[Bytes + Max] = '\0';
}
}
for (pChr = pFile->m_pReadPtr;
(*pChr != '\n') && (*pChr != '\r') && (*pChr != '\0') &&
(pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf) - 1));
pChr++);
Max = min(static_cast<int>(pChr - pFile->m_pReadPtr), MaxLen);
memcpy(pLine, pFile->m_pReadPtr, Max);
MaxLen -= Max;
pLine += Max;
if (pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf) - 1))
{
if (*pChr != '\0')
{
if ((pChr[0] == '\r') && (pChr[1] == '\n'))
pChr += 2;
else
pChr += 1;
}
if ((pChr < (pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf))) &&
(*pChr == '\0'))
pChr = pFile->m_ReadBuf + sizeof(pFile->m_ReadBuf);
*pLine = '\0';
/* setting MaxLen to -1 indicates terminating read loop */
MaxLen = -1;
}
pFile->m_pReadPtr = pChr;
}
while (MaxLen > 0);
return true;
}
static bool putLine(osl_TFile* pFile, const sal_Char *pszLine)
{
unsigned int Len = strlen(pszLine);
if ( pFile == nullptr || pFile->m_Handle == INVALID_HANDLE_VALUE )
{
return false;
}
if ( pFile->m_pWriteBuf == nullptr )
{
pFile->m_pWriteBuf = static_cast<sal_Char*>(malloc(Len+3));
pFile->m_nWriteBufLen = Len+3;
pFile->m_nWriteBufFree = Len+3;
}
else
{
if ( pFile->m_nWriteBufFree <= Len + 3 )
{
sal_Char* pTmp;
pTmp=static_cast<sal_Char*>(realloc(pFile->m_pWriteBuf,( ( pFile->m_nWriteBufLen + Len ) * 2) ));
if ( pTmp == nullptr )
{
return false;
}
pFile->m_pWriteBuf = pTmp;
pFile->m_nWriteBufFree = pFile->m_nWriteBufFree + pFile->m_nWriteBufLen + ( 2 * Len );
pFile->m_nWriteBufLen = ( pFile->m_nWriteBufLen + Len ) * 2;
memset( (pFile->m_pWriteBuf) + ( pFile->m_nWriteBufLen - pFile->m_nWriteBufFree ), 0, pFile->m_nWriteBufFree);
}
}
memcpy(pFile->m_pWriteBuf + ( pFile->m_nWriteBufLen - pFile->m_nWriteBufFree ),pszLine,Len+1);
pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len]='\r';
pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len + 1]='\n';
pFile->m_pWriteBuf[pFile->m_nWriteBufLen - pFile->m_nWriteBufFree + Len + 2]='\0';
pFile->m_nWriteBufFree-=Len+2;
return true;
}
/* platform specific end */
static const sal_Char* stripBlanks(const sal_Char* String, sal_uInt32* pLen)
{
if ( (pLen != nullptr) && ( *pLen != 0 ) )
{
while ((String[*pLen - 1] == ' ') || (String[*pLen - 1] == '\t'))
(*pLen)--;
while ((*String == ' ') || (*String == '\t'))
{
String++;
(*pLen)--;
}
}
else
while ((*String == ' ') || (*String == '\t'))
String++;
return String;
}
static const sal_Char* addLine(osl_TProfileImpl* pProfile, const sal_Char* Line)
{
if (pProfile->m_NoLines >= pProfile->m_MaxLines)
{
if (pProfile->m_Lines == nullptr)
{
pProfile->m_MaxLines = LINES_INI;
pProfile->m_Lines = static_cast<sal_Char **>(calloc(pProfile->m_MaxLines, sizeof(sal_Char *)));
}
else
{
unsigned int index=0;
unsigned int oldmax=pProfile->m_MaxLines;
pProfile->m_MaxLines += LINES_ADD;
pProfile->m_Lines = static_cast<sal_Char **>(realloc(pProfile->m_Lines, pProfile->m_MaxLines * sizeof(sal_Char *)));
for ( index = oldmax ; index < pProfile->m_MaxLines ; ++index )
{
pProfile->m_Lines[index]=nullptr;
}
}
if (pProfile->m_Lines == nullptr)
{
pProfile->m_NoLines = 0;
pProfile->m_MaxLines = 0;
return nullptr;
}
}
if ( pProfile->m_Lines != nullptr && pProfile->m_Lines[pProfile->m_NoLines] != nullptr )
{
free(pProfile->m_Lines[pProfile->m_NoLines]);
}
pProfile->m_Lines[pProfile->m_NoLines++] = strdup(Line);
return pProfile->m_Lines[pProfile->m_NoLines - 1];
}
static const sal_Char* insertLine(osl_TProfileImpl* pProfile, const sal_Char* Line, sal_uInt32 LineNo)
{
if (pProfile->m_NoLines >= pProfile->m_MaxLines)
{
if (pProfile->m_Lines == nullptr)
{
pProfile->m_MaxLines = LINES_INI;
pProfile->m_Lines = static_cast<sal_Char **>(calloc(pProfile->m_MaxLines, sizeof(sal_Char *)));
}
else
{
pProfile->m_MaxLines += LINES_ADD;
pProfile->m_Lines = static_cast<sal_Char **>(realloc(pProfile->m_Lines,
pProfile->m_MaxLines * sizeof(sal_Char *)));
memset(&pProfile->m_Lines[pProfile->m_NoLines],
0,
(pProfile->m_MaxLines - pProfile->m_NoLines - 1) * sizeof(sal_Char*));
}
if (pProfile->m_Lines == nullptr)
{
pProfile->m_NoLines = 0;
pProfile->m_MaxLines = 0;
return nullptr;
}
}
LineNo = std::min(LineNo, pProfile->m_NoLines);
if (LineNo < pProfile->m_NoLines)
{
sal_uInt32 i, n;
memmove(&pProfile->m_Lines[LineNo + 1], &pProfile->m_Lines[LineNo],
(pProfile->m_NoLines - LineNo) * sizeof(sal_Char *));
/* adjust line references */
for (i = 0; i < pProfile->m_NoSections; i++)
{
osl_TProfileSection* pSec = &pProfile->m_Sections[i];
if (pSec->m_Line >= LineNo)
pSec->m_Line++;
for (n = 0; n < pSec->m_NoEntries; n++)
if (pSec->m_Entries[n].m_Line >= LineNo)
pSec->m_Entries[n].m_Line++;
}
}
pProfile->m_NoLines++;
pProfile->m_Lines[LineNo] = strdup(Line);
return pProfile->m_Lines[LineNo];
}
static void removeLine(osl_TProfileImpl* pProfile, sal_uInt32 LineNo)
{
if (LineNo < pProfile->m_NoLines)
{
free(pProfile->m_Lines[LineNo]);
pProfile->m_Lines[LineNo]=nullptr;
if (pProfile->m_NoLines - LineNo > 1)
{
sal_uInt32 i, n;
memmove(&pProfile->m_Lines[LineNo], &pProfile->m_Lines[LineNo + 1],
(pProfile->m_NoLines - LineNo - 1) * sizeof(sal_Char *));
memset(&pProfile->m_Lines[pProfile->m_NoLines - 1],
0,
(pProfile->m_MaxLines - pProfile->m_NoLines) * sizeof(sal_Char*));
/* adjust line references */
for (i = 0; i < pProfile->m_NoSections; i++)
{
osl_TProfileSection* pSec = &pProfile->m_Sections[i];
if (pSec->m_Line > LineNo)
pSec->m_Line--;
for (n = 0; n < pSec->m_NoEntries; n++)
if (pSec->m_Entries[n].m_Line > LineNo)
pSec->m_Entries[n].m_Line--;
}
}
else
{
pProfile->m_Lines[LineNo] = nullptr;
}
pProfile->m_NoLines--;
}
return;
}
static void setEntry(osl_TProfileImpl* pProfile, osl_TProfileSection* pSection,
sal_uInt32 NoEntry, sal_uInt32 Line,
const sal_Char* Entry, sal_uInt32 Len)
{
Entry = stripBlanks(Entry, &Len);
pSection->m_Entries[NoEntry].m_Line = Line;
pSection->m_Entries[NoEntry].m_Offset = Entry - pProfile->m_Lines[Line];
pSection->m_Entries[NoEntry].m_Len = Len;
return;
}
static bool addEntry(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection,
int Line, const sal_Char* Entry, sal_uInt32 Len)
{
if (pSection != nullptr)
{
if (pSection->m_NoEntries >= pSection->m_MaxEntries)
{
if (pSection->m_Entries == nullptr)
{
pSection->m_MaxEntries = ENTRIES_INI;
pSection->m_Entries = static_cast<osl_TProfileEntry *>(malloc(
pSection->m_MaxEntries * sizeof(osl_TProfileEntry)));
}
else
{
pSection->m_MaxEntries += ENTRIES_ADD;
pSection->m_Entries = static_cast<osl_TProfileEntry *>(realloc(pSection->m_Entries,
pSection->m_MaxEntries * sizeof(osl_TProfileEntry)));
}
if (pSection->m_Entries == nullptr)
{
pSection->m_NoEntries = 0;
pSection->m_MaxEntries = 0;
return false;
}
}
pSection->m_NoEntries++;
Entry = stripBlanks(Entry, &Len);
setEntry(pProfile, pSection, pSection->m_NoEntries - 1, Line,
Entry, Len);
return true;
}
return false;
}
static void removeEntry(osl_TProfileSection *pSection, sal_uInt32 NoEntry)
{
if (NoEntry < pSection->m_NoEntries)
{
if (pSection->m_NoEntries - NoEntry > 1)
{
memmove(&pSection->m_Entries[NoEntry],
&pSection->m_Entries[NoEntry + 1],
(pSection->m_NoEntries - NoEntry - 1) * sizeof(osl_TProfileEntry));
pSection->m_Entries[pSection->m_NoEntries - 1].m_Line=0;
pSection->m_Entries[pSection->m_NoEntries - 1].m_Offset=0;
pSection->m_Entries[pSection->m_NoEntries - 1].m_Len=0;
}
pSection->m_NoEntries--;
}
return;
}
static bool addSection(osl_TProfileImpl* pProfile, int Line, const sal_Char* Section, sal_uInt32 Len)
{
if (pProfile->m_NoSections >= pProfile->m_MaxSections)
{
if (pProfile->m_Sections == nullptr)
{
pProfile->m_MaxSections = SECTIONS_INI;
pProfile->m_Sections = static_cast<osl_TProfileSection*>(calloc(pProfile->m_MaxSections, sizeof(osl_TProfileSection)));
}
else
{
unsigned int index=0;
unsigned int oldmax=pProfile->m_MaxSections;
pProfile->m_MaxSections += SECTIONS_ADD;
pProfile->m_Sections = static_cast<osl_TProfileSection*>(realloc(pProfile->m_Sections,
pProfile->m_MaxSections * sizeof(osl_TProfileSection)));
for ( index = oldmax ; index < pProfile->m_MaxSections ; ++index )
{
pProfile->m_Sections[index].m_Entries=nullptr;
}
}
if (pProfile->m_Sections == nullptr)
{
pProfile->m_NoSections = 0;
pProfile->m_MaxSections = 0;
return false;
}
}
pProfile->m_NoSections++;
if ( pProfile->m_Sections[(pProfile->m_NoSections) - 1].m_Entries != nullptr )
{
free(pProfile->m_Sections[(pProfile->m_NoSections) - 1].m_Entries);
}
pProfile->m_Sections[pProfile->m_NoSections - 1].m_Entries = nullptr;
pProfile->m_Sections[pProfile->m_NoSections - 1].m_NoEntries = 0;
pProfile->m_Sections[pProfile->m_NoSections - 1].m_MaxEntries = 0;
Section = stripBlanks(Section, &Len);
pProfile->m_Sections[pProfile->m_NoSections - 1].m_Line = Line;
pProfile->m_Sections[pProfile->m_NoSections - 1].m_Offset = Section - pProfile->m_Lines[Line];
pProfile->m_Sections[pProfile->m_NoSections - 1].m_Len = Len;
return true;
}
static void removeSection(osl_TProfileImpl* pProfile, osl_TProfileSection *pSection)
{
sal_uInt32 Section;
if ((Section = pSection - pProfile->m_Sections) < pProfile->m_NoSections)
{
free (pSection->m_Entries);
pSection->m_Entries=nullptr;
if (pProfile->m_NoSections - Section > 1)
{
memmove(&pProfile->m_Sections[Section], &pProfile->m_Sections[Section + 1],
(pProfile->m_NoSections - Section - 1) * sizeof(osl_TProfileSection));
memset(&pProfile->m_Sections[pProfile->m_NoSections - 1],
0,
(pProfile->m_MaxSections - pProfile->m_NoSections) * sizeof(osl_TProfileSection));
pProfile->m_Sections[pProfile->m_NoSections - 1].m_Entries = nullptr;
}
else
{
pSection->m_Entries = nullptr;
}
pProfile->m_NoSections--;
}
return;
}
static osl_TProfileSection* findEntry(osl_TProfileImpl* pProfile, const sal_Char* Section,
const sal_Char* Entry, sal_uInt32 *pNoEntry)
{
static sal_uInt32 Sect = 0;
sal_uInt32 i, n;
sal_uInt32 Len;
osl_TProfileSection* pSec = nullptr;
Len = strlen(Section);
Section = stripBlanks(Section, &Len);
n = Sect;
for (i = 0; i < pProfile->m_NoSections; i++)
{
n %= pProfile->m_NoSections;
pSec = &pProfile->m_Sections[n];
if ((Len == pSec->m_Len) &&
(strnicmp(Section, &pProfile->m_Lines[pSec->m_Line][pSec->m_Offset], pSec->m_Len)
== 0))
break;
n++;
}
Sect = n;
if (i < pProfile->m_NoSections)
{
Len = strlen(Entry);
Entry = stripBlanks(Entry, &Len);
*pNoEntry = pSec->m_NoEntries;
for (i = 0; i < pSec->m_NoEntries; i++)
{
const sal_Char* pStr = &pProfile->m_Lines[pSec->m_Entries[i].m_Line]
[pSec->m_Entries[i].m_Offset];
if ((Len == pSec->m_Entries[i].m_Len) &&
(strnicmp(Entry, pStr, pSec->m_Entries[i].m_Len)
== 0))
{
*pNoEntry = i;
break;
}
}
}
else
pSec = nullptr;
return pSec;
}
static bool loadProfile(osl_TFile* pFile, osl_TProfileImpl* pProfile)
{
sal_uInt32 i;
sal_Char const * pStr;
sal_Char const * pChar;
sal_Char Line[4096];
pProfile->m_NoLines = 0;
pProfile->m_NoSections = 0;
OSL_VERIFY(rewindFile(pFile, false));
while (getLine(pFile, Line, sizeof(Line)))
{
if (! addLine(pProfile, Line))
return false;
}
for (i = 0; i < pProfile->m_NoLines; i++)
{
pStr = stripBlanks(pProfile->m_Lines[i], nullptr);
if ((*pStr == '\0') || (*pStr == ';'))
continue;
if ((*pStr != '[') || ((pChar = strrchr(pStr, ']')) == nullptr) ||
((pChar - pStr) <= 2))
{
/* insert entry */
if (pProfile->m_NoSections < 1)
continue;
if ((pChar = strchr(pStr, '=')) == nullptr)
pChar = pStr + strlen(pStr);
if (! addEntry(pProfile, &pProfile->m_Sections[pProfile->m_NoSections - 1],
i, pStr, pChar - pStr))
return false;
}
else
{
/* new section */
if (! addSection(pProfile, i, pStr + 1, pChar - pStr - 1))
return false;
}
}
return true;
}
static bool storeProfile(osl_TProfileImpl* pProfile, bool bCleanup)
{
if (pProfile->m_Lines != nullptr)
{
if (pProfile->m_Flags & FLG_MODIFIED)
{
sal_uInt32 i;
osl_TFile* pTmpFile = osl_openTmpProfileImpl(pProfile);
if ( pTmpFile == nullptr )
{
return false;
}
OSL_VERIFY(rewindFile(pTmpFile, true));
for (i = 0; i < pProfile->m_NoLines; i++)
{
OSL_VERIFY(putLine(pTmpFile, pProfile->m_Lines[i]));
}
if ( ! writeProfileImpl(pTmpFile) )
{
if ( pTmpFile->m_pWriteBuf != nullptr )
{
free(pTmpFile->m_pWriteBuf);
}
pTmpFile->m_pWriteBuf=nullptr;
pTmpFile->m_nWriteBufLen=0;
pTmpFile->m_nWriteBufFree=0;
closeFileImpl(pTmpFile);
return false;
}
pProfile->m_Flags &= ~FLG_MODIFIED;
closeFileImpl(pProfile->m_pFile);
closeFileImpl(pTmpFile);
osl_ProfileSwapProfileNames(pProfile);
pProfile->m_pFile = openFileImpl(pProfile->m_strFileName,pProfile->m_Flags);
}
if (bCleanup)
{
while (pProfile->m_NoLines > 0)
removeLine(pProfile, pProfile->m_NoLines - 1);
free(pProfile->m_Lines);
pProfile->m_Lines = nullptr;
pProfile->m_MaxLines = 0;
while (pProfile->m_NoSections > 0)
removeSection(pProfile, &pProfile->m_Sections[pProfile->m_NoSections - 1]);
free(pProfile->m_Sections);
pProfile->m_Sections = nullptr;
pProfile->m_MaxSections = 0;
}
}
return true;
}
static osl_TFile* osl_openTmpProfileImpl(osl_TProfileImpl* pProfile)
{
osl_TFile* pFile=nullptr;
rtl_uString* ustrExtension=nullptr;
rtl_uString* ustrTmpName=nullptr;
oslProfileOption PFlags=0;
rtl_uString_newFromAscii(&ustrExtension,"tmp");
/* generate tmp profilename */
ustrTmpName=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
rtl_uString_release(ustrExtension);
if (ustrTmpName == nullptr)
return nullptr;
if (!(pProfile->m_Flags & osl_Profile_READLOCK))
PFlags |= osl_Profile_WRITELOCK;
/* open this file */
pFile = openFileImpl(ustrTmpName,pProfile->m_Flags | PFlags);
/* return new pFile */
return pFile;
}
static bool osl_ProfileSwapProfileNames(osl_TProfileImpl* pProfile)
{
rtl_uString* ustrBakFile=nullptr;
rtl_uString* ustrTmpFile=nullptr;
rtl_uString* ustrIniFile=nullptr;
rtl_uString* ustrExtension=nullptr;
rtl_uString_newFromAscii(&ustrExtension,"bak");
ustrBakFile=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
rtl_uString_release(ustrExtension);
ustrExtension=nullptr;
rtl_uString_newFromAscii(&ustrExtension,"ini");
ustrIniFile=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
rtl_uString_release(ustrExtension);
ustrExtension=nullptr;
rtl_uString_newFromAscii(&ustrExtension,"tmp");
ustrTmpFile=osl_ProfileGenerateExtension(pProfile->m_strFileName,ustrExtension);
rtl_uString_release(ustrExtension);
ustrExtension=nullptr;
/* unlink bak */
DeleteFileW( o3tl::toW(rtl_uString_getStr( ustrBakFile )) );
/* rename ini bak */
MoveFileExW( o3tl::toW(rtl_uString_getStr( ustrIniFile )), o3tl::toW(rtl_uString_getStr( ustrBakFile )), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH );
/* rename tmp ini */
MoveFileExW( o3tl::toW(rtl_uString_getStr( ustrTmpFile )), o3tl::toW(rtl_uString_getStr( ustrIniFile )), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH );
return false;
}
static rtl_uString* osl_ProfileGenerateExtension(rtl_uString* ustrFileName, rtl_uString* ustrExtension)
{
rtl_uString* ustrNewFileName = nullptr;
rtl_uString* ustrOldExtension = nullptr;
sal_Unicode* pFileNameBuf = rtl_uString_getStr(ustrFileName);
rtl_uString_newFromAscii(&ustrOldExtension, ".");
sal_Unicode* pExtensionBuf = rtl_uString_getStr(ustrOldExtension);
sal_Int32 nIndex = rtl_ustr_lastIndexOfChar(pFileNameBuf, *pExtensionBuf);
rtl_uString_newReplaceStrAt(&ustrNewFileName,
ustrFileName,
nIndex+1,
3,
ustrExtension);
return ustrNewFileName;
}
static osl_TProfileImpl* acquireProfile(oslProfile Profile, bool bWriteable)
{
osl_TProfileImpl* pProfile = static_cast<osl_TProfileImpl*>(Profile);
oslProfileOption PFlags=0;
if ( bWriteable )
{
PFlags = osl_Profile_DEFAULT | osl_Profile_WRITELOCK;
}
else
{
PFlags = osl_Profile_DEFAULT;
}
if (pProfile == nullptr)
{
#ifdef DEBUG_OSL_PROFILE
SAL_INFO("sal.osl", "AUTOOPEN MODE");
#endif
if ( ( pProfile = static_cast<osl_TProfileImpl*>(osl_openProfile( nullptr, PFlags )) ) != nullptr )
{
pProfile->m_Flags |= FLG_AUTOOPEN;
}
}
else
{
#ifdef DEBUG_OSL_PROFILE
SAL_INFO("sal.osl", "try to acquire");
#endif
if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
{
if (! (pProfile->m_Flags & (osl_Profile_READLOCK |
osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE)))
{
osl_TStamp Stamp;
#ifdef DEBUG_OSL_PROFILE
SAL_INFO("sal.osl", "DEFAULT MODE");
#endif
pProfile->m_pFile = openFileImpl(
pProfile->m_strFileName, pProfile->m_Flags | PFlags);
if (!pProfile->m_pFile)
return nullptr;
Stamp = getFileStamp(pProfile->m_pFile);
if (memcmp(&Stamp, &(pProfile->m_Stamp), sizeof(osl_TStamp)))
{
pProfile->m_Stamp = Stamp;
loadProfile(pProfile->m_pFile, pProfile);
}
}
else
{
#ifdef DEBUG_OSL_PROFILE
SAL_INFO("sal.osl", "READ/WRITELOCK MODE");
#endif
/* A readlock file could not be written */
if ((pProfile->m_Flags & osl_Profile_READLOCK) && bWriteable)
{
return nullptr;
}
}
}
}
return pProfile;
}
static bool releaseProfile(osl_TProfileImpl* pProfile)
{
if ( pProfile == nullptr )
{
return false;
}
if (! (pProfile->m_Flags & osl_Profile_SYSTEM))
{
if (pProfile->m_Flags & FLG_AUTOOPEN)
{
return osl_closeProfile(static_cast<oslProfile>(pProfile));
}
else
{
#ifdef DEBUG_OSL_PROFILE
SAL_INFO("sal.osl", "DEFAULT MODE");
#endif
if (! (pProfile->m_Flags & (osl_Profile_READLOCK |
osl_Profile_WRITELOCK | osl_Profile_FLUSHWRITE)))
{
if (pProfile->m_Flags & FLG_MODIFIED)
storeProfile(pProfile, false);
closeFileImpl(pProfile->m_pFile);
pProfile->m_pFile = nullptr;
}
}
}
return true;
}
static bool lookupProfile(const sal_Unicode *strPath, const sal_Unicode *strFile, sal_Unicode *strProfile)
{
sal_Char *pChr;
sal_Char Buffer[4096] = "";
sal_Char Product[132] = "";
::osl::LongPathBuffer< sal_Unicode > aPath( MAX_LONG_PATH );
aPath[0] = 0;
if (*strPath == L'"')
{
int i = 0;
strPath++;
while ((strPath[i] != L'"') && (strPath[i] != L'\0'))
i++;
WideCharToMultiByte(CP_ACP,0, o3tl::toW(strPath), i, Product, sizeof(Product), nullptr, nullptr);
Product[i] = '\0';
strPath += i;
if (*strPath == L'"')
strPath++;
if ( (*strPath == L'/') || (*strPath == L'\\') )
{
strPath++;
}
}
else
{
/* if we have not product identification, do a special handling for soffice.ini */
if (rtl_ustr_ascii_compare(strFile, SVERSION_PROFILE) == 0)
{
rtl_uString * strSVProfile = nullptr;
rtl_uString * strSVFallback = nullptr;
rtl_uString * strSVLocation = nullptr;
rtl_uString * strSVName = nullptr;
::osl::LongPathBuffer< sal_Char > aDir( MAX_LONG_PATH );
oslProfile hProfile;
rtl_uString_newFromAscii(&strSVFallback, SVERSION_FALLBACK);
rtl_uString_newFromAscii(&strSVLocation, SVERSION_LOCATION);
rtl_uString_newFromAscii(&strSVName, SVERSION_NAME);
/* open sversion.ini in the system directory, and try to locate the entry
with the highest version for StarOffice */
if (osl_getProfileName( strSVFallback, strSVName, &strSVProfile))
{
hProfile = osl_openProfile(strSVProfile, osl_Profile_READLOCK);
if (hProfile)
{
osl_getProfileSectionEntries(
hProfile, SVERSION_SECTION, Buffer, sizeof(Buffer));
for (pChr = Buffer; *pChr != '\0'; pChr += strlen(pChr) + 1)
{
if ((strnicmp(
pChr, SVERSION_SOFFICE,
sizeof(SVERSION_SOFFICE) - 1)
== 0)
&& (stricmp(Product, pChr) < 0))
{
osl_readProfileString(
hProfile, SVERSION_SECTION, pChr, aDir,
aDir.getBufSizeInSymbols(), "");
/* check for existence of path */
if (access(aDir, 0) >= 0)
strcpy(Product, pChr);
}
}
osl_closeProfile(hProfile);
}
rtl_uString_release(strSVProfile);
strSVProfile = nullptr;
}
/* open sversion.ini in the users directory, and try to locate the entry
with the highest version for StarOffice */
if ( osl_getProfileName(strSVLocation, strSVName, &strSVProfile) )
{
hProfile = osl_openProfile(strSVProfile, osl_Profile_READLOCK);
if (hProfile)
{
osl_getProfileSectionEntries(
hProfile, SVERSION_SECTION, Buffer, sizeof(Buffer));
for (pChr = Buffer; *pChr != '\0'; pChr += strlen(pChr) + 1)
{
if ((strnicmp(
pChr, SVERSION_SOFFICE,
sizeof(SVERSION_SOFFICE) - 1)
== 0)
&& (stricmp(Product, pChr) < 0))
{
osl_readProfileString(
hProfile, SVERSION_SECTION, pChr, aDir,
aDir.getBufSizeInSymbols(), "");
/* check for existence of path */
if (access(aDir, 0) >= 0)
strcpy(Product, pChr);
}
}
osl_closeProfile(hProfile);
}
rtl_uString_release(strSVProfile);
}
rtl_uString_release(strSVFallback);
rtl_uString_release(strSVLocation);
rtl_uString_release(strSVName);
/* remove any trailing build number */
if ((pChr = strrchr(Product, '/')) != nullptr)
*pChr = '\0';
}
}
rtl_uString * strExecutable = nullptr;
rtl_uString * strTmp = nullptr;
sal_Int32 nPos;
/* try to find the file in the directory of the executable */
if (osl_getExecutableFile(&strTmp) != osl_Process_E_None)
return false;
/* convert to native path */
if (osl_getSystemPathFromFileURL(strTmp, &strExecutable) != osl_File_E_None)
{
rtl_uString_release(strTmp);
return false;
}
rtl_uString_release(strTmp);
DWORD dwPathLen = 0;
/* separate path from filename */
if ((nPos = rtl_ustr_lastIndexOfChar(strExecutable->buffer, L'\\')) == -1)
{
if ((nPos = rtl_ustr_lastIndexOfChar(strExecutable->buffer, L':')) == -1)
{
rtl_uString_release(strExecutable);
return false;
}
else
{
copy_ustr_n(aPath, strExecutable->buffer, nPos);
aPath[nPos] = 0;
dwPathLen = nPos;
}
}
else
{
copy_ustr_n(aPath, strExecutable->buffer, nPos);
dwPathLen = nPos;
aPath[dwPathLen] = 0;
}
/* if we have no product identification use the executable file name */
if (*Product == 0)
{
WideCharToMultiByte(CP_ACP,0, o3tl::toW(strExecutable->buffer + nPos + 1), -1, Product, sizeof(Product), nullptr, nullptr);
/* remove extension */
if ((pChr = strrchr(Product, '.')) != nullptr)
*pChr = '\0';
}
rtl_uString_release(strExecutable);
/* remember last subdir */
nPos = rtl_ustr_lastIndexOfChar(aPath, L'\\');
copy_ustr_n(aPath + dwPathLen++, L"\\", 2);
if (*strPath)
{
copy_ustr_n(aPath + dwPathLen, strPath, rtl_ustr_getLength(strPath)+1);
dwPathLen += rtl_ustr_getLength(strPath);
}
{
::osl::LongPathBuffer< sal_Char > aTmpPath( MAX_LONG_PATH );
WideCharToMultiByte(CP_ACP,0, o3tl::toW(aPath), -1, aTmpPath, aTmpPath.getBufSizeInSymbols(), nullptr, nullptr);
/* if file not exists, remove any specified subdirectories
like "bin" or "program" */
if (((access(aTmpPath, 0) < 0) && (nPos != -1)) || (*strPath == 0))
{
static const sal_Char *SubDirs[] = SVERSION_DIRS;
unsigned i = 0;
sal_Char *pStr = aTmpPath + nPos;
for (i = 0; i < SAL_N_ELEMENTS(SubDirs); i++)
if (strnicmp(pStr + 1, SubDirs[i], strlen(SubDirs[i])) == 0)
{
if ( *strPath == 0)
{
strcpy(pStr + 1,SVERSION_USER);
if ( access(aTmpPath, 0) < 0 )
{
*(pStr+1)='\0';
}
else
{
dwPathLen = nPos + MultiByteToWideChar( CP_ACP, 0, SVERSION_USER, -1, o3tl::toW(aPath + nPos + 1), aPath.getBufSizeInSymbols() - (nPos + 1) );
}
}
else
{
copy_ustr_n(aPath + nPos + 1, strPath, rtl_ustr_getLength(strPath)+1);
dwPathLen = nPos + 1 + rtl_ustr_getLength(strPath);
}
break;
}
}
}
if ((aPath[dwPathLen - 1] != L'/') && (aPath[dwPathLen - 1] != L'\\'))
{
aPath[dwPathLen++] = L'\\';
aPath[dwPathLen] = 0;
}
copy_ustr_n(aPath + dwPathLen, strFile, rtl_ustr_getLength(strFile)+1);
{
::osl::LongPathBuffer< sal_Char > aTmpPath( MAX_LONG_PATH );
WideCharToMultiByte(CP_ACP,0, o3tl::toW(aPath), -1, aTmpPath, aTmpPath.getBufSizeInSymbols(), nullptr, nullptr);
if ((access(aTmpPath, 0) < 0) && (Product[0] != '\0'))
{
rtl_uString * strSVFallback = nullptr;
rtl_uString * strSVProfile = nullptr;
rtl_uString * strSVLocation = nullptr;
rtl_uString * strSVName = nullptr;
oslProfile hProfile;
rtl_uString_newFromAscii(&strSVFallback, SVERSION_FALLBACK);
rtl_uString_newFromAscii(&strSVLocation, SVERSION_LOCATION);
rtl_uString_newFromAscii(&strSVName, SVERSION_NAME);
/* open sversion.ini in the system directory, and try to locate the entry
with the highest version for StarOffice */
if (osl_getProfileName(strSVLocation, strSVName, &strSVProfile))
{
hProfile = osl_openProfile(
strSVProfile, osl_Profile_READLOCK);
if (hProfile)
{
osl_readProfileString(
hProfile, SVERSION_SECTION, Product, Buffer,
sizeof(Buffer), "");
osl_closeProfile(hProfile);
/* if not found, try the fallback */
if (Buffer[0] == '\0')
{
if (osl_getProfileName(
strSVFallback, strSVName, &strSVProfile))
{
hProfile = osl_openProfile(
strSVProfile, osl_Profile_READLOCK);
if (hProfile)
{
osl_readProfileString(
hProfile, SVERSION_SECTION, Product,
Buffer, sizeof(Buffer), "");
}
}
osl_closeProfile(hProfile);
}
if (Buffer[0] != '\0')
{
dwPathLen = MultiByteToWideChar(
CP_ACP, 0, Buffer, -1, o3tl::toW(aPath), aPath.getBufSizeInSymbols() );
dwPathLen -=1;
/* build full path */
if ((aPath[dwPathLen - 1] != L'/')
&& (aPath[dwPathLen - 1] != L'\\'))
{
copy_ustr_n(aPath + dwPathLen++, L"\\", 2);
}
if (*strPath)
{
copy_ustr_n(aPath + dwPathLen, strPath, rtl_ustr_getLength(strPath)+1);
dwPathLen += rtl_ustr_getLength(strPath);
}
else
{
::osl::LongPathBuffer< sal_Char > aTmpPath2( MAX_LONG_PATH );
int n;
if ((n = WideCharToMultiByte(
CP_ACP,0, o3tl::toW(aPath), -1, aTmpPath2,
aTmpPath2.getBufSizeInSymbols(), nullptr, nullptr))
> 0)
{
strcpy(aTmpPath2 + n, SVERSION_USER);
if (access(aTmpPath2, 0) >= 0)
{
dwPathLen += MultiByteToWideChar(
CP_ACP, 0, SVERSION_USER, -1,
o3tl::toW(aPath + dwPathLen),
aPath.getBufSizeInSymbols() - dwPathLen );
}
}
}
}
}
rtl_uString_release(strSVProfile);
}
rtl_uString_release(strSVFallback);
rtl_uString_release(strSVLocation);
rtl_uString_release(strSVName);
}
}
aPath[dwPathLen] = 0;
/* copy filename */
copy_ustr_n(strProfile, aPath, dwPathLen+1);
return true;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
↑ V522 There might be dereferencing of a potential null pointer 'pFile'. Check lines: 1081, 1068.
↑ V522 There might be dereferencing of a potential null pointer 'pProfile->m_Lines'. Check lines: 1365, 1362.
↑ V701 realloc() possible leak: when realloc() fails in allocating memory, original pointer 'pProfile->m_Lines' is lost. Consider assigning realloc() to a temporary pointer.
↑ V701 realloc() possible leak: when realloc() fails in allocating memory, original pointer 'pProfile->m_Lines' is lost. Consider assigning realloc() to a temporary pointer.
↑ V701 realloc() possible leak: when realloc() fails in allocating memory, original pointer 'pSection->m_Entries' is lost. Consider assigning realloc() to a temporary pointer.
↑ V701 realloc() possible leak: when realloc() fails in allocating memory, original pointer 'pProfile->m_Sections' is lost. Consider assigning realloc() to a temporary pointer.
↑ V522 There might be dereferencing of a potential null pointer 'pProfile->m_Sections'. Check lines: 1540, 1536.
↑ V522 There might be dereferencing of a potential null pointer 'pProfile'. Check lines: 215, 213.
↑ V522 There might be dereferencing of a potential null pointer 'pProfile->m_Lines'. Check lines: 1328, 1324.