ReactOS 0.4.16-dev-1946-g52006dd
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 (_In_ PWLSESSION Session)
 
static VOID CloseAllConnections (_In_ 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

◆ CloseAllConnections()

static VOID CloseAllConnections ( _In_ PWLSESSION  Session)
static

Definition at line 495 of file sas.c.

497{
498 if (!Session->UserToken || !ImpersonateLoggedOnUser(Session->UserToken))
499 return;
501 RevertToSelf();
502}
#define NULL
Definition: types.h:112
BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
Definition: misc.c:152
BOOL WINAPI RevertToSelf(void)
Definition: security.c:855
DWORD WINAPI WNetClearConnections(HWND owner)
Definition: wnet.c:2827

Referenced by HandleLogoff().

◆ CreateLogoffSecurityAttributes()

static NTSTATUS CreateLogoffSecurityAttributes ( OUT PSECURITY_ATTRIBUTES ppsa)
static

Definition at line 889 of file sas.c.

891{
892 /* The following code is not working yet and messy */
893 /* Still, it gives some ideas about data types and functions involved and */
894 /* required to set up a SECURITY_DESCRIPTOR for a SECURITY_ATTRIBUTES */
895 /* instance for a thread, to allow that thread to ImpersonateLoggedOnUser(). */
896 /* Specifically THREAD_SET_THREAD_TOKEN is required. */
899 BYTE* pMem;
900 PACL pACL;
901 EXPLICIT_ACCESS Access;
902 PSID pEveryoneSID = NULL;
904
905 *ppsa = NULL;
906
907 // Let's first try to enumerate what kind of data we need for this to ever work:
908 // 1. The Winlogon SID, to be able to give it THREAD_SET_THREAD_TOKEN.
909 // 2. The users SID (the user trying to logoff, or rather shut down the system).
910 // 3. At least two EXPLICIT_ACCESS instances:
911 // 3.1 One for Winlogon itself, giving it the rights
912 // required to THREAD_SET_THREAD_TOKEN (as it's needed to successfully call
913 // ImpersonateLoggedOnUser).
914 // 3.2 One for the user, to allow *that* thread to perform its work.
915 // 4. An ACL to hold the these EXPLICIT_ACCESS ACE's.
916 // 5. A SECURITY_DESCRIPTOR to hold the ACL, and finally.
917 // 6. A SECURITY_ATTRIBUTES instance to pull all of this required stuff
918 // together, to hand it to CreateThread.
919 //
920 // However, it seems struct LOGOFF_SHUTDOWN_DATA doesn't contain
921 // these required SID's, why they'd have to be added.
922 // The Winlogon's own SID should probably only be created once,
923 // while the user's SID obviously must be created for each new user.
924 // Might as well store it when the user logs on?
925
927 1,
929 0, 0, 0, 0, 0, 0, 0,
930 &pEveryoneSID))
931 {
932 ERR("Failed to initialize security descriptor for logoff thread!\n");
933 return STATUS_UNSUCCESSFUL;
934 }
935
936 /* set up the required security attributes to be able to shut down */
937 /* To save space and time, allocate a single block of memory holding */
938 /* both SECURITY_ATTRIBUTES and SECURITY_DESCRIPTOR */
939 pMem = HeapAlloc(GetProcessHeap(),
940 0,
941 sizeof(SECURITY_ATTRIBUTES) +
943 sizeof(ACL));
944 if (!pMem)
945 {
946 ERR("Failed to allocate memory for logoff security descriptor!\n");
947 return STATUS_NO_MEMORY;
948 }
949
950 /* Note that the security descriptor needs to be in _absolute_ format, */
951 /* meaning its members must be pointers to other structures, rather */
952 /* than the relative format using offsets */
956
957 // Initialize an EXPLICIT_ACCESS structure for an ACE.
958 // The ACE will allow this thread to log off (and shut down the system, currently).
959 ZeroMemory(&Access, sizeof(Access));
961 Access.grfAccessMode = SET_ACCESS; // GRANT_ACCESS?
965 Access.Trustee.ptstrName = pEveryoneSID;
966
967 if (SetEntriesInAcl(1, &Access, NULL, &pACL) != ERROR_SUCCESS)
968 {
969 ERR("Failed to set Access Rights for logoff thread. Logging out will most likely fail.\n");
970
971 HeapFree(GetProcessHeap(), 0, pMem);
972 return STATUS_UNSUCCESSFUL;
973 }
974
976 {
977 ERR("Failed to initialize security descriptor for logoff thread!\n");
978 HeapFree(GetProcessHeap(), 0, pMem);
979 return STATUS_UNSUCCESSFUL;
980 }
981
983 TRUE, // bDaclPresent flag
984 pACL,
985 FALSE)) // not a default DACL
986 {
987 ERR("SetSecurityDescriptorDacl Error %lu\n", GetLastError());
988 HeapFree(GetProcessHeap(), 0, pMem);
989 return STATUS_UNSUCCESSFUL;
990 }
991
992 psa->nLength = sizeof(SECURITY_ATTRIBUTES);
993 psa->lpSecurityDescriptor = SecurityDescriptor;
994 psa->bInheritHandle = FALSE;
995
996 *ppsa = psa;
997
998 return STATUS_SUCCESS;
999}
@ TRUSTEE_IS_SID
Definition: accctrl.h:190
@ TRUSTEE_IS_WELL_KNOWN_GROUP
Definition: accctrl.h:182
#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 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
#define ZeroMemory
Definition: minwinbase.h:31
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:333
TRUSTEE_A Trustee
Definition: accctrl.h:336
DWORD grfInheritance
Definition: accctrl.h:335
ACCESS_MODE grfAccessMode
Definition: accctrl.h:334
TRUSTEE_TYPE TrusteeType
Definition: accctrl.h:208
TRUSTEE_FORM TrusteeForm
Definition: accctrl.h:207
LPSTR ptstrName
Definition: accctrl.h:209
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
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 1003 of file sas.c.

1005{
1006 if (psa)
1007 {
1009 }
1010}

Referenced by HandleLogoff().

◆ DispatchSAS()

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

Definition at line 1322 of file sas.c.

