ReactOS 0.4.16-dev-1505-g12fa72a
sas.c File Reference
#include "winlogon.h"
#include <aclapi.h>
#include <mmsystem.h>
#include <userenv.h>
#include <ndk/setypes.h>
#include <ndk/sefuncs.h>
Include dependency graph for sas.c:

Go to the source code of this file.

Classes

struct  tagLOGOFF_SHUTDOWN_DATA
 
struct  tagLOGON_SOUND_DATA
 

Macros

#define WIN32_LEAN_AND_MEAN
 
#define WINLOGON_SAS_CLASS   L"SAS Window class"
 
#define WINLOGON_SAS_TITLE   L"SAS window"
 
#define IDHK_CTRL_ALT_DEL   0
 
#define IDHK_CTRL_SHIFT_ESC   1
 
#define IDHK_WIN_L   2
 
#define IDHK_WIN_U   3
 
#define EWX_ACTION_MASK   0x5C0F
 

Typedefs

typedef struct tagLOGOFF_SHUTDOWN_DATA LOGOFF_SHUTDOWN_DATA
 
typedef struct tagLOGOFF_SHUTDOWN_DATAPLOGOFF_SHUTDOWN_DATA
 
typedef struct tagLOGON_SOUND_DATA LOGON_SOUND_DATA
 
typedef struct tagLOGON_SOUND_DATAPLOGON_SOUND_DATA
 

Functions

static BOOL StartTaskManager (IN OUT PWLSESSION Session)
 
static BOOL StartUserShell (IN OUT PWLSESSION Session)
 
BOOL SetDefaultLanguage (IN PWLSESSION Session)
 
BOOL PlaySoundRoutine (IN LPCWSTR FileName, IN UINT bLogon, IN UINT Flags)
 
static DWORD WINAPI PlayLogonSoundThread (_In_ LPVOID lpParameter)
 
static VOID PlayLogonSound (_In_ PWLSESSION Session)
 
static VOID PlayLogoffShutdownSound (_In_ PWLSESSION Session, _In_ BOOL bShutdown)
 
static BOOL PlayEventSound (_In_ PWLSESSION Session, _In_ LPCWSTR EventName)
 
static VOID RestoreAllConnections (PWLSESSION Session)
 
static VOID FreeWlxProfileInfo (_Inout_ PVOID Profile)
 Frees the Profile information structure (WLX_PROFILE_V1_0 or WLX_PROFILE_V2_0) allocated by the GINA.
 
static VOID FreeWlxMprInfo (_Inout_ PWLX_MPR_NOTIFY_INFO MprNotifyInfo)
 Frees the MPR information structure allocated by the GINA.
 
static BOOL HandleLogon (IN OUT PWLSESSION Session)
 
static DWORD WINAPI LogoffShutdownThread (LPVOID Parameter)
 
static NTSTATUS RunLogoffShutdownThread (_In_ PWLSESSION Session, _In_opt_ PSECURITY_ATTRIBUTES psa, _In_ DWORD wlxAction)
 
static DWORD WINAPI KillComProcesses (LPVOID Parameter)
 
static NTSTATUS CreateLogoffSecurityAttributes (OUT PSECURITY_ATTRIBUTES *ppsa)
 
static VOID DestroyLogoffSecurityAttributes (IN PSECURITY_ATTRIBUTES psa)
 
static NTSTATUS HandleLogoff (_Inout_ PWLSESSION Session, _In_ DWORD wlxAction)
 
static INT_PTR CALLBACK ShutdownComputerWindowProc (IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam)
 
static VOID UninitializeSAS (IN OUT PWLSESSION Session)
 
NTSTATUS HandleShutdown (IN OUT PWLSESSION Session, IN DWORD wlxAction)
 
static VOID DoGenericAction (IN OUT PWLSESSION Session, IN DWORD wlxAction)
 
static VOID DispatchSAS (IN OUT PWLSESSION Session, IN DWORD dwSasType)
 
static BOOL RegisterHotKeys (IN PWLSESSION Session, IN HWND hwndSAS)
 
static BOOL UnregisterHotKeys (IN PWLSESSION Session, IN HWND hwndSAS)
 
static BOOL HandleMessageBeep (_In_ PWLSESSION Session, _In_ UINT uType)
 
static LRESULT CALLBACK SASWindowProc (IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam)
 
BOOL InitializeSAS (IN OUT PWLSESSION Session)
 

Variables

static BOOL ExitReactOSInProgress = FALSE
 
LUID LuidNone = {0, 0}
 

Macro Definition Documentation

◆ EWX_ACTION_MASK

#define EWX_ACTION_MASK   0x5C0F

Definition at line 39 of file sas.c.

◆ IDHK_CTRL_ALT_DEL

#define IDHK_CTRL_ALT_DEL   0

Definition at line 29 of file sas.c.

◆ IDHK_CTRL_SHIFT_ESC

#define IDHK_CTRL_SHIFT_ESC   1

Definition at line 30 of file sas.c.

◆ IDHK_WIN_L

#define IDHK_WIN_L   2

Definition at line 31 of file sas.c.

◆ IDHK_WIN_U

#define IDHK_WIN_U   3

Definition at line 32 of file sas.c.

◆ WIN32_LEAN_AND_MEAN

#define WIN32_LEAN_AND_MEAN

Definition at line 17 of file sas.c.

◆ WINLOGON_SAS_CLASS

#define WINLOGON_SAS_CLASS   L"SAS Window class"

Definition at line 26 of file sas.c.

◆ WINLOGON_SAS_TITLE

#define WINLOGON_SAS_TITLE   L"SAS window"

Definition at line 27 of file sas.c.

Typedef Documentation

◆ LOGOFF_SHUTDOWN_DATA

◆ LOGON_SOUND_DATA

◆ PLOGOFF_SHUTDOWN_DATA

◆ PLOGON_SOUND_DATA

Function Documentation

◆ CreateLogoffSecurityAttributes()

static NTSTATUS CreateLogoffSecurityAttributes ( OUT PSECURITY_ATTRIBUTES ppsa)
static

Definition at line 873 of file sas.c.

875{
876 /* The following code is not working yet and messy */
877 /* Still, it gives some ideas about data types and functions involved and */
878 /* required to set up a SECURITY_DESCRIPTOR for a SECURITY_ATTRIBUTES */
879 /* instance for a thread, to allow that thread to ImpersonateLoggedOnUser(). */
880 /* Specifically THREAD_SET_THREAD_TOKEN is required. */
883 BYTE* pMem;
884 PACL pACL;
885 EXPLICIT_ACCESS Access;
886 PSID pEveryoneSID = NULL;
888
889 *ppsa = NULL;
890
891 // Let's first try to enumerate what kind of data we need for this to ever work:
892 // 1. The Winlogon SID, to be able to give it THREAD_SET_THREAD_TOKEN.
893 // 2. The users SID (the user trying to logoff, or rather shut down the system).
894 // 3. At least two EXPLICIT_ACCESS instances:
895 // 3.1 One for Winlogon itself, giving it the rights
896 // required to THREAD_SET_THREAD_TOKEN (as it's needed to successfully call
897 // ImpersonateLoggedOnUser).
898 // 3.2 One for the user, to allow *that* thread to perform its work.
899 // 4. An ACL to hold the these EXPLICIT_ACCESS ACE's.
900 // 5. A SECURITY_DESCRIPTOR to hold the ACL, and finally.
901 // 6. A SECURITY_ATTRIBUTES instance to pull all of this required stuff
902 // together, to hand it to CreateThread.
903 //
904 // However, it seems struct LOGOFF_SHUTDOWN_DATA doesn't contain
905 // these required SID's, why they'd have to be added.
906 // The Winlogon's own SID should probably only be created once,
907 // while the user's SID obviously must be created for each new user.
908 // Might as well store it when the user logs on?
909
911 1,
913 0, 0, 0, 0, 0, 0, 0,
914 &pEveryoneSID))
915 {
916 ERR("Failed to initialize security descriptor for logoff thread!\n");
917 return STATUS_UNSUCCESSFUL;
918 }
919
920 /* set up the required security attributes to be able to shut down */
921 /* To save space and time, allocate a single block of memory holding */
922 /* both SECURITY_ATTRIBUTES and SECURITY_DESCRIPTOR */
923 pMem = HeapAlloc(GetProcessHeap(),
924 0,
925 sizeof(SECURITY_ATTRIBUTES) +
927 sizeof(ACL));
928 if (!pMem)
929 {
930 ERR("Failed to allocate memory for logoff security descriptor!\n");
931 return STATUS_NO_MEMORY;
932 }
933
934 /* Note that the security descriptor needs to be in _absolute_ format, */
935 /* meaning its members must be pointers to other structures, rather */
936 /* than the relative format using offsets */
940
941 // Initialize an EXPLICIT_ACCESS structure for an ACE.
942 // The ACE will allow this thread to log off (and shut down the system, currently).
943 ZeroMemory(&Access, sizeof(Access));
945 Access.grfAccessMode = SET_ACCESS; // GRANT_ACCESS?
949 Access.Trustee.ptstrName = pEveryoneSID;
950
951 if (SetEntriesInAcl(1, &Access, NULL, &pACL) != ERROR_SUCCESS)
952 {
953 ERR("Failed to set Access Rights for logoff thread. Logging out will most likely fail.\n");
954
955 HeapFree(GetProcessHeap(), 0, pMem);
956 return STATUS_UNSUCCESSFUL;
957 }
958
960 {
961 ERR("Failed to initialize security descriptor for logoff thread!\n");
962 HeapFree(GetProcessHeap(), 0, pMem);
963 return STATUS_UNSUCCESSFUL;
964 }
965
967 TRUE, // bDaclPresent flag
968 pACL,
969 FALSE)) // not a default DACL
970 {
971 ERR("SetSecurityDescriptorDacl Error %lu\n", GetLastError());
972 HeapFree(GetProcessHeap(), 0, pMem);
973 return STATUS_UNSUCCESSFUL;
974 }
975
976 psa->nLength = sizeof(SECURITY_ATTRIBUTES);
977 psa->lpSecurityDescriptor = SecurityDescriptor;
978 psa->bInheritHandle = FALSE;
979
980 *ppsa = psa;
981
982 return STATUS_SUCCESS;
983}
@ TRUSTEE_IS_SID
Definition: accctrl.h:189
@ TRUSTEE_IS_WELL_KNOWN_GROUP
Definition: accctrl.h:181
#define NO_INHERITANCE
Definition: accctrl.h:103
@ SET_ACCESS
Definition: accctrl.h:150
#define SetEntriesInAcl
Definition: aclapi.h:240
#define ERR(fmt,...)
Definition: precomp.h:57
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOL WINAPI AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, BYTE nSubAuthorityCount, DWORD nSubAuthority0, DWORD nSubAuthority1, DWORD nSubAuthority2, DWORD nSubAuthority3, DWORD nSubAuthority4, DWORD nSubAuthority5, DWORD nSubAuthority6, DWORD nSubAuthority7, PSID *pSid)
Definition: security.c:674
BOOL WINAPI InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD dwRevision)
Definition: security.c:929
#define GetProcessHeap()
Definition: compat.h:736
struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES
#define HeapAlloc
Definition: compat.h:733
struct _SECURITY_ATTRIBUTES * PSECURITY_ATTRIBUTES
#define HeapFree(x, y, z)
Definition: compat.h:735
static SID_IDENTIFIER_AUTHORITY WorldAuthority
Definition: security.c:14
#define THREAD_SET_THREAD_TOKEN
Definition: pstypes.h:151
static SCRIPT_CACHE SCRIPT_ANALYSIS * psa
Definition: usp10.c:64
struct _SECURITY_DESCRIPTOR * PSECURITY_DESCRIPTOR
Definition: security.c:98
struct _ACL * PACL
Definition: security.c:105
BYTE * PBYTE
Definition: pedump.c:66
BOOL WINAPI SetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR pSecurityDescriptor, BOOL bDaclPresent, PACL pDacl, BOOL bDaclDefaulted)
Definition: sec.c:262
#define STATUS_SUCCESS
Definition: shellext.h:65
DWORD grfAccessPermissions
Definition: accctrl.h:332
TRUSTEE_A Trustee
Definition: accctrl.h:335
DWORD grfInheritance
Definition: accctrl.h:334
ACCESS_MODE grfAccessMode
Definition: accctrl.h:333
TRUSTEE_TYPE TrusteeType
Definition: accctrl.h:207
TRUSTEE_FORM TrusteeForm
Definition: accctrl.h:206
LPSTR ptstrName
Definition: accctrl.h:208
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ZeroMemory
Definition: winbase.h:1753
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:191
#define SECURITY_WORLD_SID_AUTHORITY
Definition: setypes.h:527
#define SECURITY_WORLD_RID
Definition: setypes.h:541
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define SECURITY_DESCRIPTOR_MIN_LENGTH
Definition: setypes.h:827
unsigned char BYTE
Definition: xxhash.c:193

