5#include <QLoggingCategory>
6#include <RabbitCommonTools.h>
11#include "HookWindows.h"
12#include "RabbitCommonTools.h"
14static Q_LOGGING_CATEGORY(log,
"Plugin.Hook.Windows")
17 :
CHook(pParaClient, parent),
22CHookWindows::~CHookWindows()
24 qDebug(log) <<
"CHookWindows::~CHookWindows()";
28LRESULT CALLBACK CHookWindows::keyboardHookProc(INT code, WPARAM wparam, LPARAM lparam)
30 if (code == HC_ACTION)
32 KBDLLHOOKSTRUCT* hook =
reinterpret_cast<KBDLLHOOKSTRUCT*
>(lparam);
38 Qt::KeyboardModifiers keyMdf = Qt::NoModifier;
54 key = Qt::Key_Super_L;
55 keyMdf = Qt::MetaModifier;
60 key = Qt::Key_Super_R;
61 keyMdf = Qt::MetaModifier;
76 key = Qt::Key_Control;
92 CFrmViewer* self = qobject_cast<CFrmViewer*>(QApplication::focusWidget());
93 WId foreground_window =
reinterpret_cast<WId
>(GetForegroundWindow());
94 if (self && self->parentWidget()->window()->winId() == foreground_window)
96 if(wparam == WM_KEYDOWN || wparam == WM_SYSKEYDOWN)
97 emit self->sigKeyPressEvent(
new QKeyEvent(QKeyEvent::KeyPress, key, keyMdf));
99 if(wparam == WM_KEYUP || wparam == WM_SYSKEYUP)
100 emit self->sigKeyReleaseEvent(
new QKeyEvent(QKeyEvent::KeyRelease, key, Qt::NoModifier));
103 qDebug(log) <<
"process vkCode:" << hook->vkCode
104 <<
"scanCode:" << hook->scanCode
105 <<
"flags:" << hook->flags;
121 return CallNextHookEx(
nullptr, code, wparam, lparam);
125int CHookWindows::OnRegisterKeyboard()
128 UnRegisterKeyboard();
129 m_hKeyboard = SetWindowsHookExW(WH_KEYBOARD_LL, keyboardHookProc,
nullptr, 0);
130 if(NULL == m_hKeyboard) {
131 qCritical(log) <<
"SetWindowsHookExW error:" << GetLastError();
137int CHookWindows::OnUnRegisterKeyboard()
141 UnhookWindowsHookEx(m_hKeyboard);
142 m_hKeyboard =
nullptr;
147int CHookWindows::OnDisableDesktopShortcuts()
149 DisableTaskManager(
true);
153int CHookWindows::OnRestoreDesktopShortcuts()
155 DisableTaskManager(
false);
160bool EnableDebugPrivileges() {
161 HANDLE hToken = NULL;
162 LUID sedebugnameValue;
163 TOKEN_PRIVILEGES tkp;
166 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
167 qDebug(log) <<
"OpenProcessToken failed. Error:" << GetLastError();
173 if (!LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &sedebugnameValue)) {
174 qDebug(log) <<
"LookupPrivilegeValue (SE_DEBUG_NAME) failed. Error:" << GetLastError();
179 tkp.PrivilegeCount = 1;
180 tkp.Privileges[0].Luid = sedebugnameValue;
181 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
184 if (!AdjustTokenPrivileges(hToken, FALSE, &tkp,
sizeof(tkp), NULL, NULL)) {
185 qDebug(log) <<
"AdjustTokenPrivileges failed. Error:" << GetLastError();
190 if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) {
191 qDebug(log) <<
"The token does not have the specified privileges.";
194 qDebug(log) <<
"Debug privileges enabled successfully.";
203#define TASKMANAGERSystem "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"
204#define TASKMANAGERExplorer "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer"
205#define WINLOGON "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"
206void CHookWindows::DisableTaskManager(
bool flag)
209 int value = flag ? 0x00000001 : 0x00000000;
210 QSettings system(TASKMANAGERSystem, QSettings::NativeFormat);
211 system.setValue(
"DisableTaskMgr", value);
212 system.setValue(
"DisableChangePassword", value);
213 system.setValue(
"DisableSwitchUserOption", value);
214 system.setValue(
"DisableCAD", value);
215 system.setValue(
"DisableLockWorkstation", value);
217 QSettings explorer(TASKMANAGERExplorer, QSettings::NativeFormat);
218 explorer.setValue(
"NoLogOff", value);
227bool CHookWindows::DisableWindowsKey()
233 if (!RegisterHotKey(
nullptr, 1, MOD_WIN, VK_LWIN)) {
234 qCritical(log) <<
"注册左 Windows 键拦截失败:" << GetLastError();
238 if (!RegisterHotKey(
nullptr, 2, MOD_WIN, VK_RWIN)) {
239 qCritical(log) <<
"注册右 Windows 键拦截失败:" << GetLastError();
245 LONG result = RegCreateKeyExW(HKEY_CURRENT_USER,
246 L
"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer",
247 0,
nullptr, 0, KEY_ALL_ACCESS,
nullptr, &hKey,
nullptr);
249 if (result == ERROR_SUCCESS) {
251 result = RegSetValueExW(hKey, L
"NoWinKeys", 0, REG_DWORD,
252 reinterpret_cast<const BYTE*
>(&value),
sizeof(value));
254 if (result == ERROR_SUCCESS) {
255 qDebug(log) <<
"注册表设置成功,Windows 键已禁用";
257 qWarning(log) <<
"注册表设置失败:" << result;
262 qWarning(log) <<
"创建注册表键失败:" << result;
269bool CHookWindows::EnableWindowsKey()
274 UnregisterHotKey(
nullptr, 1);
275 UnregisterHotKey(
nullptr, 2);
279 LONG result = RegOpenKeyExW(HKEY_CURRENT_USER,
280 L
"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer",
281 0, KEY_ALL_ACCESS, &hKey);
283 if (result == ERROR_SUCCESS) {
284 result = RegDeleteValueW(hKey, L
"NoWinKeys");
285 if (result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND) {
286 qDebug(log) <<
"Windows 键已恢复";
288 qWarning(log) <<
"删除注册表值失败:" << result;
297bool CHookWindows::DisableTaskManager()
301 LONG result = RegCreateKeyExW(HKEY_CURRENT_USER,
302 L
"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System",
303 0,
nullptr, 0, KEY_ALL_ACCESS,
nullptr, &hKey,
nullptr);
305 if (result == ERROR_SUCCESS) {
307 result = RegSetValueExW(hKey, L
"DisableTaskMgr", 0, REG_DWORD,
308 reinterpret_cast<const BYTE*
>(&value),
sizeof(value));
310 if (result == ERROR_SUCCESS) {
311 qDebug(log) <<
"任务管理器已禁用";
314 qWarning(log) <<
"禁用任务管理器失败:" << result;
322bool CHookWindows::EnableTaskManager()
325 LONG result = RegOpenKeyExW(HKEY_CURRENT_USER,
326 L
"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System",
327 0, KEY_ALL_ACCESS, &hKey);
329 if (result == ERROR_SUCCESS) {
330 result = RegDeleteValueW(hKey, L
"DisableTaskMgr");
333 if (result == ERROR_SUCCESS || result == ERROR_FILE_NOT_FOUND) {
334 qDebug(log) <<
"任务管理器已恢复";
用于显示从 CConnectDesktop 输出的图像,和向 CConnectDesktop 发送键盘、鼠标事件。
The class is the HOOK abstract class.