1325{
1326 DWORD wlxAction = WLX_SAS_ACTION_NONE;
1327 PSID LogonSid = NULL; /* FIXME */
1328 BOOL bSecure = TRUE;
1329
1330 switch (dwSasType)
1331 {
1333 switch (Session->LogonState)
1334 {
1335 case STATE_INIT:
1336 Session->LogonState = STATE_LOGGED_OFF;
1337 Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context);
1338 return;
1339
1340 case STATE_LOGGED_OFF:
1341 Session->LogonState = STATE_LOGGED_OFF_SAS;
1342
1344
1345 Session->Options = 0;
1346
1347 wlxAction = (DWORD)Session->Gina.Functions.WlxLoggedOutSAS(
1348 Session->Gina.Context,
1349 Session->SASAction,
1350 &Session->LogonId,
1351 LogonSid,
1352 &Session->Options,
1353 &Session->UserToken,
1354 &Session->MprNotifyInfo,
1355 (PVOID*)&Session->Profile);
1356 break;
1357
1359 /* Ignore SAS if we are already in an SAS state */
1360 return;
1361
1362 case STATE_LOGGED_ON:
1363 Session->LogonState = STATE_LOGGED_ON_SAS;
1364 SwitchDesktop(Session->WinlogonDesktop);
1365 wlxAction = (DWORD)Session->Gina.Functions.WlxLoggedOnSAS(Session->Gina.Context, dwSasType, NULL);
1366 if ((wlxAction == WLX_SAS_ACTION_NONE) ||
1367 (wlxAction == WLX_SAS_ACTION_TASKLIST))
1368 {
1369 /*
1370 * If the user canceled (WLX_SAS_ACTION_NONE) the
1371 * Logged-On SAS dialog, or clicked on the Task-Manager
1372 * button (WLX_SAS_ACTION_TASKLIST), switch back to
1373 * the application desktop and return to log-on state.
1374 * In the latter case, the Task-Manager is launched
1375 * by DoGenericAction(WLX_SAS_ACTION_TASKLIST), which
1376 * doesn't automatically do the switch back, because
1377 * the user may have also pressed on Ctrl-Shift-Esc
1378 * to start it while being on the Logged-On SAS dialog
1379 * and wanting to stay there.
1380 */
1381 SwitchDesktop(Session->ApplicationDesktop);
1382 Session->LogonState = STATE_LOGGED_ON;
1383 }
1384 break;
1385
1387 /* Ignore SAS if we are already in an SAS state */
1388 return;
1389
1390 case STATE_LOCKED:
1391 Session->LogonState = STATE_LOCKED_SAS;
1392
1394
1395 wlxAction = (DWORD)Session->Gina.Functions.WlxWkstaLockedSAS(Session->Gina.Context, dwSasType);
1396 break;
1397
1398 case STATE_LOCKED_SAS:
1399 /* Ignore SAS if we are already in an SAS state */
1400 return;
1401
1402 default:
1403 return;
1404 }
1405 break;
1406
1408 return;
1409
1411 if (!Session->Gina.Functions.WlxScreenSaverNotify(Session->Gina.Context, &bSecure))
1412 {
1413 /* Skip start of screen saver */
1414 SetEvent(Session->hEndOfScreenSaver);
1415 }
1416 else
1417 {
1418 StartScreenSaver(Session);
1419 if (bSecure)
1420 {
1421 wlxAction = WLX_SAS_ACTION_LOCK_WKSTA;
1422// DoGenericAction(Session, WLX_SAS_ACTION_LOCK_WKSTA);
1423 }
1424 }
1425 break;
1426
1428 SetEvent(Session->hUserActivity);
1429 break;
1430 }
1431
1432 DoGenericAction(Session, wlxAction);
1433}
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:1208
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 1208 of file sas.c.

1211{
1212 switch (wlxAction)
1213 {
1214 case WLX_SAS_ACTION_LOGON: /* 0x01 */
1215 if (Session->LogonState == STATE_LOGGED_OFF_SAS)
1216 {
1217 if (!HandleLogon(Session))
1218 {
1219 Session->LogonState = STATE_LOGGED_OFF;
1220 Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context);
1221 }
1222 }
1223 break;
1224 case WLX_SAS_ACTION_NONE: /* 0x02 */
1225 if (Session->LogonState == STATE_LOGGED_OFF_SAS)
1226 {
1227 Session->LogonState = STATE_LOGGED_OFF;
1228 Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context);
1229 }
1230 else if (Session->LogonState == STATE_LOGGED_ON_SAS)
1231 {
1232 Session->LogonState = STATE_LOGGED_ON;
1233 }
1234 else if (Session->LogonState == STATE_LOCKED_SAS)
1235 {
1236 Session->LogonState = STATE_LOCKED;
1237 Session->Gina.Functions.WlxDisplayLockedNotice(Session->Gina.Context);
1238 }
1239 break;
1240 case WLX_SAS_ACTION_LOCK_WKSTA: /* 0x03 */
1241 if ((Session->LogonState == STATE_LOGGED_ON) ||
1242 (Session->LogonState == STATE_LOGGED_ON_SAS))
1243 {
1244 if (Session->Gina.Functions.WlxIsLockOk(Session->Gina.Context))
1245 {
1246 Session->LogonState = STATE_LOCKED;
1247 SwitchDesktop(Session->WinlogonDesktop);
1248 /* We may be on the Logged-On SAS dialog, in which case
1249 * we need to close it if the lock action came via Win-L */
1252 Session->Gina.Functions.WlxDisplayLockedNotice(Session->Gina.Context);
1253 }
1254 }
1255 break;
1256 case WLX_SAS_ACTION_LOGOFF: /* 0x04 */
1257 case WLX_SAS_ACTION_SHUTDOWN: /* 0x05 */
1258 case WLX_SAS_ACTION_FORCE_LOGOFF: /* 0x09 */
1259 case WLX_SAS_ACTION_SHUTDOWN_POWER_OFF: /* 0x0a */
1260 case WLX_SAS_ACTION_SHUTDOWN_REBOOT: /* 0x0b */
1261 if ((Session->LogonState != STATE_INIT) &&
1262 (Session->LogonState != STATE_LOGGED_OFF) &&
1263 (Session->LogonState != STATE_LOGGED_OFF_SAS) &&
1264 (Session->LogonState != STATE_SHUT_DOWN))
1265 {
1266 ASSERT((Session->LogonState == STATE_LOGGED_ON) ||
1267 (Session->LogonState == STATE_LOGGED_ON_SAS) ||
1268 (Session->LogonState == STATE_LOCKED) ||
1269 (Session->LogonState == STATE_LOCKED_SAS));
1270
1271 if (!Session->Gina.Functions.WlxIsLogoffOk(Session->Gina.Context))
1272 break;
1273 if (!NT_SUCCESS(HandleLogoff(Session, wlxAction)))
1274 {
1275 RemoveStatusMessage(Session);
1276 break;
1277 }
1278 Session->Gina.Functions.WlxLogoff(Session->Gina.Context);
1279 }
1280 if (WLX_SHUTTINGDOWN(wlxAction))
1281 {
1282 if (!NT_SUCCESS(HandleShutdown(Session, wlxAction)))
1283 {
1284 RemoveStatusMessage(Session);
1285 Session->LogonState = STATE_LOGGED_OFF;
1286 Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context);
1287 }
1288 }
1289 else
1290 {
1291 RemoveStatusMessage(Session);
1292 Session->LogonState = STATE_LOGGED_OFF;
1293 Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context);
1294 }
1295 break;
1296 case WLX_SAS_ACTION_TASKLIST: /* 0x07 */
1297 if ((Session->LogonState == STATE_LOGGED_ON) ||
1298 (Session->LogonState == STATE_LOGGED_ON_SAS))
1299 {
1300 /* Start a Task-Manager instance on the application desktop.
1301 * If the user pressed Ctrl-Shift-Esc while being on the
1302 * Logged-On SAS dialog (on the Winlogon desktop), stay there. */
1303 StartTaskManager(Session);
1304 }
1305 break;
1306 case WLX_SAS_ACTION_UNLOCK_WKSTA: /* 0x08 */
1307 if ((Session->LogonState == STATE_LOCKED) ||
1308 (Session->LogonState == STATE_LOCKED_SAS))
1309 {
1311 SwitchDesktop(Session->ApplicationDesktop);
1312 Session->LogonState = STATE_LOGGED_ON;
1313 }
1314 break;
1315 default:
1316 WARN("Unknown SAS action 0x%lx\n", wlxAction);
1317 }
1318}
#define WARN(fmt,...)
Definition: precomp.h:61
VOID CallNotificationDlls(PWLSESSION pSession, NOTIFICATION_TYPE Type)
Definition: notify.c:530
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define ASSERT(a)
Definition: mode.c:44
NTSTATUS HandleShutdown(IN OUT PWLSESSION Session, IN DWORD wlxAction)
Definition: sas.c:1149
static BOOL StartTaskManager(IN OUT PWLSESSION Session)
Definition: sas.c:60
static BOOL HandleLogon(IN OUT PWLSESSION Session)
Definition: sas.c:571
static NTSTATUS HandleLogoff(_Inout_ PWLSESSION Session, _In_ DWORD wlxAction)
Definition: sas.c:1015
BOOL RemoveStatusMessage(IN PWLSESSION Session)
Definition: winlogon.c:391
@ STATE_SHUT_DOWN
Definition: winlogon.h:213
#define WLX_SHUTTINGDOWN(wlxAction)
Definition: winlogon.h:286
@ UnlockHandler
Definition: winlogon.h:267
@ LockHandler
Definition: winlogon.h:266
#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 546 of file sas.c.