Referenced by HandleLogoff().

◆ DestroyLogoffSecurityAttributes()

static VOID DestroyLogoffSecurityAttributes ( IN PSECURITY_ATTRIBUTES  psa)
static

Definition at line 987 of file sas.c.

989{
990 if (psa)
991 {
993 }
994}

Referenced by HandleLogoff().

◆ DispatchSAS()

static VOID DispatchSAS ( IN OUT PWLSESSION  Session,
IN DWORD  dwSasType 
)
static

Definition at line 1283 of file sas.c.

1286{
1287 DWORD wlxAction = WLX_SAS_ACTION_NONE;
1288 PSID LogonSid = NULL; /* FIXME */
1289 BOOL bSecure = TRUE;
1290
1291 switch (dwSasType)
1292 {
1294 switch (Session->LogonState)
1295 {
1296 case STATE_INIT:
1297 Session->LogonState = STATE_LOGGED_OFF;
1298 Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context);
1299 return;
1300
1301 case STATE_LOGGED_OFF:
1302 Session->LogonState = STATE_LOGGED_OFF_SAS;
1303
1305
1306 Session->Options = 0;
1307
1308 wlxAction = (DWORD)Session->Gina.Functions.WlxLoggedOutSAS(
1309 Session->Gina.Context,
1310 Session->SASAction,
1311 &Session->LogonId,
1312 LogonSid,
1313 &Session->Options,
1314 &Session->UserToken,
1315 &Session->MprNotifyInfo,
1316 (PVOID*)&Session->Profile);
1317 break;
1318
1320 /* Ignore SAS if we are already in an SAS state */
1321 return;
1322
1323 case STATE_LOGGED_ON:
1324 Session->LogonState = STATE_LOGGED_ON_SAS;
1325 SwitchDesktop(Session->WinlogonDesktop);
1326 wlxAction = (DWORD)Session->Gina.Functions.WlxLoggedOnSAS(Session->Gina.Context, dwSasType, NULL);
1327 if ((wlxAction == WLX_SAS_ACTION_NONE) ||
1328 (wlxAction == WLX_SAS_ACTION_TASKLIST))
1329 {
1330 /*
1331 * If the user canceled (WLX_SAS_ACTION_NONE) the
1332 * Logged-On SAS dialog, or clicked on the Task-Manager
1333 * button (WLX_SAS_ACTION_TASKLIST), switch back to
1334 * the application desktop and return to log-on state.
1335 * In the latter case, the Task-Manager is launched
1336 * by DoGenericAction(WLX_SAS_ACTION_TASKLIST), which
1337 * doesn't automatically do the switch back, because
1338 * the user may have also pressed on Ctrl-Shift-Esc
1339 * to start it while being on the Logged-On SAS dialog
1340 * and wanting to stay there.
1341 */
1342 SwitchDesktop(Session->ApplicationDesktop);
1343 Session->LogonState = STATE_LOGGED_ON;
1344 }
1345 break;
1346
1348 /* Ignore SAS if we are already in an SAS state */
1349 return;
1350
1351 case STATE_LOCKED:
1352 Session->LogonState = STATE_LOCKED_SAS;
1353
1355
1356 wlxAction = (DWORD)Session->Gina.Functions.WlxWkstaLockedSAS(Session->Gina.Context, dwSasType);
1357 break;
1358
1359 case STATE_LOCKED_SAS:
1360 /* Ignore SAS if we are already in an SAS state */
1361 return;
1362
1363 default:
1364 return;
1365 }
1366 break;
1367
1369 return;
1370
1372 if (!Session->Gina.Functions.WlxScreenSaverNotify(Session->Gina.Context, &bSecure))
1373 {
1374 /* Skip start of screen saver */
1375 SetEvent(Session->hEndOfScreenSaver);
1376 }
1377 else
1378 {
1379 StartScreenSaver(Session);
1380 if (bSecure)
1381 {
1382 wlxAction = WLX_SAS_ACTION_LOCK_WKSTA;
1383// DoGenericAction(Session, WLX_SAS_ACTION_LOCK_WKSTA);
1384 }
1385 }
1386 break;
1387
1389 SetEvent(Session->hUserActivity);
1390 break;
1391 }
1392
1393 DoGenericAction(Session, wlxAction);
1394}
VOID StartScreenSaver(IN PWLSESSION Session)
Definition: screensaver.c:258
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define DWORD
Definition: nt_native.h:44
static VOID DoGenericAction(IN OUT PWLSESSION Session, IN DWORD wlxAction)
Definition: sas.c:1173
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
@ STATE_LOGGED_ON
Definition: winlogon.h:207
@ STATE_LOGGED_OFF_SAS
Definition: winlogon.h:206
@ STATE_LOCKED_SAS
Definition: winlogon.h:210
@ STATE_INIT
Definition: winlogon.h:204
@ STATE_LOGGED_OFF
Definition: winlogon.h:205
@ STATE_LOGGED_ON_SAS
Definition: winlogon.h:208
@ STATE_LOCKED
Definition: winlogon.h:209
VOID CloseAllDialogWindows(VOID)
Definition: wlx.c:95
BOOL WINAPI SwitchDesktop(_In_ HDESK)
#define WLX_SAS_TYPE_TIMEOUT
Definition: winwlx.h:35
#define WLX_SAS_ACTION_NONE
Definition: winwlx.h:54
#define WLX_SAS_TYPE_CTRL_ALT_DEL
Definition: winwlx.h:36
#define WLX_SAS_ACTION_TASKLIST
Definition: winwlx.h:59
#define WLX_SAS_TYPE_SCRNSVR_TIMEOUT
Definition: winwlx.h:37
#define WLX_SAS_TYPE_SCRNSVR_ACTIVITY
Definition: winwlx.h:38
#define WLX_SAS_ACTION_LOCK_WKSTA
Definition: winwlx.h:55

Referenced by SASWindowProc().

◆ DoGenericAction()

static VOID DoGenericAction ( IN OUT PWLSESSION  Session,
IN DWORD  wlxAction 
)
static

Definition at line 1173 of file sas.c.

