15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Как запретить Ctrl-Alt-Del или Alt-Tab в Windows XP.

Компилятор: Visual C++ 6.0

Автор: Paul DiLascia

Скачать исходник к статье - 56 Кб

   Наверное, нет такого программиста, который не догадывается для чего необходимо отключать так называемую "комбинацию из трёх пальцев". В первую очередь это необходимо, чтобы пользователь не смог заметить приложение удалённого управления его компьютером (в простонародье называемым Троянским конём). Однако, есть и масса других случаев, когда необходимо запретить Ctrl+Alt+Del. Так же, справедливости ради, стоит заметить, что очень часто вызов менеджера задач, это единственный способ снять зависшее приложение.

   В таких операционных системах как Windows 95, Windows 98 и Windows Me можно запретить Ctrl+Alt+Del (а так же любые другие комбинации клавиш для переключения задач), введя операционную систему в заблуждение, заставив её думать, что запущен скринсейвер, следующей командой:

BOOL bOldState;
SystemParametersInfo(SPI_SETSCREENSAVERRUNNING, TRUE, &bOldState, 0);

   Однако, такая команда не сработает в Windows NT®, Windows 2000 и Windows XP. Эти версии операционных систем используют Winlogon и GINA (сокращение от Graphical Identification and Authentication). Winlogon это часть Windows, которая обеспечивает интерактивный вход в систему, а GINA, это DLL, которую использует Winlogon, для проведения авторизации. DLL GINA экспортирует некоторые функции, такие как WlxInitialize для инициализации самой себя и WlxActivateUserShell для запуска пользовательского шелла. Для проведения обычной авторизации по имени и паролю в Windows используется msgina.dll, однако, любой разработчик (т.е. Вы) спокойно может заменить msgina.dll своей собственной GINA. Например, это может потребоваться для включения авторизации по смарткартам, retinal-scan, DNA-check, или Divine Awareness  и т.д.

В Таблице приведён полный список функций GINA. Одна из них WlxLoggedOnSAS, которая вызывается Winlogon-ом когда он получает "secure attention sequence," больше известную как Ctrl+Alt+Del. По умолчанию GINA отображает диалог входа в систему и Вы начинаете авторизоваться.... Один из способов запретить Ctrl+Alt+Del, это написать новую MyGina.dll с заглушками, которые будут вызывать старую msgina.dll и перехватить нужным образом WlxLoggedOnSAS. Второй способ, это написание драйвера клавиатуры.

   Оба выше перечисленных способа требуют приложить давольно много усилий. Есть конечно и более простые способы. Например, чтобы запретить Ctrl+Alt+Del достаточно установить политики. Для этого идём в меню "Пуск", выбираем Выполнить...(Run), и запускаем Редактор Политики Групп ("gpedit.msc"). Смотрим в User Configuration | Administrative Templates | System и там уже можно найти секцию с именем Ctrl+Alt+Del Options:

"Remove Task Manager" это тот самый ключ, который запрещает Ctrl+Alt+Del. Программно можно просто добавить в реестр ключ:

HKCU\
 Software\
  Microsoft\
   Windows\
    CurrentVersion\
     Policies\
      System\DisableTaskMgr = dword:1

Теперь, если пользователь нажмёт Ctrl+Alt+Del, то получит сообщение:

 

   Итак, это первая половина ответа в опросе запрета Ctrl+Alt+Del в Windows XP. Я предполагаю, что Вы уже отключили Ctrl+Alt+Del для входа в систему установив "Use the Welcome screen" в Control Panel | User Accounts:

иначе Вы бы не спрашивали про Менеджер задач. Если же Вы не используете экран Welcome, то установка DisableTaskMgr запрещает кнопку Менеджера задач в диалоге входа/выхода из системы.

   Ключ DisableTaskMgr является недокументированным, и я обнаружил его через GPEDIT. GPEDIT очень полезная утилитка, которая позволяет контролировать многие аспекты Windows, от прав доступа до классического вида Microsoft® Internet Explorer; от отображения панели Places в диалогах до разрешения вызова Менеджера задач при помощи Ctrl+Alt+Del. При помощи этой утилиты можно изменить сотни настроек пользовательского интерфейса, заставив системного администратор пускать слюни :)

   Каков механизм поиска в реестре определённой политики? Есть два способа. Первый, это "в лоб": экспортируя ключи реестра в файл .reg, а затем изменяя политики и сравнивая различия. Все политики находятся в одном из четырёх ключей:

// относятся к данному пользователю
HKEY_CURRENT_USER\Software\Policies 
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies

// относятся к локальной машине
HKEY_LOCAL_MACHINE\Software\Policies 
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies

   Второй способ заключается в исследовании административных шаблонов (файлы .adm), которые описаны в политиках. Ниже представлен отрывок из \windows\system32\GroupPolicy\Adm\system.adm, который описывает DisableTaskMgr:

CATEGORY !!CADOptions
    #if version >= 4
        EXPLAIN !!CADOptions_Help
    #endif
    KEYNAME "Software\Microsoft\Windows\CurrentVersion\Policies\System"

    POLICY !!DisableTaskMgr    
        #if version >= 4
            SUPPORTED !!SUPPORTED_Win2k
        #endif

        EXPLAIN !!DisableTaskMgr_Help
        VALUENAME "DisableTaskMgr"
    END POLICY

    ;
    ; More Ctrl+Alt+Del policies here...
    ;