548{
549 if (MprNotifyInfo->pszUserName)
550 LocalFree(MprNotifyInfo->pszUserName);
551 if (MprNotifyInfo->pszDomain)
552 LocalFree(MprNotifyInfo->pszDomain);
553 if (MprNotifyInfo->pszPassword)
554 {
555 /* Zero out the password buffer before freeing it */
556 SIZE_T pwdLen = (wcslen(MprNotifyInfo->pszPassword) + 1) * sizeof(WCHAR);
557 SecureZeroMemory(MprNotifyInfo->pszPassword, pwdLen);
558 LocalFree(MprNotifyInfo->pszPassword);
559 }
560 if (MprNotifyInfo->pszOldPassword)
561 {
562 /* Zero out the password buffer before freeing it */
563 SIZE_T pwdLen = (wcslen(MprNotifyInfo->pszOldPassword) + 1) * sizeof(WCHAR);
564 SecureZeroMemory(MprNotifyInfo->pszOldPassword, pwdLen);
565 LocalFree(MprNotifyInfo->pszOldPassword);
566 }
567}
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:1465
__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 510 of file sas.c.

512{
513 PWLX_PROFILE_V2_0 pProfile = (PWLX_PROFILE_V2_0)Profile;
514
515 if (pProfile->dwType != WLX_PROFILE_TYPE_V1_0
516 && pProfile->dwType != WLX_PROFILE_TYPE_V2_0)
517 {
518 ERR("WL: Wrong profile info\n");
519 return;
520 }
521
522 if (pProfile->pszProfile)
523 LocalFree(pProfile->pszProfile);
524 if (pProfile->dwType >= WLX_PROFILE_TYPE_V2_0)
525 {
526 if (pProfile->pszPolicy)
527 LocalFree(pProfile->pszPolicy);
528 if (pProfile->pszNetworkDefaultUserProfile)
530 if (pProfile->pszServerName)
531 LocalFree(pProfile->pszServerName);
532 if (pProfile->pszEnvironment)
533 LocalFree(pProfile->pszEnvironment);
534 }
535}
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 1015 of file sas.c.