1176{
1177 switch (wlxAction)
1178 {
1179 case WLX_SAS_ACTION_LOGON: /* 0x01 */
1180 if (Session->LogonState == STATE_LOGGED_OFF_SAS)
1181 {
1182 if (!HandleLogon(Session))
1183 {
1184 Session->LogonState = STATE_LOGGED_OFF;
1185 Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context);
1187 }
1188 }
1189 break;
1190 case WLX_SAS_ACTION_NONE: /* 0x02 */
1191 if (Session->LogonState == STATE_LOGGED_OFF_SAS)
1192 {
1193 Session->LogonState = STATE_LOGGED_OFF;
1194 Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context);
1195 }
1196 else if (Session->LogonState == STATE_LOGGED_ON_SAS)
1197 {
1198 Session->LogonState = STATE_LOGGED_ON;
1199 }
1200 else if (Session->LogonState == STATE_LOCKED_SAS)
1201 {
1202 Session->LogonState = STATE_LOCKED;
1203 Session->Gina.Functions.WlxDisplayLockedNotice(Session->Gina.Context);
1204 }
1205 break;
1206 case WLX_SAS_ACTION_LOCK_WKSTA: /* 0x03 */
1207 if ((Session->LogonState == STATE_LOGGED_ON) ||
1208 (Session->LogonState == STATE_LOGGED_ON_SAS))
1209 {
1210 if (Session->Gina.Functions.WlxIsLockOk(Session->Gina.Context))
1211 {
1212 Session->LogonState = STATE_LOCKED;
1213 SwitchDesktop(Session->WinlogonDesktop);
1214 /* We may be on the Logged-On SAS dialog, in which case
1215 * we need to close it if the lock action came via Win-L */
1218 Session->Gina.Functions.WlxDisplayLockedNotice(Session->Gina.Context);
1219 }
1220 }
1221 break;
1222 case WLX_SAS_ACTION_LOGOFF: /* 0x04 */
1223 case WLX_SAS_ACTION_SHUTDOWN: /* 0x05 */
1224 case WLX_SAS_ACTION_FORCE_LOGOFF: /* 0x09 */
1225 case WLX_SAS_ACTION_SHUTDOWN_POWER_OFF: /* 0x0a */
1226 case WLX_SAS_ACTION_SHUTDOWN_REBOOT: /* 0x0b */
1227 if (Session->LogonState != STATE_LOGGED_OFF)
1228 {
1229 if (!Session->Gina.Functions.WlxIsLogoffOk(Session->Gina.Context))
1230 break;
1231 if (!NT_SUCCESS(HandleLogoff(Session, wlxAction)))
1232 {
1233 RemoveStatusMessage(Session);
1234 break;
1235 }
1236 Session->Gina.Functions.WlxLogoff(Session->Gina.Context);
1237 }
1238 if (WLX_SHUTTINGDOWN(wlxAction))
1239 {
1240 // FIXME: WlxShutdown should be done from inside HandleShutdown,
1241 // after having displayed "ReactOS is shutting down" message.
1242 Session->Gina.Functions.WlxShutdown(Session->Gina.Context, wlxAction);
1243 if (!NT_SUCCESS(HandleShutdown(Session, wlxAction)))
1244 {
1245 RemoveStatusMessage(Session);
1246 Session->LogonState = STATE_LOGGED_OFF;
1247 Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context);
1248 }
1249 }
1250 else
1251 {
1252 RemoveStatusMessage(Session);
1253 Session->LogonState = STATE_LOGGED_OFF;
1254 Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context);
1255 }
1256 break;
1257 case WLX_SAS_ACTION_TASKLIST: /* 0x07 */
1258 if ((Session->LogonState == STATE_LOGGED_ON) ||
1259 (Session->LogonState == STATE_LOGGED_ON_SAS))
1260 {
1261 /* Start a Task-Manager instance on the application desktop.
1262 * If the user pressed Ctrl-Shift-Esc while being on the
1263 * Logged-On SAS dialog (on the Winlogon desktop), stay there. */
1264 StartTaskManager(Session);
1265 }
1266 break;
1267 case WLX_SAS_ACTION_UNLOCK_WKSTA: /* 0x08 */
1268 if ((Session->LogonState == STATE_LOCKED) ||
1269 (Session->LogonState == STATE_LOCKED_SAS))
1270 {
1272 SwitchDesktop(Session->ApplicationDesktop);
1273 Session->LogonState = STATE_LOGGED_ON;
1274 }
1275 break;
1276 default:
1277 WARN("Unknown SAS action 0x%lx\n", wlxAction);
1278 }
1279}
#define WARN(fmt,...)
Definition: precomp.h:61
VOID CallNotificationDlls(PWLSESSION pSession, NOTIFICATION_TYPE Type)
Definition: notify.c:390
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
NTSTATUS HandleShutdown(IN OUT PWLSESSION Session, IN DWORD wlxAction)
Definition: sas.c:1122
static BOOL StartTaskManager(IN OUT PWLSESSION Session)
Definition: sas.c:60
static BOOL HandleLogon(IN OUT PWLSESSION Session)
Definition: sas.c:561
static NTSTATUS HandleLogoff(_Inout_ PWLSESSION Session, _In_ DWORD wlxAction)
Definition: sas.c:999
BOOL RemoveStatusMessage(IN PWLSESSION Session)
Definition: winlogon.c:370
#define WLX_SHUTTINGDOWN(wlxAction)
Definition: winlogon.h:284
@ LogonHandler
Definition: winlogon.h:262
@ UnlockHandler
Definition: winlogon.h:265
@ LockHandler
Definition: winlogon.h:264
#define WLX_SAS_ACTION_FORCE_LOGOFF
Definition: winwlx.h:61
#define WLX_SAS_ACTION_UNLOCK_WKSTA
Definition: winwlx.h:60
#define WLX_SAS_ACTION_LOGON
Definition: winwlx.h:53
#define WLX_SAS_ACTION_SHUTDOWN_POWER_OFF
Definition: winwlx.h:62
#define WLX_SAS_ACTION_SHUTDOWN
Definition: winwlx.h:57
#define WLX_SAS_ACTION_SHUTDOWN_REBOOT
Definition: winwlx.h:63
#define WLX_SAS_ACTION_LOGOFF
Definition: winwlx.h:56

Referenced by DispatchSAS(), and SASWindowProc().

◆ FreeWlxMprInfo()

static VOID FreeWlxMprInfo ( _Inout_ PWLX_MPR_NOTIFY_INFO  MprNotifyInfo)
static

Frees the MPR information structure allocated by the GINA.

Note
Currently used only in HandleLogon(), but will also be used by WlxChangePasswordNotify(Ex) once implemented.

Definition at line 536 of file sas.c.

538{
539 if (MprNotifyInfo->pszUserName)
540 LocalFree(MprNotifyInfo->pszUserName);
541 if (MprNotifyInfo->pszDomain)
542 LocalFree(MprNotifyInfo->pszDomain);
543 if (MprNotifyInfo->pszPassword)
544 {
545 /* Zero out the password buffer before freeing it */
546 SIZE_T pwdLen = (wcslen(MprNotifyInfo->pszPassword) + 1) * sizeof(WCHAR);
547 SecureZeroMemory(MprNotifyInfo->pszPassword, pwdLen);
548 LocalFree(MprNotifyInfo->pszPassword);
549 }
550 if (MprNotifyInfo->pszOldPassword)
551 {
552 /* Zero out the password buffer before freeing it */
553 SIZE_T pwdLen = (wcslen(MprNotifyInfo->pszOldPassword) + 1) * sizeof(WCHAR);
554 SecureZeroMemory(MprNotifyInfo->pszOldPassword, pwdLen);
555 LocalFree(MprNotifyInfo->pszOldPassword);
556 }
557}
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define SecureZeroMemory
Definition: winbase.h:1754
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by HandleLogon().

◆ FreeWlxProfileInfo()

static VOID FreeWlxProfileInfo ( _Inout_ PVOID  Profile)
static

Frees the Profile information structure (WLX_PROFILE_V1_0 or WLX_PROFILE_V2_0) allocated by the GINA.

Definition at line 500 of file sas.c.

502{
503 PWLX_PROFILE_V2_0 pProfile = (PWLX_PROFILE_V2_0)Profile;
504
505 if (pProfile->dwType != WLX_PROFILE_TYPE_V1_0
506 && pProfile->dwType != WLX_PROFILE_TYPE_V2_0)
507 {
508 ERR("WL: Wrong profile info\n");
509 return;
510 }
511
512 if (pProfile->pszProfile)
513 LocalFree(pProfile->pszProfile);
514 if (pProfile->dwType >= WLX_PROFILE_TYPE_V2_0)
515 {
516 if (pProfile->pszPolicy)
517 LocalFree(pProfile->pszPolicy);
518 if (pProfile->pszNetworkDefaultUserProfile)
520 if (pProfile->pszServerName)
521 LocalFree(pProfile->pszServerName);
522 if (pProfile->pszEnvironment)
523 LocalFree(pProfile->pszEnvironment);
524 }
525}
PWSTR pszPolicy
Definition: winwlx.h:150
PWSTR pszEnvironment
Definition: winwlx.h:153
PWSTR pszServerName
Definition: winwlx.h:152
PWSTR pszProfile
Definition: winwlx.h:149
PWSTR pszNetworkDefaultUserProfile
Definition: winwlx.h:151
struct _WLX_PROFILE_V2_0 * PWLX_PROFILE_V2_0
#define WLX_PROFILE_TYPE_V1_0
Definition: winwlx.h:50
#define WLX_PROFILE_TYPE_V2_0
Definition: winwlx.h:51

Referenced by HandleLogon().

◆ HandleLogoff()

static NTSTATUS HandleLogoff ( _Inout_ PWLSESSION  Session,
_In_ DWORD  wlxAction 
)
static

Definition at line 999 of file sas.c.

1002{
1006
1008 if (!NT_SUCCESS(Status))
1009 {
1010 ERR("Failed to create Logoff security descriptor. Status 0x%08lx\n", Status);
1011 return Status;
1012 }
1013
1014 /* Run the Logoff thread. Log off as well if we are
1015 * invoked as part of a shutdown operation. */
1017 WLX_LOGGINGOFF(wlxAction)
1018 ? wlxAction
1020 if (!NT_SUCCESS(Status))
1021 {
1022 ERR("Failed to start the Logoff thread, Status 0x%08lx\n", Status);
1024 return Status;
1025 }
1026
1027 SwitchDesktop(Session->WinlogonDesktop);
1028
1029 PlayLogoffShutdownSound(Session, WLX_SHUTTINGDOWN(wlxAction));
1030
1031 SetWindowStationUser(Session->InteractiveWindowStation,
1032 &LuidNone, NULL, 0);
1033
1034 // DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_LOGGINGOFF);
1036
1037 // FIXME: Closing network connections!
1038 // DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_CLOSINGNETWORKCONNECTIONS);
1039
1040 /* Kill remaining COM processes that may have been started by logoff scripts */
1041 hThread = CreateThread(psa, 0, KillComProcesses, (PVOID)Session->UserToken, 0, NULL);
1042 if (hThread)
1043 {
1046 }
1047
1048 /* We're done with the SECURITY_DESCRIPTOR */
1050
1051 DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_SAVEYOURSETTINGS);
1052
1053 if (Session->hProfileInfo)
1054 UnloadUserProfile(Session->UserToken, Session->hProfileInfo);
1055 Session->hProfileInfo = NULL;
1056
1057 /* Restore default system parameters */
1059
1060 // TODO: Remove session access to window station
1061 // (revert what security.c!AllowAccessOnSession() does).
1062
1063 /* Switch back to default SYSTEM user */
1064 CloseHandle(Session->UserToken);
1065 Session->UserToken = NULL;
1066 Session->LogonId = LuidNone;
1067
1068 Session->LogonState = STATE_LOGGED_OFF;
1069
1070 return STATUS_SUCCESS;
1071}
DWORD WINAPI UpdatePerUserSystemParameters(DWORD dw1, DWORD dw2)
LONG NTSTATUS
Definition: precomp.h:26
#define IDS_SAVEYOURSETTINGS
Definition: resource.h:34
#define CloseHandle
Definition: compat.h:739
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
BOOL WINAPI UnloadUserProfile(_In_ HANDLE hToken, _In_ HANDLE hProfile)
Definition: profile.c:2197
#define INFINITE
Definition: serial.h:102
Status
Definition: gdiplustypes.h:25
HANDLE hThread
Definition: wizard.c:28
static NTSTATUS CreateLogoffSecurityAttributes(OUT PSECURITY_ATTRIBUTES *ppsa)
Definition: sas.c:873
static DWORD WINAPI KillComProcesses(LPVOID Parameter)
Definition: sas.c:843
LUID LuidNone
Definition: sas.c:49
static NTSTATUS RunLogoffShutdownThread(_In_ PWLSESSION Session, _In_opt_ PSECURITY_ATTRIBUTES psa, _In_ DWORD wlxAction)
Definition: sas.c:763
static VOID PlayLogoffShutdownSound(_In_ PWLSESSION Session, _In_ BOOL bShutdown)
Definition: sas.c:397
static VOID DestroyLogoffSecurityAttributes(IN PSECURITY_ATTRIBUTES psa)
Definition: sas.c:987
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
BOOL DisplayStatusMessage(IN PWLSESSION Session, IN HDESK hDesktop, IN UINT ResourceId)
Definition: winlogon.c:349
BOOL WINAPI SetWindowStationUser(IN HWINSTA hWindowStation, IN PLUID pluid, IN PSID psid OPTIONAL, IN DWORD size)
Definition: winsta.c:419
#define WLX_LOGGINGOFF(wlxAction)
Definition: winlogon.h:280
@ LogoffHandler
Definition: winlogon.h:263

Referenced by DoGenericAction().

