#include "stdafx.h" #include "SupportDialog.h" #include "SandMan.h" #include "../MiscHelpers/Common/Common.h" #include "SettingsWindow.h" #include #include "OnlineUpdater.h" bool CSupportDialog::m_ReminderShown = false; QDateTime GetSbieInstallationDate() { time_t InstalDate = 0; theAPI->GetSecureParam("InstallationDate", &InstalDate, sizeof(InstalDate)); time_t CurrentDate = QDateTime::currentDateTimeUtc().toSecsSinceEpoch(); if (InstalDate == 0 || InstalDate > CurrentDate) { InstalDate = CurrentDate; theAPI->SetSecureParam("InstallationDate", &InstalDate, sizeof(InstalDate)); } return QDateTime::fromSecsSinceEpoch(InstalDate); } bool CSupportDialog::IsBusinessUse() { if (CERT_IS_TYPE(g_CertInfo, eCertBusiness)) return true; uchar UsageFlags = 0; theAPI->GetSecureParam("UsageFlags", &UsageFlags, sizeof(UsageFlags)); return (UsageFlags & 1) != 0; } bool CSupportDialog::CheckSupport(bool bOnRun) { bool NoGo = false; #ifdef INSIDER_BUILD if (g_CertInfo.active) { if (!CERT_IS_INSIDER(g_CertInfo)) { TArguments args = GetArguments(g_Certificate, L'\n', L':'); if (args.value("TYPE").contains("PATREON")) { if (QMessageBox::question(NULL, "Sandboxie-Plus", tr("This Insider build requires a special certificate of type GREAT_PATREON, PERSONAL-HUGE, or CONTRIBUTOR.\n" "If you are a Great Supporter on Patreon already, Sandboxie can check online for an update of your certificate."), QMessageBox::Ok, QMessageBox::Cancel) == QMessageBox::Ok) { theGUI->m_pUpdater->UpdateCert(true); if (CERT_IS_INSIDER(g_CertInfo)) return false; } } else QMessageBox::warning(NULL, "Sandboxie-Plus", tr("This Insider build requires a special certificate of type GREAT_PATREON, PERSONAL-HUGE, or CONTRIBUTOR.")); } else return false; } NoGo = true; #else if (g_CertInfo.active) return false; QDateTime InstallDate = GetSbieInstallationDate(); bool bOnARM64 = (g_FeatureFlags & CSbieAPI::eSbieFeatureARM64) != 0; QDateTime CurretnDate = QDateTime::currentDateTimeUtc(); int Days = InstallDate.daysTo(CurretnDate); if (Days < 40) return false; if (IsBusinessUse()) { if (g_CertInfo.expired) Days = -g_CertInfo.expirers_in_sec / (24 * 3600); NoGo = (Days > 60); if (!NoGo && m_ReminderShown && !bOnRun) return false; } else if (!bOnARM64 && !theAPI->GetGlobalSettings()->GetBool("AlwaysShowReminder")) { // Note: the old sandboxie showed a message after 30 days every 12 hours for 5 seconds int Interval; if (Days > 730) Interval = 5 * 24; else if (Days > 365) Interval = 10 * 24; else if (Days > 180) Interval = 20 * 24; else Interval = 30 * 24; //USHORT ReminderRevision = 0; //theAPI->GetSecureParam("ReminderRevision", &ReminderRevision, sizeof(ReminderRevision)); USHORT ReminderShedule[2*11]; if (theAPI->GetSecureParam("ReminderShedule", &ReminderShedule, sizeof(ReminderShedule))) { for (USHORT* Cur = ReminderShedule; (ULONG_PTR)Cur < (ULONG_PTR)ReminderShedule + sizeof(ReminderShedule) && *Cur != 0; Cur += 2) { if (Days > Cur[0]) { if (Cur[1] < Interval) Interval = Cur[1]; break; } } } time_t LastReminder = 0; theAPI->GetSecureParam("LastReminder", &LastReminder, sizeof(LastReminder)); if (LastReminder > 0 && LastReminder < CurretnDate.toSecsSinceEpoch()) { if (CurretnDate.toSecsSinceEpoch() - LastReminder < (time_t(Interval) * 3600)) return false; } //ULONG ReminderConfig = 0; //theAPI->GetSecureParam("ReminderConfig", &ReminderConfig, sizeof(ReminderConfig)); if ((rand() % 5) != 0) return false; } m_ReminderShown = true; #endif if (!ShowDialog(NoGo)) PostQuitMessage(0); return true; } extern int g_CertAmount; int CountSeats(); bool CSupportDialog::ShowDialog(bool NoGo, int Wait) { QDateTime InstallDate = GetSbieInstallationDate(); int Days = InstallDate.daysTo(QDateTime::currentDateTimeUtc()); QString Message; #ifdef INSIDER_BUILD if (!CERT_IS_INSIDER(g_CertInfo)) { Message += tr("This is a exclusive Insider build of Sandboxie-Plus it is only available to Patreon Supporters on higher tiers as well as to project contributors and owners of a HUGE supporter certificate."); } else #endif if (CountSeats() > g_CertAmount) { Message = tr("The installed supporter certificate allows for %1 seats to be active.