1018{
1022
1024 if (!NT_SUCCESS(Status))
1025 {
1026 ERR("Failed to create Logoff security descriptor. Status 0x%08lx\n", Status);
1027 return Status;
1028 }
1029
1030 /* Run the Logoff thread. Log off as well if we are
1031 * invoked as part of a shutdown operation. */
1033 WLX_LOGGINGOFF(wlxAction)
1034 ? wlxAction
1036 if (!NT_SUCCESS(Status))
1037 {
1038 ERR("Failed to start the Logoff thread, Status 0x%08lx\n", Status);
1040 return Status;
1041 }
1042
1043 /* Invoke Logoff notifications on the application desktop */
1044 SwitchDesktop(Session->ApplicationDesktop);
1045 DisplayStatusMessage(Session, Session->ApplicationDesktop, IDS_LOGGINGOFF);
1047 RemoveStatusMessage(Session);
1048
1049 /* The remaining Logoff steps run on the Winlogon desktop */
1050 SwitchDesktop(Session->WinlogonDesktop);
1051
1052 PlayLogoffShutdownSound(Session, WLX_SHUTTINGDOWN(wlxAction));
1053
1054 /* Close all user network connections */
1055 DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_CLOSINGNETWORKCONNECTIONS);
1056 CloseAllConnections(Session);
1057 // TODO: Do any other user-specific network-related cleaning:
1058 // user-added NetAPI message aliases; user cached credentials (remote login)...
1059
1060 SetWindowStationUser(Session->InteractiveWindowStation,
1061 &LuidNone, NULL, 0);
1062
1063 /* Kill remaining COM processes that may have been started by logoff scripts */
1064 hThread = CreateThread(psa, 0, KillComProcesses, (PVOID)Session->UserToken, 0, NULL);
1065 if (hThread)
1066 {
1069 }
1070
1071 /* We're done with the SECURITY_DESCRIPTOR */
1073
1074 DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_SAVEYOURSETTINGS);
1075
1076 RtlFreeHeap(RtlGetProcessHeap(), 0, Session->UserName);
1077 RtlFreeHeap(RtlGetProcessHeap(), 0, Session->Domain);
1078 Session->UserName = Session->Domain = NULL;
1079
1080 if (Session->hProfileInfo)
1081 UnloadUserProfile(Session->UserToken, Session->hProfileInfo);
1082 Session->hProfileInfo = NULL;
1083
1084 /* Restore default system parameters */
1086
1087 // TODO: Remove session access to window station
1088 // (revert what security.c!AllowAccessOnSession() does).
1089
1090 /* Switch back to default SYSTEM user */
1091 CloseHandle(Session->UserToken);
1092 Session->UserToken = NULL;
1093 Session->LogonId = LuidNone;
1094
1095 Session->LogonState = STATE_LOGGED_OFF;
1096
1097 return STATUS_SUCCESS;
1098}
DWORD WINAPI UpdatePerUserSystemParameters(DWORD dw1, DWORD dw2)
LONG NTSTATUS
Definition: precomp.h:26
#define IDS_CLOSINGNETWORKCONNECTIONS
Definition: resource.h:32
#define IDS_SAVEYOURSETTINGS
Definition: resource.h:36
#define IDS_LOGGINGOFF
Definition: resource.h:38
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
#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:2206
#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:889
static DWORD WINAPI KillComProcesses(LPVOID Parameter)
Definition: sas.c:859
LUID LuidNone
Definition: sas.c:49
static NTSTATUS RunLogoffShutdownThread(_In_ PWLSESSION Session, _In_opt_ PSECURITY_ATTRIBUTES psa, _In_ DWORD wlxAction)
Definition: sas.c:779
static VOID PlayLogoffShutdownSound(_In_ PWLSESSION Session, _In_ BOOL bShutdown)
Definition: sas.c:397
static VOID DestroyLogoffSecurityAttributes(IN PSECURITY_ATTRIBUTES psa)
Definition: sas.c:1003
static VOID CloseAllConnections(_In_ PWLSESSION Session)
Definition: sas.c:495
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:370
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:282
@ LogoffHandler
Definition: winlogon.h:265

Referenced by DoGenericAction().

◆ HandleLogon()

static BOOL HandleLogon ( IN OUT PWLSESSION  Session)
static

Definition at line 571 of file sas.c.