◆ HandleLogon()

static BOOL HandleLogon ( IN OUT PWLSESSION  Session)
static

Definition at line 561 of file sas.c.

563{
564 BOOL ret = FALSE;
565
566 /* Loading personal settings */
567 DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_LOADINGYOURPERSONALSETTINGS);
568
569 Session->hProfileInfo = NULL;
570 if (!(Session->Options & WLX_LOGON_OPT_NO_PROFILE))
571 {
572 HKEY hKey;
573 LONG lError;
574 BOOL bNoPopups = FALSE;
575 PROFILEINFOW ProfileInfo;
576
577 if (Session->Profile == NULL
578 || (Session->Profile->dwType != WLX_PROFILE_TYPE_V1_0
579 && Session->Profile->dwType != WLX_PROFILE_TYPE_V2_0))
580 {
581 ERR("WL: Wrong profile\n");
582 goto cleanup;
583 }
584
585 /* Check whether error messages may be displayed when loading the user profile */
587 L"System\\CurrentControlSet\\Control\\Windows",
588 0,
590 &hKey);
591 if (lError == ERROR_SUCCESS)
592 {
593 DWORD dwValue, dwType, cbData = sizeof(dwValue);
594 lError = RegQueryValueExW(hKey, L"NoPopupsOnBoot", NULL,
595 &dwType, (PBYTE)&dwValue, &cbData);
596 if ((lError == ERROR_SUCCESS) && (dwType == REG_DWORD) && (cbData == sizeof(dwValue)))
597 bNoPopups = !!dwValue;
598
600 }
601
602 /* Load the user profile */
603 ZeroMemory(&ProfileInfo, sizeof(ProfileInfo));
604 ProfileInfo.dwSize = sizeof(ProfileInfo);
605 if (bNoPopups)
606 ProfileInfo.dwFlags |= PI_NOUI;
607 ProfileInfo.lpUserName = Session->MprNotifyInfo.pszUserName;
608 ProfileInfo.lpProfilePath = Session->Profile->pszProfile;
609 if (Session->Profile->dwType >= WLX_PROFILE_TYPE_V2_0)
610 {
611 ProfileInfo.lpDefaultPath = Session->Profile->pszNetworkDefaultUserProfile;
612 ProfileInfo.lpServerName = Session->Profile->pszServerName;
613 ProfileInfo.lpPolicyPath = Session->Profile->pszPolicy;
614 }
615
616 if (!LoadUserProfileW(Session->UserToken, &ProfileInfo))
617 {
618 ERR("WL: LoadUserProfileW() failed\n");
619 goto cleanup;
620 }
621 Session->hProfileInfo = ProfileInfo.hProfile;
622 }
623
624 /* Create environment block for the user */
625 if (!CreateUserEnvironment(Session))
626 {
627 WARN("WL: CreateUserEnvironment() failed\n");
628 goto cleanup;
629 }
630
632
633 /* Enable per-user settings */
634 DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_APPLYINGYOURPERSONALSETTINGS);
636
637 /* Set default user language */
638 if (!SetDefaultLanguage(Session))
639 {
640 WARN("WL: SetDefaultLanguage() failed\n");
641 goto cleanup;
642 }
643
644 /* Allow winsta and desktop access for this session */
645 if (!AllowAccessOnSession(Session))
646 {
647 WARN("WL: AllowAccessOnSession() failed to give winsta & desktop access for this session\n");
648 goto cleanup;
649 }
650
651 /* Connect remote resources */
652 RestoreAllConnections(Session);
653
654 if (!StartUserShell(Session))
655 {
656 //WCHAR StatusMsg[256];
657 WARN("WL: WlxActivateUserShell() failed\n");
658 //LoadStringW(hAppInstance, IDS_FAILEDACTIVATEUSERSHELL, StatusMsg, sizeof(StatusMsg) / sizeof(StatusMsg[0]));
659 //MessageBoxW(0, StatusMsg, NULL, MB_ICONERROR);
660 goto cleanup;
661 }
662
664
665 if (!InitializeScreenSaver(Session))
666 WARN("WL: Failed to initialize screen saver\n");
667
668 /* Logon has succeeded. Play sound. */
669 PlayLogonSound(Session);
670
671 /* NOTE: The logon timestamp has to be set after calling PlayLogonSound
672 * to correctly detect the startup event (first logon) */
673 SetLogonTimestamp(Session);
674 ret = TRUE;
675
676cleanup:
677 if (Session->Profile)
678 {
679 FreeWlxProfileInfo(Session->Profile);
680 LocalFree(Session->Profile);
681 Session->Profile = NULL;
682 }
683 FreeWlxMprInfo(&Session->MprNotifyInfo);
684 ZeroMemory(&Session->MprNotifyInfo, sizeof(Session->MprNotifyInfo));
685
686 RemoveStatusMessage(Session);
687
688 if (!ret)
689 {
690 if (Session->hProfileInfo)
691 UnloadUserProfile(Session->UserToken, Session->hProfileInfo);
692 Session->hProfileInfo = NULL;
693
694 /* Restore default system parameters */
696
697 // TODO: Remove session access to window station
698 // (revert what security.c!AllowAccessOnSession() does).
699 SetWindowStationUser(Session->InteractiveWindowStation,
700 &LuidNone, NULL, 0);
701
702 /* Switch back to default SYSTEM user */
703 CloseHandle(Session->UserToken);
704 Session->UserToken = NULL;
705 Session->LogonId = LuidNone;
706 }
707 else // if (ret)
708 {
709 SwitchDesktop(Session->ApplicationDesktop);
710 Session->LogonState = STATE_LOGGED_ON;
711 }
712 return ret;
713}
BOOL CreateUserEnvironment(IN PWLSESSION Session)
Definition: environment.c:128
#define IDS_APPLYINGYOURPERSONALSETTINGS
Definition: resource.h:26
#define IDS_LOADINGYOURPERSONALSETTINGS
Definition: resource.h:29
BOOL InitializeScreenSaver(IN OUT PWLSESSION Session)
Definition: screensaver.c:205
BOOL AllowAccessOnSession(_In_ PWLSESSION Session)
Assigns both window station and desktop access to the specific session currently active on the system...
Definition: security.c:1391
#define RegCloseKey(hKey)
Definition: registry.h:49
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
static void cleanup(void)
Definition: main.c:1335
BOOL WINAPI LoadUserProfileW(_In_ HANDLE hToken, _Inout_ LPPROFILEINFOW lpProfileInfo)
Definition: profile.c:2005
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
FxAutoRegKey hKey
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
long LONG
Definition: pedump.c:60
static BOOL StartUserShell(IN OUT PWLSESSION Session)
Definition: sas.c:88
static VOID FreeWlxMprInfo(_Inout_ PWLX_MPR_NOTIFY_INFO MprNotifyInfo)
Frees the MPR information structure allocated by the GINA.
Definition: sas.c:536
static VOID FreeWlxProfileInfo(_Inout_ PVOID Profile)
Frees the Profile information structure (WLX_PROFILE_V1_0 or WLX_PROFILE_V2_0) allocated by the GINA.
Definition: sas.c:500
BOOL SetDefaultLanguage(IN PWLSESSION Session)
Definition: sas.c:119
static VOID PlayLogonSound(_In_ PWLSESSION Session)
Definition: sas.c:373
static VOID RestoreAllConnections(PWLSESSION Session)
Definition: sas.c:432
#define REG_DWORD
Definition: sdbapi.c:596
LPWSTR lpPolicyPath
Definition: userenv.h:42
LPWSTR lpServerName
Definition: userenv.h:41
LPWSTR lpProfilePath
Definition: userenv.h:39
DWORD dwFlags
Definition: userenv.h:37
DWORD dwSize
Definition: userenv.h:36
HANDLE hProfile
Definition: userenv.h:43
LPWSTR lpUserName
Definition: userenv.h:38
LPWSTR lpDefaultPath
Definition: userenv.h:40
#define PI_NOUI
Definition: userenv.h:8
FORCEINLINE VOID SetLogonTimestamp(_Inout_ PWLSESSION Session)
Definition: winlogon.h:296
@ StartShellHandler
Definition: winlogon.h:272
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define WLX_LOGON_OPT_NO_PROFILE
Definition: winwlx.h:48

Referenced by DoGenericAction().

◆ HandleMessageBeep()

static BOOL HandleMessageBeep ( _In_ PWLSESSION  Session,
_In_ UINT  uType 
)
static

Definition at line 1450 of file sas.c.

1453{
1454 LPWSTR EventName;
1455
1456 switch (uType)
1457 {
1458 case 0xFFFFFFFF:
1459 EventName = NULL;
1460 break;
1461 case MB_OK:
1462 EventName = L"SystemDefault";
1463 break;
1464 case MB_ICONASTERISK:
1465 EventName = L"SystemAsterisk";
1466 break;
1467 case MB_ICONEXCLAMATION:
1468 EventName = L"SystemExclamation";
1469 break;
1470 case MB_ICONHAND:
1471 EventName = L"SystemHand";
1472 break;
1473 case MB_ICONQUESTION:
1474 EventName = L"SystemQuestion";
1475 break;
1476 default:
1477 WARN("Unhandled type %d\n", uType);
1478 EventName = L"SystemDefault";
1479 }
1480
1481 return PlayEventSound(Session, EventName);
1482}
static BOOL PlayEventSound(_In_ PWLSESSION Session, _In_ LPCWSTR EventName)
Definition: sas.c:414
#define MB_ICONHAND
Definition: winuser.h:799
#define MB_ICONEXCLAMATION
Definition: winuser.h:796
#define MB_OK
Definition: winuser.h:801
#define MB_ICONQUESTION
Definition: winuser.h:800
#define MB_ICONASTERISK
Definition: winuser.h:795
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by SASWindowProc().

◆ HandleShutdown()

NTSTATUS HandleShutdown ( IN OUT PWLSESSION  Session,
IN DWORD  wlxAction 
)

Definition at line 1122 of file sas.c.