").arg(g_CertAmount); Message += tr("There seams to be howeever %1 Sandboxie-Plus instances on your network, you need to obtain additional support certificates.

").arg(CountSeats()); } else if (IsBusinessUse()) { if (g_CertInfo.expired) { Days = -g_CertInfo.expirers_in_sec / (24 * 3600); Message = tr("The installed supporter certificate has expired %1 days ago and must be renewed.

").arg(Days); } else Message = tr("You have installed Sandboxie-Plus more than %1 days ago.

").arg(Days); Message += tr("Commercial use of Sandboxie past the evaluation period, requires a valid support certificate.").arg(Days); } else { bool bOnARM64 = (g_FeatureFlags & CSbieAPI::eSbieFeatureARM64) != 0; if (g_CertInfo.outdated) Message = tr("The installed supporter certificate is outdated and it is not valid for this version of Sandboxie-Plus.

"); else if (g_CertInfo.expired) Message = tr("The installed supporter certificate is expired and should be renewed.

"); else Message = tr("You have been using Sandboxie-Plus for more than %1 days now.

").arg(Days); if (bOnARM64) Message += tr("Sandboxie on ARM64 requires a valid supporter certificate for continued use.

"); else Message += tr("Personal use of Sandboxie is free of charge on x86/x64, although some functionality is only available to project supporters.

"); if (g_CertInfo.expired) Message += tr("Please continue supporting the project " "by renewing your supporter certificate and continue using the enhanced functionality in new builds."); else Message += tr("Sandboxie without a valid supporter certificate will sometimes pause for a few seconds. This pause allows you to consider purchasing a supporter certificate or earning one by contributing to the project.