573{
574 BOOL ret = FALSE;
575
576 /* Loading personal settings */
577 DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_LOADINGYOURPERSONALSETTINGS);
578
579 Session->hProfileInfo = NULL;
580 if (!(Session->Options & WLX_LOGON_OPT_NO_PROFILE))
581 {
582 HKEY hKey;
583 LONG lError;
584 BOOL bNoPopups = FALSE;
585 PROFILEINFOW ProfileInfo;
586
587 if (Session->Profile == NULL
588 || (Session->Profile->dwType != WLX_PROFILE_TYPE_V1_0
589 && Session->Profile->dwType != WLX_PROFILE_TYPE_V2_0))
590 {
591 ERR("WL: Wrong profile\n");
592 goto cleanup;
593 }
594
595 /* Check whether error messages may be displayed when loading the user profile */
597 L"System\\CurrentControlSet\\Control\\Windows",
598 0,
600 &hKey);
601 if (lError == ERROR_SUCCESS)
602 {
603 DWORD dwValue, dwType, cbData = sizeof(dwValue);
604 lError = RegQueryValueExW(hKey, L"NoPopupsOnBoot", NULL,
605 &dwType, (PBYTE)&dwValue, &cbData);
606 if ((lError == ERROR_SUCCESS) && (dwType == REG_DWORD) && (cbData == sizeof(dwValue)))
607 bNoPopups = !!dwValue;
608
610 }
611
612 /* Load the user profile */
613 ZeroMemory(&ProfileInfo, sizeof(ProfileInfo));
614 ProfileInfo.dwSize = sizeof(ProfileInfo);
615 if (bNoPopups)
616 ProfileInfo.dwFlags |= PI_NOUI;
617 ProfileInfo.lpUserName = Session->MprNotifyInfo.pszUserName;
618 ProfileInfo.lpProfilePath = Session->Profile->pszProfile;
619 if (Session->Profile->dwType >= WLX_PROFILE_TYPE_V2_0)
620 {
621 ProfileInfo.lpDefaultPath = Session->Profile->pszNetworkDefaultUserProfile;
622 ProfileInfo.lpServerName = Session->Profile->pszServerName;
623 ProfileInfo.lpPolicyPath = Session->Profile->pszPolicy;
624 }
625
626 if (!LoadUserProfileW(Session->UserToken, &ProfileInfo))
627 {
628 ERR("WL: LoadUserProfileW() failed\n");
629 goto cleanup;
630 }
631 Session->hProfileInfo = ProfileInfo.hProfile;
632 }
633
634 /* Cache the username and domain */
635 Session->UserName = WlStrDup(Session->MprNotifyInfo.pszUserName);
636 Session->Domain = WlStrDup(Session->MprNotifyInfo.pszDomain);
637
638 /* Create environment block for the user */
639 if (!CreateUserEnvironment(Session))
640 {
641 WARN("WL: CreateUserEnvironment() failed\n");
642 goto cleanup;
643 }
644
645 /* Enable per-user settings */
646 DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_APPLYINGYOURPERSONALSETTINGS);
648
649 /* Set default user language */
650 if (!SetDefaultLanguage(Session))
651 {
652 WARN("WL: SetDefaultLanguage() failed\n");
653 goto cleanup;
654 }
655
656 /* Allow winsta and desktop access for this session */
657 if (!AllowAccessOnSession(Session))
658 {
659 WARN("WL: AllowAccessOnSession() failed to give winsta & desktop access for this session\n");
660 goto cleanup;
661 }
662
664
665 /* Connect remote resources */
666 RestoreAllConnections(Session);
667
668 /* Start the user shell */
670 if (!StartUserShell(Session))
671 {
672 //WCHAR StatusMsg[256];
673 WARN("WL: WlxActivateUserShell() failed\n");
674 //LoadStringW(hAppInstance, IDS_FAILEDACTIVATEUSERSHELL, StatusMsg, ARRAYSIZE(StatusMsg));
675 //MessageBoxW(0, StatusMsg, NULL, MB_ICONERROR);
676 goto cleanup;
677 }
679
680 if (!InitializeScreenSaver(Session))
681 WARN("WL: Failed to initialize screen saver\n");
682
683 /* Logon has succeeded. Play sound. */
684 PlayLogonSound(Session);
685
686 /* NOTE: The logon timestamp has to be set after calling PlayLogonSound
687 * to correctly detect the startup event (first logon) */
688 SetLogonTimestamp(Session);
689 ret = TRUE;
690
691cleanup:
692 if (Session->Profile)
693 {
694 FreeWlxProfileInfo(Session->Profile);
695 LocalFree(Session->Profile);
696 Session->Profile = NULL;
697 }
698 FreeWlxMprInfo(&Session->MprNotifyInfo);
699 ZeroMemory(&Session->MprNotifyInfo, sizeof(Session->MprNotifyInfo));
700
701 RemoveStatusMessage(Session);
702
703 if (!ret)
704 {
705 RtlFreeHeap(RtlGetProcessHeap(), 0, Session->UserName);
706 RtlFreeHeap(RtlGetProcessHeap(), 0, Session->Domain);
707 Session->UserName = Session->Domain = NULL;
708
709 if (Session->hProfileInfo)
710 UnloadUserProfile(Session->UserToken, Session->hProfileInfo);
711 Session->hProfileInfo = NULL;
712
713 /* Restore default system parameters */
715
716 // TODO: Remove session access to window station
717 // (revert what security.c!AllowAccessOnSession() does).
718 SetWindowStationUser(Session->InteractiveWindowStation,
719 &LuidNone, NULL, 0);
720
721 /* Switch back to default SYSTEM user */
722 CloseHandle(Session->UserToken);
723 Session->UserToken = NULL;
724 Session->LogonId = LuidNone;
725 }
726 else // if (ret)
727 {
728 SwitchDesktop(Session->ApplicationDesktop);
729 Session->LogonState = STATE_LOGGED_ON;
730 }
731 return ret;
732}
BOOL CreateUserEnvironment(IN PWLSESSION Session)
Definition: environment.c:128
#define IDS_APPLYINGYOURPERSONALSETTINGS
Definition: resource.h:28
#define IDS_LOADINGYOURPERSONALSETTINGS
Definition: resource.h:31
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:1392
#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:1019
long LONG
Definition: pedump.c:60
_In_opt_ _In_opt_ _In_ _In_ DWORD cbData
Definition: shlwapi.h:761
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:546
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:510
BOOL SetDefaultLanguage(IN PWLSESSION Session)
Definition: sas.c:119
static VOID PlayLogonSound(_In_ PWLSESSION Session)
Definition: sas.c:373
static VOID RestoreAllConnections(_In_ PWLSESSION Session)
Definition: sas.c:432
#define REG_DWORD
Definition: sdbapi.c:615
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
PWSTR WlStrDup(_In_opt_ PCWSTR String)
Duplicates the given string, allocating a buffer on the heap.
Definition: winlogon.c:29
FORCEINLINE VOID SetLogonTimestamp(_Inout_ PWLSESSION Session)
Definition: winlogon.h:298
@ PostShellHandler
Definition: winlogon.h:275
@ LogonHandler
Definition: winlogon.h:264
@ StartShellHandler
Definition: winlogon.h:274
#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 1489 of file sas.c.

1492{
1493 LPWSTR EventName;
1494
1495 switch (uType)
1496 {
1497 case 0xFFFFFFFF:
1498 EventName = NULL;
1499 break;
1500 case MB_OK:
1501 EventName = L"SystemDefault";
1502 break;
1503 case MB_ICONASTERISK:
1504 EventName = L"SystemAsterisk";
1505 break;
1506 case MB_ICONEXCLAMATION:
1507 EventName = L"SystemExclamation";
1508 break;
1509 case MB_ICONHAND:
1510 EventName = L"SystemHand";
1511 break;
1512 case MB_ICONQUESTION:
1513 EventName = L"SystemQuestion";
1514 break;
1515 default:
1516 WARN("Unhandled type %d\n", uType);
1517 EventName = L"SystemDefault";
1518 }
1519
1520 return PlayEventSound(Session, EventName);
1521}
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 1149 of file sas.c.

1152{
1154 UINT uMsgId;
1155 BOOLEAN Old;
1156
1157 /* Display the appropriate shutdown or reboot message */
1158 if (wlxAction == WLX_SAS_ACTION_SHUTDOWN_REBOOT)
1159 uMsgId = IDS_REACTOSISRESTARTING;
1160 else
1162
1163 // SwitchDesktop(Session->WinlogonDesktop);
1164 DisplayStatusMessage(Session, Session->WinlogonDesktop, uMsgId);
1165
1166 /* Invoke Shutdown notifications and notify GINA */
1168 Session->Gina.Functions.WlxShutdown(Session->Gina.Context, wlxAction);
1169
1170 /* Run the shutdown thread. *IGNORE* all failures as we want to force shutting down! */
1171 Status = RunLogoffShutdownThread(Session, NULL, wlxAction);
1172 if (!NT_SUCCESS(Status))
1173 ERR("Failed to start the Shutdown thread, Status 0x%08lx\n", Status);
1174
1175 /* Show again the shutdown message */
1176 // SwitchDesktop(Session->WinlogonDesktop); // Re-enable if you notice the desktop may have switched to something else.
1177 DisplayStatusMessage(Session, Session->WinlogonDesktop, uMsgId);
1178
1179 /* Destroy SAS window */
1180 UninitializeSAS(Session);
1181
1182 /* Now we can shut down NT */
1183 ERR("Shutting down NT...\n");
1185 if (wlxAction == WLX_SAS_ACTION_SHUTDOWN_REBOOT)
1186 {
1188 }
1189 else
1190 {
1191 if (FALSE)
1192 {
1193 /* FIXME - only show this dialog if it's a shutdown and the computer doesn't support APM */
1196 }
1197 if (wlxAction == WLX_SAS_ACTION_SHUTDOWN_POWER_OFF)
1199 else // if (wlxAction == WLX_SAS_ACTION_SHUTDOWN)
1201 }
1203 return STATUS_SUCCESS;
1204}
unsigned char BOOLEAN
HINSTANCE hAppInstance
Definition: mmc.c:23
#define IDS_REACTOSISSHUTTINGDOWN
Definition: resource.h:33
#define IDD_SHUTDOWNCOMPUTER
Definition: resource.h:9
#define IDS_REACTOSISRESTARTING
Definition: resource.h:41
#define SE_SHUTDOWN_PRIVILEGE
Definition: security.c:673
unsigned int UINT
Definition: ndis.h:50
@ 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:1103
static VOID UninitializeSAS(IN OUT PWLSESSION Session)
Definition: sas.c:1135
@ ShutdownHandler
Definition: winlogon.h:269
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 1740 of file sas.c.

