Rabbit Remote Control 0.0.34
Loading...
Searching...
No Matches
HookWindows.cpp
1#include "HookWindows.h"
2#include "FrmViewer.h"
3#include <QApplication>
4#include <QKeyEvent>
5#include <QLoggingCategory>
6#include <RabbitCommonTools.h>
7#include <QMessageBox>
8#include <QCheckBox>
9
10static Q_LOGGING_CATEGORY(log, "Client.Hook.Windows")
11
12CHook* CHook::GetHook(QObject *parent)
13{
14 CHookWindows* p = nullptr;
15 if(!p)
16 p = new CHookWindows(parent);
17 return p;
18}
19
20CHookWindows::CHookWindows(QObject *parent)
21 : CHook(parent),
22 m_hKeyboard(nullptr)
23{
24 RegisterKeyboard();
25}
26
27CHookWindows::~CHookWindows()
28{
29 qDebug(log) << "CHookWindows::~CHookWindows()";
30 UnRegisterKeyboard();
31}
32
33// See: https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms644985(v=vs.85)
34LRESULT CALLBACK CHookWindows::keyboardHookProc(INT code, WPARAM wparam, LPARAM lparam)
35{
36 if (code == HC_ACTION)
37 {
38 KBDLLHOOKSTRUCT* hook = reinterpret_cast<KBDLLHOOKSTRUCT*>(lparam);
39 /*
40 qDebug(log) << "process vkCode:" << hook->vkCode
41 << "scanCode:" << hook->scanCode
42 << "flags:" << hook->flags;//*/
43 int key = 0;
44 Qt::KeyboardModifiers keyMdf = Qt::NoModifier;
45 // See: [virtual-key-codes](https://learn.microsoft.com/zh-cn/windows/win32/inputdev/virtual-key-codes)
46 switch(hook->vkCode)
47 {
48 case VK_TAB:
49 {
50 key = Qt::Key_Tab;
51 break;
52 }
53 case VK_DELETE:
54 {
55 key = Qt::Key_Delete;
56 break;
57 }
58 case VK_LWIN:
59 {
60 key = Qt::Key_Super_L;
61 keyMdf = Qt::MetaModifier;
62 break;
63 }
64 case VK_RWIN:
65 {
66 key = Qt::Key_Super_R;
67 keyMdf = Qt::MetaModifier;
68 break;
69 }
70 case VK_MENU:
71 case VK_LMENU:
72 case VK_RMENU:
73 {
74 key = Qt::Key_Alt;
75 //keyMdf = Qt::KeyboardModifier::AltModifier;
76 break;
77 }
78 case VK_CONTROL:
79 case VK_LCONTROL:
80 case VK_RCONTROL:
81 {
82 key = Qt::Key_Control;
83 //keyMdf = Qt::KeyboardModifier::ControlModifier;
84 break;
85 }
86 case VK_SHIFT:
87 case VK_LSHIFT:
88 case VK_RSHIFT:
89 {
90 key = Qt::Key_Shift;
91 //keyMdf = Qt::KeyboardModifier::ShiftModifier;
92 break;
93 }
94 default:
95 break;
96 }
97 if(key) {
98 CFrmViewer* self = qobject_cast<CFrmViewer*>(QApplication::focusWidget());
99 WId foreground_window = reinterpret_cast<WId>(GetForegroundWindow());
100 if (self && self->parentWidget()->window()->winId() == foreground_window)
101 {
102 if(wparam == WM_KEYDOWN || wparam == WM_SYSKEYDOWN)
103 emit self->sigKeyPressEvent(new QKeyEvent(QKeyEvent::KeyPress, key, keyMdf));
104 //QApplication::postEvent(self, new QKeyEvent(QKeyEvent::KeyPress, key, keyMdf));
105 if(wparam == WM_KEYUP || wparam == WM_SYSKEYUP)
106 emit self->sigKeyReleaseEvent(new QKeyEvent(QKeyEvent::KeyRelease, key, Qt::NoModifier));
107 //QApplication::postEvent(self, new QKeyEvent(QKeyEvent::KeyRelease, key, Qt::NoModifier));
108 //*
109 qDebug(log) << "process vkCode:" << hook->vkCode
110 << "scanCode:" << hook->scanCode
111 << "flags:" << hook->flags;//*/
112 /* the hook procedure did not process the message,
113 * it is highly recommended that you call CallNextHookEx
114 * and return the value it returns; otherwise,
115 * other applications that have installed WH_KEYBOARD_LL hooks
116 * will not receive hook notifications and may behave incorrectly
117 * as a result. If the hook procedure processed the message,
118 * it may return a nonzero value to prevent the system
119 * from passing the message to the rest of the hook chain
120 * or the target window procedure.
121 */
122 return 1;
123 }
124 }
125 }
126
127 return CallNextHookEx(nullptr, code, wparam, lparam);
128}
129
130// See: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexw
131int CHookWindows::RegisterKeyboard()
132{
133 if(m_hKeyboard)
134 UnRegisterKeyboard();
135 DisableTaskManager(true);
136 m_hKeyboard = SetWindowsHookExW(WH_KEYBOARD_LL, keyboardHookProc, nullptr, 0);
137 if(NULL == m_hKeyboard) {
138 qCritical(log) << "SetWindowsHookExW error:" << GetLastError();
139 return -1;
140 }
141 return 0;
142}
143
144int CHookWindows::UnRegisterKeyboard()
145{
146 if(m_hKeyboard)
147 {
148 UnhookWindowsHookEx(m_hKeyboard);
149 m_hKeyboard = nullptr;
150 }
151 DisableTaskManager(false);
152 return 0;
153}
154
155// 启用备份和恢复权限
156bool EnableDebugPrivileges() {
157 HANDLE hToken = NULL;
158 LUID sedebugnameValue;
159 TOKEN_PRIVILEGES tkp;
160
161 // 获取当前进程的访问令牌
162 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
163 qDebug(log) << "OpenProcessToken failed. Error:" << GetLastError();
164 return false;
165 }
166
167 do {
168 // 查找 SE_DEBUG_NAME 权限的LUID
169 if (!LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &sedebugnameValue)) {
170 qDebug(log) << "LookupPrivilegeValue (SE_DEBUG_NAME) failed. Error:" << GetLastError();
171 break;
172 }
173
174 // 设置权限结构
175 tkp.PrivilegeCount = 1;
176 tkp.Privileges[0].Luid = sedebugnameValue;
177 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
178
179 // 调整权限
180 if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL)) {
181 qDebug(log) << "AdjustTokenPrivileges failed. Error:" << GetLastError();
182 break;
183 }
184
185 // 检查权限是否成功启用
186 if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) {
187 qDebug(log) << "The token does not have the specified privileges.";
188 break;
189 }
190 qDebug(log) << "Debug privileges enabled successfully.";
191 }while(0);
192
193 CloseHandle(hToken);
194 return true;
195}
196
197//添加注册屏蔽 Ctrl+Alt+del
198//在注册表该目录下增加新内容
199#define TASKMANAGERSystem "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"
200#define TASKMANAGERExplorer "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer"
201void CHookWindows::DisableTaskManager(bool flag)
202{
203 // 屏蔽ctrl + alt +del 需要修改注册表的值, 取得管理员权限, 关闭360等杀毒软件
204 int value = flag ? 0x00000001 : 0x00000000;
205 QSettings settings(TASKMANAGERSystem, QSettings::NativeFormat);
206 settings.setValue("DisableTaskMgr", value); //任务管理器
207 settings.setValue("DisableChangePassword", value); //更改密码
208 settings.setValue("DisableLockWorkstation", value); //锁定计算机
209 settings.setValue("DisableSwitchUserOption", value); //切换用户
210
211 QSettings settings2(TASKMANAGERExplorer, QSettings::NativeFormat);
212 settings2.setValue("NoLogOff", value); //注销
213}
A widget which displays output image from a CConnectDesktop and sends input keypresses and mouse acti...
Definition FrmViewer.h:49
The class is the HOOK abstract class.
Definition Hook.h:14