1.10.2
This commit is contained in:
parent
c638c63c36
commit
3912dbfd53
|
@ -6,6 +6,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
## [1.10.2 / 5.65.2] - 2023-07-??
|
## [1.10.2 / 5.65.2] - 2023-07-??
|
||||||
|
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- re-added option to suspend sandboxed processes [#3126](https://github.com/sandboxie-plus/Sandboxie/issues/3126)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- changed format of the addon data [#3135](https://github.com/sandboxie-plus/Sandboxie/issues/3135)
|
- changed format of the addon data [#3135](https://github.com/sandboxie-plus/Sandboxie/issues/3135)
|
||||||
- all users coming from versions 1.10.0 and 1.10.1 will need to reinstall the components in the addon manager
|
- all users coming from versions 1.10.0 and 1.10.1 will need to reinstall the components in the addon manager
|
||||||
|
|
|
@ -54,7 +54,7 @@ CBoxedProcess::CBoxedProcess(quint32 ProcessId, class CSandBox* pBox)
|
||||||
m_ReturnCode = STATUS_PENDING;
|
m_ReturnCode = STATUS_PENDING;
|
||||||
|
|
||||||
m_uTerminated = 0;
|
m_uTerminated = 0;
|
||||||
//m_bSuspended = IsSuspended();
|
m_bSuspended = false;
|
||||||
|
|
||||||
m_bIsWoW64 = false;
|
m_bIsWoW64 = false;
|
||||||
}
|
}
|
||||||
|
@ -280,6 +280,8 @@ void CBoxedProcess::InitProcessInfoImpl(void* ProcessHandle)
|
||||||
{
|
{
|
||||||
m_WorkingDir = CBoxedProcess__GetPebString(ProcessHandle, PhpoCurrentDirectory);
|
m_WorkingDir = CBoxedProcess__GetPebString(ProcessHandle, PhpoCurrentDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_bSuspended = IsSuspended();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBoxedProcess::InitProcessInfoEx()
|
bool CBoxedProcess::InitProcessInfoEx()
|
||||||
|
@ -291,14 +293,20 @@ bool CBoxedProcess::InitProcessInfoEx()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//extern "C"
|
extern "C"
|
||||||
//{
|
{
|
||||||
// NTSYSCALLAPI NTSTATUS NTAPI NtTerminateProcess(_In_opt_ HANDLE ProcessHandle, _In_ NTSTATUS ExitStatus);
|
NTSYSCALLAPI NTSTATUS NTAPI NtTerminateProcess(_In_opt_ HANDLE ProcessHandle, _In_ NTSTATUS ExitStatus);
|
||||||
// NTSYSCALLAPI NTSTATUS NTAPI NtSuspendProcess(_In_ HANDLE ProcessHandle);
|
NTSYSCALLAPI NTSTATUS NTAPI NtSuspendProcess(_In_ HANDLE ProcessHandle);
|
||||||
// NTSYSCALLAPI NTSTATUS NTAPI NtResumeProcess(_In_ HANDLE ProcessHandle);
|
NTSYSCALLAPI NTSTATUS NTAPI NtResumeProcess(_In_ HANDLE ProcessHandle);
|
||||||
//}
|
|
||||||
|
|
||||||
#include <TlHelp32.h>
|
NTSYSCALLAPI NTSTATUS NTAPI NtGetNextThread(HANDLE ProcessHandle, HANDLE ThreadHandle, ACCESS_MASK DesiredAccess, ULONG HandleAttributes, ULONG Flags, PHANDLE NewThreadHandle);
|
||||||
|
|
||||||
|
#define OBJ_KERNEL_EXCLUSIVE 0x00010000L
|
||||||
|
#define OBJ_VALID_PRIVATE_ATTRIBUTES 0x00010000L
|
||||||
|
#define OBJ_ALL_VALID_ATTRIBUTES (OBJ_VALID_PRIVATE_ATTRIBUTES | OBJ_VALID_ATTRIBUTES)
|
||||||
|
}
|
||||||
|
|
||||||
|
//#include <TlHelp32.h>
|
||||||
|
|
||||||
SB_STATUS CBoxedProcess::Terminate()
|
SB_STATUS CBoxedProcess::Terminate()
|
||||||
{
|
{
|
||||||
|
@ -327,7 +335,7 @@ bool CBoxedProcess::IsTerminated(quint64 forMs) const
|
||||||
return ::GetTickCount64() - m_uTerminated > forMs;
|
return ::GetTickCount64() - m_uTerminated > forMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*SB_STATUS CBoxedProcess::SetSuspend(bool bSet)
|
SB_STATUS CBoxedProcess::SetSuspend(bool bSet)
|
||||||
{
|
{
|
||||||
HANDLE ProcessHandle = OpenProcess(PROCESS_SUSPEND_RESUME, FALSE, (DWORD)m_ProcessId);
|
HANDLE ProcessHandle = OpenProcess(PROCESS_SUSPEND_RESUME, FALSE, (DWORD)m_ProcessId);
|
||||||
if (ProcessHandle != INVALID_HANDLE_VALUE)
|
if (ProcessHandle != INVALID_HANDLE_VALUE)
|
||||||
|
@ -351,43 +359,26 @@ bool CBoxedProcess::IsSuspended() const
|
||||||
{
|
{
|
||||||
bool isSuspended = true;
|
bool isSuspended = true;
|
||||||
|
|
||||||
// todo: do that globally once per sec for all boxed processes
|
for(HANDLE hThread = NULL;;)
|
||||||
|
|
||||||
// Note: If the specified process is a 64-bit process and the caller is a 32-bit process, this function fails and the last error code is ERROR_PARTIAL_COPY (299).
|
|
||||||
HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
|
|
||||||
if (hThreadSnap == INVALID_HANDLE_VALUE)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
THREADENTRY32 te32 = { 0 };
|
|
||||||
te32.dwSize = sizeof(THREADENTRY32);
|
|
||||||
if (Thread32First(hThreadSnap, &te32))
|
|
||||||
{
|
{
|
||||||
do
|
HANDLE nNextThread = NULL;
|
||||||
{
|
NTSTATUS status = NtGetNextThread(m->Handle, hThread, THREAD_QUERY_INFORMATION, 0, 0, &nNextThread);
|
||||||
if (te32.th32OwnerProcessID != m_ProcessId)
|
if(hThread) NtClose(hThread);
|
||||||
continue;
|
if (!NT_SUCCESS(status))
|
||||||
|
break;
|
||||||
HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, te32.th32ThreadID);
|
hThread = nNextThread;
|
||||||
|
|
||||||
ULONG SuspendCount = 0;
|
ULONG SuspendCount = 0;
|
||||||
NTSTATUS status = NtQueryInformationThread(hThread, (THREADINFOCLASS)35/ThreadSuspendCount/, &SuspendCount, sizeof(ULONG), NULL);
|
status = NtQueryInformationThread(hThread, (THREADINFOCLASS)35/*ThreadSuspendCount*/, &SuspendCount, sizeof(ULONG), NULL);
|
||||||
|
if (SuspendCount == 0) {
|
||||||
CloseHandle(hThread);
|
isSuspended = false;
|
||||||
|
NtClose(hThread);
|
||||||
if (SuspendCount == 0)
|
break;
|
||||||
{
|
}
|
||||||
isSuspended = false;
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
} while (Thread32Next(hThreadSnap, &te32));
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseHandle(hThreadSnap);
|
|
||||||
|
|
||||||
return isSuspended;
|
return isSuspended;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
void CBoxedProcess::ResolveSymbols(const QVector<quint64>& Addresses)
|
void CBoxedProcess::ResolveSymbols(const QVector<quint64>& Addresses)
|
||||||
{
|
{
|
||||||
|
|
|
@ -47,8 +47,8 @@ public:
|
||||||
virtual bool IsTerminated(quint64 forMs = 0) const;
|
virtual bool IsTerminated(quint64 forMs = 0) const;
|
||||||
virtual void SetTerminated();
|
virtual void SetTerminated();
|
||||||
|
|
||||||
//virtual SB_STATUS SetSuspend(bool bSet);
|
virtual SB_STATUS SetSuspend(bool bSet);
|
||||||
//virtual bool IsSuspended() const;
|
virtual bool IsSuspended() const;
|
||||||
|
|
||||||
virtual bool IsWoW64() const { return m_bIsWoW64; }
|
virtual bool IsWoW64() const { return m_bIsWoW64; }
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ protected:
|
||||||
QDateTime m_StartTime;
|
QDateTime m_StartTime;
|
||||||
quint32 m_ReturnCode;
|
quint32 m_ReturnCode;
|
||||||
quint64 m_uTerminated;
|
quint64 m_uTerminated;
|
||||||
//bool m_bSuspended;
|
bool m_bSuspended;
|
||||||
bool m_bIsWoW64;
|
bool m_bIsWoW64;
|
||||||
|
|
||||||
class CSandBox* m_pBox;
|
class CSandBox* m_pBox;
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include "../QSbieAPI/Sandboxie/SbieTemplates.h"
|
#include "../QSbieAPI/Sandboxie/SbieTemplates.h"
|
||||||
#include <QtConcurrent>
|
#include <QtConcurrent>
|
||||||
#include "../MiscHelpers/Archive/Archive.h"
|
#include "../../SandboxieTools/UpdUtil/UpdUtil.h"
|
||||||
|
|
||||||
|
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
@ -27,8 +27,8 @@ void CAddonManager::UpdateAddonsWhenNotCached()
|
||||||
OnUpdateData(Data, QVariantMap());
|
OnUpdateData(Data, QVariantMap());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (!m_Addons.isEmpty()) {
|
else if (!m_KnownAddons.isEmpty()) {
|
||||||
QFileInfo info(theConf->GetConfigDir() + "/addons.json");
|
QFileInfo info(theConf->GetConfigDir() + "/" ADDONS_FILE);
|
||||||
if (info.birthTime() > QDateTime::currentDateTime().addDays(-1))
|
if (info.birthTime() > QDateTime::currentDateTime().addDays(-1))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -49,77 +49,111 @@ void CAddonManager::OnUpdateData(const QVariantMap& Data, const QVariantMap& Par
|
||||||
QVariantMap Addons = Data["addons"].toMap();
|
QVariantMap Addons = Data["addons"].toMap();
|
||||||
|
|
||||||
QJsonDocument doc(QJsonValue::fromVariant(Addons).toObject());
|
QJsonDocument doc(QJsonValue::fromVariant(Addons).toObject());
|
||||||
QFile::remove(theConf->GetConfigDir() + "/addons.json");
|
QFile::remove(theConf->GetConfigDir() + "/" ADDONS_FILE);
|
||||||
WriteStringToFile(theConf->GetConfigDir() + "/addons.json", doc.toJson());
|
WriteStringToFile(theConf->GetConfigDir() + "/" ADDONS_FILE, doc.toJson());
|
||||||
|
|
||||||
LoadAddons();
|
LoadAddons();
|
||||||
emit DataUpdated();
|
emit DataUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<CAddonPtr> CAddonManager::GetAddons()
|
QList<CAddonInfoPtr> CAddonManager::GetAddons()
|
||||||
{
|
{
|
||||||
if (m_Addons.isEmpty()) {
|
if (m_KnownAddons.isEmpty()) {
|
||||||
if (!LoadAddons())
|
if (!LoadAddons())
|
||||||
UpdateAddons();
|
UpdateAddons();
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
foreach(const CAddonPtr& pAddon, m_Addons)
|
QMap<QString, CAddonInfoPtr> Addons;
|
||||||
pAddon->Installed = CheckAddon(pAddon);
|
|
||||||
|
m_Installed.clear();
|
||||||
|
QDir Dir(theAPI->GetSbiePath() + ADDONS_PATH);
|
||||||
|
foreach(const QFileInfo & Info, Dir.entryInfoList(QStringList() << "*.json", QDir::Files | QDir::Hidden | QDir::System)) {
|
||||||
|
QString AddonPath = theAPI->GetSbiePath() + ADDONS_PATH + Info.fileName();
|
||||||
|
QString AddonStr = ReadFileAsString(AddonPath);
|
||||||
|
QVariantMap Data = QJsonDocument::fromJson(AddonStr.toUtf8()).toVariant().toMap();
|
||||||
|
m_Installed.append(CAddonPtr(new CAddon(Data)));
|
||||||
|
Addons.insert(Data["id"].toString().toLower(), CAddonInfoPtr(new CAddonInfo(Data, true)));
|
||||||
}
|
}
|
||||||
return m_Addons;
|
|
||||||
|
foreach(const CAddonPtr& pAddon, m_KnownAddons) {
|
||||||
|
CAddonInfoPtr& pInfo = Addons[pAddon->Id.toLower()];
|
||||||
|
if (pInfo.isNull()) {
|
||||||
|
bool Installed = false;
|
||||||
|
|
||||||
|
QString Key = pAddon->GetSpecificEntry("uninstallKey").toString();
|
||||||
|
if (!Key.isEmpty()) {
|
||||||
|
QSettings settings(Key, QSettings::NativeFormat);
|
||||||
|
QString Uninstall = settings.value("UninstallString").toString();
|
||||||
|
if (!Uninstall.isEmpty()) {
|
||||||
|
Installed = true;
|
||||||
|
m_Installed.append(CAddonPtr(new CAddon(pAddon->Data)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pInfo = CAddonInfoPtr(new CAddonInfo(pAddon->Data, Installed));
|
||||||
|
}
|
||||||
|
else if (pInfo->Data["version"] != pAddon->Data["version"])
|
||||||
|
pInfo->UpdateVersion = pAddon->Data["version"].toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Addons.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CAddonManager::LoadAddons()
|
bool CAddonManager::LoadAddons()
|
||||||
{
|
{
|
||||||
m_Addons.clear();
|
m_KnownAddons.clear();
|
||||||
|
|
||||||
QString AddonPath = theConf->GetConfigDir() + "/addons.json";
|
QString AddonPath = theConf->GetConfigDir() + "/" ADDONS_FILE;
|
||||||
QVariantMap Data = QJsonDocument::fromJson(ReadFileAsString(AddonPath).toUtf8()).toVariant().toMap();
|
QString AddonStr = ReadFileAsString(AddonPath);
|
||||||
foreach(const QVariant vAddon, Data["list"].toList()) {
|
QVariantMap Data = QJsonDocument::fromJson(AddonStr.toUtf8()).toVariant().toMap();
|
||||||
CAddonPtr pAddon = CAddonPtr(new CAddon(vAddon.toMap()));
|
foreach(const QVariant vAddon, Data["list"].toList())
|
||||||
pAddon->Installed = CheckAddon(pAddon);
|
m_KnownAddons.append(CAddonPtr(new CAddon(vAddon.toMap())));
|
||||||
m_Addons.append(pAddon);
|
|
||||||
}
|
|
||||||
|
|
||||||
return !m_Addons.isEmpty();
|
return !m_KnownAddons.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
CAddonPtr CAddonManager::GetAddon(const QString& Id)
|
CAddonPtr CAddonManager::GetAddon(const QString& Id, EState State)
|
||||||
{
|
{
|
||||||
if (m_Addons.isEmpty())
|
if (State != eNotINstalled)
|
||||||
LoadAddons();
|
{
|
||||||
|
foreach(const CAddonPtr & pAddon, m_Installed) {
|
||||||
|
if (pAddon->Id.compare(Id, Qt::CaseInsensitive) == 0)
|
||||||
|
return pAddon;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach(const CAddonPtr& pAddon, m_Addons) {
|
if (State != eInstalled)
|
||||||
if (pAddon->Id.compare(Id, Qt::CaseInsensitive) == 0) {
|
{
|
||||||
pAddon->Installed = CheckAddon(pAddon);
|
if (m_KnownAddons.isEmpty())
|
||||||
return pAddon;
|
LoadAddons();
|
||||||
|
|
||||||
|
foreach(const CAddonPtr & pAddon, m_KnownAddons) {
|
||||||
|
if (pAddon->Id.compare(Id, Qt::CaseInsensitive) == 0)
|
||||||
|
return pAddon;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return CAddonPtr();
|
return CAddonPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CAddonManager::HasAddon(const QString& Id)
|
/*bool CAddonManager::CheckAddon(const CAddonPtr& pAddon)
|
||||||
{
|
{
|
||||||
CAddonPtr pAddon = GetAddon(Id);
|
QString Key = pAddon->GetSpecificEntry("uninstallKey").toString();
|
||||||
return pAddon && pAddon->Installed;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CAddonManager::CheckAddon(const CAddonPtr& pAddon)
|
|
||||||
{
|
|
||||||
QString Key = pAddon->GetSpecificEntry("uninstall_key").toString();
|
|
||||||
if (!Key.isEmpty()) {
|
if (!Key.isEmpty()) {
|
||||||
QSettings settings(Key, QSettings::NativeFormat);
|
QSettings settings(Key, QSettings::NativeFormat);
|
||||||
QString Uninstall = settings.value("UninstallString").toString();
|
QString Uninstall = settings.value("UninstallString").toString();
|
||||||
return !Uninstall.isEmpty();
|
return !Uninstall.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList Files = pAddon->GetSpecificEntry("files").toStringList();
|
/ *QStringList Files = pAddon->GetSpecificEntry("files").toStringList();
|
||||||
foreach(const QString & File, Files) {
|
foreach(const QString & File, Files) {
|
||||||
if (theGUI->GetCompat()->CheckFile(ExpandPath(File)))
|
if (theGUI->GetCompat()->CheckFile(ExpandPath(File)))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;* /
|
||||||
}
|
|
||||||
|
QString AddonFile = theAPI->GetSbiePath() + ADDONS_PATH + pAddon->Id + ".json";
|
||||||
|
return QFile::exists(AddonFile);
|
||||||
|
}*/
|
||||||
|
|
||||||
SB_PROGRESS CAddonManager::TryInstallAddon(const QString& Id, QWidget* pParent, const QString& Prompt)
|
SB_PROGRESS CAddonManager::TryInstallAddon(const QString& Id, QWidget* pParent, const QString& Prompt)
|
||||||
{
|
{
|
||||||
|
@ -135,151 +169,6 @@ SB_PROGRESS CAddonManager::TryInstallAddon(const QString& Id, QWidget* pParent,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
SB_PROGRESS CAddonManager::InstallAddon(const QString& Id)
|
|
||||||
{
|
|
||||||
CAddonPtr pAddon = GetAddon(Id);
|
|
||||||
if (!pAddon)
|
|
||||||
return SB_ERR(SB_OtherError, QVariantList() << tr("Addon not found, please try updating the addon list in the global settings!"));
|
|
||||||
if (pAddon->Installed)
|
|
||||||
return SB_ERR(SB_OtherError, QVariantList() << tr("Addon already installed!"));
|
|
||||||
|
|
||||||
QString Entry;
|
|
||||||
QString Url = pAddon->GetSpecificEntry("download", &Entry).toString();
|
|
||||||
if (Url.isEmpty())
|
|
||||||
return SB_ERR(SB_OtherError, QVariantList() << tr("Addon has no download url, addon may not be available for your platform."));
|
|
||||||
|
|
||||||
QVariantMap Params;
|
|
||||||
Params["name"] = Id;
|
|
||||||
Params["path"] = theGUI->m_pUpdater->GetUpdateDir(true) + "/" + QUrl(Url).fileName();
|
|
||||||
Params["signature"] = pAddon->Data.value(Entry + "_sig");
|
|
||||||
theGUI->m_pUpdater->DownloadFile(Url, this, SLOT(OnAddonDownloaded(const QString&, const QVariantMap&)), Params);
|
|
||||||
|
|
||||||
pAddon->pProgress = CSbieProgressPtr(new CSbieProgress());
|
|
||||||
connect(pAddon->pProgress.data(), SIGNAL(Finished()), this, SIGNAL(AddonInstalled()));
|
|
||||||
pAddon->pProgress->ShowMessage(tr("Downloading Addon %1").arg(pAddon->Id));
|
|
||||||
return SB_PROGRESS(OP_ASYNC, pAddon->pProgress);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" NTSTATUS VerifyFileSignatureImpl(const wchar_t* FilePath, PVOID Signature, ULONG SignatureSize);
|
|
||||||
|
|
||||||
void CAddonManager::OnAddonDownloaded(const QString& Path, const QVariantMap& Params)
|
|
||||||
{
|
|
||||||
CAddonPtr pAddon = GetAddon(Params["name"].toString());
|
|
||||||
|
|
||||||
QByteArray Signature = QByteArray::fromBase64(Params["signature"].toByteArray());
|
|
||||||
|
|
||||||
if (VerifyFileSignatureImpl(QString(Path).replace("/","\\").toStdWString().c_str(), Signature.data(), Signature.size()) < 0) { // !NT_SUCCESS
|
|
||||||
pAddon->pProgress->Finish(SB_ERR(SB_OtherError, QVariantList() << tr("Download signature is not valid!")));
|
|
||||||
pAddon->pProgress.create();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pAddon->pProgress->ShowMessage(tr("Installing Addon %1").arg(pAddon->Id));
|
|
||||||
|
|
||||||
QtConcurrent::run(CAddonManager::InstallAddonAsync, Path, pAddon);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CAddonManager::InstallAddonAsync(const QString& FilePath, CAddonPtr pAddon)
|
|
||||||
{
|
|
||||||
SB_STATUS Status = SB_OK;
|
|
||||||
|
|
||||||
CArchive Archive(FilePath);
|
|
||||||
|
|
||||||
if (Archive.Open() == 1)
|
|
||||||
{
|
|
||||||
QString FileDir = Split2(FilePath, ".", true).first.replace("/", "\\");
|
|
||||||
if (Archive.Extract(FileDir)) {
|
|
||||||
|
|
||||||
QString Cmd = pAddon->GetSpecificEntry("installer").toString();
|
|
||||||
QString Path = ExpandPath(pAddon->GetSpecificEntry("install_path").toString());
|
|
||||||
if (!Cmd.isEmpty() && QFile::exists(FileDir + Cmd))
|
|
||||||
{
|
|
||||||
pAddon->pProgress->ShowMessage(tr("Running Installer for %1").arg(pAddon->Id));
|
|
||||||
|
|
||||||
std::wstring sbiehome = theAPI->GetSbiePath().toStdWString();
|
|
||||||
std::wstring plusdata = theConf->GetConfigDir().toStdWString();
|
|
||||||
|
|
||||||
LPWCH environmentStrings = GetEnvironmentStrings();
|
|
||||||
|
|
||||||
DWORD environmentLen = 0;
|
|
||||||
for (LPWCH current = environmentStrings; *current; current += wcslen(current) + 1)
|
|
||||||
environmentLen += wcslen(current) + 1;
|
|
||||||
|
|
||||||
LPWCH modifiedEnvironment = (LPWCH)LocalAlloc(0, (environmentLen + sbiehome.length() + 1 + plusdata.length() + 1 + 1) * sizeof(wchar_t));
|
|
||||||
memcpy(modifiedEnvironment, environmentStrings, (environmentLen + 1) * sizeof(wchar_t));
|
|
||||||
|
|
||||||
FreeEnvironmentStrings(environmentStrings);
|
|
||||||
|
|
||||||
LPWCH modifiedEnvironmentEnd = modifiedEnvironment + environmentLen;
|
|
||||||
|
|
||||||
wcscpy(modifiedEnvironmentEnd, L"SBIEHOME=");
|
|
||||||
wcscat(modifiedEnvironmentEnd, sbiehome.c_str());
|
|
||||||
modifiedEnvironmentEnd += wcslen(modifiedEnvironmentEnd) + 1;
|
|
||||||
|
|
||||||
wcscpy(modifiedEnvironmentEnd, L"PLUSDATA=");
|
|
||||||
wcscat(modifiedEnvironmentEnd, plusdata.c_str());
|
|
||||||
modifiedEnvironmentEnd += wcslen(modifiedEnvironmentEnd) + 1;
|
|
||||||
|
|
||||||
*modifiedEnvironmentEnd = 0;
|
|
||||||
|
|
||||||
STARTUPINFO si = { sizeof(si), 0 };
|
|
||||||
PROCESS_INFORMATION pi = { 0 };
|
|
||||||
if (CreateProcessW(NULL, (wchar_t*)(FileDir + Cmd).toStdWString().c_str(), NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT, modifiedEnvironment, NULL, &si, &pi))
|
|
||||||
{
|
|
||||||
while (WaitForSingleObject(pi.hProcess, 1000) == WAIT_TIMEOUT && !pAddon->pProgress->IsCanceled());
|
|
||||||
CloseHandle(pi.hProcess);
|
|
||||||
CloseHandle(pi.hThread);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Status = SB_ERR(SB_OtherError, QVariantList() << tr("Failed to start installer (%1)!").arg(GetLastError()));
|
|
||||||
|
|
||||||
LocalFree(modifiedEnvironment);
|
|
||||||
}
|
|
||||||
else if (!Path.isEmpty())
|
|
||||||
{
|
|
||||||
pAddon->pProgress->ShowMessage(tr("Copying Files for %1").arg(pAddon->Id));
|
|
||||||
|
|
||||||
std::wstring from;
|
|
||||||
foreach(const QString & file, ListDir(FileDir)) {
|
|
||||||
QString File = QString(file).replace("/", "\\");
|
|
||||||
from.append((FileDir + "\\" + File).toStdWString());
|
|
||||||
from.append(L"\0", 1);
|
|
||||||
}
|
|
||||||
from.append(L"\0", 1);
|
|
||||||
|
|
||||||
std::wstring to;
|
|
||||||
to.append(Path.toStdWString());
|
|
||||||
to.append(L"\0", 1);
|
|
||||||
|
|
||||||
SHFILEOPSTRUCT SHFileOp;
|
|
||||||
memset(&SHFileOp, 0, sizeof(SHFILEOPSTRUCT));
|
|
||||||
SHFileOp.hwnd = NULL;
|
|
||||||
SHFileOp.wFunc = FO_MOVE;
|
|
||||||
SHFileOp.pFrom = from.c_str();
|
|
||||||
SHFileOp.pTo = to.c_str();
|
|
||||||
SHFileOp.fFlags = FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR;
|
|
||||||
|
|
||||||
SHFileOperation(&SHFileOp);
|
|
||||||
}
|
|
||||||
|
|
||||||
QDir(FileDir).removeRecursively();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Status = SB_ERR(SB_OtherError, QVariantList() << tr("Failed to unpack addon!"));
|
|
||||||
Archive.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
QFile::remove(FilePath);
|
|
||||||
|
|
||||||
if (!Status.IsError()) {
|
|
||||||
pAddon->Installed = CheckAddon(pAddon);
|
|
||||||
if (!pAddon->Installed)
|
|
||||||
Status = SB_ERR(SB_OtherError, QVariantList() << tr("Addon Installation Failed!"));
|
|
||||||
}
|
|
||||||
pAddon->pProgress->Finish(Status);
|
|
||||||
pAddon->pProgress.create();
|
|
||||||
}
|
|
||||||
|
|
||||||
SB_PROGRESS CAddonManager::TryRemoveAddon(const QString& Id, QWidget* pParent)
|
SB_PROGRESS CAddonManager::TryRemoveAddon(const QString& Id, QWidget* pParent)
|
||||||
{
|
{
|
||||||
if (QMessageBox("Sandboxie-Plus", tr("Do you want to remove %1?").arg(Id),
|
if (QMessageBox("Sandboxie-Plus", tr("Do you want to remove %1?").arg(Id),
|
||||||
|
@ -294,100 +183,92 @@ SB_PROGRESS CAddonManager::TryRemoveAddon(const QString& Id, QWidget* pParent)
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
SB_PROGRESS CAddonManager::RemoveAddon(const QString& Id)
|
SB_PROGRESS CAddonManager::InstallAddon(const QString& Id)
|
||||||
{
|
{
|
||||||
CAddonPtr pAddon = GetAddon(Id);
|
CAddonPtr pAddon = GetAddon(Id, eNotINstalled);
|
||||||
if (!pAddon)
|
if (!pAddon)
|
||||||
return SB_ERR(SB_OtherError, QVariantList() << tr("Addon not found!"));
|
return SB_ERR(SB_OtherError, QVariantList() << tr("Addon not found, please try updating the addon list in the global settings!"));
|
||||||
|
|
||||||
|
QFile::remove(theGUI->m_pUpdater->GetUpdateDir(true) + "/" ADDONS_FILE);
|
||||||
|
QFile::copy(theConf->GetConfigDir() + "/" ADDONS_FILE, theGUI->m_pUpdater->GetUpdateDir(true) + "/" ADDONS_FILE);
|
||||||
|
|
||||||
|
QStringList Params;
|
||||||
|
Params.append("modify");
|
||||||
|
Params.append("add:" + pAddon->Id);
|
||||||
|
Params.append("/agent_arch:" + GetAppArch());
|
||||||
|
Params.append("/framework:" + GetFramework());
|
||||||
|
Params.append("/step:apply");
|
||||||
|
Params.append("/embedded");
|
||||||
|
Params.append("/temp:" + theGUI->m_pUpdater->GetUpdateDir().replace("/", "\\"));
|
||||||
|
|
||||||
pAddon->pProgress = CSbieProgressPtr(new CSbieProgress());
|
pAddon->pProgress = CSbieProgressPtr(new CSbieProgress());
|
||||||
QtConcurrent::run(CAddonManager::RemoveAddonAsync, pAddon);
|
QtConcurrent::run(CAddonManager::RunUpdaterAsync, pAddon, Params);
|
||||||
|
//QTimer::singleShot(10, this, [=]() { CAddonManager::RunUpdaterAsync(pAddon, Params); });
|
||||||
return SB_PROGRESS(OP_ASYNC, pAddon->pProgress);
|
return SB_PROGRESS(OP_ASYNC, pAddon->pProgress);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAddonManager::CleanupPath(const QString& Path)
|
SB_PROGRESS CAddonManager::RemoveAddon(const QString& Id)
|
||||||
{
|
{
|
||||||
StrPair PathName = Split2(Path, "\\", true);
|
CAddonPtr pAddon = GetAddon(Id, eInstalled);
|
||||||
if (ListDir(PathName.first).isEmpty())
|
if (!pAddon)
|
||||||
|
return SB_ERR(SB_OtherError, QVariantList() << tr("Addon not found!"));
|
||||||
|
|
||||||
|
QStringList Params;
|
||||||
|
Params.append("modify");
|
||||||
|
Params.append("remove:" + pAddon->Id);
|
||||||
|
Params.append("/step:apply");
|
||||||
|
Params.append("/embedded");
|
||||||
|
|
||||||
|
pAddon->pProgress = CSbieProgressPtr(new CSbieProgress());
|
||||||
|
QtConcurrent::run(CAddonManager::RunUpdaterAsync, pAddon, Params);
|
||||||
|
//QTimer::singleShot(10, this, [=]() { CAddonManager::RunUpdaterAsync(pAddon, Params); });
|
||||||
|
return SB_PROGRESS(OP_ASYNC, pAddon->pProgress);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString GetUpdErrorStr(int exitCode);
|
||||||
|
|
||||||
|
QString GetUpdErrorStr2(int exitCode)
|
||||||
|
{
|
||||||
|
switch (exitCode)
|
||||||
{
|
{
|
||||||
QDir().rmdir(PathName.first);
|
case ERROR_NO_ADDON: return CAddonManager::tr("Addon Not Found");
|
||||||
//qDebug() << "delete dir" << PathName.first;
|
case ERROR_NO_ADDON2: return CAddonManager::tr("Addon is not available for this paltform");
|
||||||
CleanupPath(PathName.first);
|
case ERROR_BAD_ADDON: return CAddonManager::tr("Missing instalation instructions");
|
||||||
|
case ERROR_BAD_ADDON2: return CAddonManager::tr("Executing addon setup failed");
|
||||||
|
case ERROR_DELETE: return CAddonManager::tr("Failed to delete a file during addon removal");
|
||||||
|
default: return GetUpdErrorStr(exitCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAddonManager::RemoveAddonAsync(CAddonPtr pAddon)
|
void CAddonManager::RunUpdaterAsync(CAddonPtr pAddon, const QStringList& Params)
|
||||||
{
|
{
|
||||||
SB_STATUS Status = SB_OK;
|
#ifdef _DEBUG
|
||||||
|
CSbieResult<int> Status = COnlineUpdater::RunUpdater(Params, false, true);
|
||||||
|
#else
|
||||||
|
CSbieResult<int> Status = COnlineUpdater::RunUpdater(Params, true, true);
|
||||||
|
#endif
|
||||||
|
|
||||||
QString Key = pAddon->GetSpecificEntry("uninstall_key").toString();
|
if(Status.IsError())
|
||||||
if (!Key.isEmpty())
|
pAddon->pProgress->Finish(SB_ERR(SB_OtherError, QVariantList() << tr("Updater failed to to perform plugin operation")));
|
||||||
{
|
else if(Status.GetValue() < 0)
|
||||||
QSettings settings(Key, QSettings::NativeFormat);
|
pAddon->pProgress->Finish(SB_ERR(SB_OtherError, QVariantList() << tr("Updater failed to to perform plugin operation, error: %1").arg(GetUpdErrorStr2(Status.GetValue()))));
|
||||||
QString Cmd = settings.value("UninstallString").toString();
|
|
||||||
|
|
||||||
pAddon->pProgress->ShowMessage(tr("Running Uninstaller for %1").arg(pAddon->Id));
|
|
||||||
|
|
||||||
STARTUPINFO si = { sizeof(si), 0 };
|
|
||||||
PROCESS_INFORMATION pi = { 0 };
|
|
||||||
if (CreateProcessW(NULL, (wchar_t*)Cmd.toStdWString().c_str(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
|
|
||||||
{
|
|
||||||
while (WaitForSingleObject(pi.hProcess, 1000) == WAIT_TIMEOUT && !pAddon->pProgress->IsCanceled());
|
|
||||||
CloseHandle(pi.hProcess);
|
|
||||||
CloseHandle(pi.hThread);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Status = SB_ERR(SB_OtherError, QVariantList() << tr("Failed to start uninstaller!"));
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
pAddon->pProgress->Finish(SB_OK);
|
||||||
QStringList Files = pAddon->GetSpecificEntry("files").toStringList();
|
pAddon->pProgress.clear();
|
||||||
//foreach(const QString & File, Files) {
|
|
||||||
// pAddon->pProgress->ShowMessage(tr("Removing %1").arg(File));
|
|
||||||
// QString FilePath = ExpandPath(File);
|
|
||||||
// QFile::remove(FilePath);
|
|
||||||
// CleanupPath(FilePath);
|
|
||||||
//}
|
|
||||||
|
|
||||||
std::wstring from;
|
|
||||||
foreach(const QString & File, Files) {
|
|
||||||
QString FilePath = ExpandPath(File);
|
|
||||||
if (QFile::exists(FilePath)) {
|
|
||||||
from.append(FilePath.toStdWString());
|
|
||||||
from.append(L"\0", 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
from.append(L"\0", 1);
|
|
||||||
|
|
||||||
SHFILEOPSTRUCT SHFileOp;
|
|
||||||
memset(&SHFileOp, 0, sizeof(SHFILEOPSTRUCT));
|
|
||||||
SHFileOp.hwnd = NULL;
|
|
||||||
SHFileOp.wFunc = FO_DELETE;
|
|
||||||
SHFileOp.pFrom = from.c_str();
|
|
||||||
SHFileOp.pTo = NULL;
|
|
||||||
SHFileOp.fFlags = FOF_NOCONFIRMATION;
|
|
||||||
|
|
||||||
SHFileOperation(&SHFileOp);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Status.IsError()) {
|
|
||||||
pAddon->Installed = CheckAddon(pAddon);
|
|
||||||
if (pAddon->Installed)
|
|
||||||
Status = SB_ERR(SB_OtherError, QVariantList() << tr("Addon Removal Failed!"));
|
|
||||||
}
|
|
||||||
pAddon->pProgress->Finish(Status);
|
|
||||||
pAddon->pProgress.create();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CAddonManager::ExpandPath(QString Path)
|
QString CAddonManager::GetAppArch()
|
||||||
{
|
{
|
||||||
Path.replace("%SbieHome%", theAPI->GetSbiePath(), Qt::CaseInsensitive);
|
#ifdef _M_ARM64
|
||||||
Path.replace("%PlusData%", theConf->GetConfigDir(), Qt::CaseInsensitive);
|
return "a64";
|
||||||
|
#elif _WIN64
|
||||||
return theGUI->GetCompat()->ExpandPath(Path);
|
return "x64";
|
||||||
|
#else
|
||||||
|
return "x86";
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
QString GetArch()
|
QString CAddonManager::GetSysArch()
|
||||||
{
|
{
|
||||||
SYSTEM_INFO systemInfo;
|
SYSTEM_INFO systemInfo;
|
||||||
GetSystemInfo(&systemInfo);
|
GetSystemInfo(&systemInfo);
|
||||||
|
@ -397,42 +278,43 @@ QString GetArch()
|
||||||
case PROCESSOR_ARCHITECTURE_AMD64: return "x64";
|
case PROCESSOR_ARCHITECTURE_AMD64: return "x64";
|
||||||
case PROCESSOR_ARCHITECTURE_ARM64: return "a64";
|
case PROCESSOR_ARCHITECTURE_ARM64: return "a64";
|
||||||
}
|
}
|
||||||
return "???";
|
return GetAppArch(); // fallback
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CAddonManager::GetFramework()
|
||||||
|
{
|
||||||
|
QString qt = QString("qt%1.%2.%3").arg(QT_VERSION_MAJOR).arg(QT_VERSION_MINOR).arg(QT_VERSION_PATCH);
|
||||||
|
#ifdef _DEBUG
|
||||||
|
qt.append("d");
|
||||||
|
#endif // _DEBUG
|
||||||
|
qt.append("_" + GetAppArch());
|
||||||
|
return qt;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant CAddon::GetSpecificEntry(const QString& Name, QString* pName)
|
QVariant CAddon::GetSpecificEntry(const QString& Name, QString* pName)
|
||||||
{
|
{
|
||||||
#ifdef _M_ARM64
|
|
||||||
QString arch = "a64";
|
|
||||||
#elif _WIN64
|
|
||||||
QString arch = "x64";
|
|
||||||
#else
|
|
||||||
QString arch = "x86";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// First we check the qt cpecific entry for our version of qt and platform
|
// First we check the qt cpecific entry for our version of qt and platform
|
||||||
//
|
//
|
||||||
|
|
||||||
QString qt = QString("qt%1_%2_%3_%4").arg(QT_VERSION_MAJOR).arg(QT_VERSION_MINOR).arg(QT_VERSION_PATCH).arg(arch);
|
QString qt = CAddonManager::GetFramework();
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
qt.append("d");
|
qt.append("d");
|
||||||
#endif // _DEBUG
|
#endif // _DEBUG
|
||||||
if (Data.contains(Name + "_" + qt)) {
|
if (Data.contains(Name + "-" + qt)) {
|
||||||
if (pName) *pName = Name + "_" + qt;
|
if (pName) *pName = Name + "-" + qt;
|
||||||
return Data[Name + "_" + qt];
|
return Data[Name + "-" + qt];
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Second we check the actual architecture
|
// Second we check the actual architecture
|
||||||
//
|
//
|
||||||
|
|
||||||
QString match = Data["match_arch"].toString();
|
QString match = Data["matchArch"].toString();
|
||||||
if (match != "agent")
|
QString arch = match != "agent" ? CAddonManager::GetSysArch() : CAddonManager::GetAppArch();
|
||||||
arch = GetArch();
|
if (Data.contains(Name + "-" + arch)) {
|
||||||
if (Data.contains(Name + "_" + arch)) {
|
if (pName) *pName = Name + "-" + arch;
|
||||||
if (pName) *pName = Name + "_" + arch;
|
return Data[Name + "-" + arch];
|
||||||
return Data[Name + "_" + arch];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -447,7 +329,7 @@ QVariant CAddon::GetSpecificEntry(const QString& Name, QString* pName)
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CAddon::GetLocalizedEntry(const QString& Name)
|
QString CAddonInfo::GetLocalizedEntry(const QString& Name)
|
||||||
{
|
{
|
||||||
if (Data.contains(Name + "_" + theGUI->m_Language))
|
if (Data.contains(Name + "_" + theGUI->m_Language))
|
||||||
return Data[Name + "_" + theGUI->m_Language].toString();
|
return Data[Name + "_" + theGUI->m_Language].toString();
|
||||||
|
@ -458,4 +340,4 @@ QString CAddon::GetLocalizedEntry(const QString& Name)
|
||||||
return Data[Name + "_" + LangAux].toString();
|
return Data[Name + "_" + LangAux].toString();
|
||||||
|
|
||||||
return Data[Name].toString();
|
return Data[Name].toString();
|
||||||
}
|
}
|
|
@ -6,21 +6,37 @@
|
||||||
class CAddon : public QObject
|
class CAddon : public QObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CAddon(const QVariantMap& Data) : Installed(false), Data(Data)
|
CAddon(const QVariantMap& Data) : Data(Data)
|
||||||
{
|
{
|
||||||
Id = Data["id"].toString();
|
Id = Data["id"].toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Id;
|
QString Id;
|
||||||
QVariantMap Data;
|
QVariantMap Data;
|
||||||
bool Installed;
|
|
||||||
CSbieProgressPtr pProgress;
|
CSbieProgressPtr pProgress;
|
||||||
|
|
||||||
QVariant GetSpecificEntry(const QString& Name, QString* pName = NULL);
|
QVariant GetSpecificEntry(const QString& Name, QString* pName = NULL);
|
||||||
QString GetLocalizedEntry(const QString& Name);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef QSharedPointer<CAddon> CAddonPtr;
|
typedef QSharedPointer<CAddon> CAddonPtr;
|
||||||
|
|
||||||
|
class CAddonInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CAddonInfo(const QVariantMap& data, bool installed) : Data(data), Installed(installed) {
|
||||||
|
Id = Data["id"].toString();
|
||||||
|
};
|
||||||
|
|
||||||
|
QString Id;
|
||||||
|
QVariantMap Data;
|
||||||
|
bool Installed;
|
||||||
|
QString UpdateVersion;
|
||||||
|
|
||||||
|
QString GetLocalizedEntry(const QString& Name);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef QSharedPointer<CAddonInfo> CAddonInfoPtr;
|
||||||
|
|
||||||
class CAddonManager : public QObject
|
class CAddonManager : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -32,15 +48,24 @@ public:
|
||||||
void UpdateAddonsWhenNotCached();
|
void UpdateAddonsWhenNotCached();
|
||||||
void UpdateAddons();
|
void UpdateAddons();
|
||||||
|
|
||||||
QList<CAddonPtr> GetAddons();
|
QList<CAddonInfoPtr> GetAddons();
|
||||||
|
|
||||||
CAddonPtr GetAddon(const QString& Id);
|
enum EState {
|
||||||
bool HasAddon(const QString& Id);
|
eAny = 0,
|
||||||
|
eInstalled,
|
||||||
|
eNotINstalled
|
||||||
|
};
|
||||||
|
|
||||||
|
CAddonPtr GetAddon(const QString& Id, EState State = eAny);
|
||||||
|
|
||||||
SB_PROGRESS TryInstallAddon(const QString& Id, QWidget* pParent, const QString& Prompt = QString());
|
SB_PROGRESS TryInstallAddon(const QString& Id, QWidget* pParent, const QString& Prompt = QString());
|
||||||
SB_PROGRESS InstallAddon(const QString& Id);
|
SB_PROGRESS InstallAddon(const QString& Id);
|
||||||
SB_PROGRESS TryRemoveAddon(const QString& Id, QWidget* pParent);
|
SB_PROGRESS TryRemoveAddon(const QString& Id, QWidget* pParent);
|
||||||
SB_PROGRESS RemoveAddon(const QString& Id);
|
SB_PROGRESS RemoveAddon(const QString& Id);
|
||||||
|
|
||||||
|
static QString GetAppArch();
|
||||||
|
static QString GetSysArch();
|
||||||
|
static QString GetFramework();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void DataUpdated();
|
void DataUpdated();
|
||||||
|
@ -48,18 +73,12 @@ signals:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void OnUpdateData(const QVariantMap& Data, const QVariantMap& Params);
|
void OnUpdateData(const QVariantMap& Data, const QVariantMap& Params);
|
||||||
void OnAddonDownloaded(const QString& Path, const QVariantMap& Params);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static bool CheckAddon(const CAddonPtr& pAddon);
|
|
||||||
|
|
||||||
static void CleanupPath(const QString& Path);
|
static void RunUpdaterAsync(CAddonPtr pAddon, const QStringList& Params);
|
||||||
|
|
||||||
static void InstallAddonAsync(const QString& FilePath, CAddonPtr pAddon);
|
QList<CAddonPtr> m_Installed;
|
||||||
static void RemoveAddonAsync(CAddonPtr pAddon);
|
QList<CAddonPtr> m_KnownAddons;
|
||||||
|
|
||||||
static QString ExpandPath(QString Path);
|
|
||||||
|
|
||||||
QList<CAddonPtr> m_Addons;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1227,6 +1227,11 @@
|
||||||
<string>Status</string>
|
<string>Status</string>
|
||||||
</property>
|
</property>
|
||||||
</column>
|
</column>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>Version</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
<column>
|
<column>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Description</string>
|
<string>Description</string>
|
||||||
|
|
|
@ -676,7 +676,8 @@ bool COnlineUpdater::ApplyUpdate(bool bSilent)
|
||||||
if (Scope == eFull)
|
if (Scope == eFull)
|
||||||
Params.append("/open:sandman.exe");
|
Params.append("/open:sandman.exe");
|
||||||
|
|
||||||
if (RunUpdater(Params, bSilent, Scope != eFull)) {
|
SB_RESULT(int) status = RunUpdater(Params, bSilent, Scope != eFull);
|
||||||
|
if (!status.IsError()) {
|
||||||
if(bSilent)
|
if(bSilent)
|
||||||
theConf->DelValue("Updater/UpdateVersion");
|
theConf->DelValue("Updater/UpdateVersion");
|
||||||
if (Scope == eMeta)
|
if (Scope == eMeta)
|
||||||
|
@ -690,15 +691,15 @@ bool COnlineUpdater::ApplyUpdate(bool bSilent)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool COnlineUpdater::RunUpdater(const QStringList& Params, bool bSilent, bool Wait)
|
SB_RESULT(int) COnlineUpdater::RunUpdater(const QStringList& Params, bool bSilent, bool Wait)
|
||||||
{
|
{
|
||||||
if (bSilent) {
|
if (bSilent) {
|
||||||
SB_RESULT(int) Result = theAPI->RunUpdateUtility(Params, 2, Wait);
|
SB_RESULT(int) Result = theAPI->RunUpdateUtility(Params, 2, Wait);
|
||||||
if (!Result.IsError())
|
if (!Result.IsError())
|
||||||
return true;
|
return Result;
|
||||||
// else fallback to ShellExecuteEx
|
// else fallback to ShellExecuteEx
|
||||||
if (theConf->GetBool("Options/UpdateNoFallback", false))
|
if (theConf->GetBool("Options/UpdateNoFallback", false))
|
||||||
return false;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::wstring wFile = QString(QApplication::applicationDirPath() + "/UpdUtil.exe").replace("/", "\\").toStdWString();
|
std::wstring wFile = QString(QApplication::applicationDirPath() + "/UpdUtil.exe").replace("/", "\\").toStdWString();
|
||||||
|
@ -708,7 +709,10 @@ bool COnlineUpdater::RunUpdater(const QStringList& Params, bool bSilent, bool Wa
|
||||||
wParams += L"\"" + Param.toStdWString() + L"\"";
|
wParams += L"\"" + Param.toStdWString() + L"\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
return RunElevated(wFile, wParams, Wait ? INFINITE : 0) == 0;
|
int ExitCode = RunElevated(wFile, wParams, Wait ? INFINITE : 0);
|
||||||
|
if (ExitCode == STATUS_PENDING && !Wait)
|
||||||
|
ExitCode = 0;
|
||||||
|
return CSbieResult<int>(ExitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void COnlineUpdater::DownloadFile(const QString& Url, QObject* receiver, const char* member, const QVariantMap& Params)
|
void COnlineUpdater::DownloadFile(const QString& Url, QObject* receiver, const char* member, const QVariantMap& Params)
|
||||||
|
|
|
@ -92,8 +92,10 @@ protected:
|
||||||
|
|
||||||
bool AskDownload(const QVariantMap& Update);
|
bool AskDownload(const QVariantMap& Update);
|
||||||
|
|
||||||
bool RunUpdater(const QStringList& Params, bool bSilent, bool Wait = false);
|
friend class CAddonManager;
|
||||||
bool RunInstaller2(const QString& FilePath, bool bSilent);
|
|
||||||
|
static SB_RESULT(int) RunUpdater(const QStringList& Params, bool bSilent, bool Wait = false);
|
||||||
|
static bool RunInstaller2(const QString& FilePath, bool bSilent);
|
||||||
|
|
||||||
CNetworkAccessManager* m_RequestManager;
|
CNetworkAccessManager* m_RequestManager;
|
||||||
CSbieProgressPtr m_pUpdateProgress;
|
CSbieProgressPtr m_pUpdateProgress;
|
||||||
|
|
|
@ -76,8 +76,8 @@ QStringList CSandMan::GetFileCheckers(const CSandBoxPtr& pBox)
|
||||||
{
|
{
|
||||||
QStringList Checkers;
|
QStringList Checkers;
|
||||||
|
|
||||||
if (theGUI->GetAddonManager()->HasAddon("FileChecker"))
|
if (!theGUI->GetAddonManager()->GetAddon("FileChecker", CAddonManager::eInstalled).isNull())
|
||||||
Checkers.append(pBox->Expand("powershell -exec bypass -nop -File \"%SbieHome%\\bin\\CheckFile.ps1\" -bin"));
|
Checkers.append(pBox->Expand("powershell -exec bypass -nop -File \"%SbieHome%\\addons\\FileChecker\\CheckFile.ps1\" -bin"));
|
||||||
|
|
||||||
if (!pBox.isNull()) {
|
if (!pBox.isNull()) {
|
||||||
foreach(const QString & Value, pBox->GetTextList("OnFileRecovery", true, false, true)) {
|
foreach(const QString & Value, pBox->GetTextList("OnFileRecovery", true, false, true)) {
|
||||||
|
|
|
@ -272,8 +272,8 @@ void CSbieView::CreateMenu()
|
||||||
m_pMenuMarkLinger->setCheckable(true);
|
m_pMenuMarkLinger->setCheckable(true);
|
||||||
m_pMenuMarkLeader = m_pMenuPreset->addAction(tr("Set Leader Process"), this, SLOT(OnProcessAction()));
|
m_pMenuMarkLeader = m_pMenuPreset->addAction(tr("Set Leader Process"), this, SLOT(OnProcessAction()));
|
||||||
m_pMenuMarkLeader->setCheckable(true);
|
m_pMenuMarkLeader->setCheckable(true);
|
||||||
//m_pMenuSuspend = m_pMenuProcess->addAction(tr("Suspend"), this, SLOT(OnProcessAction()));
|
m_pMenuSuspend = m_pMenuProcess->addAction(tr("Suspend"), this, SLOT(OnProcessAction()));
|
||||||
//m_pMenuResume = m_pMenuProcess->addAction(tr("Resume"), this, SLOT(OnProcessAction()));
|
m_pMenuResume = m_pMenuProcess->addAction(tr("Resume"), this, SLOT(OnProcessAction()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSbieView::CreateOldMenu()
|
void CSbieView::CreateOldMenu()
|
||||||
|
@ -607,7 +607,7 @@ bool CSbieView::UpdateMenu(bool bAdvanced, const CSandBoxPtr &pBox, int iSandBox
|
||||||
return bBoxBusy == false;
|
return bBoxBusy == false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSbieView::UpdateProcMenu(const CBoxedProcessPtr& pProcess, int iProcessCount)
|
void CSbieView::UpdateProcMenu(const CBoxedProcessPtr& pProcess, int iProcessCount, int iSuspendedCount)
|
||||||
{
|
{
|
||||||
m_pMenuLinkTo->setEnabled(iProcessCount == 1);
|
m_pMenuLinkTo->setEnabled(iProcessCount == 1);
|
||||||
|
|
||||||
|
@ -640,8 +640,8 @@ void CSbieView::UpdateProcMenu(const CBoxedProcessPtr& pProcess, int iProcessCou
|
||||||
m_pMenuMarkLeader->setChecked(pProcess.objectCast<CSbieProcess>()->IsLeaderProgram());
|
m_pMenuMarkLeader->setChecked(pProcess.objectCast<CSbieProcess>()->IsLeaderProgram());
|
||||||
}
|
}
|
||||||
|
|
||||||
//m_pMenuSuspend->setEnabled(iProcessCount > iSuspendedCount);
|
m_pMenuSuspend->setEnabled(iProcessCount > iSuspendedCount);
|
||||||
//m_pMenuResume->setEnabled(iSuspendedCount > 0);
|
m_pMenuResume->setEnabled(iSuspendedCount > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSbieView::UpdateMenu()
|
bool CSbieView::UpdateMenu()
|
||||||
|
@ -655,7 +655,7 @@ bool CSbieView::UpdateMenu()
|
||||||
int iProcessCount = 0;
|
int iProcessCount = 0;
|
||||||
int iSandBoxeCount = 0;
|
int iSandBoxeCount = 0;
|
||||||
int iGroupe = 0;
|
int iGroupe = 0;
|
||||||
//int iSuspendedCount = 0;
|
int iSuspendedCount = 0;
|
||||||
QModelIndexList Rows = m_pSbieTree->selectedRows();
|
QModelIndexList Rows = m_pSbieTree->selectedRows();
|
||||||
foreach(const QModelIndex& Index, Rows)
|
foreach(const QModelIndex& Index, Rows)
|
||||||
{
|
{
|
||||||
|
@ -666,8 +666,8 @@ bool CSbieView::UpdateMenu()
|
||||||
{
|
{
|
||||||
m_CurProcesses.append(pProcess);
|
m_CurProcesses.append(pProcess);
|
||||||
iProcessCount++;
|
iProcessCount++;
|
||||||
//if (pProcess->IsSuspended())
|
if (pProcess->IsSuspended())
|
||||||
// iSuspendedCount++;
|
iSuspendedCount++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -699,7 +699,7 @@ bool CSbieView::UpdateMenu()
|
||||||
m_pDelGroupe->setVisible(iGroupe > 0 && iSandBoxeCount == 0 && iProcessCount == 0);
|
m_pDelGroupe->setVisible(iGroupe > 0 && iSandBoxeCount == 0 && iProcessCount == 0);
|
||||||
|
|
||||||
if (!pProcess.isNull())
|
if (!pProcess.isNull())
|
||||||
UpdateProcMenu(pProcess, iProcessCount);
|
UpdateProcMenu(pProcess, iProcessCount, iSuspendedCount);
|
||||||
|
|
||||||
return UpdateMenu(bAdvanced, pBox, iSandBoxeCount, bBoxBusy);
|
return UpdateMenu(bAdvanced, pBox, iSandBoxeCount, bBoxBusy);
|
||||||
}
|
}
|
||||||
|
@ -1596,10 +1596,10 @@ void CSbieView::OnProcessAction(QAction* Action, const QList<CBoxedProcessPtr>&
|
||||||
pProcess.objectCast<CSbieProcess>()->SetLingeringProgram(m_pMenuMarkLinger->isChecked());
|
pProcess.objectCast<CSbieProcess>()->SetLingeringProgram(m_pMenuMarkLinger->isChecked());
|
||||||
else if (Action == m_pMenuMarkLeader)
|
else if (Action == m_pMenuMarkLeader)
|
||||||
pProcess.objectCast<CSbieProcess>()->SetLeaderProgram(m_pMenuMarkLeader->isChecked());
|
pProcess.objectCast<CSbieProcess>()->SetLeaderProgram(m_pMenuMarkLeader->isChecked());
|
||||||
/*else if (Action == m_pMenuSuspend)
|
else if (Action == m_pMenuSuspend)
|
||||||
Results.append(pProcess->SetSuspend(true));
|
Results.append(pProcess->SetSuspend(true));
|
||||||
else if (Action == m_pMenuResume)
|
else if (Action == m_pMenuResume)
|
||||||
Results.append(pProcess->SetSuspend(false));*/
|
Results.append(pProcess->SetSuspend(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
theGUI->CheckResults(Results, this);
|
theGUI->CheckResults(Results, this);
|
||||||
|
|
|
@ -124,7 +124,7 @@ private:
|
||||||
void CreateTrayMenu();
|
void CreateTrayMenu();
|
||||||
|
|
||||||
bool UpdateMenu(bool bAdvanced, const CSandBoxPtr &pBox, int iSandBoxeCount = 1, bool bBoxBusy = false);
|
bool UpdateMenu(bool bAdvanced, const CSandBoxPtr &pBox, int iSandBoxeCount = 1, bool bBoxBusy = false);
|
||||||
void UpdateProcMenu(const CBoxedProcessPtr &pProcess = CBoxedProcessPtr(), int iProcessCount = 0);
|
void UpdateProcMenu(const CBoxedProcessPtr &pProcess = CBoxedProcessPtr(), int iProcessCount = 0, int iSuspendedCount = 0);
|
||||||
bool UpdateMenu();
|
bool UpdateMenu();
|
||||||
void UpdateMoveMenu();
|
void UpdateMoveMenu();
|
||||||
void RenameGroup(const QString OldName, const QString NewName);
|
void RenameGroup(const QString OldName, const QString NewName);
|
||||||
|
@ -212,8 +212,8 @@ private:
|
||||||
QAction* m_pMenuMarkLinger;
|
QAction* m_pMenuMarkLinger;
|
||||||
QAction* m_pMenuMarkLeader;
|
QAction* m_pMenuMarkLeader;
|
||||||
QAction* m_pMenuPinToRun;
|
QAction* m_pMenuPinToRun;
|
||||||
//QAction* m_pMenuSuspend;
|
QAction* m_pMenuSuspend;
|
||||||
//QAction* m_pMenuResume;
|
QAction* m_pMenuResume;
|
||||||
|
|
||||||
QAction* m_pRemove;
|
QAction* m_pRemove;
|
||||||
|
|
||||||
|
|
|
@ -378,7 +378,7 @@ void CTraceView::SetEnabled(bool bSet)
|
||||||
|
|
||||||
void CTraceView::OnShowStack()
|
void CTraceView::OnShowStack()
|
||||||
{
|
{
|
||||||
if (!theGUI->GetAddonManager()->HasAddon("DbgHelp"))
|
if (!theGUI->GetAddonManager()->GetAddon("DbgHelp", CAddonManager::eInstalled).isNull())
|
||||||
theGUI->GetAddonManager()->TryInstallAddon("DbgHelp", this, tr("To use the stack traces feature the DbgHelp.dll and SymSrv.dll are required, do you want to download and install them?"));
|
theGUI->GetAddonManager()->TryInstallAddon("DbgHelp", this, tr("To use the stack traces feature the DbgHelp.dll and SymSrv.dll are required, do you want to download and install them?"));
|
||||||
theAPI->GetGlobalSettings()->SetBool("MonitorStackTrace", m_pShowStack->isChecked());
|
theAPI->GetGlobalSettings()->SetBool("MonitorStackTrace", m_pShowStack->isChecked());
|
||||||
m_pTrace->m_pStackView->setVisible(m_pShowStack->isChecked());
|
m_pTrace->m_pStackView->setVisible(m_pShowStack->isChecked());
|
||||||
|
|
|
@ -1536,15 +1536,21 @@ void CSettingsWindow::OnOptChanged()
|
||||||
void CSettingsWindow::OnLoadAddon()
|
void CSettingsWindow::OnLoadAddon()
|
||||||
{
|
{
|
||||||
ui.treeAddons->clear();
|
ui.treeAddons->clear();
|
||||||
foreach(const CAddonPtr pAddon, theGUI->GetAddonManager()->GetAddons()) {
|
foreach(const CAddonInfoPtr pAddon, theGUI->GetAddonManager()->GetAddons()) {
|
||||||
|
|
||||||
QTreeWidgetItem* pItem = new QTreeWidgetItem;
|
QTreeWidgetItem* pItem = new QTreeWidgetItem;
|
||||||
pItem->setText(0, pAddon->GetLocalizedEntry("name"));
|
pItem->setText(0, pAddon->GetLocalizedEntry("name"));
|
||||||
if(!pAddon->Data["mandatory"].toBool())
|
if(!pAddon->Data["mandatory"].toBool())
|
||||||
pItem->setData(0, Qt::UserRole, pAddon->Id);
|
pItem->setData(0, Qt::UserRole, pAddon->Id);
|
||||||
pItem->setIcon(0, pAddon->Data.contains("icon") ? CSandMan::GetIcon(pAddon->Data["icon"].toString()) : CSandMan::GetIcon("Addon"));
|
pItem->setIcon(0, pAddon->Data.contains("icon") ? CSandMan::GetIcon(pAddon->Data["icon"].toString()) : CSandMan::GetIcon("Addon"));
|
||||||
pItem->setText(1, pAddon->Installed ? tr("Installed") : "");
|
if (pAddon->Installed) {
|
||||||
pItem->setText(2, pAddon->GetLocalizedEntry("description"));
|
if(!pAddon->UpdateVersion.isEmpty())
|
||||||
|
pItem->setText(1, tr("Update Available"));
|
||||||
|
else
|
||||||
|
pItem->setText(1, tr("Installed"));
|
||||||
|
}
|
||||||
|
pItem->setText(2, pAddon->Data["version"].toString());
|
||||||
|
pItem->setText(3, pAddon->GetLocalizedEntry("description"));
|
||||||
|
|
||||||
ui.treeAddons->addTopLevelItem(pItem);
|
ui.treeAddons->addTopLevelItem(pItem);
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,7 @@ void CBoxAssistant::OnToggleDebugger()
|
||||||
{
|
{
|
||||||
m_bUseDebugger = !m_bUseDebugger;
|
m_bUseDebugger = !m_bUseDebugger;
|
||||||
|
|
||||||
if (m_bUseDebugger && !theGUI->GetAddonManager()->HasAddon("V4dbg"))
|
if (m_bUseDebugger && theGUI->GetAddonManager()->GetAddon("V4dbg", CAddonManager::eInstalled).isNull())
|
||||||
theGUI->GetAddonManager()->TryInstallAddon("V4dbg", this, tr("To debug troubleshooting scripts you need the V4 Script Debugger addon, do you want to download and install it?"));
|
theGUI->GetAddonManager()->TryInstallAddon("V4dbg", this, tr("To debug troubleshooting scripts you need the V4 Script Debugger addon, do you want to download and install it?"));
|
||||||
|
|
||||||
QString title = windowTitle();
|
QString title = windowTitle();
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
#define VERSION_MJR 1
|
#define VERSION_MJR 1
|
||||||
#define VERSION_MIN 10
|
#define VERSION_MIN 10
|
||||||
#define VERSION_REV 1
|
#define VERSION_REV 2
|
||||||
#define VERSION_UPD 1
|
#define VERSION_UPD 0
|
||||||
|
|
||||||
#ifndef STR
|
#ifndef STR
|
||||||
#define STR2(X) #X
|
#define STR2(X) #X
|
||||||
|
|
|
@ -876,7 +876,7 @@ std::wstring JSONValue::StringifyString(const std::wstring &str)
|
||||||
{
|
{
|
||||||
wchar_t chr = *iter;
|
wchar_t chr = *iter;
|
||||||
|
|
||||||
if (chr == L'"' || chr == L'\\' || chr == L'/')
|
if (chr == L'"' || chr == L'\\' /*|| chr == L'/'*/)
|
||||||
{
|
{
|
||||||
str_out += L'\\';
|
str_out += L'\\';
|
||||||
str_out += chr;
|
str_out += chr;
|
||||||
|
|
|
@ -279,7 +279,6 @@ NTSTATUS MyHashBuffer(
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
IO_STATUS_BLOCK iosb;
|
|
||||||
MY_HASH_OBJ hashObj;
|
MY_HASH_OBJ hashObj;
|
||||||
|
|
||||||
if (!NT_SUCCESS(status = MyInitHash(&hashObj)))
|
if (!NT_SUCCESS(status = MyInitHash(&hashObj)))
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,6 +3,8 @@
|
||||||
#define UPDATE_DOMAIN "sandboxie-plus.com"
|
#define UPDATE_DOMAIN "sandboxie-plus.com"
|
||||||
|
|
||||||
#define UPDATE_FILE "update.json"
|
#define UPDATE_FILE "update.json"
|
||||||
|
#define ADDONS_FILE "addons.json"
|
||||||
|
#define ADDONS_PATH "\\addons\\"
|
||||||
|
|
||||||
|
|
||||||
#define SCOPE_CORE_FILES L"32\\SbieDll.dll\0"\
|
#define SCOPE_CORE_FILES L"32\\SbieDll.dll\0"\
|
||||||
|
@ -33,5 +35,10 @@
|
||||||
#define ERROR_EXEC (-8)
|
#define ERROR_EXEC (-8)
|
||||||
#define ERROR_CANCELED (-9)
|
#define ERROR_CANCELED (-9)
|
||||||
#define ERROR_INTERNAL (-10) // internal error, should not happen
|
#define ERROR_INTERNAL (-10) // internal error, should not happen
|
||||||
|
#define ERROR_NO_ADDON (-11) // addon not found
|
||||||
|
#define ERROR_NO_ADDON2 (-12) // no addon for this paltform or framework
|
||||||
|
#define ERROR_BAD_ADDON (-13)
|
||||||
|
#define ERROR_BAD_ADDON2 (-14)
|
||||||
|
#define ERROR_DELETE (-15)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -126,11 +126,12 @@
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<SupportJustMyCode>false</SupportJustMyCode>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<AdditionalDependencies>ntdll.lib;bcrypt.lib;wininet.lib;winhttp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>ntdll.lib;bcrypt.lib;wininet.lib;winhttp.lib;%(AdditionalDependencies);Version.lib</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
@ -147,7 +148,7 @@
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<AdditionalDependencies>ntdll.lib;bcrypt.lib;wininet.lib;winhttp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>ntdll.lib;bcrypt.lib;wininet.lib;winhttp.lib;%(AdditionalDependencies);Version.lib</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
@ -156,11 +157,12 @@
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<SupportJustMyCode>false</SupportJustMyCode>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<AdditionalDependencies>noenv.obj;ntdll.lib;bcrypt.lib;wininet.lib;winhttp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>noenv.obj;ntdll.lib;bcrypt.lib;wininet.lib;winhttp.lib;%(AdditionalDependencies);Version.lib</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||||
|
@ -169,11 +171,12 @@
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<SupportJustMyCode>false</SupportJustMyCode>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<AdditionalDependencies>noenv.obj;ntdll.lib;bcrypt.lib;wininet.lib;winhttp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>noenv.obj;ntdll.lib;bcrypt.lib;wininet.lib;winhttp.lib;%(AdditionalDependencies);Version.lib</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
@ -190,7 +193,7 @@
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<AdditionalDependencies>noenv.obj;ntdll.lib;bcrypt.lib;wininet.lib;winhttp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>noenv.obj;ntdll.lib;bcrypt.lib;wininet.lib;winhttp.lib;%(AdditionalDependencies);Version.lib</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||||
|
@ -207,7 +210,7 @@
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<AdditionalDependencies>noenv.obj;ntdll.lib;bcrypt.lib;wininet.lib;winhttp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>noenv.obj;ntdll.lib;bcrypt.lib;wininet.lib;winhttp.lib;%(AdditionalDependencies);Version.lib</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
Loading…
Reference in New Issue