sas.c
来自「一个类似windows」· C语言 代码 · 共 291 行
C
291 行
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/winlogon/sas.c
* PURPOSE: Secure Attention Sequence
* PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
* UPDATE HISTORY:
* Created 28/03/2004
*/
#include "winlogon.h"
#define NDEBUG
#include <debug.h>
#define WINLOGON_SAS_CLASS L"SAS window class"
#define WINLOGON_SAS_TITLE L"SAS"
#define HK_CTRL_ALT_DEL 0
#define HK_CTRL_SHIFT_ESC 1
#ifdef __USE_W32API
extern BOOL STDCALL SetLogonNotifyWindow(HWND Wnd, HWINSTA WinSta);
#endif
void
DispatchSAS(PWLSESSION Session, DWORD dwSasType)
{
Session->SASAction = dwSasType;
}
void
UninitSAS(PWLSESSION Session)
{
if(Session->SASWindow)
{
DestroyWindow(Session->SASWindow);
Session->SASWindow = NULL;
}
}
BOOL
SetupSAS(PWLSESSION Session, HWND hwndSAS)
{
/* Register Ctrl+Alt+Del Hotkey */
if(!RegisterHotKey(hwndSAS, HK_CTRL_ALT_DEL, MOD_CONTROL | MOD_ALT, VK_DELETE))
{
DPRINT1("WL-SAS: Unable to register Ctrl+Alt+Del hotkey!\n");
return FALSE;
}
/* Register Ctrl+Shift+Esc */
Session->TaskManHotkey = RegisterHotKey(hwndSAS, HK_CTRL_SHIFT_ESC, MOD_CONTROL | MOD_SHIFT, VK_ESCAPE);
if(!Session->TaskManHotkey)
{
DPRINT1("WL-SAS: Warning: Unable to register Ctrl+Alt+Esc hotkey!\n");
}
return TRUE;
}
BOOL
DestroySAS(PWLSESSION Session, HWND hwndSAS)
{
/* Unregister hotkeys */
UnregisterHotKey(hwndSAS, HK_CTRL_ALT_DEL);
if(Session->TaskManHotkey)
{
UnregisterHotKey(hwndSAS, HK_CTRL_SHIFT_ESC);
}
return TRUE;
}
#define EWX_ACTION_MASK 0xffffffeb
#define EWX_FLAGS_MASK 0x00000014
typedef struct tagLOGOFF_SHUTDOWN_DATA
{
UINT Flags;
PWLSESSION Session;
} LOGOFF_SHUTDOWN_DATA, *PLOGOFF_SHUTDOWN_DATA;
static DWORD WINAPI
LogoffShutdownThread(LPVOID Parameter)
{
PLOGOFF_SHUTDOWN_DATA LSData = (PLOGOFF_SHUTDOWN_DATA) Parameter;
if (! ImpersonateLoggedOnUser(LSData->Session->UserToken))
{
DPRINT1("ImpersonateLoggedOnUser failed with error %d\n", GetLastError());
return 0;
}
if (! ExitWindowsEx(EWX_INTERNAL_KILL_USER_APPS | (LSData->Flags & EWX_FLAGS_MASK)
| (EWX_LOGOFF == (LSData->Flags & EWX_ACTION_MASK) ? EWX_INTERNAL_FLAG_LOGOFF : 0),
0))
{
DPRINT1("Unable to kill user apps, error %d\n", GetLastError());
RevertToSelf();
return 0;
}
RevertToSelf();
HeapFree(GetProcessHeap(), 0, LSData);
return 1;
}
static LRESULT
HandleExitWindows(PWLSESSION Session, DWORD RequestingProcessId, UINT Flags)
{
UINT Action;
HANDLE Process;
HANDLE Token;
HANDLE Thread;
BOOL CheckResult;
PPRIVILEGE_SET PrivSet;
PLOGOFF_SHUTDOWN_DATA LSData;
/* Check parameters */
Action = Flags & EWX_ACTION_MASK;
if (EWX_LOGOFF != Action && EWX_SHUTDOWN != Action && EWX_REBOOT != Action
&& EWX_POWEROFF != Action)
{
DPRINT1("Invalid ExitWindows action 0x%x\n", Action);
return STATUS_INVALID_PARAMETER;
}
/* Check privilege */
if (EWX_LOGOFF != Action)
{
Process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, RequestingProcessId);
if (NULL == Process)
{
DPRINT1("OpenProcess failed with error %d\n", GetLastError());
return STATUS_INVALID_HANDLE;
}
if (! OpenProcessToken(Process, TOKEN_QUERY, &Token))
{
DPRINT1("OpenProcessToken failed with error %d\n", GetLastError());
CloseHandle(Process);
return STATUS_INVALID_HANDLE;
}
CloseHandle(Process);
PrivSet = HeapAlloc(GetProcessHeap(), 0, sizeof(PRIVILEGE_SET) + sizeof(LUID_AND_ATTRIBUTES));
if (NULL == PrivSet)
{
DPRINT1("Failed to allocate mem for privilege set\n");
CloseHandle(Token);
return STATUS_NO_MEMORY;
}
PrivSet->PrivilegeCount = 1;
PrivSet->Control = PRIVILEGE_SET_ALL_NECESSARY;
if (! LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &PrivSet->Privilege[0].Luid))
{
DPRINT1("LookupPrivilegeValue failed with error %d\n", GetLastError());
HeapFree(GetProcessHeap(), 0, PrivSet);
CloseHandle(Token);
return STATUS_UNSUCCESSFUL;
}
if (! PrivilegeCheck(Token, PrivSet, &CheckResult))
{
DPRINT1("PrivilegeCheck failed with error %d\n", GetLastError());
HeapFree(GetProcessHeap(), 0, PrivSet);
CloseHandle(Token);
return STATUS_ACCESS_DENIED;
}
HeapFree(GetProcessHeap(), 0, PrivSet);
CloseHandle(Token);
if (! CheckResult)
{
DPRINT1("SE_SHUTDOWN privilege not enabled\n");
return STATUS_ACCESS_DENIED;
}
}
LSData = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGOFF_SHUTDOWN_DATA));
if (NULL == LSData)
{
DPRINT1("Failed to allocate mem for thread data\n");
return STATUS_NO_MEMORY;
}
LSData->Flags = Flags;
LSData->Session = Session;
Thread = CreateThread(NULL, 0, LogoffShutdownThread, (LPVOID) LSData, 0, NULL);
if (NULL == Thread)
{
DPRINT1("Unable to create shutdown thread, error %d\n", GetLastError());
HeapFree(GetProcessHeap(), 0, LSData);
return STATUS_UNSUCCESSFUL;
}
CloseHandle(Thread);
return 1;
}
LRESULT CALLBACK
SASProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
PWLSESSION Session = (PWLSESSION)GetWindowLongPtr(hwnd, GWLP_USERDATA);
if(!Session)
{
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
switch(uMsg)
{
case WM_HOTKEY:
{
switch(wParam)
{
case HK_CTRL_ALT_DEL:
DPRINT1("SAS: CTR+ALT+DEL\n");
break;
case HK_CTRL_SHIFT_ESC:
DPRINT1("SAS: CTR+SHIFT+ESC\n");
break;
}
return 0;
}
case WM_CREATE:
{
/* Get the session pointer from the create data */
Session = (PWLSESSION)((LPCREATESTRUCT)lParam)->lpCreateParams;
/* Save the Session pointer */
SetWindowLongPtr(Session->SASWindow, GWLP_USERDATA, (DWORD_PTR)Session);
if(!SetupSAS(Session, hwnd))
{
/* Fail! */
return 1;
}
return 0;
}
case PM_WINLOGON_EXITWINDOWS:
{
return HandleExitWindows(Session, (DWORD) wParam, (UINT) lParam);
}
case WM_DESTROY:
{
DestroySAS(Session, hwnd);
return 0;
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
BOOL
InitializeSAS(PWLSESSION Session)
{
WNDCLASSEX swc;
/* register SAS window class.
WARNING! MAKE SURE WE ARE IN THE WINLOGON DESKTOP! */
swc.cbSize = sizeof(WNDCLASSEXW);
swc.style = CS_SAVEBITS;
swc.lpfnWndProc = SASProc;
swc.cbClsExtra = 0;
swc.cbWndExtra = 0;
swc.hInstance = hAppInstance;
swc.hIcon = NULL;
swc.hCursor = NULL;
swc.hbrBackground = NULL;
swc.lpszMenuName = NULL;
swc.lpszClassName = WINLOGON_SAS_CLASS;
swc.hIconSm = NULL;
RegisterClassEx(&swc);
/* create invisible SAS window */
Session->SASWindow = CreateWindowEx(0, WINLOGON_SAS_CLASS, WINLOGON_SAS_TITLE, WS_POPUP,
0, 0, 0, 0, 0, 0, hAppInstance, Session);
if(!Session->SASWindow)
{
DPRINT1("WL: Failed to create SAS window\n");
return FALSE;
}
/* Register SAS window to receive SAS notifications */
if(!SetLogonNotifyWindow(Session->SASWindow, Session->InteractiveWindowStation))
{
UninitSAS(Session);
DPRINT1("WL: Failed to register SAS window\n");
return FALSE;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?