1125{
1127 BOOLEAN Old;
1128
1129 // SwitchDesktop(Session->WinlogonDesktop);
1130
1131 /* If the system is rebooting, show the appropriate string */
1132 if (wlxAction == WLX_SAS_ACTION_SHUTDOWN_REBOOT)
1133 DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_REACTOSISRESTARTING);
1134 else
1135 DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_REACTOSISSHUTTINGDOWN);
1136
1137 /* Run the shutdown thread. *IGNORE* all failures as we want to force shutting down! */
1138 Status = RunLogoffShutdownThread(Session, NULL, wlxAction);
1139 if (!NT_SUCCESS(Status))
1140 ERR("Failed to start the Shutdown thread, Status 0x%08lx\n", Status);
1141
1143
1144 /* Destroy SAS window */
1145 UninitializeSAS(Session);
1146
1147 /* Now we can shut down NT */
1148 ERR("Shutting down NT...\n");
1150 if (wlxAction == WLX_SAS_ACTION_SHUTDOWN_REBOOT)
1151 {
1153 }
1154 else
1155 {
1156 if (FALSE)
1157 {
1158 /* FIXME - only show this dialog if it's a shutdown and the computer doesn't support APM */
1161 }
1162 if (wlxAction == WLX_SAS_ACTION_SHUTDOWN_POWER_OFF)
1164 else // if (wlxAction == WLX_SAS_ACTION_SHUTDOWN)
1166 }
1168 return STATUS_SUCCESS;
1169}
unsigned char BOOLEAN
HINSTANCE hAppInstance
Definition: mmc.c:23
#define IDS_REACTOSISSHUTTINGDOWN
Definition: resource.h:31
#define IDD_SHUTDOWNCOMPUTER
Definition: resource.h:7
#define IDS_REACTOSISRESTARTING
Definition: resource.h:38
#define SE_SHUTDOWN_PRIVILEGE
Definition: security.c:673
@ ShutdownReboot
Definition: extypes.h:177
@ ShutdownPowerOff
Definition: extypes.h:178
@ ShutdownNoReboot
Definition: extypes.h:176
NTSYSAPI NTSTATUS NTAPI RtlAdjustPrivilege(_In_ ULONG Privilege, _In_ BOOLEAN NewValue, _In_ BOOLEAN ForThread, _Out_ PBOOLEAN OldValue)
NTSTATUS NTAPI NtShutdownSystem(IN SHUTDOWN_ACTION Action)
Definition: shutdown.c:43
#define MAKEINTRESOURCE(i)
Definition: ntverrsrc.c:25
static INT_PTR CALLBACK ShutdownComputerWindowProc(IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam)
Definition: sas.c:1076
static VOID UninitializeSAS(IN OUT PWLSESSION Session)
Definition: sas.c:1108
@ ShutdownHandler
Definition: winlogon.h:267
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:628
#define DialogBox
Definition: winuser.h:5872

Referenced by DoGenericAction(), and WinMain().

◆ InitializeSAS()

BOOL InitializeSAS ( IN OUT PWLSESSION  Session)

Definition at line 1700 of file sas.c.

