File indexing completed on 2023-05-30 09:17:23

0001 /*
0002  * SPDX-FileCopyrightText: 2019 Weixuan XIAO <veyx.shaw@gmail.com>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  */
0006 
0007 #include <QDebug>
0008 #include <QFile>
0009 #include <QIcon>
0010 #include <QStandardPaths>
0011 
0012 #include <iostream>
0013 
0014 #include <Windows.h>
0015 #include <tlhelp32.h>
0016 
0017 #include "indicator_debug.h"
0018 #include "indicatorhelper.h"
0019 
0020 IndicatorHelper::IndicatorHelper(const QUrl &indicatorUrl)
0021     : m_indicatorUrl(indicatorUrl)
0022 {
0023 }
0024 
0025 IndicatorHelper::~IndicatorHelper()
0026 {
0027     this->terminateProcess(processes::dbus_daemon, m_indicatorUrl);
0028     this->terminateProcess(processes::kdeconnect_app, m_indicatorUrl);
0029     this->terminateProcess(processes::kdeconnect_handler, m_indicatorUrl);
0030     this->terminateProcess(processes::kdeconnect_settings, m_indicatorUrl);
0031     this->terminateProcess(processes::kdeconnect_sms, m_indicatorUrl);
0032     this->terminateProcess(processes::kdeconnect_daemon, m_indicatorUrl);
0033 }
0034 
0035 void IndicatorHelper::preInit()
0036 {
0037 }
0038 
0039 void IndicatorHelper::postInit()
0040 {
0041 }
0042 
0043 void IndicatorHelper::iconPathHook()
0044 {
0045 }
0046 
0047 int IndicatorHelper::daemonHook(QProcess &kdeconnectd)
0048 {
0049     kdeconnectd.start(processes::kdeconnect_daemon);
0050     return 0;
0051 }
0052 
0053 #ifdef QSYSTRAY
0054 void IndicatorHelper::systrayIconHook(QSystemTrayIcon &systray)
0055 {
0056     systray.setIcon(QIcon::fromTheme(QStringLiteral("kdeconnect-tray")));
0057 }
0058 #else
0059 void IndicatorHelper::systrayIconHook(KStatusNotifierItem &systray)
0060 {
0061     Q_UNUSED(systray);
0062 }
0063 #endif
0064 
0065 bool IndicatorHelper::terminateProcess(const QString &processName, const QUrl &indicatorUrl) const
0066 {
0067     HANDLE hProcessSnap;
0068     HANDLE hProcess;
0069 
0070     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
0071     if (hProcessSnap == INVALID_HANDLE_VALUE) {
0072         qCWarning(KDECONNECT_INDICATOR) << "Failed to get snapshot of processes.";
0073         return FALSE;
0074     }
0075 
0076     PROCESSENTRY32 pe32;
0077     pe32.dwSize = sizeof(PROCESSENTRY32);
0078 
0079     if (!Process32First(hProcessSnap, &pe32)) {
0080         qCWarning(KDECONNECT_INDICATOR) << "Failed to get handle for the first process.";
0081         CloseHandle(hProcessSnap);
0082         return FALSE;
0083     }
0084 
0085     do {
0086         if (QString::fromWCharArray((wchar_t *)pe32.szExeFile) == processName) {
0087             hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
0088 
0089             if (hProcess == NULL) {
0090                 qCWarning(KDECONNECT_INDICATOR) << "Failed to get handle for the process:" << processName;
0091                 return FALSE;
0092             } else {
0093                 const DWORD processPathSize = 4096;
0094                 CHAR processPathString[processPathSize];
0095 
0096                 BOOL gotProcessPath = QueryFullProcessImageNameA(hProcess, 0, (LPSTR)processPathString, (PDWORD)&processPathSize);
0097 
0098                 if (gotProcessPath) {
0099                     const QUrl processUrl = QUrl::fromLocalFile(QString::fromStdString(processPathString)); // to replace \\ with /
0100                     if (indicatorUrl.isParentOf(processUrl)) {
0101                         BOOL terminateSuccess = TerminateProcess(hProcess, 0);
0102                         if (!terminateSuccess) {
0103                             qCWarning(KDECONNECT_INDICATOR) << "Failed to terminate process:" << processName;
0104                             return FALSE;
0105                         }
0106                     }
0107                 }
0108             }
0109         }
0110     } while (Process32Next(hProcessSnap, &pe32));
0111 
0112     CloseHandle(hProcessSnap);
0113     return TRUE;
0114 }