END CATEGORY ; Ctrl+Alt+Del options

•••

DisableTaskMgr_Help="Prevents users from starting Task Manager 
(Taskmgr.exe).\n\nIf this setting is enabled and users try to start
Task Manager, a message appears explaining that a policy prevents the 
action.\n\nTask Manager lets users start and stop programs; monitor the 
performance of their computers; view and monitor all programs running 
on their computers, including system services; find the executable 
names of programs; and change the priority of the process in which 
programs run."

DisableTaskMgr="Remove Task Manager"

   Для указания ключа в реестре и его значения используются две основные команды KEYNAME и VALUENAME. Вы можете создать свой собственный административный шаблон и политики для своего приложения, но редактировать его нужно редактором, поддерживающим Unicode. Мой любимы Epsilon 11.0, но Notepad и WordPad тоже подойдут. Административные шаблоны позволяют сисадмину конфигурировать системы в масштабах предприятия (вот где сила!). Более подробно см. "Administrative Template File Format" в Platform SDK.

   Перед тем как двинуться дальше, позвольте заметить, что DisableTaskMgr позволяет запретить Ctrl+Alt+Del, но не перехватить её. Для перехвата Ctrl+Alt+Del, необходима любая из трёх вещей: написать собственную заглушку для GINA, написать драйвер клавиатуры, или заменить TaskMgr.exe собственной программой.

   Теперь давайте посмотрим, что можно сделать с комбинацией Alt+Tab и другими клавишами переключения задач. Например, в Windows 3.1, можно было обработать WM_SYSKEYDOWN. В Windows 95 и Windows 98 срабатывает тот же обманный метод SPI_SETSCREENSAVERRUNNING, который я упоминал в самом начале статьи. Но опять же, в Windows NT 4.0 (SP3 и позже), Windows 2000, и Windows XP эти штучки не пройдут. Прийдётся писать низкоуровневую ловушку для клавиатуры. Уж извиняйте. Впринципе это не так сложно. В Примере демонстрируется DLL (TaskKeyHook.dll), которую я написал и, которая делает всю необходимую работу. TaskKeyHook экспортирует две функции, DisableTaskKeys и AreTaskKeysDisabled. Первая устанавливает ловушку WH_KEYBOARD_LL; а вторая сообщает - установлена ли ловушка. Сама по себе процедура ловушки перехватывает Alt+Tab, Ctrl+Esc, Alt+Esc, а так же виндузовык клавиши (VK_LWIN и VK_RWIN, о которых я расскажу ниже). Как только срабатывает одна из этих комбинаций клавиш, то управление передаётся сразу же в вызывающую программу, и не происходит вызова CallNextHookEx.

LRESULT CALLBACK MyTaskKeyHookLL(...)
{
   if (/* нужная комбинация клавиш *)
      return 1;
   return CallNextHookEx(...);
}

   Код TaskKeyHook не сложен. Единственная хитрость заключается в использовании #pragma data_seg для имени сегмента данных, который содержит глобальные данные, и #pragma comment (linker...), чтобы указать линковщику сделать этот сегмент доступным (расшаренным).


Рисунок 7 TrapKeys

   Так же я написал небольшую программу TrapKeys (см. Рисунок 7 и Пример), которая совмещает всё вместе: DisableTaskMgr, клавиатурную ловушку, и запрещение панели задач. Если уж Вам понадобится запретить переключение задач, то возможно потребуется и запрещение самой панели задач:

HWND hwnd = FindWindow("Shell_traywnd", NULL);
EnableWindow(hwnd, FALSE); // запрещаем его

   Здесь присутствует небольшая причуда. Если Вы запретите панель задач, а затем нажмёте клавишу Windows (которая находится на клавиатуре между Ctrl и Alt), то откроется меню Пуск. Упс! Очевидно, панель задач перед нажатием VK_LWIN не проверяет - доступна она или нет. Если окно заблокировано (после вызова EnableWindow(FALSE)), то оно не должно обрабатывать пользовательский ввод. Похоже, что обработка VK_LWIN происходит каким-то другим способом, поэтому мне пришлось добавить обработку таких клавиш в TaskKeyHook. Теперь, если нажать клавишу меню Пуск, то ничего не произойдёт.

   Чтобы облегчить жизнь, я включил все запрещающие функции в класс CTaskKeyMgr (см. Пример). Все функции статические. Вы можете спокойно использовать этот класс в своих приложениях для блокирования переключения задач, а так же для блокирования самой панели задач. Например, чтобы заблокировать переключение задач или саму панель задач, но не Ctrl+Alt+Del, достаточно вызвать следующий метод:

CTaskKeyMgr::Disable(CTaskKeyMgr::TASKKEYS |
                     CTaskKeyMgr::TASKBAR, TRUE);

Так же в классе присутствуют функции для определения, что в данный момент заблокировано и можно даже подать звуковой сигнал, если пользователь нажмёт одну из ключевых комбинаций клавиш.

При публикации материала ссылка на сайт обязательна!