Да, это так.
CTRL + ALT + DEL, известная как Secure Attention Sequence (SAS) , не может быть перехвачен через общий механизм Global Windows Hook.
Возможность перехвата SAS, о которой я знаю, независимо от ситуации, это всего лишь один: драйвер.
Но это не обязательно должен быть полноценный драйвер устройства, он может быть более простым, известным как драйвер фильтра. Вам нужно научиться делать разработку ядра, которая не так тривиальна и потребует от вас, например, отладки ядра на двух машинах. Если вы планируете использовать драйвер на других компьютерах с более новой версией Windows, вам нужно будет подписать драйвер, поскольку Windows Vista x64 и новее не будет загружать не подписанные драйверы, это разрешено делать только в версии x86 этих операционных систем. И вы рискуете получить немного забавного BSOD.
Официальным примером Microsoft для драйвера фильтра клавиатуры является kbfiltr образец.
Теперь есть гораздо более простой способ обойти все это: использовать некоторую библиотеку, которая взаимодействует с драйвером, чтобы выполнить всю эту грязную работу. И это то, что я пытался сделать.
Я разработал библиотеку, которую я называю Перехват , которая позволяет, ну ... перехватывать ввод устройства из обычной программы пользовательского режима при использовании полномочий драйвера устройства. Это небольшой и простой C api, который внутренне взаимодействует с драйверами, которые я правильно подписал.
Вы должны использовать installer для установки драйверов в вашей системе перед использованием API.
На моем веб-сайте уже есть образец для перехвата SAS, и вы также можете проверить его здесь , на github. Я оставлю это здесь для справки:
#include <iostream>
#include <utils.h>
#include <interception.h>
using namespace std;
namespace scancode {
enum {
esc = 0x01,
ctrl = 0x1D,
alt = 0x38,
del = 0x53,
};
}
InterceptionKeyStroke ctrl_down = {scancode::ctrl, INTERCEPTION_KEY_DOWN , 0};
InterceptionKeyStroke alt_down = {scancode::alt , INTERCEPTION_KEY_DOWN , 0};
InterceptionKeyStroke del_down = {scancode::del , INTERCEPTION_KEY_DOWN | INTERCEPTION_KEY_E0, 0};
InterceptionKeyStroke ctrl_up = {scancode::ctrl, INTERCEPTION_KEY_UP , 0};
InterceptionKeyStroke alt_up = {scancode::alt , INTERCEPTION_KEY_UP , 0};
InterceptionKeyStroke del_up = {scancode::del , INTERCEPTION_KEY_UP | INTERCEPTION_KEY_E0 , 0};
bool operator==(const InterceptionKeyStroke &first,
const InterceptionKeyStroke &second) {
return first.code == second.code && first.state == second.state;
}
bool shall_produce_keystroke(const InterceptionKeyStroke &kstroke) {
static int ctrl_is_down = 0, alt_is_down = 0, del_is_down = 0;
if (ctrl_is_down + alt_is_down + del_is_down < 2) {
if (kstroke == ctrl_down) { ctrl_is_down = 1; }
if (kstroke == ctrl_up ) { ctrl_is_down = 0; }
if (kstroke == alt_down ) { alt_is_down = 1; }
if (kstroke == alt_up ) { alt_is_down = 0; }
if (kstroke == del_down ) { del_is_down = 1; }
if (kstroke == del_up ) { del_is_down = 0; }
return true;
}
if (ctrl_is_down == 0 && (kstroke == ctrl_down || kstroke == ctrl_up)) {
return false;
}
if (alt_is_down == 0 && (kstroke == alt_down || kstroke == alt_up)) {
return false;
}
if (del_is_down == 0 && (kstroke == del_down || kstroke == del_up)) {
return false;
}
if (kstroke == ctrl_up) {
ctrl_is_down = 0;
} else if (kstroke == alt_up) {
alt_is_down = 0;
} else if (kstroke == del_up) {
del_is_down = 0;
}
return true;
}
int main() {
InterceptionContext context;
InterceptionDevice device;
InterceptionKeyStroke kstroke;
raise_process_priority();
context = interception_create_context();
interception_set_filter(context, interception_is_keyboard,
INTERCEPTION_FILTER_KEY_ALL);
while (interception_receive(context, device = interception_wait(context),
(InterceptionStroke *)&kstroke, 1) > 0) {
if (!shall_produce_keystroke(kstroke)) {
cout << "ctrl-alt-del pressed" << endl;
continue;
}
interception_send(context, device, (InterceptionStroke *)&kstroke, 1);
if (kstroke.code == scancode::esc)
break;
}
interception_destroy_context(context);
return 0;
}