Sandboxie/SandboxiePlus/QSbieAPI/Sandboxie/SbieIni.cpp

342 lines
9.4 KiB
C++
Raw Normal View History

2021-10-16 16:19:51 +01:00
/*
*
2023-08-06 19:14:29 +01:00
* Copyright 2020-2023 David Xanatos, xanasoft.com
2021-10-16 16:19:51 +01:00
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "stdafx.h"
#include "SbieIni.h"
#include "../SbieAPI.h"
2023-04-20 20:52:30 +01:00
#include "../SbieDefs.h"
2021-10-16 16:19:51 +01:00
#include <ntstatus.h>
#define WIN32_NO_STATUS
typedef long NTSTATUS;
#include "..\..\Sandboxie\core\drv\api_flags.h"
CSbieIni::CSbieIni(const QString& Section, class CSbieAPI* pAPI, QObject* parent) : QObject(parent)
{
2022-01-13 22:52:58 +00:00
Q_ASSERT(!Section.isEmpty());
2021-10-16 16:19:51 +01:00
m_Name = Section;
m_pAPI = pAPI;
m_RefreshOnChange = true;
}
CSbieIni::~CSbieIni()
{
}
SB_STATUS CSbieIni::SetText(const QString& Setting, const QString& Value)
{
if (GetText(Setting) == Value)
return SB_OK;
return m_pAPI->SbieIniSet(m_Name, Setting, Value, CSbieAPI::eIniUpdate, m_RefreshOnChange);
}
SB_STATUS CSbieIni::SetNum(const QString& Setting, int Value)
{
return SetText(Setting, QString::number(Value));
}
SB_STATUS CSbieIni::SetNum64(const QString& Setting, __int64 Value)
{
return SetText(Setting, QString::number(Value));
}
SB_STATUS CSbieIni::SetBool(const QString& Setting, bool Value)
{
return SetText(Setting, Value ? "y" : "n");
}
2022-11-29 15:49:16 +00:00
SB_STATUS CSbieIni::SetBoolSafe(const QString& Setting, bool Value)
{
2022-12-06 09:33:17 +00:00
QString StrValue = Value ? "y" : "n";
bool bAdd = true;
2022-11-29 15:49:16 +00:00
QStringList Values = GetTextList(Setting, false);
2022-12-06 09:33:17 +00:00
foreach(const QString & CurValue, Values) {
if (CurValue.contains(","))
2022-11-29 15:49:16 +00:00
continue;
2022-12-06 09:33:17 +00:00
if (CurValue == StrValue)
bAdd = false;
else
DelValue(Setting, CurValue);
2022-11-29 15:49:16 +00:00
}
2022-12-06 09:33:17 +00:00
if(bAdd)
return InsertText(Setting, StrValue);
return SB_OK;
2022-11-29 15:49:16 +00:00
}
2022-06-27 07:33:15 +01:00
QString CSbieIni::GetText(const QString& Setting, const QString& Default, bool bWithGlobal, bool bNoExpand, bool withTemplates) const
2021-10-16 16:19:51 +01:00
{
2022-06-27 07:33:15 +01:00
int flags = (bWithGlobal ? 0 : CONF_GET_NO_GLOBAL);
if (!withTemplates)
flags |= CONF_GET_NO_TEMPLS;
if (bNoExpand)
flags |= CONF_GET_NO_EXPAND;
2021-10-16 16:19:51 +01:00
QString Value = m_pAPI->SbieIniGet(m_Name, Setting, flags);
if (Value.isNull()) Value = Default;
return Value;
}
2022-08-10 19:14:37 +01:00
int CSbieIni::GetNum(const QString& Setting, int Default, bool bWithGlobal, bool withTemplates) const
2021-10-16 16:19:51 +01:00
{
2022-08-10 19:14:37 +01:00
QString StrValue = GetText(Setting, QString(), bWithGlobal, true, withTemplates);
2021-10-16 16:19:51 +01:00
bool ok;
int Value = StrValue.toInt(&ok);
if (!ok) return Default;
return Value;
}
2022-08-10 19:14:37 +01:00
__int64 CSbieIni::GetNum64(const QString& Setting, __int64 Default, bool bWithGlobal, bool withTemplates) const
2021-10-16 16:19:51 +01:00
{
2022-08-10 19:14:37 +01:00
QString StrValue = GetText(Setting, QString(), bWithGlobal, true, withTemplates);
2021-10-16 16:19:51 +01:00
bool ok;
2023-07-01 17:54:53 +01:00
__int64 Value = StrValue.toLongLong(&ok);
2021-10-16 16:19:51 +01:00
if (!ok) return Default;
return Value;
}
2022-08-10 19:14:37 +01:00
bool CSbieIni::GetBool(const QString& Setting, bool Default, bool bWithGlobal, bool withTemplates) const
2021-10-16 16:19:51 +01:00
{
2022-11-29 15:49:16 +00:00
QStringList Values = GetTextList(Setting, withTemplates, false, bWithGlobal);
foreach(const QString &StrValue, Values) {
if (StrValue.contains(","))
continue;
if (StrValue.compare("y", Qt::CaseInsensitive) == 0)
return true;
if (StrValue.compare("n", Qt::CaseInsensitive) == 0)
return false;
}
2021-10-16 16:19:51 +01:00
return Default;
}
2022-01-13 22:52:58 +00:00
QStringList CSbieIni::GetTextList(const QString &Setting, bool withTemplates, bool bExpand, bool bWithGlobal) const
2021-10-16 16:19:51 +01:00
{
QStringList TextList;
2022-01-13 22:52:58 +00:00
int flags = (bWithGlobal ? 0 : CONF_GET_NO_GLOBAL);
2021-10-16 16:19:51 +01:00
if (!withTemplates)
flags |= CONF_GET_NO_TEMPLS;
2022-01-13 22:52:58 +00:00
if (!bExpand)
2021-10-16 16:19:51 +01:00
flags |= CONF_GET_NO_EXPAND;
for (int index = 0; ; index++)
{
QString Value = m_pAPI->SbieIniGet(m_Name, Setting, index | flags);
if (Value.isNull())
break;
TextList.append(Value);
}
return TextList;
}
SB_STATUS CSbieIni::UpdateTextList(const QString &Setting, const QStringList& List, bool withTemplates)
{
QStringList OldSettings = GetTextList(Setting, withTemplates);
QStringList NewSettings;
foreach(const QString& Value, List) {
if (!OldSettings.removeOne(Value))
NewSettings.append(Value);
}
// delete removed or changed settings
foreach(const QString& Value, OldSettings)
DelValue(Setting, Value);
// add new or changed settings
foreach(const QString& Value, NewSettings)
2023-04-13 18:46:51 +01:00
AppendText(Setting, Value);
2021-10-16 16:19:51 +01:00
return SB_OK;
}
QStringList CSbieIni::GetTemplates() const
{
QStringList Templates;
2022-06-27 07:33:15 +01:00
Templates.append("GlobalSettings");
2021-10-16 16:19:51 +01:00
for (int tmpl_index = 0; ; tmpl_index++)
{
QString TmplName = m_pAPI->SbieIniGet(m_Name, "Template", tmpl_index | CONF_GET_NO_TEMPLS);
if (TmplName.isNull())
break;
Templates.append(TmplName);
}
return Templates;
}
QStringList CSbieIni::GetTextListTmpl(const QString &Setting, const QString& Template) const
{
QStringList TextList;
for (int index = 0; ; index++)
{
2022-06-27 07:33:15 +01:00
QString Value = m_pAPI->SbieIniGet((Template != "GlobalSettings") ? "Template_" + Template : Template, Setting, index | CONF_GET_NO_GLOBAL | CONF_GET_NO_EXPAND);
2021-10-16 16:19:51 +01:00
if (Value.isNull())
break;
TextList.append(Value);
}
return TextList;
}
SB_STATUS CSbieIni::InsertText(const QString& Setting, const QString& Value)
{
return m_pAPI->SbieIniSet(m_Name, Setting, Value, CSbieAPI::eIniInsert, m_RefreshOnChange);
}
SB_STATUS CSbieIni::AppendText(const QString& Setting, const QString& Value)
{
return m_pAPI->SbieIniSet(m_Name, Setting, Value, CSbieAPI::eIniAppend, m_RefreshOnChange);
}
SB_STATUS CSbieIni::DelValue(const QString& Setting, const QString& Value)
{
return m_pAPI->SbieIniSet(m_Name, Setting, Value, CSbieAPI::eIniDelete, m_RefreshOnChange);
}
2023-04-20 20:52:30 +01:00
void CSbieIni::SetTextMap(const QString& Setting, const QMap<QString, QStringList> Map)
{
QStringList Mapping;
foreach(const QString& Group, Map.keys())
{
QString CurrentLine;
foreach(const QString & Name, Map[Group]) {
if (Setting.length() + 1 + Group.length() + 1 + CurrentLine.length() + 1 + Name.length() >= CONF_LINE_LEN) { // limit line length
Mapping.append(Group + ":" + CurrentLine);
CurrentLine.clear();
}
if (!CurrentLine.isEmpty()) CurrentLine.append(",");
CurrentLine.append(Name);
}
if(!CurrentLine.isEmpty())
Mapping.append(Group + ":" + CurrentLine);
}
DelValue(Setting);
foreach(const QString & Value, Mapping)
AppendText(Setting, Value);
}
QMap<QString, QStringList> CSbieIni::GetTextMap(const QString& Setting)
{
QMap<QString, QStringList> Map;
foreach(const QString &CurrentLine, GetTextList(Setting, false)) {
int pos = CurrentLine.lastIndexOf(":");
Map[pos == -1 ? "" : CurrentLine.left(pos)].append(CurrentLine.mid(pos+1).split(","));
}
return Map;
}
2021-10-16 16:19:51 +01:00
QList<QPair<QString, QString>> CSbieIni::GetIniSection(qint32* pStatus, bool withTemplates) const
{
qint32 status = STATUS_SUCCESS;
int flags = CONF_GET_NO_EXPAND;
if (!withTemplates)
flags |= CONF_GET_NO_TEMPLS;
QList<QPair<QString, QString>> Settings;
for (int setting_index = 0; ; setting_index++)
{
QString setting_name = m_pAPI->SbieIniGet(m_Name, "", setting_index | flags, &status);
if (status == STATUS_RESOURCE_NAME_NOT_FOUND) {
status = STATUS_SUCCESS;
break;
}
if (status != STATUS_SUCCESS)
break;
for (int value_index = 0; ; value_index++)
{
QString setting_value = m_pAPI->SbieIniGet(m_Name, setting_name, value_index | CONF_GET_NO_GLOBAL | flags, &status);
if (status == STATUS_RESOURCE_NAME_NOT_FOUND) {
status = STATUS_SUCCESS;
break;
}
if (status != STATUS_SUCCESS)
break;
Settings.append(qMakePair(setting_name, setting_value));
}
if (status != STATUS_SUCCESS)
break;
}
if (pStatus) *pStatus = status;
return Settings;
}
2023-05-27 08:03:42 +01:00
SB_STATUS CSbieIni::RenameSection(const QString& NewName, bool deleteOld) // Note: deleteOld is used when duplicating a box
2021-10-16 16:19:51 +01:00
{
qint32 status = STATUS_SUCCESS;
if (m_Name.isEmpty() || NewName.isEmpty())
return SB_ERR();
bool SameName = (bool)(NewName.compare(m_Name, Qt::CaseInsensitive) == 0);
2022-12-07 10:58:37 +00:00
// Get all Settings
2021-10-16 16:19:51 +01:00
QList<QPair<QString, QString>> Settings = GetIniSection(&status);
if (status != STATUS_SUCCESS)
return SB_ERR(SB_FailedCopyConf, QVariantList() << m_Name << (quint32)status, status);
// check if such a box already exists
if (!SameName)
{
m_pAPI->SbieIniGet(NewName, "", CONF_GET_NO_EXPAND, &status);
if (status != STATUS_RESOURCE_NAME_NOT_FOUND)
return SB_ERR(SB_AlreadyExists, QVariantList() << NewName);
}
// if the name is the same we first delete than write,
2022-12-07 16:32:40 +00:00
// else we first write and than delete, for safety reasons
2021-10-16 16:19:51 +01:00
if (deleteOld && SameName)
goto do_delete;
do_write:
2022-12-07 10:58:37 +00:00
// Apply all Settings
2021-10-16 16:19:51 +01:00
for (QList<QPair<QString, QString>>::iterator I = Settings.begin(); I != Settings.end(); ++I)
{
SB_STATUS Status = m_pAPI->SbieIniSet(NewName, I->first, I->second, CSbieAPI::eIniInsert, true);
if (Status.IsError())
return Status;
}
do_delete:
2023-08-06 19:14:29 +01:00
// Delete ini section
2021-10-16 16:19:51 +01:00
if (deleteOld)
{
SB_STATUS Status = m_pAPI->SbieIniSet(m_Name, "*", "", CSbieAPI::eIniUpdate, true);
if (Status.IsError())
return SB_ERR(SB_DeleteFailed, QVariantList() << m_Name << (quint32)Status.GetStatus(), Status.GetStatus());
deleteOld = false;
if (SameName)
goto do_write;
}
if (m_RefreshOnChange)
m_pAPI->CommitIniChanges();
2023-05-27 08:03:42 +01:00
m_Name = NewName;
2021-10-16 16:19:51 +01:00
return SB_OK;
}
SB_STATUS CSbieIni::RemoveSection()
{
return m_pAPI->SbieIniSet(m_Name, "*", "", CSbieAPI::eIniUpdate, m_RefreshOnChange);
2022-12-07 16:32:40 +00:00
}