aboutsummaryrefslogtreecommitdiff
path: root/VMProtect/watermarks_window.cc
diff options
context:
space:
mode:
Diffstat (limited to 'VMProtect/watermarks_window.cc')
-rw-r--r--VMProtect/watermarks_window.cc596
1 files changed, 596 insertions, 0 deletions
diff --git a/VMProtect/watermarks_window.cc b/VMProtect/watermarks_window.cc
new file mode 100644
index 0000000..462a00b
--- /dev/null
+++ b/VMProtect/watermarks_window.cc
@@ -0,0 +1,596 @@
+#include "../core/objects.h"
+#include "../core/osutils.h"
+#include "../core/core.h"
+#include "../core/streams.h"
+#include "../core/files.h"
+#include "../core/pefile.h"
+#include "../core/macfile.h"
+#include "../core/elffile.h"
+#include "../core/lang.h"
+#include "models.h"
+#include "widgets.h"
+#include "progress_dialog.h"
+#include "watermarks_window.h"
+#include "moc/moc_watermarks_window.cc"
+#include "message_dialog.h"
+#include "watermark_dialog.h"
+#include "wait_cursor.h"
+#include "help_browser.h"
+#include "application.h"
+
+WatermarksModel *WatermarksWindow::watermarks_model = NULL;
+
+WatermarksWindow::WatermarksWindow(bool selectMode, QWidget *parent)
+ : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint), processEditLocked(false)
+#ifndef VMP_GNU
+ , debugPrivilegeEnabled(false)
+#endif
+{
+ setWindowTitle(QString::fromUtf8(language[lsWatermarks].c_str()));
+
+ searchModel = new SearchModel(this);
+ scanModel = new WatermarkScanModel(this);
+
+ tabBar = new TabWidget(this);
+ tabBar->setIconSize(QSize(18, 18));
+
+ addAct = new QAction(QString::fromUtf8(language[lsAddWatermark].c_str()) + "...", this);
+ addAct->setShortcut(QString("Ins"));
+ connect(addAct, SIGNAL(triggered()), this, SLOT(addClicked()));
+ renameAct = new QAction(QString::fromUtf8(language[lsRename].c_str()), this);
+ renameAct->setShortcut(QString("F2"));
+ renameAct->setEnabled(false);
+ connect(renameAct, SIGNAL(triggered()), this, SLOT(renameClicked()));
+ delAct = new QAction(QString::fromUtf8(language[lsDelete].c_str()), this);
+ delAct->setShortcut(QString("Del"));
+ delAct->setEnabled(false);
+ connect(delAct, SIGNAL(triggered()), this, SLOT(delClicked()));
+ blockAct = new QAction(QString::fromUtf8(language[lsBlocked].c_str()), this);
+ blockAct->setEnabled(false);
+ blockAct->setCheckable(true);
+ connect(blockAct, SIGNAL(triggered()), this, SLOT(blockClicked()));
+
+ contextMenu = new QMenu(this);
+ contextMenu->addAction(addAct);
+ contextMenu->addSeparator();
+ contextMenu->addAction(delAct);
+ contextMenu->addAction(renameAct);
+ contextMenu->addSeparator();
+ contextMenu->addAction(blockAct);
+
+ pagePanel = new QStackedWidget(this);
+
+ addButton = new QToolButton(this);
+ addButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ addButton->setAutoRaise(true);
+ addButton->setText(addAct->text());
+ addButton->setIconSize(QSize(20, 20));
+ addButton->setIcon(QIcon(":/images/add_gray.png"));
+ connect(addButton, SIGNAL(clicked(bool)), this, SLOT(addClicked()));
+
+ watermarkFilter = new SearchLineEdit(this);
+ watermarkFilter->setPlaceholderText(QString::fromUtf8(language[lsSearch].c_str()));
+ connect(watermarkFilter, SIGNAL(textChanged(const QString &)), this, SLOT(watermarkSearchChanged()));
+ connect(watermarkFilter, SIGNAL(returnPressed()), this, SLOT(watermarkSearchChanged()));
+
+ watermarkTree = new TreeView(this);
+ watermarkTree->setObjectName("grid");
+ watermarkTree->setRootIsDecorated(false);
+ watermarkTree->setUniformRowHeights(true);
+ watermarkTree->setIconSize(QSize(18, 18));
+ watermarkTree->setContextMenuPolicy(Qt::CustomContextMenu);
+ watermarkTree->setItemDelegate(new WatermarksTreeDelegate(this));
+ watermarkTree->setModel(watermarks_model);
+ watermarkTree->addAction(addAct);
+ watermarkTree->addAction(delAct);
+ connect(watermarkTree->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(watermarkIndexChanged()));
+ connect(watermarkTree, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(itemDoubleClicked(QModelIndex)));
+ connect(watermarkTree, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(contextMenuRequested(const QPoint &)));
+ pagePanel->addWidget(watermarkTree);
+
+ searchTree = new TreeView(this);
+ searchTree->setObjectName("grid");
+ searchTree->setIconSize(QSize(18, 18));
+ searchTree->setRootIsDecorated(false);
+ searchTree->setUniformRowHeights(true);
+ //searchTree->setFrameShape(QFrame::NoFrame);
+ searchTree->setModel(searchModel);
+ connect(searchTree->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(watermarkIndexChanged()));
+ connect(searchTree, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(itemDoubleClicked(QModelIndex)));
+ pagePanel->addWidget(searchTree);
+
+ QTreeView *scanTree = new TreeView(this);
+ scanTree->setObjectName("grid");
+ scanTree->setRootIsDecorated(false);
+ scanTree->setIconSize(QSize(18, 18));
+ scanTree->setModel(scanModel);
+ scanTree->header()->resizeSection(0, 300 * Application::stylesheetScaleFactor());
+
+ QToolButton *helpButton = new QToolButton(this);
+ helpButton->setShortcut(HelpContentsKeySequence());
+ helpButton->setIconSize(QSize(20, 20));
+ helpButton->setIcon(QIcon(":/images/help_gray.png"));
+ helpButton->setToolTip(QString::fromUtf8(language[lsHelp].c_str()));
+ connect(helpButton, SIGNAL(clicked(bool)), this, SLOT(helpClicked()));
+
+ okButton = new PushButton(QString::fromUtf8(language[lsOK].c_str()), this);
+ okButton->setVisible(selectMode);
+ connect(okButton, SIGNAL(clicked()), this, SLOT(okButtonClicked()));
+
+ QPushButton *cancelButton = new PushButton(QString::fromUtf8(language[selectMode ? lsCancel : lsClose].c_str()), this);
+ connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
+
+ QHBoxLayout *buttonLayout = new QHBoxLayout();
+ buttonLayout->setContentsMargins(0, 0, 0, 0);
+ buttonLayout->setSpacing(10);
+ buttonLayout->addWidget(helpButton);
+ buttonLayout->addStretch();
+#ifdef __APPLE__
+ buttonLayout->addWidget(cancelButton);
+ buttonLayout->addWidget(okButton);
+#else
+ buttonLayout->addWidget(okButton);
+ buttonLayout->addWidget(cancelButton);
+#endif
+
+ QFrame *panel = new QFrame(this);
+ QGridLayout *gridLayout = new QGridLayout();
+ gridLayout->setContentsMargins(0, 10, 0, 0);
+ gridLayout->setVerticalSpacing(10);
+ gridLayout->addWidget(addButton, 0, 0);
+ gridLayout->addItem(new QSpacerItem(30, 0, QSizePolicy::Expanding, QSizePolicy::Ignored), 0, 1);
+ gridLayout->addWidget(watermarkFilter, 0, 2);
+ gridLayout->addWidget(pagePanel, 1, 0, 1, 3);
+ panel->setLayout(gridLayout);
+ tabBar->addTab(panel, QIcon(":/images/tool.png"), QString::fromUtf8(language[lsSetup].c_str()));
+
+ QFrame *filePanel = new QFrame(this);
+ filePanel->setObjectName("gridEditor");
+ filePanel->setFrameShape(QFrame::StyledPanel);
+
+ fileButton = new QRadioButton(QString::fromUtf8(language[lsSearchInFile].c_str()), this);
+ fileButton->setObjectName("editor");
+ connect(fileButton, SIGNAL(clicked()), this, SLOT(fileButtonClicked()));
+
+ QFrame *fileSpacer = new QFrame(this);
+ fileSpacer->setObjectName("editor");
+ fileSpacer->setFixedWidth(17);
+
+ QFont font;
+ font.setBold(true);
+
+ fileNameLabel = new QLabel(QString::fromUtf8(language[lsFileName].c_str()), this);
+ fileNameLabel->setObjectName("editor");
+
+ fileNameEdit = new FileNameEdit(this);
+ fileNameEdit->setObjectName("editor");
+ fileNameEdit->setFrame(false);
+ fileNameEdit->setFilter(QString(
+#ifdef VMP_GNU
+ "%1 (*)"
+#else
+ "%1 (*.*)"
+#endif
+ ).arg(QString::fromUtf8(language[lsAllFiles].c_str())));
+
+ processButton = new QRadioButton(QString::fromUtf8(language[lsSearchInModule].c_str()), this);
+ processButton->setObjectName("editor");
+ connect(processButton, SIGNAL(clicked()), this, SLOT(processButtonClicked()));
+
+ QFrame *processSpacer = new QFrame(this);
+ processSpacer->setObjectName("editor");
+ processSpacer->setFixedWidth(17);
+
+ processLabel = new QLabel(QString::fromUtf8(language[lsProcess].c_str()), this);
+ processLabel->setObjectName("editor");
+
+ processEdit = new EnumEdit(this, QStringList());
+ processEdit->setFrame(false);
+ processEdit->setObjectName("editor");
+ processEdit->setFont(font);
+ connect(processEdit, SIGNAL(dropDown()), this, SLOT(processEditDropDown()));
+ connect(processEdit, SIGNAL(currentIndexChanged(int)), this, SLOT(processEditChanged()));
+
+ QFrame *moduleSpacer = new QFrame(this);
+ moduleSpacer->setObjectName("editor");
+ moduleSpacer->setFixedWidth(17);
+
+ moduleLabel = new QLabel(QString::fromUtf8(language[lsModule].c_str()), this);
+ moduleLabel->setObjectName("editor");
+
+ moduleEdit = new EnumEdit(this, QStringList());
+ moduleEdit->setFrame(false);
+ moduleEdit->setObjectName("editor");
+ moduleEdit->setFont(font);
+
+ gridLayout = new QGridLayout();
+ gridLayout->setContentsMargins(0, 0, 0, 0);
+ gridLayout->setHorizontalSpacing(0);
+ gridLayout->setVerticalSpacing(1);
+ gridLayout->addWidget(fileButton, 0, 0, 1, 3);
+ gridLayout->addWidget(fileSpacer, 1, 0);
+ gridLayout->addWidget(fileNameLabel, 1, 1);
+ gridLayout->addWidget(fileNameEdit, 1, 2);
+ gridLayout->addWidget(processButton, 2, 0, 1, 3);
+ gridLayout->addWidget(processSpacer, 3, 0);
+ gridLayout->addWidget(processLabel, 3, 1);
+ gridLayout->addWidget(processEdit, 3, 2);
+ gridLayout->addWidget(moduleSpacer, 4, 0);
+ gridLayout->addWidget(moduleLabel, 4, 1);
+ gridLayout->addWidget(moduleEdit, 4, 2);
+ gridLayout->setColumnMinimumWidth(1, 100 * Application::stylesheetScaleFactor());
+ gridLayout->setColumnStretch(2, 1);
+ filePanel->setLayout(gridLayout);
+
+ QPushButton *scanButton = new PushButton(QString::fromUtf8(language[lsStart].c_str()), this);
+ connect(scanButton, SIGNAL(clicked()), this, SLOT(scanButtonClicked()));
+
+ panel = new QFrame(this);
+ QBoxLayout *layout = new QVBoxLayout();
+ layout->setContentsMargins(0, 10, 0, 0);
+ layout->setSpacing(10);
+ layout->addWidget(filePanel);
+ layout->addWidget(scanButton, 0, Qt::AlignCenter);
+ layout->addWidget(scanTree, 1);
+ panel->setLayout(layout);
+ tabBar->addTab(panel, QIcon(":/images/search_gray.png"), QString::fromUtf8(language[lsSearch].c_str()));
+
+ layout = new QVBoxLayout();
+ layout->setContentsMargins(10, 10, 10, 10);
+ layout->setSpacing(10);
+ layout->addWidget(tabBar);
+ layout->addLayout(buttonLayout);
+ setLayout(layout);
+
+ connect(watermarks_model, SIGNAL(nodeUpdated(ProjectNode *)), this, SLOT(watermarkNodeUpdated(ProjectNode *)));
+ connect(watermarks_model, SIGNAL(nodeRemoved(ProjectNode *)), this, SLOT(watermarkNodeRemoved(ProjectNode *)));
+
+ fileButton->setChecked(true);
+ fileButtonClicked();
+
+ setMinimumSize(450 * Application::stylesheetScaleFactor(), 300 * Application::stylesheetScaleFactor());
+}
+
+WatermarksWindow::~WatermarksWindow()
+{
+ disconnect(watermarks_model, SIGNAL(nodeUpdated(ProjectNode *)), this, SLOT(watermarkNodeUpdated(ProjectNode *)));
+ disconnect(watermarks_model, SIGNAL(nodeRemoved(ProjectNode *)), this, SLOT(watermarkNodeRemoved(ProjectNode *)));
+
+ delete searchModel;
+ delete scanModel;
+}
+
+void WatermarksWindow::watermarkNodeUpdated(ProjectNode *node)
+{
+ searchModel->updateNode(node);
+}
+
+void WatermarksWindow::watermarkNodeRemoved(ProjectNode *node)
+{
+ searchModel->removeNode(node);
+ scanModel->removeWatermark(static_cast<Watermark *>(node->data()));
+}
+
+void WatermarksWindow::okButtonClicked()
+{
+ if (selectedWatermark())
+ accept();
+}
+
+ProjectNode *WatermarksWindow::currentNode() const
+{
+ ProjectNode *res = NULL;
+ if (pagePanel->currentWidget() == watermarkTree) {
+ res = watermarks_model->indexToNode(watermarkTree->currentIndex());
+ } else if (pagePanel->currentWidget() == searchTree) {
+ res = searchModel->indexToNode(searchTree->currentIndex());
+ }
+ return res;
+}
+
+Watermark *WatermarksWindow::selectedWatermark() const
+{
+ ProjectNode *node = currentNode();
+ return (node && node->type() == NODE_WATERMARK) ? reinterpret_cast<Watermark *>(node->data()) : NULL;
+}
+
+void WatermarksWindow::watermarkSearchChanged()
+{
+ Watermark *watermark = selectedWatermark();
+ if (!watermarkFilter->text().isEmpty()) {
+ searchModel->search(watermarks_model->root(), watermarkFilter->text());
+ pagePanel->setCurrentWidget(searchTree);
+ searchTree->setCurrentIndex(searchModel->nodeToIndex(watermarks_model->objectToNode(watermark)));
+ } else {
+ pagePanel->setCurrentWidget(watermarkTree);
+ watermarkTree->setCurrentIndex(watermarks_model->objectToIndex(watermark));
+ }
+
+ watermarkIndexChanged();
+}
+
+QTreeView *WatermarksWindow::currentTreeView() const
+{
+ if (pagePanel->currentWidget() == watermarkTree)
+ return watermarkTree;
+ else
+ return searchTree;
+}
+
+void WatermarksWindow::watermarkIndexChanged()
+{
+ Watermark *watermark = selectedWatermark();
+
+ okButton->setEnabled(watermark != NULL);
+ delAct->setEnabled(watermark != NULL);
+ renameAct->setEnabled(watermark != NULL);
+ blockAct->setEnabled(watermark != NULL);
+ blockAct->setChecked(watermark != NULL && !watermark->enabled());
+}
+
+void WatermarksWindow::itemDoubleClicked(const QModelIndex & /*index*/)
+{
+ if (!okButton->isVisible())
+ return;
+
+ okButtonClicked();
+}
+
+QString WatermarksWindow::watermarkName() const
+{
+ Watermark *watermark = selectedWatermark();
+ return watermark ? QString::fromUtf8(watermark->name().c_str()) : QString();
+}
+
+void WatermarksWindow::setWatermarkName(const QString &name)
+{
+ QModelIndex index = watermarks_model->indexByName(name);
+ watermarkTree->setCurrentIndex(index);
+ if (index.isValid())
+ watermarkTree->scrollTo(index, QAbstractItemView::PositionAtTop);
+}
+
+std::map<Watermark*, size_t> WatermarksWindow::internalScanWatermarks(IFile *file)
+{
+ std::map<Watermark*, size_t> res;
+ try {
+ res = file->SearchWatermarks(*watermarks_model->core()->watermark_manager());
+ } catch(canceled_error &error) {
+ file->Notify(mtWarning, NULL, error.what());
+ } catch(std::runtime_error &error) {
+ file->Notify(mtError, NULL, error.what());
+ }
+ return res;
+}
+
+void WatermarksWindow::scanButtonClicked()
+{
+ if (fileButton->isChecked()) {
+ if (fileNameEdit->text().isEmpty()) {
+ MessageDialog::critical(this, QString::fromUtf8(language[lsFileNameNotSpecified].c_str()), QMessageBox::Ok);
+ fileNameEdit->setFocus();
+ return;
+ }
+ } else {
+ if (processEdit->currentIndex() == -1) {
+ MessageDialog::critical(this, QString::fromUtf8(language[lsProcessNotSpecified].c_str()), QMessageBox::Ok);
+ processEdit->setFocus();
+ return;
+ }
+ if (moduleEdit->currentIndex() == -1) {
+ MessageDialog::critical(this, QString::fromUtf8(language[lsModuleNotSpecified].c_str()), QMessageBox::Ok);
+ moduleEdit->setFocus();
+ return;
+ }
+ }
+
+ scanModel->clear();
+ std::auto_ptr<IFile> file;
+ GUILog log;
+
+ if (fileButton->isChecked()) {
+ std::string fileName = fileNameEdit->text().toUtf8().data();
+ std::auto_ptr<IFile> files[] = {
+ std::auto_ptr<IFile>(new PEFile(qobject_cast<ILog*>(&log)))
+ , std::auto_ptr<IFile>(new MacFile(qobject_cast<ILog*>(&log)))
+ , std::auto_ptr<IFile>(new ELFFile(qobject_cast<ILog*>(&log)))
+ , std::auto_ptr<IFile>(new IFile(qobject_cast<ILog*>(&log)))
+ };
+ for (size_t i = 0; i < _countof(files); i++) {
+
+ OpenStatus status = files[i]->Open(fileName.c_str(), foRead | foHeaderOnly);
+ if (status == osSuccess) {
+ file = files[i];
+ break;
+ }
+
+ if (status == osOpenError) {
+ MessageDialog::critical(this, QString::fromUtf8(string_format(language[lsOpenFileError].c_str(), fileName.c_str()).c_str()), QMessageBox::Ok);
+ break;
+ } else if (status != osUnknownFormat) {
+ LangString message_id;
+ switch (status) {
+ case osUnsupportedCPU:
+ message_id = lsFileHasUnsupportedProcessor;
+ break;
+ case osUnsupportedSubsystem:
+ message_id = lsFileHasUnsupportedSubsystem;
+ break;
+ default:
+ message_id = lsFileHasIncorrectFormat;
+ break;
+ }
+ if (MessageDialog::warning(this, QString::fromUtf8(string_format(language[message_id].c_str(), fileName.c_str(), "").append("\n").append(language[lsContinue]).append("?").c_str()), QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
+ break;
+ }
+ }
+ } else {
+ QVariant process = processEdit->itemData(processEdit->currentIndex());
+ QVariant module = moduleEdit->itemData(moduleEdit->currentIndex());
+ std::string moduleName = moduleEdit->currentText().toUtf8().data();
+ file.reset(new IFile(qobject_cast<ILog*>(&log)));
+ if (!file->OpenModule(process.toUInt(), reinterpret_cast<HMODULE>(module.toULongLong()))) {
+ MessageDialog::critical(this, QString::fromUtf8(string_format(language[lsOpenModuleError].c_str(), moduleName.c_str()).c_str()), QMessageBox::Ok);
+ }
+ }
+
+ if (file.get()) {
+ QFutureWatcher<std::map<Watermark*, size_t>> watcher;
+ ProgressDialog progress(this);
+
+ connect(&watcher, SIGNAL(finished()), &progress, SLOT(reject()));
+ connect(&progress, SIGNAL(cancel()), &log, SLOT(cancel()));
+ connect(&log, SIGNAL(notify(MessageType, IObject *, const QString &)), &progress, SLOT(notify(MessageType, IObject *, const QString &)));
+ connect(&log, SIGNAL(startProgress(const QString &, unsigned long long)), &progress, SLOT(startProgress(const QString &, unsigned long long)));
+ connect(&log, SIGNAL(stepProgress(unsigned long long)), &progress, SLOT(stepProgress(unsigned long long)));
+
+ watcher.setFuture(QtConcurrent::run(this, &WatermarksWindow::internalScanWatermarks, file.get()));
+ progress.exec();
+ watcher.waitForFinished();
+ scanModel->setWatermarkData(watcher.result());
+ }
+}
+
+void WatermarksWindow::addClicked()
+{
+ WatermarkDialog dialog(watermarks_model->manager(), this);
+
+ if (dialog.exec() == QDialog::Accepted) {
+ watermarkFilter->clear();
+ Watermark *watermark = dialog.watermark();
+ watermarkTree->setCurrentIndex(watermarks_model->objectToIndex(watermark));
+ }
+}
+
+void WatermarksWindow::delClicked()
+{
+ Watermark *watermark = selectedWatermark();
+ if (!watermark)
+ return;
+
+ int res;
+ if (watermark->use_count()) {
+ res = MessageDialog::warning(this, QString("%1.\n%2?").arg(QString::fromUtf8(string_format(language[lsWatermarkIsUsed].c_str(), watermark->name().c_str()).c_str())).arg(QString(QString::fromUtf8(language[lsDeleteWatermark].c_str()))), QMessageBox::Yes | QMessageBox::No);
+ } else {
+ res = MessageDialog::question(this, QString(QString::fromUtf8(language[lsDeleteWatermark].c_str()) + "?"), QMessageBox::Yes | QMessageBox::No);
+ }
+ if (res == QMessageBox::Yes)
+ delete watermark;
+}
+
+void WatermarksWindow::renameClicked()
+{
+ QTreeView *tree_view = currentTreeView();
+ tree_view->edit(tree_view->currentIndex());
+}
+
+void WatermarksWindow::blockClicked()
+{
+ Watermark *watermark = selectedWatermark();
+ if (!watermark)
+ return;
+
+ watermark->set_enabled(!watermark->enabled());
+}
+
+void WatermarksWindow::fileButtonClicked()
+{
+ fileNameLabel->setEnabled(true);
+ fileNameEdit->setEnabled(true);
+ processLabel->setEnabled(false);
+ processEdit->setEnabled(false);
+ moduleLabel->setEnabled(false);
+ moduleEdit->setEnabled(false);
+
+ fileNameEdit->setFocus();
+ fileNameEdit->selectAll();
+}
+
+void WatermarksWindow::processButtonClicked()
+{
+ fileNameLabel->setEnabled(false);
+ fileNameEdit->setEnabled(false);
+ processLabel->setEnabled(true);
+ processEdit->setEnabled(true);
+ moduleLabel->setEnabled(true);
+ moduleEdit->setEnabled(true);
+
+ processEdit->setFocus();
+ processEdit->lineEdit()->selectAll();
+}
+
+void WatermarksWindow::processEditDropDown()
+{
+#ifndef VMP_GNU
+ if (!debugPrivilegeEnabled) {
+ HANDLE token;
+ if (OpenProcessToken(INVALID_HANDLE_VALUE, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) {
+ LUID value;
+ if (LookupPrivilegeValueA(NULL, "SeDebugPrivilege", &value)) {
+ TOKEN_PRIVILEGES privileges;
+ privileges.PrivilegeCount = 1;
+ privileges.Privileges[0].Luid = value;
+ privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+ debugPrivilegeEnabled = !!(AdjustTokenPrivileges(token, FALSE, &privileges, sizeof(privileges), NULL, NULL));
+ }
+ CloseHandle(token);
+ }
+ }
+#endif
+
+ processEditLocked = true;
+
+ QString oldText = processEdit->currentText();
+ processEdit->clear();
+ processEdit->setCurrentIndex(-1);
+
+ std::vector<PROCESS_ITEM> processes = os::EnumProcesses();
+ for (size_t i = 0; i < processes.size(); i++) {
+ processEdit->addItem(
+ QString("[%1] ").arg(processes[i].id) + QString::fromUtf8(processes[i].name.c_str()),
+ QVariant(static_cast<qulonglong>(processes[i].id)));
+ }
+
+ processEdit->setCurrentIndex(processEdit->findText(oldText));
+ if (processEdit->currentIndex() == -1)
+ moduleEdit->clear();
+
+ processEditLocked = false;
+}
+
+void WatermarksWindow::processEditChanged()
+{
+ if (processEditLocked)
+ return;
+
+ moduleEdit->clear();
+ int i = processEdit->currentIndex();
+ if (i == -1)
+ return;
+
+ QVariant data = processEdit->itemData(i);
+ std::vector<MODULE_ITEM> modules = os::EnumModules(data.toInt());
+ for (size_t i = 0; i < modules.size(); i++) {
+
+ moduleEdit->addItem(
+ QString::fromUtf8(modules[i].name.c_str())
+#ifdef __unix__ // может быть много строк для одного файла по разным адресам (addr === HANDLE)
+ + QString(" @%1").arg((uint64_t)modules[i].handle, sizeof(void *) * 2, 16, QLatin1Char('0')).toUpper()
+#endif
+ ,
+ QVariant(reinterpret_cast<qulonglong>(modules[i].handle)));
+ }
+
+ if (moduleEdit->count())
+ moduleEdit->setCurrentIndex(0);
+}
+
+void WatermarksWindow::contextMenuRequested(const QPoint &p)
+{
+ contextMenu->exec(watermarkTree->viewport()->mapToGlobal(p));
+}
+
+void WatermarksWindow::helpClicked()
+{
+ HelpBrowser::showTopic(tabBar->currentIndex() == 0 ? "watermarks::setup" : "watermarks::search");
+} \ No newline at end of file