ctrl+alt+del emulation checkpoint.

This commit is contained in:
crs
2003-06-08 22:12:12 +00:00
parent 921526ab56
commit 784ab183ae
5 changed files with 119 additions and 7 deletions

View File

@@ -16,6 +16,8 @@
#include "CMSWindowsScreen.h"
#include "XScreen.h"
#include "CLock.h"
#include "CThread.h"
#include "CFunctionJob.h"
#include "CLog.h"
#include "CArchMiscWindows.h"
#include <cctype>
@@ -94,6 +96,14 @@ CMSWindowsSecondaryScreen::keyDown(KeyID key,
CLock lock(&m_mutex);
m_screen->syncDesktop();
// check for ctrl+alt+del emulation
if (key == kKeyDelete &&
(mask & (KeyModifierControl | KeyModifierAlt)) ==
(KeyModifierControl | KeyModifierAlt)) {
synthesizeCtrlAltDel();
return;
}
// get the sequence of keys to simulate key press and the final
// modifier state.
m_mask = mapKey(keys, virtualKey, key, mask, kPress);
@@ -1517,3 +1527,52 @@ CMSWindowsSecondaryScreen::getCodePageFromLangID(LANGID langid) const
return codePage;
}
void
CMSWindowsSecondaryScreen::synthesizeCtrlAltDel()
{
LOG((CLOG_DEBUG "emulating ctrl+alt+del"));
if (!m_is95Family) {
// to fake ctrl+alt+del on the NT family we broadcast a suitable
// hotkey to all windows on the winlogon desktop. however, we
// the current thread must be on that desktop to do the broadcast
// and we can't switch just any thread because some own windows
// or hooks. so start a new thread to do the real work.
CThread cad(new CFunctionJob(
&CMSWindowsSecondaryScreen::ctrlAltDelThread));
cad.wait();
}
else {
Keystrokes keys;
UINT virtualKey;
KeyID key = kKeyDelete;
KeyModifierMask mask = KeyModifierControl | KeyModifierAlt;
// get the sequence of keys to simulate ctrl+alt+del
mapKey(keys, virtualKey, key, mask, kPress);
if (!keys.empty()) {
// generate key events
doKeystrokes(keys, 1);
}
}
}
void
CMSWindowsSecondaryScreen::ctrlAltDelThread(void*)
{
// get the Winlogon desktop at whatever privilege we can
HDESK desk = OpenDesktop("Winlogon", 0, FALSE, MAXIMUM_ALLOWED);
if (desk != NULL) {
if (SetThreadDesktop(desk)) {
PostMessage(HWND_BROADCAST, WM_HOTKEY, 0,
MAKELPARAM(MOD_CONTROL | MOD_ALT, VK_DELETE));
}
else {
LOG((CLOG_DEBUG "can't switch to Winlogon desk: %d", GetLastError()));
}
CloseDesktop(desk);
}
else {
LOG((CLOG_DEBUG "can't open Winlogon desk: %d", GetLastError()));
}
}