1702{
1703 WNDCLASSEXW swc;
1704 BOOL ret = FALSE;
1705
1706 if (!SwitchDesktop(Session->WinlogonDesktop))
1707 {
1708 ERR("WL: Failed to switch to winlogon desktop\n");
1709 goto cleanup;
1710 }
1711
1712 /* Register SAS window class */
1713 swc.cbSize = sizeof(WNDCLASSEXW);
1714 swc.style = CS_SAVEBITS;
1716 swc.cbClsExtra = 0;
1717 swc.cbWndExtra = 0;
1718 swc.hInstance = hAppInstance;
1719 swc.hIcon = NULL;
1720 swc.hCursor = NULL;
1721 swc.hbrBackground = NULL;
1722 swc.lpszMenuName = NULL;
1724 swc.hIconSm = NULL;
1725 if (RegisterClassExW(&swc) == 0)
1726 {
1727 ERR("WL: Failed to register SAS window class\n");
1728 goto cleanup;
1729 }
1730
1731 /* Create invisible SAS window */
1732 Session->SASWindow = CreateWindowExW(
1733 0,
1736 WS_POPUP,
1737 0, 0, 0, 0, 0, 0,
1738 hAppInstance, Session);
1739 if (!Session->SASWindow)
1740 {
1741 ERR("WL: Failed to create SAS window\n");
1742 goto cleanup;
1743 }
1744
1745 /* Register SAS window to receive SAS notifications */
1746 if (!SetLogonNotifyWindow(Session->SASWindow))
1747 {
1748 ERR("WL: Failed to register SAS window\n");
1749 goto cleanup;
1750 }
1751
1753 return FALSE;
1754
1755 ret = TRUE;
1756
1757cleanup:
1758 if (!ret)
1759 UninitializeSAS(Session);
1760 return ret;
1761}
#define WS_POPUP
Definition: pedump.c:616
#define WINLOGON_SAS_TITLE
Definition: sas.c:27
#define WINLOGON_SAS_CLASS
Definition: sas.c:26
static LRESULT CALLBACK SASWindowProc(IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam)
Definition: sas.c:1487
LPCWSTR lpszClassName
Definition: winuser.h:3328
LPCWSTR lpszMenuName
Definition: winuser.h:3327
HBRUSH hbrBackground
Definition: winuser.h:3326
WNDPROC lpfnWndProc
Definition: winuser.h:3320
UINT cbSize
Definition: winuser.h:3318
int cbWndExtra
Definition: winuser.h:3322
HCURSOR hCursor
Definition: winuser.h:3325
HICON hIconSm
Definition: winuser.h:3329
HINSTANCE hInstance
Definition: winuser.h:3323
UINT style
Definition: winuser.h:3319
int cbClsExtra
Definition: winuser.h:3321
HICON hIcon
Definition: winuser.h:3324
BOOL WINAPI SetLogonNotifyWindow(HWND Wnd)
Definition: logon.c:91
HWND WINAPI CreateWindowExW(_In_ DWORD dwExStyle, _In_opt_ LPCWSTR lpClassName, _In_opt_ LPCWSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
ATOM WINAPI RegisterClassExW(_In_ CONST WNDCLASSEXW *)
#define CS_SAVEBITS
Definition: winuser.h:665
struct _WNDCLASSEXW WNDCLASSEXW

Referenced by WinMain().

◆ KillComProcesses()

static DWORD WINAPI KillComProcesses ( LPVOID  Parameter)
static

Definition at line 843 of file sas.c.

845{
846 HANDLE UserToken = (HANDLE)Parameter;
847 DWORD ret = TRUE;
848
849 TRACE("In KillComProcesses\n");
850
851 if (UserToken && !ImpersonateLoggedOnUser(UserToken))
852 {
853 ERR("ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
854 return FALSE;
855 }
856
857 /* Attempt to kill remaining processes. No notifications needed. */
859 {
860 ERR("Unable to kill COM apps, error %lu\n", GetLastError());
861 ret = FALSE;
862 }
863
864 if (UserToken)
865 RevertToSelf();
866
867 return ret;
868}
BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
Definition: misc.c:152
BOOL WINAPI RevertToSelf(void)
Definition: security.c:855
#define TRACE(s)
Definition: solgame.cpp:4
PVOID HANDLE
Definition: typedefs.h:73
#define EWX_NONOTIFY
Definition: undocuser.h:136
#define EWX_CALLER_WINLOGON
Definition: undocuser.h:130
#define EWX_LOGOFF
Definition: winuser.h:644
#define EWX_FORCE
Definition: winuser.h:643
BOOL WINAPI ExitWindowsEx(_In_ UINT, _In_ DWORD)
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:336

Referenced by HandleLogoff().

◆ LogoffShutdownThread()

static DWORD WINAPI LogoffShutdownThread ( LPVOID  Parameter)
static

Definition at line 719 of file sas.c.

721{
723 HANDLE UserToken = LSData->Session->UserToken;
724 DWORD ret = TRUE;
725 UINT uFlags;
726
727 if (UserToken && !ImpersonateLoggedOnUser(UserToken))
728 {
729 ERR("ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
730 return FALSE;
731 }
732
733 // FIXME: To be really fixed: need to check what needs to be kept and what needs to be removed there.
734 //
735 // uFlags = EWX_INTERNAL_KILL_USER_APPS | (LSData->Flags & EWX_FLAGS_MASK) |
736 // ((LSData->Flags & EWX_ACTION_MASK) == EWX_LOGOFF ? EWX_CALLER_WINLOGON_LOGOFF : 0);
737
738 uFlags = EWX_CALLER_WINLOGON | (LSData->Flags & 0x0F);
739
740 TRACE("In LogoffShutdownThread with uFlags == 0x%x; exit_in_progress == %s\n",
741 uFlags, ExitReactOSInProgress ? "TRUE" : "FALSE");
742
744
745 /* Close processes of the interactive user */
746 if (!ExitWindowsEx(uFlags, 0))
747 {
748 ERR("Unable to kill user apps, error %lu\n", GetLastError());
749 ret = FALSE;
750 }
751
752 /* Cancel all the user connections */
754
755 if (UserToken)
756 RevertToSelf();
757
758 return ret;
759}
UINT uFlags
Definition: api.c:59
unsigned int UINT
Definition: ndis.h:50
struct tagLOGOFF_SHUTDOWN_DATA * PLOGOFF_SHUTDOWN_DATA
static BOOL ExitReactOSInProgress
Definition: sas.c:47
HANDLE UserToken
Definition: winlogon.h:235
PWLSESSION Session
Definition: sas.c:44
DWORD WINAPI WNetClearConnections(HWND owner)
Definition: wnet.c:2827

Referenced by RunLogoffShutdownThread().

◆ PlayEventSound()

static BOOL PlayEventSound ( _In_ PWLSESSION  Session,
_In_ LPCWSTR  EventName 
)
static

Definition at line 414 of file sas.c.

417{
418 BOOL bRet;
419
420 if (!ImpersonateLoggedOnUser(Session->UserToken))
421 return FALSE;
422
424
425 RevertToSelf();
426
427 return bRet;
428}
#define SND_ALIAS
Definition: mmsystem.h:160
#define SND_ASYNC
Definition: mmsystem.h:154
#define SND_NODEFAULT
Definition: mmsystem.h:155
BOOL PlaySoundRoutine(IN LPCWSTR FileName, IN UINT bLogon, IN UINT Flags)
Definition: sas.c:248

Referenced by HandleMessageBeep().

◆ PlayLogoffShutdownSound()

static VOID PlayLogoffShutdownSound ( _In_ PWLSESSION  Session,
_In_ BOOL  bShutdown 
)
static

Definition at line 397 of file sas.c.

400{
401 if (!ImpersonateLoggedOnUser(Session->UserToken))
402 return;
403
404 /* NOTE: Logoff and shutdown sounds play synchronously */
405 PlaySoundRoutine(bShutdown ? L"SystemExit" : L"WindowsLogoff",
406 FALSE,
408
409 RevertToSelf();
410}
volatile BOOL bShutdown
Definition: tcpsvcs.c:16

Referenced by HandleLogoff().

◆ PlayLogonSound()

static VOID PlayLogonSound ( _In_ PWLSESSION  Session)
static

Definition at line 373 of file sas.c.

375{
376 PLOGON_SOUND_DATA SoundData;
378
379 SoundData = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGON_SOUND_DATA));
380 if (!SoundData)
381 return;
382
383 SoundData->UserToken = Session->UserToken;
384 SoundData->IsStartup = IsFirstLogon(Session);
385
386 hThread = CreateThread(NULL, 0, PlayLogonSoundThread, SoundData, 0, NULL);
387 if (!hThread)
388 {
389 HeapFree(GetProcessHeap(), 0, SoundData);
390 return;
391 }
393}
static DWORD WINAPI PlayLogonSoundThread(_In_ LPVOID lpParameter)
Definition: sas.c:299
BOOL IsStartup
Definition: sas.c:54
HANDLE UserToken
Definition: sas.c:53
FORCEINLINE BOOL IsFirstLogon(_In_ PWLSESSION Session)
Definition: winlogon.h:304

Referenced by HandleLogon().

◆ PlayLogonSoundThread()

static DWORD WINAPI PlayLogonSoundThread ( _In_ LPVOID  lpParameter)
static

Definition at line 299 of file sas.c.

301{
302 PLOGON_SOUND_DATA SoundData = (PLOGON_SOUND_DATA)lpParameter;
305 ULONG Index = 0;
306 SC_HANDLE hSCManager, hService;
307
308 /* Open the service manager */
310 if (!hSCManager)
311 {
312 ERR("OpenSCManager failed (%x)\n", GetLastError());
313 goto Cleanup;
314 }
315
316 /* Open the wdmaud service */
317 hService = OpenServiceW(hSCManager, L"wdmaud", GENERIC_READ);
318 if (!hService)
319 {
320 /* The service is not installed */
321 TRACE("Failed to open wdmaud service (%x)\n", GetLastError());
323 goto Cleanup;
324 }
325
326 /* Wait for wdmaud to start */
327 do
328 {
330 {
331 TRACE("QueryServiceStatusEx failed (%x)\n", GetLastError());
332 break;
333 }
334
335 if (Info.dwCurrentState == SERVICE_RUNNING)
336 break;
337
338 Sleep(1000);
339
340 } while (Index++ < 20);
341
342 CloseServiceHandle(hService);
344
345 /* If wdmaud is not running exit */
346 if (Info.dwCurrentState != SERVICE_RUNNING)
347 {
348 WARN("wdmaud has not started!\n");
349 goto Cleanup;
350 }
351
352 /* Sound subsystem is running. Play logon sound. */
353 TRACE("Playing %s sound\n", SoundData->IsStartup ? "startup" : "logon");
354 if (!ImpersonateLoggedOnUser(SoundData->UserToken))
355 {
356 ERR("ImpersonateLoggedOnUser failed (%x)\n", GetLastError());
357 }
358 else
359 {
360 PlaySoundRoutine(SoundData->IsStartup ? L"SystemStart" : L"WindowsLogon",
361 TRUE,
363 RevertToSelf();
364 }
365
366Cleanup:
367 HeapFree(GetProcessHeap(), 0, SoundData);
368 return 0;
369}
#define GENERIC_READ
Definition: compat.h:135
static const WCHAR Cleanup[]
Definition: register.c:80
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
struct tagLOGON_SOUND_DATA * PLOGON_SOUND_DATA
SC_HANDLE hSCManager
Definition: sc.c:12
BOOL WINAPI QueryServiceStatusEx(SC_HANDLE hService, SC_STATUS_TYPE InfoLevel, LPBYTE lpBuffer, DWORD cbBufSize, LPDWORD pcbBytesNeeded)
Definition: scm.c:2926
SC_HANDLE WINAPI OpenServiceW(SC_HANDLE hSCManager, LPCWSTR lpServiceName, DWORD dwDesiredAccess)
Definition: scm.c:2199
BOOL WINAPI CloseServiceHandle(SC_HANDLE hSCObject)
Definition: scm.c:580
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
unsigned char * LPBYTE
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_In_ WDFCOLLECTION _In_ ULONG Index
#define OpenSCManager
Definition: winsvc.h:575
@ SC_STATUS_PROCESS_INFO
Definition: winsvc.h:119
#define SC_MANAGER_CONNECT
Definition: winsvc.h:14
#define SERVICE_RUNNING
Definition: winsvc.h:24

Referenced by PlayLogonSound().

◆ PlaySoundRoutine()

BOOL PlaySoundRoutine ( IN LPCWSTR  FileName,
IN UINT  bLogon,
IN UINT  Flags 
)

Definition at line 248 of file sas.c.

252{
253 typedef BOOL (WINAPI *PLAYSOUNDW)(LPCWSTR,HMODULE,DWORD);
254 typedef UINT (WINAPI *WAVEOUTGETNUMDEVS)(VOID);
255 PLAYSOUNDW Play;
256 WAVEOUTGETNUMDEVS waveOutGetNumDevs;
257 UINT NumDevs;
259 BOOL Ret = FALSE;
260
261 hLibrary = LoadLibraryW(L"winmm.dll");
262 if (!hLibrary)
263 return FALSE;
264
265 waveOutGetNumDevs = (WAVEOUTGETNUMDEVS)GetProcAddress(hLibrary, "waveOutGetNumDevs");
266 Play = (PLAYSOUNDW)GetProcAddress(hLibrary, "PlaySoundW");
267
269 {
271 {
272 NumDevs = waveOutGetNumDevs();
273 if (!NumDevs)
274 {
275 if (!bLogon)
276 Beep(440, 125);
278 }
279 }
280
281 if (Play)
282 Ret = Play(FileName, NULL, Flags);
283 }
285 {
286 ERR("WL: Exception while playing sound '%S', Status 0x%08lx\n",
288 }
289 _SEH2_END;
290
292
293 return Ret;
294}
#define VOID
Definition: acefi.h:82
HMODULE hLibrary
Definition: odbccp32.c:12
BOOL WINAPI Beep(IN DWORD dwFreq, IN DWORD dwDuration)
Definition: deviceio.c:48
#define GetProcAddress(x, y)
Definition: compat.h:753
#define FreeLibrary(x)
Definition: compat.h:748
#define LoadLibraryW(x)
Definition: compat.h:747
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define BOOL
Definition: nt_native.h:43
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:181
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:82
#define _SEH2_END
Definition: pseh2_64.h:171
#define _SEH2_TRY
Definition: pseh2_64.h:71
#define _SEH2_LEAVE
Definition: pseh2_64.h:183
HANDLE HMODULE
Definition: typedefs.h:77
#define WINAPI
Definition: msvc.h:6
UINT WINAPI waveOutGetNumDevs(void)
Definition: winmm.c:2137
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

Referenced by PlayEventSound(), PlayLogoffShutdownSound(), and PlayLogonSoundThread().

◆ RegisterHotKeys()

static BOOL RegisterHotKeys ( IN PWLSESSION  Session,
IN HWND  hwndSAS 
)
static

Definition at line 1398 of file sas.c.

1401{
1402 /* Register Ctrl+Alt+Del hotkey */
1404 {
1405 ERR("WL: Unable to register Ctrl+Alt+Del hotkey\n");
1406 return FALSE;
1407 }
1408
1409 /* Register Ctrl+Shift+Esc "Task Manager" hotkey (optional) */
1411 if (!Session->TaskManHotkey)
1412 WARN("WL: Unable to register Ctrl+Shift+Esc hotkey\n");
1413
1414 /* Register Win+L "Lock Workstation" hotkey (optional) */
1415 Session->LockWkStaHotkey = RegisterHotKey(hwndSAS, IDHK_WIN_L, MOD_WIN, 'L');
1416 if (!Session->LockWkStaHotkey)
1417 WARN("WL: Unable to register Win+L hotkey\n");
1418
1419 /* Register Win+U "Accessibility Utility" hotkey (optional) */
1420 Session->UtilManHotkey = RegisterHotKey(hwndSAS, IDHK_WIN_U, MOD_WIN, 'U');
1421 if (!Session->UtilManHotkey)
1422 WARN("WL: Unable to register Win+U hotkey\n");
1423
1424 return TRUE;
1425}
#define MOD_ALT
Definition: imm.h:184
#define MOD_SHIFT
Definition: imm.h:186
#define MOD_CONTROL
Definition: imm.h:185
HWND hwndSAS
Definition: winsta.c:24
#define IDHK_CTRL_ALT_DEL
Definition: sas.c:29
#define IDHK_WIN_L
Definition: sas.c:31
#define IDHK_CTRL_SHIFT_ESC
Definition: sas.c:30
#define IDHK_WIN_U
Definition: sas.c:32
#define MOD_WIN
Definition: winuser.h:2686
BOOL WINAPI RegisterHotKey(_In_opt_ HWND, _In_ int, _In_ UINT, _In_ UINT)
#define VK_DELETE
Definition: winuser.h:2269
#define VK_ESCAPE
Definition: winuser.h:2250

Referenced by SASWindowProc().

◆ RestoreAllConnections()

static VOID RestoreAllConnections ( PWLSESSION  Session)
static

Definition at line 432 of file sas.c.

433{
434 DWORD dRet;
435 HANDLE hEnum;
436 LPNETRESOURCE lpRes;
437 DWORD dSize = 0x1000;
438 DWORD dCount = -1;
439 LPNETRESOURCE lpCur;
440 BOOL UserProfile;
441
442 UserProfile = (Session && Session->UserToken);
443 if (!UserProfile)
444 {
445 return;
446 }
447
448 if (!ImpersonateLoggedOnUser(Session->UserToken))
449 {
450 ERR("WL: ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
451 return;
452 }
453
455 if (dRet != WN_SUCCESS)
456 {
457 ERR("Failed to open enumeration: %lu\n", dRet);
458 goto quit;
459 }
460
461 lpRes = HeapAlloc(GetProcessHeap(), 0, dSize);
462 if (!lpRes)
463 {
464 ERR("Failed to allocate memory\n");
465 WNetCloseEnum(hEnum);
466 goto quit;
467 }
468
469 do
470 {
471 dSize = 0x1000;
472 dCount = -1;
473
474 memset(lpRes, 0, dSize);
475 dRet = WNetEnumResource(hEnum, &dCount, lpRes, &dSize);
476 if (dRet == WN_SUCCESS || dRet == WN_MORE_DATA)
477 {
478 lpCur = lpRes;
479 for (; dCount; dCount--)
480 {
482 lpCur++;
483 }
484 }
485 } while (dRet != WN_NO_MORE_ENTRIES);
486
487 HeapFree(GetProcessHeap(), 0, lpRes);
488 WNetCloseEnum(hEnum);
489
490quit:
491 RevertToSelf();
492}
void quit(int argc, const char *argv[])
Definition: cmds.c:1606
#define memset(x, y, z)
Definition: compat.h:39
LPSTR lpLocalName
Definition: winnetwk.h:171
LPSTR lpRemoteName
Definition: winnetwk.h:172
#define RESOURCETYPE_DISK
Definition: winnetwk.h:64
#define WN_MORE_DATA
Definition: winnetwk.h:117
#define WN_SUCCESS
Definition: winnetwk.h:111
#define RESOURCE_REMEMBERED
Definition: winnetwk.h:60
#define WNetEnumResource
Definition: winnetwk.h:599
#define WNetOpenEnum
Definition: winnetwk.h:598
#define WNetAddConnection
Definition: winnetwk.h:611
#define WN_NO_MORE_ENTRIES
Definition: winnetwk.h:146
DWORD WINAPI WNetCloseEnum(HANDLE hEnum)
Definition: wnet.c:1762

Referenced by HandleLogon().

◆ RunLogoffShutdownThread()

static NTSTATUS RunLogoffShutdownThread ( _In_ PWLSESSION  Session,
_In_opt_ PSECURITY_ATTRIBUTES  psa,
_In_ DWORD  wlxAction 
)
static

Definition at line 763 of file sas.c.

767{
768 PCSTR pDescName;
771 DWORD dwExitCode;
772
773 /* Validate the action */
774 if (WLX_LOGGINGOFF(wlxAction))
775 {
776 pDescName = "Logoff";
777 }
778 else if (WLX_SHUTTINGDOWN(wlxAction))
779 {
780 pDescName = "Shutdown";
781 }
782 else
783 {
784 ASSERT(FALSE);
786 }
787
788 /* Prepare data for the logoff/shutdown thread */
789 LSData = HeapAlloc(GetProcessHeap(), 0, sizeof(*LSData));
790 if (!LSData)
791 {
792 ERR("Failed to allocate %s thread data\n", pDescName);
793 return STATUS_NO_MEMORY;
794 }
795
796 /* Set the flags accordingly */
797 if (WLX_LOGGINGOFF(wlxAction))
798 {
799 LSData->Flags = EWX_LOGOFF;
800 if (wlxAction == WLX_SAS_ACTION_FORCE_LOGOFF)
801 LSData->Flags |= EWX_FORCE;
802 }
803 else // if (WLX_SHUTTINGDOWN(wlxAction))
804 {
805 /* Because we are shutting down the OS, force processes termination too */
806 LSData->Flags = EWX_SHUTDOWN | EWX_FORCE;
807 if (wlxAction == WLX_SAS_ACTION_SHUTDOWN_POWER_OFF)
808 LSData->Flags |= EWX_POWEROFF;
809 else if (wlxAction == WLX_SAS_ACTION_SHUTDOWN_REBOOT)
810 LSData->Flags |= EWX_REBOOT;
811 }
812
813 LSData->Session = Session;
814
815 /* Run the logoff/shutdown thread */
817 if (!hThread)
818 {
819 ERR("Unable to create %s thread, error %lu\n", pDescName, GetLastError());
820 HeapFree(GetProcessHeap(), 0, LSData);
821 return STATUS_UNSUCCESSFUL;
822 }
824 HeapFree(GetProcessHeap(), 0, LSData);
825 if (!GetExitCodeThread(hThread, &dwExitCode))
826 {
827 ERR("Unable to get %s thread exit code (error %lu)\n", pDescName, GetLastError());
829 return STATUS_UNSUCCESSFUL;
830 }
832 if (dwExitCode == 0)
833 {
834 ERR("%s thread returned failure\n", pDescName);
835 return STATUS_UNSUCCESSFUL;
836 }
837 return STATUS_SUCCESS;
838}
BOOL WINAPI GetExitCodeThread(IN HANDLE hThread, OUT LPDWORD lpExitCode)
Definition: thread.c:541
#define ASSERT(a)
Definition: mode.c:44
static DWORD WINAPI LogoffShutdownThread(LPVOID Parameter)
Definition: sas.c:719
const char * PCSTR
Definition: typedefs.h:52
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define EWX_POWEROFF
Definition: winuser.h:645
#define EWX_SHUTDOWN
Definition: winuser.h:647
#define EWX_REBOOT
Definition: winuser.h:646

Referenced by HandleLogoff(), and HandleShutdown().

◆ SASWindowProc()

static LRESULT CALLBACK SASWindowProc ( IN HWND  hwndDlg,
IN UINT  uMsg,
IN WPARAM  wParam,
IN LPARAM  lParam 
)
static

Definition at line 1487 of file sas.c.

1492{
1494
1495 switch (uMsg)
1496 {
1497 case WM_HOTKEY:
1498 {
1499 switch (wParam)
1500 {
1501 case IDHK_CTRL_ALT_DEL:
1502 {
1503 TRACE("SAS: CONTROL+ALT+DELETE\n");
1504 if (!Session->Gina.UseCtrlAltDelete)
1505 break;
1507 return TRUE;
1508 }
1510 {
1511 TRACE("SAS: CONTROL+SHIFT+ESCAPE\n");
1513 return TRUE;
1514 }
1515 case IDHK_WIN_L:
1516 {
1517 TRACE("SAS: WIN+L\n");
1519 return TRUE;
1520 }
1521 case IDHK_WIN_U:
1522 {
1523 TRACE("SAS: WIN+U\n");
1524 // PostMessageW(Session->SASWindow, WM_LOGONNOTIFY, LN_ACCESSIBILITY, 0);
1525 return TRUE;
1526 }
1527 }
1528 break;
1529 }
1530 case WM_CREATE:
1531 {
1532 /* Get the session pointer from the create data */
1533 Session = (PWLSESSION)((LPCREATESTRUCT)lParam)->lpCreateParams;
1534
1535 /* Save the Session pointer */
1536 SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (LONG_PTR)Session);
1537 if (GetSetupType())
1538 return TRUE;
1539 return RegisterHotKeys(Session, hwndDlg);
1540 }
1541 case WM_DESTROY:
1542 {
1543 if (!GetSetupType())
1544 UnregisterHotKeys(Session, hwndDlg);
1545 return TRUE;
1546 }
1547 case WM_SETTINGCHANGE:
1548 {
1549 UINT uiAction = (UINT)wParam;
1550 if (uiAction == SPI_SETSCREENSAVETIMEOUT
1551 || uiAction == SPI_SETSCREENSAVEACTIVE)
1552 {
1554 }
1555 return TRUE;
1556 }
1557 case WM_LOGONNOTIFY:
1558 {
1559 switch(wParam)
1560 {
1561 case LN_MESSAGE_BEEP:
1562 {
1563 return HandleMessageBeep(Session, lParam);
1564 }
1565 case LN_SHELL_EXITED:
1566 {
1567 /* lParam is the exit code */
1568 if (lParam != 1 &&
1569 Session->LogonState != STATE_LOGGED_OFF &&
1570 Session->LogonState != STATE_LOGGED_OFF_SAS)
1571 {
1572 SetTimer(hwndDlg, 1, 1000, NULL);
1573 }
1574 break;
1575 }
1577 {
1579 break;
1580 }
1581#if 0
1582 case LN_ACCESSIBILITY:
1583 {
1584 ERR("LN_ACCESSIBILITY(lParam = %lu)\n", lParam);
1585 break;
1586 }
1587#endif
1589 {
1591 break;
1592 }
1593 case LN_LOGOFF:
1594 {
1595 UINT Flags = (UINT)lParam;
1597 DWORD wlxAction;
1598
1599 TRACE("\tFlags : 0x%lx\n", lParam);
1600
1601 /*
1602 * Our caller (USERSRV) should have added the shutdown flag
1603 * when setting also poweroff or reboot.
1604 */
1605 if ((Action & (EWX_POWEROFF | EWX_REBOOT)) && !(Action & EWX_SHUTDOWN))
1606 {
1607 ERR("Missing EWX_SHUTDOWN flag for poweroff or reboot; action 0x%x\n", Action);
1609 }
1610
1611 // INVESTIGATE: Our HandleLogoff/HandleShutdown may instead
1612 // take an EWX_* flags combination to determine what to do
1613 // more precisely.
1614 /* Map EWX_* flags to WLX_* actions and check for any unhandled flag */
1615 if (Action & EWX_POWEROFF)
1616 {
1619 }
1620 else if (Action & EWX_REBOOT)
1621 {
1624 }
1625 else if (Action & EWX_SHUTDOWN)
1626 {
1627 wlxAction = WLX_SAS_ACTION_SHUTDOWN;
1628 Action &= ~EWX_SHUTDOWN;
1629 }
1630 else // EWX_LOGOFF
1631 {
1632 if (Action & EWX_FORCE)
1633 wlxAction = WLX_SAS_ACTION_FORCE_LOGOFF;
1634 else
1635 wlxAction = WLX_SAS_ACTION_LOGOFF;
1636 Action &= ~(EWX_LOGOFF | EWX_FORCE);
1637 }
1638 if (Action)
1639 ERR("Unhandled EWX_* action flags: 0x%x\n", Action);
1640
1641 TRACE("In LN_LOGOFF, exit_in_progress == %s\n",
1642 ExitReactOSInProgress ? "TRUE" : "FALSE");
1643
1644 /*
1645 * In case a parallel shutdown request is done (while we are
1646 * being to shut down) and it was not done by Winlogon itself,
1647 * then just stop here.
1648 */
1649#if 0
1650// This code is commented at the moment (even if it's correct) because
1651// our log-offs do not really work: the shell is restarted, no app is killed
1652// etc... and as a result you just get explorer opening "My Documents". And
1653// if you try now a shut down, it won't work because winlogon thinks it is
1654// still in the middle of a shutdown.
1655// Maybe we also need to reset ExitReactOSInProgress somewhere else??
1657 {
1658 break;
1659 }
1660#endif
1661 /* Now do the shutdown action proper */
1662 DoGenericAction(Session, wlxAction);
1663 return 1;
1664 }
1665 case LN_LOGOFF_CANCELED:
1666 {
1667 ERR("Logoff canceled! Before: exit_in_progress == %s; After: FALSE\n",
1668 ExitReactOSInProgress ? "TRUE" : "FALSE");
1669
1671 return 1;
1672 }
1673 default:
1674 {
1675 ERR("WM_LOGONNOTIFY case %d is unimplemented\n", wParam);
1676 }
1677 }
1678 return 0;
1679 }
1680 case WM_TIMER:
1681 {
1682 if (wParam == 1)
1683 {
1684 KillTimer(hwndDlg, 1);
1685 StartUserShell(Session);
1686 }
1687 break;
1688 }
1689 case WLX_WM_SAS:
1690 {
1691 DispatchSAS(Session, (DWORD)wParam);
1692 return TRUE;
1693 }
1694 }
1695
1696 return DefWindowProc(hwndDlg, uMsg, wParam, lParam);
1697}
DWORD GetSetupType(VOID)
Definition: setup.c:16
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define DefWindowProc
Definition: ros2win.h:31
static BOOL RegisterHotKeys(IN PWLSESSION Session, IN HWND hwndSAS)
Definition: sas.c:1398
static VOID DispatchSAS(IN OUT PWLSESSION Session, IN DWORD dwSasType)
Definition: sas.c:1283
static BOOL HandleMessageBeep(_In_ PWLSESSION Session, _In_ UINT uType)
Definition: sas.c:1450
#define EWX_ACTION_MASK
Definition: sas.c:39
static BOOL UnregisterHotKeys(IN PWLSESSION Session, IN HWND hwndSAS)
Definition: sas.c:1429
BOOL UseCtrlAltDelete
Definition: winlogon.h:132
HANDLE hScreenSaverParametersChanged
Definition: winlogon.h:247
LOGON_STATE LogonState
Definition: winlogon.h:237
HWND SASWindow
Definition: winlogon.h:228
GINAINSTANCE Gina
Definition: winlogon.h:222
#define GetWindowLongPtr
Definition: treelist.c:73
#define GWLP_USERDATA
Definition: treelist.c:63
#define LN_SHELL_EXITED
Definition: undocuser.h:117
#define LN_LOCK_WORKSTATION
Definition: undocuser.h:119
#define WM_LOGONNOTIFY
Definition: undocuser.h:39
#define LN_START_SCREENSAVE
Definition: undocuser.h:122
#define LN_MESSAGE_BEEP
Definition: undocuser.h:121
#define LN_LOGOFF
Definition: undocuser.h:116
#define LN_LOGOFF_CANCELED
Definition: undocuser.h:123
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510
struct _WLSESSION * PWLSESSION
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define WM_CREATE
Definition: winuser.h:1636
#define SPI_SETSCREENSAVEACTIVE
Definition: winuser.h:1377
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
#define WM_SETTINGCHANGE
Definition: winuser.h:1657
#define WM_TIMER
Definition: winuser.h:1770
#define WM_HOTKEY
Definition: winuser.h:1907
#define WM_DESTROY
Definition: winuser.h:1637
BOOL WINAPI KillTimer(_In_opt_ HWND, _In_ UINT_PTR)
#define SetWindowLongPtrW
Definition: winuser.h:5457
#define SPI_SETSCREENSAVETIMEOUT
Definition: winuser.h:1375
#define WLX_WM_SAS
Definition: winwlx.h:71

Referenced by InitializeSAS().

◆ SetDefaultLanguage()

BOOL SetDefaultLanguage ( IN PWLSESSION  Session)

Definition at line 119 of file sas.c.

121{
122 BOOL ret = FALSE;
123 BOOL UserProfile;
124 LONG rc;
125 HKEY UserKey, hKey = NULL;
126 LPCWSTR SubKey, ValueName;
127 DWORD dwType, dwSize;
128 LPWSTR Value = NULL;
129 UNICODE_STRING ValueString;
131 LCID Lcid;
132
133 UserProfile = (Session && Session->UserToken);
134
135 if (UserProfile && !ImpersonateLoggedOnUser(Session->UserToken))
136 {
137 ERR("WL: ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
138 return FALSE;
139 // FIXME: ... or use the default language of the system??
140 // UserProfile = FALSE;
141 }
142
143 if (UserProfile)
144 {
145 rc = RegOpenCurrentUser(MAXIMUM_ALLOWED, &UserKey);
146 if (rc != ERROR_SUCCESS)
147 {
148 TRACE("RegOpenCurrentUser() failed with error %lu\n", rc);
149 goto cleanup;
150 }
151
152 SubKey = L"Control Panel\\International";
153 ValueName = L"Locale";
154 }
155 else
156 {
157 UserKey = NULL;
158 SubKey = L"System\\CurrentControlSet\\Control\\Nls\\Language";
159 ValueName = L"Default";
160 }
161
162 rc = RegOpenKeyExW(UserKey ? UserKey : HKEY_LOCAL_MACHINE,
163 SubKey,
164 0,
165 KEY_READ,
166 &hKey);
167
168 if (UserKey)
169 RegCloseKey(UserKey);
170
171 if (rc != ERROR_SUCCESS)
172 {
173 TRACE("RegOpenKeyEx() failed with error %lu\n", rc);
174 goto cleanup;
175 }
176
178 ValueName,
179 NULL,
180 &dwType,
181 NULL,
182 &dwSize);
183 if (rc != ERROR_SUCCESS)
184 {
185 TRACE("RegQueryValueEx() failed with error %lu\n", rc);
186 goto cleanup;
187 }
188 else if (dwType != REG_SZ)
189 {
190 TRACE("Wrong type for %S\\%S registry entry (got 0x%lx, expected 0x%x)\n",
191 SubKey, ValueName, dwType, REG_SZ);
192 goto cleanup;
193 }
194
196 if (!Value)
197 {
198 TRACE("HeapAlloc() failed\n");
199 goto cleanup;
200 }
202 ValueName,
203 NULL,
204 NULL,
205 (LPBYTE)Value,
206 &dwSize);
207 if (rc != ERROR_SUCCESS)
208 {
209 TRACE("RegQueryValueEx() failed with error %lu\n", rc);
210 goto cleanup;
211 }
212
213 /* Convert Value to a Lcid */
214 ValueString.Length = ValueString.MaximumLength = (USHORT)dwSize;
215 ValueString.Buffer = Value;
216 Status = RtlUnicodeStringToInteger(&ValueString, 16, (PULONG)&Lcid);
217 if (!NT_SUCCESS(Status))
218 {
219 TRACE("RtlUnicodeStringToInteger() failed with status 0x%08lx\n", Status);
220 goto cleanup;
221 }
222
223 TRACE("%s language is 0x%08lx\n",
224 UserProfile ? "User" : "System", Lcid);
225 Status = NtSetDefaultLocale(UserProfile, Lcid);
226 if (!NT_SUCCESS(Status))
227 {
228 TRACE("NtSetDefaultLocale() failed with status 0x%08lx\n", Status);
229 goto cleanup;
230 }
231
232 ret = TRUE;
233
234cleanup:
235 if (Value)
237
238 if (hKey)
240
241 if (UserProfile)
242 RevertToSelf();
243
244 return ret;
245}
LONG WINAPI RegOpenCurrentUser(IN REGSAM samDesired, OUT PHKEY phkResult)
Definition: reg.c:3209
#define REG_SZ
Definition: layer.c:22
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
NTSTATUS NTAPI NtSetDefaultLocale(IN BOOLEAN UserProfile, IN LCID DefaultLocaleId)
Definition: locale.c:437
unsigned short USHORT
Definition: pedump.c:61
DWORD LCID
Definition: nls.h:13
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint32_t * PULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_In_ CONST DEVPROPKEY _In_ LCID Lcid
Definition: iofuncs.h:2415

Referenced by HandleLogon(), and InitializeSAS().

◆ ShutdownComputerWindowProc()

static INT_PTR CALLBACK ShutdownComputerWindowProc ( IN HWND  hwndDlg,
IN UINT  uMsg,
IN WPARAM  wParam,
IN LPARAM  lParam 
)
static

Definition at line 1076 of file sas.c.

1081{
1083
1084 switch (uMsg)
1085 {
1086 case WM_COMMAND:
1087 {
1088 switch (LOWORD(wParam))
1089 {
1092 return TRUE;
1093 }
1094 break;
1095 }
1096 case WM_INITDIALOG:
1097 {
1100 return TRUE;
1101 }
1102 }
1103 return FALSE;
1104}
#define IDC_BTNSHTDOWNCOMPUTER
Definition: resource.h:10
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
#define LOWORD(l)
Definition: pedump.c:82
#define MF_BYCOMMAND
Definition: winuser.h:202
#define WM_COMMAND
Definition: winuser.h:1768
#define WM_INITDIALOG
Definition: winuser.h:1767
HMENU WINAPI GetSystemMenu(_In_ HWND, _In_ BOOL)
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
HWND WINAPI SetFocus(_In_opt_ HWND)
BOOL WINAPI RemoveMenu(_In_ HMENU, _In_ UINT, _In_ UINT)
#define SC_CLOSE
Definition: winuser.h:2628
BOOL WINAPI EndDialog(_In_ HWND, _In_ INT_PTR)

Referenced by HandleShutdown().

◆ StartTaskManager()

static BOOL StartTaskManager ( IN OUT PWLSESSION  Session)
static

Definition at line 60 of file sas.c.

62{
63 LPVOID lpEnvironment;
64 BOOL ret;
65
66 if (!Session->Gina.Functions.WlxStartApplication)
67 return FALSE;
68
70 &lpEnvironment,
71 Session->UserToken,
72 TRUE))
73 {
74 return FALSE;
75 }
76
77 ret = Session->Gina.Functions.WlxStartApplication(
78 Session->Gina.Context,
79 L"Default",
80 lpEnvironment,
81 L"taskmgr.exe");
82
83 DestroyEnvironmentBlock(lpEnvironment);
84 return ret;
85}
BOOL WINAPI DestroyEnvironmentBlock(IN LPVOID lpEnvironment)
Definition: environment.c:725
BOOL WINAPI CreateEnvironmentBlock(OUT LPVOID *lpEnvironment, IN HANDLE hToken, IN BOOL bInherit)
Definition: environment.c:503

Referenced by DoGenericAction().

◆ StartUserShell()

static BOOL StartUserShell ( IN OUT PWLSESSION  Session)
static

Definition at line 88 of file sas.c.

90{
91 LPVOID lpEnvironment = NULL;
92 BOOLEAN Old;
93 BOOL ret;
94
95 /* Create environment block for the user */
96 if (!CreateEnvironmentBlock(&lpEnvironment, Session->UserToken, TRUE))
97 {
98 WARN("WL: CreateEnvironmentBlock() failed\n");
99 return FALSE;
100 }
101
102 /* Get privilege */
103 /* FIXME: who should do it? winlogon or gina? */
104 /* FIXME: reverting to lower privileges after creating user shell? */
106
107 ret = Session->Gina.Functions.WlxActivateUserShell(
108 Session->Gina.Context,
109 L"Default",
110 NULL, /* FIXME */
111 lpEnvironment);
112
113 DestroyEnvironmentBlock(lpEnvironment);
114 return ret;
115}
#define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
Definition: security.c:657

Referenced by HandleLogon(), and SASWindowProc().

◆ UninitializeSAS()

static VOID UninitializeSAS ( IN OUT PWLSESSION  Session)
static

Definition at line 1108 of file sas.c.

1110{
1111 if (Session->SASWindow)
1112 {
1113 DestroyWindow(Session->SASWindow);
1114 Session->SASWindow = NULL;
1115 }
1116 if (Session->hEndOfScreenSaverThread)
1117 SetEvent(Session->hEndOfScreenSaverThread);
1119}
BOOL WINAPI UnregisterClassW(_In_ LPCWSTR, HINSTANCE)
BOOL WINAPI DestroyWindow(_In_ HWND)

Referenced by HandleShutdown(), and InitializeSAS().

◆ UnregisterHotKeys()

static BOOL UnregisterHotKeys ( IN PWLSESSION  Session,
IN HWND  hwndSAS 
)
static

Definition at line 1429 of file sas.c.

1432{
1433 /* Unregister the hotkeys */
1435
1436 if (Session->TaskManHotkey)
1438
1439 if (Session->LockWkStaHotkey)
1441
1442 if (Session->UtilManHotkey)
1444
1445 return TRUE;
1446}
BOOL WINAPI UnregisterHotKey(_In_opt_ HWND, _In_ int)

Referenced by SASWindowProc().

Variable Documentation

◆ ExitReactOSInProgress

BOOL ExitReactOSInProgress = FALSE
static

Definition at line 47 of file sas.c.

Referenced by LogoffShutdownThread(), and SASWindowProc().

◆ LuidNone

LUID LuidNone = {0, 0}