1742{
1743 WNDCLASSEXW swc;
1744 BOOL ret = FALSE;
1745
1746 if (!SwitchDesktop(Session->WinlogonDesktop))
1747 {
1748 ERR("WL: Failed to switch to winlogon desktop\n");
1749 goto cleanup;
1750 }
1751
1752 /* Register SAS window class */
1753 swc.cbSize = sizeof(WNDCLASSEXW);
1754 swc.style = CS_SAVEBITS;
1756 swc.cbClsExtra = 0;
1757 swc.cbWndExtra = 0;
1758 swc.hInstance = hAppInstance;
1759 swc.hIcon = NULL;
1760 swc.hCursor = NULL;
1761 swc.hbrBackground = NULL;
1762 swc.lpszMenuName = NULL;
1764 swc.hIconSm = NULL;
1765 if (RegisterClassExW(&swc) == 0)
1766 {
1767 ERR("WL: Failed to register SAS window class\n");
1768 goto cleanup;
1769 }
1770
1771 /* Create invisible SAS window */
1772 Session->SASWindow = CreateWindowExW(
1773 0,
1776 WS_POPUP,
1777 0, 0, 0, 0, 0, 0,
1778 hAppInstance, Session);
1779 if (!Session->SASWindow)
1780 {
1781 ERR("WL: Failed to create SAS window\n");
1782 goto cleanup;
1783 }
1784
1785 /* Register SAS window to receive SAS notifications */
1786 if (!SetLogonNotifyWindow(Session->SASWindow))
1787 {
1788 ERR("WL: Failed to register SAS window\n");
1789 goto cleanup;
1790 }
1791
1793 return FALSE;
1794
1795 ret = TRUE;
1796
1797cleanup:
1798 if (!ret)
1799 UninitializeSAS(Session);
1800 return ret;
1801}
#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:1526
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 859 of file sas.c.