" "A supporter certificate not just removes this reminder, but also enables exclusive enhanced functionality providing better security and compatibility."); } time_t LastReminder = QDateTime::currentDateTimeUtc().toSecsSinceEpoch(); theAPI->SetSecureParam("LastReminder", &LastReminder, sizeof(LastReminder)); CSupportDialog dialog(Message, NoGo); return dialog.exec() != QDialog::Rejected; } CSupportDialog::CSupportDialog(const QString& Message, bool NoGo, int Wait, QWidget *parent) : QDialog(parent) { Qt::WindowFlags flags = windowFlags(); flags |= Qt::CustomizeWindowHint; //flags &= ~Qt::WindowContextHelpButtonHint; //flags &= ~Qt::WindowSystemMenuHint; //flags &= ~Qt::WindowMinMaxButtonsHint; //flags |= Qt::WindowMinimizeButtonHint; //flags &= ~Qt::WindowCloseButtonHint; flags &= ~Qt::WindowContextHelpButtonHint; //flags &= ~Qt::WindowSystemMenuHint; setWindowFlags(flags); //setWindowState(Qt::WindowActive); SetForegroundWindow((HWND)QWidget::winId()); bool bAlwaysOnTop = theConf->GetBool("Options/AlwaysOnTop", false); this->setWindowFlag(Qt::WindowStaysOnTopHint, bAlwaysOnTop); this->setWindowTitle(tr("Sandboxie-Plus - Support Reminder")); this->resize(420, 300); QVBoxLayout* verticalLayout = new QVBoxLayout(this); QGridLayout* gridLayout = new QGridLayout(); QHBoxLayout* horizontalLayout = new QHBoxLayout(); m_Buttons[0] = new QPushButton(this); horizontalLayout->addWidget(m_Buttons[0]); m_Buttons[1] = new QPushButton(this); horizontalLayout->addWidget(m_Buttons[1]); m_Buttons[2] = new QPushButton(this); horizontalLayout->addWidget(m_Buttons[2]); gridLayout->addLayout(horizontalLayout, 2, 0, 1, 1); QLabel* label = new QLabel(this); QSizePolicy sizePolicy(QSizePolicy::Ignored, QSizePolicy::Expanding); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); sizePolicy.setHeightForWidth(label->sizePolicy().hasHeightForWidth()); label->setSizePolicy(sizePolicy); label->setAlignment(Qt::AlignCenter); label->setWordWrap(true); label->setText(Message); connect(label, SIGNAL(linkActivated(const QString&)), theGUI, SLOT(OpenUrl(const QString&))); gridLayout->addWidget(label, 1, 0, 1, 1); QLabel* logo = new QLabel(this); logo->setFrameShape(QFrame::StyledPanel); logo->setFrameShadow(QFrame::Plain); //QPalette back = logo->palette(); //SetPaleteTexture(back, QPalette::Window, QImage(":/Assets/sandboxie-back.png")); //logo->setPalette(back); //logo->setAutoFillBackground(true); logo->setStyleSheet("background-image: url(:/Assets/sandboxie-back.png);"); logo->setPixmap(QPixmap::fromImage(QImage(":/Assets/sandboxie-logo.png"))); logo->setAlignment(Qt::AlignCenter); gridLayout->addWidget(logo, 0, 0, 1, 1); verticalLayout->addLayout(gridLayout); for (int s = rand() % 3, i = 0; i < 3; i++) { QPushButton* pButton = m_Buttons[(s + i) % 3]; pButton->setAutoDefault(false); //pButton->setEnabled(false); if(i == 1 && NoGo) pButton->setEnabled(false); if (i == 2 && NoGo) i = 3; pButton->setProperty("Action", i); connect(pButton, SIGNAL(clicked(bool)), this, SLOT(OnButton())); } m_CountDown = Wait; UpdateButtons(); m_uTimerID = startTimer(1000); } CSupportDialog::~CSupportDialog() { killTimer(m_uTimerID); } void CSupportDialog::timerEvent(QTimerEvent* pEvent) { if (pEvent->timerId() != m_uTimerID) return; if (m_CountDown >= 0) UpdateButtons(); } void CSupportDialog::UpdateButtons() { if (m_CountDown-- > 0) m_Buttons[1]->setText(tr("%1").arg(m_CountDown + 1)); else { for (int i = 0; i < 3; i++) { QPushButton* pButton = m_Buttons[i]; //pButton->setEnabled(true); switch (pButton->property("Action").toInt()) { case 0: pButton->setText(tr("Quit")); break; case 1: pButton->setText(tr("Continue")); break; case 2: pButton->setText(tr("Get Certificate")); break; case 3: pButton->setText(tr("Enter Certificate")); break; } } } } void CSupportDialog::OnButton() { int Action = ((QPushButton*)sender())->property("Action").toInt(); if (Action == 3) { CSettingsWindow* pSettingsWindow = new CSettingsWindow(this); pSettingsWindow->showTab("Support", true); connect(pSettingsWindow, &CSettingsWindow::Closed, [this]() { #ifdef INSIDER_BUILD if (g_CertInfo.active && !CERT_IS_INSIDER(g_CertInfo)) { TArguments args = GetArguments(g_Certificate, L'\n', L':'); if (args.value("TYPE").contains("PATREON")) { theGUI->m_pUpdater->UpdateCert(true); if (CERT_IS_INSIDER(g_CertInfo)) { accept(); return; } } QMessageBox::warning(this, "Sandboxie-Plus", tr("This Insider build requires a special certificate of type GREAT_PATREON, PERSONAL-HUGE, or CONTRIBUTOR.")); return; } #endif if (g_CertInfo.active) accept(); }); } else if (Action == 2) return theGUI->OpenUrl(QUrl("https://sandboxie-plus.com/go.php?to=sbie-get-cert")); else if (Action == 1) accept(); else reject(); }