861{
862 HANDLE UserToken = (HANDLE)Parameter;
863 DWORD ret = TRUE;
864
865 TRACE("In KillComProcesses\n");
866
867 if (UserToken && !ImpersonateLoggedOnUser(UserToken))
868 {
869 ERR("ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
870 return FALSE;
871 }
872
873 /* Attempt to kill remaining processes. No notifications needed. */
875 {
876 ERR("Unable to kill COM apps, error %lu\n", GetLastError());
877 ret = FALSE;
878 }
879
880 if (UserToken)
881 RevertToSelf();
882
883 return ret;
884}
#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 738 of file sas.c.

740{
742 HANDLE UserToken = LSData->Session->UserToken;
743 DWORD ret = TRUE;
744 UINT uFlags;
745
746 if (UserToken && !ImpersonateLoggedOnUser(UserToken))
747 {
748 ERR("ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
749 return FALSE;
750 }
751
752 // FIXME: To be really fixed: need to check what needs to be kept and what needs to be removed there.
753 //
754 // uFlags = EWX_INTERNAL_KILL_USER_APPS | (LSData->Flags & EWX_FLAGS_MASK) |
755 // ((LSData->Flags & EWX_ACTION_MASK) == EWX_LOGOFF ? EWX_CALLER_WINLOGON_LOGOFF : 0);
756
757 uFlags = EWX_CALLER_WINLOGON | (LSData->Flags & 0x0F);
758
759 TRACE("In LogoffShutdownThread with uFlags == 0x%x; exit_in_progress == %s\n",
760 uFlags, ExitReactOSInProgress ? "TRUE" : "FALSE");
761
763
764 /* Close processes of the interactive user */
765 if (!ExitWindowsEx(uFlags, 0))
766 {
767 ERR("Unable to kill user apps, error %lu\n", GetLastError());
768 ret = FALSE;
769 }
770
771 if (UserToken)
772 RevertToSelf();
773
774 return ret;
775}
UINT uFlags
Definition: api.c:59
struct tagLOGOFF_SHUTDOWN_DATA * PLOGOFF_SHUTDOWN_DATA
static BOOL ExitReactOSInProgress
Definition: sas.c:47
HANDLE UserToken
Definition: winlogon.h:237
PWLSESSION Session
Definition: sas.c:44

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:306

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:581
@ SC_STATUS_PROCESS_INFO
Definition: winsvc.h:125
#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 1437 of file sas.c.

1440{
1441 /* Register Ctrl+Alt+Del hotkey */
1443 {
1444 ERR("WL: Unable to register Ctrl+Alt+Del hotkey\n");
1445 return FALSE;
1446 }
1447
1448 /* Register Ctrl+Shift+Esc "Task Manager" hotkey (optional) */
1450 if (!Session->TaskManHotkey)
1451 WARN("WL: Unable to register Ctrl+Shift+Esc hotkey\n");
1452
1453 /* Register Win+L "Lock Workstation" hotkey (optional) */
1454 Session->LockWkStaHotkey = RegisterHotKey(hwndSAS, IDHK_WIN_L, MOD_WIN, 'L');
1455 if (!Session->LockWkStaHotkey)
1456 WARN("WL: Unable to register Win+L hotkey\n");
1457
1458 /* Register Win+U "Accessibility Utility" hotkey (optional) */
1459 Session->UtilManHotkey = RegisterHotKey(hwndSAS, IDHK_WIN_U, MOD_WIN, 'U');
1460 if (!Session->UtilManHotkey)
1461 WARN("WL: Unable to register Win+U hotkey\n");
1462
1463 return TRUE;
1464}
#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 ( _In_ PWLSESSION  Session)
static

Definition at line 432 of file sas.c.

434{
435 DWORD dRet;
436 HANDLE hEnum;
437 LPNETRESOURCE lpRes;
438 DWORD dSize = 0x1000;
439 DWORD dCount = -1;
440 LPNETRESOURCE lpCur;
441 BOOL UserProfile;
442
443 UserProfile = (Session && Session->UserToken);
444 if (!UserProfile)
445 return;
446
447 if (!ImpersonateLoggedOnUser(Session->UserToken))
448 {
449 ERR("WL: ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
450 return;
451 }
452
454 if (dRet != WN_SUCCESS)
455 {
456 ERR("Failed to open enumeration: %lu\n", dRet);
457 goto quit;
458 }
459
460 lpRes = HeapAlloc(GetProcessHeap(), 0, dSize);
461 if (!lpRes)
462 {
463 ERR("Failed to allocate memory\n");
464 WNetCloseEnum(hEnum);
465 goto quit;
466 }
467
468 do
469 {
470 dSize = 0x1000;
471 dCount = -1;
472
473 ZeroMemory(lpRes, dSize);
474 dRet = WNetEnumResource(hEnum, &dCount, lpRes, &dSize);
475 if (dRet == WN_SUCCESS || dRet == WN_MORE_DATA)
476 {
477 lpCur = lpRes;
478 for (; dCount; dCount--)
479 {
481 lpCur++;
482 }
483 }
484 } while (dRet != WN_NO_MORE_ENTRIES);
485
486 HeapFree(GetProcessHeap(), 0, lpRes);
487 WNetCloseEnum(hEnum);
488
489quit:
490 RevertToSelf();
491}
void quit(int argc, const char *argv[])
Definition: cmds.c:1606
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 779 of file sas.c.

783{
784 PCSTR pDescName;
787 DWORD dwExitCode;
788
789 /* Validate the action */
790 if (WLX_LOGGINGOFF(wlxAction))
791 {
792 pDescName = "Logoff";
793 }
794 else if (WLX_SHUTTINGDOWN(wlxAction))
795 {
796 pDescName = "Shutdown";
797 }
798 else
799 {
800 ASSERT(FALSE);
802 }
803
804 /* Prepare data for the logoff/shutdown thread */
805 LSData = HeapAlloc(GetProcessHeap(), 0, sizeof(*LSData));
806 if (!LSData)
807 {
808 ERR("Failed to allocate %s thread data\n", pDescName);
809 return STATUS_NO_MEMORY;
810 }
811
812 /* Set the flags accordingly */
813 if (WLX_LOGGINGOFF(wlxAction))
814 {
815 LSData->Flags = EWX_LOGOFF;
816 if (wlxAction == WLX_SAS_ACTION_FORCE_LOGOFF)
817 LSData->Flags |= EWX_FORCE;
818 }
819 else // if (WLX_SHUTTINGDOWN(wlxAction))
820 {
821 /* Because we are shutting down the OS, force processes termination too */
822 LSData->Flags = EWX_SHUTDOWN | EWX_FORCE;
823 if (wlxAction == WLX_SAS_ACTION_SHUTDOWN_POWER_OFF)
824 LSData->Flags |= EWX_POWEROFF;
825 else if (wlxAction == WLX_SAS_ACTION_SHUTDOWN_REBOOT)
826 LSData->Flags |= EWX_REBOOT;
827 }
828
829 LSData->Session = Session;
830
831 /* Run the logoff/shutdown thread */
833 if (!hThread)
834 {
835 ERR("Unable to create %s thread, error %lu\n", pDescName, GetLastError());
836 HeapFree(GetProcessHeap(), 0, LSData);
837 return STATUS_UNSUCCESSFUL;
838 }
840 HeapFree(GetProcessHeap(), 0, LSData);
841 if (!GetExitCodeThread(hThread, &dwExitCode))
842 {
843 ERR("Unable to get %s thread exit code (error %lu)\n", pDescName, GetLastError());
845 return STATUS_UNSUCCESSFUL;
846 }
848 if (dwExitCode == 0)
849 {
850 ERR("%s thread returned failure\n", pDescName);
851 return STATUS_UNSUCCESSFUL;
852 }
853 return STATUS_SUCCESS;
854}
BOOL WINAPI GetExitCodeThread(IN HANDLE hThread, OUT LPDWORD lpExitCode)
Definition: thread.c:541
static DWORD WINAPI LogoffShutdownThread(LPVOID Parameter)
Definition: sas.c:738
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 1526 of file sas.c.

1531{
1533
1534 switch (uMsg)
1535 {
1536 case WM_HOTKEY:
1537 {
1538 switch (wParam)
1539 {
1540 case IDHK_CTRL_ALT_DEL:
1541 {
1542 TRACE("SAS: CONTROL+ALT+DELETE\n");
1543 if (!Session->Gina.UseCtrlAltDelete)
1544 break;
1546 return TRUE;
1547 }
1549 {
1550 TRACE("SAS: CONTROL+SHIFT+ESCAPE\n");
1552 return TRUE;
1553 }
1554 case IDHK_WIN_L:
1555 {
1556 TRACE("SAS: WIN+L\n");
1558 return TRUE;
1559 }
1560 case IDHK_WIN_U:
1561 {
1562 TRACE("SAS: WIN+U\n");
1563 // PostMessageW(Session->SASWindow, WM_LOGONNOTIFY, LN_ACCESSIBILITY, 0);
1564 return TRUE;
1565 }
1566 }
1567 break;
1568 }
1569 case WM_CREATE:
1570 {
1571 /* Get the session pointer from the create data */
1572 Session = (PWLSESSION)((LPCREATESTRUCT)lParam)->lpCreateParams;
1573
1574 /* Save the Session pointer */
1575 SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (LONG_PTR)Session);
1576 if (GetSetupType())
1577 return TRUE;
1578 return RegisterHotKeys(Session, hwndDlg);
1579 }
1580 case WM_DESTROY:
1581 {
1582 if (!GetSetupType())
1583 UnregisterHotKeys(Session, hwndDlg);
1584 PostQuitMessage(0);
1585 return TRUE;
1586 }
1587 case WM_SETTINGCHANGE:
1588 {
1589 UINT uiAction = (UINT)wParam;
1590 if (uiAction == SPI_SETSCREENSAVETIMEOUT
1591 || uiAction == SPI_SETSCREENSAVEACTIVE)
1592 {
1594 }
1595 return TRUE;
1596 }
1597 case WM_LOGONNOTIFY:
1598 {
1599 switch(wParam)
1600 {
1601 case LN_MESSAGE_BEEP:
1602 {
1603 return HandleMessageBeep(Session, lParam);
1604 }
1605 case LN_SHELL_EXITED:
1606 {
1607 /* lParam is the exit code */
1608 if (lParam != 1 &&
1609 Session->LogonState != STATE_LOGGED_OFF &&
1610 Session->LogonState != STATE_LOGGED_OFF_SAS)
1611 {
1612 SetTimer(hwndDlg, 1, 1000, NULL);
1613 }
1614 break;
1615 }
1617 {
1619 break;
1620 }
1621#if 0
1622 case LN_ACCESSIBILITY:
1623 {
1624 ERR("LN_ACCESSIBILITY(lParam = %lu)\n", lParam);
1625 break;
1626 }
1627#endif
1629 {
1631 break;
1632 }
1633 case LN_LOGOFF:
1634 {
1635 UINT Flags = (UINT)lParam;
1637 DWORD wlxAction;
1638
1639 TRACE("\tFlags : 0x%lx\n", lParam);
1640
1641 /*
1642 * Our caller (USERSRV) should have added the shutdown flag
1643 * when setting also poweroff or reboot.
1644 */
1645 if ((Action & (EWX_POWEROFF | EWX_REBOOT)) && !(Action & EWX_SHUTDOWN))
1646 {
1647 ERR("Missing EWX_SHUTDOWN flag for poweroff or reboot; action 0x%x\n", Action);
1649 }
1650
1651 // INVESTIGATE: Our HandleLogoff/HandleShutdown may instead
1652 // take an EWX_* flags combination to determine what to do
1653 // more precisely.
1654 /* Map EWX_* flags to WLX_* actions and check for any unhandled flag */
1655 if (Action & EWX_POWEROFF)
1656 {
1659 }
1660 else if (Action & EWX_REBOOT)
1661 {
1664 }
1665 else if (Action & EWX_SHUTDOWN)
1666 {
1667 wlxAction = WLX_SAS_ACTION_SHUTDOWN;
1668 Action &= ~EWX_SHUTDOWN;
1669 }
1670 else // EWX_LOGOFF
1671 {
1672 if (Action & EWX_FORCE)
1673 wlxAction = WLX_SAS_ACTION_FORCE_LOGOFF;
1674 else
1675 wlxAction = WLX_SAS_ACTION_LOGOFF;
1676 Action &= ~(EWX_LOGOFF | EWX_FORCE);
1677 }
1678 if (Action)
1679 ERR("Unhandled EWX_* action flags: 0x%x\n", Action);
1680
1681 TRACE("In LN_LOGOFF, exit_in_progress == %s\n",
1682 ExitReactOSInProgress ? "TRUE" : "FALSE");
1683
1684 /*
1685 * In case a parallel shutdown request is done (while we are
1686 * being to shut down) and it was not done by Winlogon itself,
1687 * then just stop here.
1688 */
1689#if 0
1690// This code is commented at the moment (even if it's correct) because
1691// our log-offs do not really work: the shell is restarted, no app is killed
1692// etc... and as a result you just get explorer opening "My Documents". And
1693// if you try now a shut down, it won't work because winlogon thinks it is
1694// still in the middle of a shutdown.
1695// Maybe we also need to reset ExitReactOSInProgress somewhere else??
1697 {
1698 break;
1699 }
1700#endif
1701 /* Now do the shutdown action proper */
1702 DoGenericAction(Session, wlxAction);
1703 return 1;
1704 }
1705 case LN_LOGOFF_CANCELED:
1706 {
1707 ERR("Logoff canceled! Before: exit_in_progress == %s; After: FALSE\n",
1708 ExitReactOSInProgress ? "TRUE" : "FALSE");
1709
1711 return 1;
1712 }
1713 default:
1714 {
1715 ERR("WM_LOGONNOTIFY case %d is unimplemented\n", wParam);
1716 }
1717 }
1718 return 0;
1719 }
1720 case WM_TIMER:
1721 {
1722 if (wParam == 1)
1723 {
1724 KillTimer(hwndDlg, 1);
1725 StartUserShell(Session);
1726 }
1727 break;
1728 }
1729 case WLX_WM_SAS:
1730 {
1731 DispatchSAS(Session, (DWORD)wParam);
1732 return TRUE;
1733 }
1734 }
1735
1736 return DefWindowProc(hwndDlg, uMsg, wParam, lParam);
1737}
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:1437
static VOID DispatchSAS(IN OUT PWLSESSION Session, IN DWORD dwSasType)
Definition: sas.c:1322
static BOOL HandleMessageBeep(_In_ PWLSESSION Session, _In_ UINT uType)
Definition: sas.c:1489
#define EWX_ACTION_MASK
Definition: sas.c:39
static BOOL UnregisterHotKeys(IN PWLSESSION Session, IN HWND hwndSAS)
Definition: sas.c:1468
BOOL UseCtrlAltDelete
Definition: winlogon.h:132
HANDLE hScreenSaverParametersChanged
Definition: winlogon.h:249
LOGON_STATE LogonState
Definition: winlogon.h:239
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
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
#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:1026
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 1103 of file sas.c.

1108{
1110
1111 switch (uMsg)
1112 {
1113 case WM_COMMAND:
1114 {
1115 switch (LOWORD(wParam))
1116 {
1119 return TRUE;
1120 }
1121 break;
1122 }
1123 case WM_INITDIALOG:
1124 {
1125 /* Remove the Close menu item */
1127 return TRUE;
1128 }
1129 }
1130 return FALSE;
1131}
#define IDC_BTNSHTDOWNCOMPUTER
Definition: resource.h:12
#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
BOOL WINAPI DeleteMenu(_In_ HMENU, _In_ UINT, _In_ UINT)
#define WM_INITDIALOG
Definition: winuser.h:1767
HMENU WINAPI GetSystemMenu(_In_ HWND, _In_ BOOL)
#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 1135 of file sas.c.

1137{
1138 if (Session->SASWindow)
1139 {
1140 DestroyWindow(Session->SASWindow);
1141 Session->SASWindow = NULL;
1142 }
1143 if (Session->hEndOfScreenSaverThread)
1144 SetEvent(Session->hEndOfScreenSaverThread);
1146}
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 1468 of file sas.c.

1471{
1472 /* Unregister the hotkeys */
1474
1475 if (Session->TaskManHotkey)
1477
1478 if (Session->LockWkStaHotkey)
1480
1481 if (Session->UtilManHotkey)
1483
1484 return TRUE;
1485}
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}