ReactOS 0.4.15-dev-7961-gdcf9eb0
sas.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Winlogon
4 * FILE: base/system/winlogon/sas.c
5 * PURPOSE: Secure Attention Sequence
6 * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net)
7 * Hervé Poussineau (hpoussin@reactos.org)
8 * Arnav Bhatt (arnavbhatt288@gmail.com)
9 * UPDATE HISTORY:
10 * Created 28/03/2004
11 */
12
13/* INCLUDES *****************************************************************/
14
15#include "winlogon.h"
16
17#define WIN32_LEAN_AND_MEAN
18#include <aclapi.h>
19#include <mmsystem.h>
20#include <userenv.h>
21#include <ndk/setypes.h>
22#include <ndk/sefuncs.h>
23
24/* GLOBALS ******************************************************************/
25
26#define WINLOGON_SAS_CLASS L"SAS Window class"
27#define WINLOGON_SAS_TITLE L"SAS window"
28
29#define HK_CTRL_ALT_DEL 0
30#define HK_CTRL_SHIFT_ESC 1
31
32// #define EWX_FLAGS_MASK 0x00000014
33// #define EWX_ACTION_MASK ~EWX_FLAGS_MASK
34
35// FIXME: At the moment we use this value (select the lowbyte flags and some highbytes ones).
36// It should be set such that it makes winlogon accepting only valid flags.
37#define EWX_ACTION_MASK 0x5C0F
38
40{
44
46
47LUID LuidNone = {0, 0};
48
49/* FUNCTIONS ****************************************************************/
50
51static BOOL
53 IN OUT PWLSESSION Session)
54{
55 LPVOID lpEnvironment;
56 BOOL ret;
57
58 if (!Session->Gina.Functions.WlxStartApplication)
59 return FALSE;
60
62 &lpEnvironment,
63 Session->UserToken,
64 TRUE))
65 {
66 return FALSE;
67 }
68
69 ret = Session->Gina.Functions.WlxStartApplication(
70 Session->Gina.Context,
71 L"Default",
72 lpEnvironment,
73 L"taskmgr.exe");
74
75 DestroyEnvironmentBlock(lpEnvironment);
76 return ret;
77}
78
79static BOOL
81 IN OUT PWLSESSION Session)
82{
83 LPVOID lpEnvironment = NULL;
84 BOOLEAN Old;
85 BOOL ret;
86
87 /* Create environment block for the user */
88 if (!CreateEnvironmentBlock(&lpEnvironment, Session->UserToken, TRUE))
89 {
90 WARN("WL: CreateEnvironmentBlock() failed\n");
91 return FALSE;
92 }
93
94 /* Get privilege */
95 /* FIXME: who should do it? winlogon or gina? */
96 /* FIXME: reverting to lower privileges after creating user shell? */
98
99 ret = Session->Gina.Functions.WlxActivateUserShell(
100 Session->Gina.Context,
101 L"Default",
102 NULL, /* FIXME */
103 lpEnvironment);
104
105 DestroyEnvironmentBlock(lpEnvironment);
106 return ret;
107}
108
109
110BOOL
112 IN PWLSESSION Session)
113{
114 BOOL ret = FALSE;
115 BOOL UserProfile;
116 LONG rc;
117 HKEY UserKey, hKey = NULL;
118 LPCWSTR SubKey, ValueName;
119 DWORD dwType, dwSize;
120 LPWSTR Value = NULL;
121 UNICODE_STRING ValueString;
123 LCID Lcid;
124
125 UserProfile = (Session && Session->UserToken);
126
127 if (UserProfile && !ImpersonateLoggedOnUser(Session->UserToken))
128 {
129 ERR("WL: ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
130 return FALSE;
131 // FIXME: ... or use the default language of the system??
132 // UserProfile = FALSE;
133 }
134
135 if (UserProfile)
136 {
137 rc = RegOpenCurrentUser(MAXIMUM_ALLOWED, &UserKey);
138 if (rc != ERROR_SUCCESS)
139 {
140 TRACE("RegOpenCurrentUser() failed with error %lu\n", rc);
141 goto cleanup;
142 }
143
144 SubKey = L"Control Panel\\International";
145 ValueName = L"Locale";
146 }
147 else
148 {
149 UserKey = NULL;
150 SubKey = L"System\\CurrentControlSet\\Control\\Nls\\Language";
151 ValueName = L"Default";
152 }
153
154 rc = RegOpenKeyExW(UserKey ? UserKey : HKEY_LOCAL_MACHINE,
155 SubKey,
156 0,
157 KEY_READ,
158 &hKey);
159
160 if (UserKey)
161 RegCloseKey(UserKey);
162
163 if (rc != ERROR_SUCCESS)
164 {
165 TRACE("RegOpenKeyEx() failed with error %lu\n", rc);
166 goto cleanup;
167 }
168
170 ValueName,
171 NULL,
172 &dwType,
173 NULL,
174 &dwSize);
175 if (rc != ERROR_SUCCESS)
176 {
177 TRACE("RegQueryValueEx() failed with error %lu\n", rc);
178 goto cleanup;
179 }
180 else if (dwType != REG_SZ)
181 {
182 TRACE("Wrong type for %S\\%S registry entry (got 0x%lx, expected 0x%x)\n",
183 SubKey, ValueName, dwType, REG_SZ);
184 goto cleanup;
185 }
186
188 if (!Value)
189 {
190 TRACE("HeapAlloc() failed\n");
191 goto cleanup;
192 }
194 ValueName,
195 NULL,
196 NULL,
197 (LPBYTE)Value,
198 &dwSize);
199 if (rc != ERROR_SUCCESS)
200 {
201 TRACE("RegQueryValueEx() failed with error %lu\n", rc);
202 goto cleanup;
203 }
204
205 /* Convert Value to a Lcid */
206 ValueString.Length = ValueString.MaximumLength = (USHORT)dwSize;
207 ValueString.Buffer = Value;
208 Status = RtlUnicodeStringToInteger(&ValueString, 16, (PULONG)&Lcid);
209 if (!NT_SUCCESS(Status))
210 {
211 TRACE("RtlUnicodeStringToInteger() failed with status 0x%08lx\n", Status);
212 goto cleanup;
213 }
214
215 TRACE("%s language is 0x%08lx\n",
216 UserProfile ? "User" : "System", Lcid);
217 Status = NtSetDefaultLocale(UserProfile, Lcid);
218 if (!NT_SUCCESS(Status))
219 {
220 TRACE("NtSetDefaultLocale() failed with status 0x%08lx\n", Status);
221 goto cleanup;
222 }
223
224 ret = TRUE;
225
226cleanup:
227 if (Value)
229
230 if (hKey)
232
233 if (UserProfile)
234 RevertToSelf();
235
236 return ret;
237}
238
239BOOL
242 IN UINT bLogon,
243 IN UINT Flags)
244{
245 typedef BOOL (WINAPI *PLAYSOUNDW)(LPCWSTR,HMODULE,DWORD);
246 typedef UINT (WINAPI *WAVEOUTGETNUMDEVS)(VOID);
247 PLAYSOUNDW Play;
248 WAVEOUTGETNUMDEVS waveOutGetNumDevs;
249 UINT NumDevs;
251 BOOL Ret = FALSE;
252
253 hLibrary = LoadLibraryW(L"winmm.dll");
254 if (!hLibrary)
255 return FALSE;
256
257 waveOutGetNumDevs = (WAVEOUTGETNUMDEVS)GetProcAddress(hLibrary, "waveOutGetNumDevs");
258 Play = (PLAYSOUNDW)GetProcAddress(hLibrary, "PlaySoundW");
259
261 {
263 {
264 NumDevs = waveOutGetNumDevs();
265 if (!NumDevs)
266 {
267 if (!bLogon)
268 Beep(440, 125);
270 }
271 }
272
273 if (Play)
274 Ret = Play(FileName, NULL, Flags);
275 }
277 {
278 ERR("WL: Exception while playing sound '%S', Status 0x%08lx\n",
280 }
281 _SEH2_END;
282
284
285 return Ret;
286}
287
288DWORD
289WINAPI
291 IN LPVOID lpParameter)
292{
295 ULONG Index = 0;
296 SC_HANDLE hSCManager, hService;
297
298 /* Open the service manager */
300 if (!hSCManager)
301 {
302 ERR("OpenSCManager failed (%x)\n", GetLastError());
303 return 0;
304 }
305
306 /* Open the wdmaud service */
307 hService = OpenServiceW(hSCManager, L"wdmaud", GENERIC_READ);
308 if (!hService)
309 {
310 /* The service is not installed */
311 TRACE("Failed to open wdmaud service (%x)\n", GetLastError());
313 return 0;
314 }
315
316 /* Wait for wdmaud to start */
317 do
318 {
320 {
321 TRACE("QueryServiceStatusEx failed (%x)\n", GetLastError());
322 break;
323 }
324
325 if (Info.dwCurrentState == SERVICE_RUNNING)
326 break;
327
328 Sleep(1000);
329
330 } while (Index++ < 20);
331
332 CloseServiceHandle(hService);
334
335 /* If wdmaud is not running exit */
336 if (Info.dwCurrentState != SERVICE_RUNNING)
337 {
338 WARN("wdmaud has not started!\n");
339 return 0;
340 }
341
342 /* Sound subsystem is running. Play logon sound. */
343 TRACE("Playing logon sound\n");
344 if (!ImpersonateLoggedOnUser((HANDLE)lpParameter))
345 {
346 ERR("ImpersonateLoggedOnUser failed (%x)\n", GetLastError());
347 }
348 else
349 {
350 PlaySoundRoutine(L"WindowsLogon", TRUE, SND_ALIAS | SND_NODEFAULT);
351 RevertToSelf();
352 }
353 return 0;
354}
355
356static
357VOID
359 IN OUT PWLSESSION Session)
360{
362
363 hThread = CreateThread(NULL, 0, PlayLogonSoundThread, (PVOID)Session->UserToken, 0, NULL);
364 if (hThread)
366}
367
368static
369VOID
371 _In_ PWLSESSION Session)
372{
373 if (!ImpersonateLoggedOnUser(Session->UserToken))
374 return;
375
376 PlaySoundRoutine(L"WindowsLogoff", FALSE, SND_ALIAS | SND_NODEFAULT);
377
378 RevertToSelf();
379}
380
381static
382BOOL
384 _In_ PWLSESSION Session,
385 _In_ LPCWSTR EventName)
386{
387 BOOL bRet;
388
389 if (!ImpersonateLoggedOnUser(Session->UserToken))
390 return FALSE;
391
393
394 RevertToSelf();
395
396 return bRet;
397}
398
399static
400VOID
402{
403 DWORD dRet;
404 HANDLE hEnum;
405 LPNETRESOURCE lpRes;
406 DWORD dSize = 0x1000;
407 DWORD dCount = -1;
408 LPNETRESOURCE lpCur;
409 BOOL UserProfile;
410
411 UserProfile = (Session && Session->UserToken);
412 if (!UserProfile)
413 {
414 return;
415 }
416
417 if (!ImpersonateLoggedOnUser(Session->UserToken))
418 {
419 ERR("WL: ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
420 return;
421 }
422
424 if (dRet != WN_SUCCESS)
425 {
426 ERR("Failed to open enumeration: %lu\n", dRet);
427 goto quit;
428 }
429
430 lpRes = HeapAlloc(GetProcessHeap(), 0, dSize);
431 if (!lpRes)
432 {
433 ERR("Failed to allocate memory\n");
434 WNetCloseEnum(hEnum);
435 goto quit;
436 }
437
438 do
439 {
440 dSize = 0x1000;
441 dCount = -1;
442
443 memset(lpRes, 0, dSize);
444 dRet = WNetEnumResource(hEnum, &dCount, lpRes, &dSize);
445 if (dRet == WN_SUCCESS || dRet == WN_MORE_DATA)
446 {
447 lpCur = lpRes;
448 for (; dCount; dCount--)
449 {
451 lpCur++;
452 }
453 }
454 } while (dRet != WN_NO_MORE_ENTRIES);
455
456 HeapFree(GetProcessHeap(), 0, lpRes);
457 WNetCloseEnum(hEnum);
458
459quit:
460 RevertToSelf();
461}
462
463static
464BOOL
466 IN OUT PWLSESSION Session)
467{
468 PROFILEINFOW ProfileInfo;
469 BOOL ret = FALSE;
470
471 /* Loading personal settings */
472 DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_LOADINGYOURPERSONALSETTINGS);
473 ProfileInfo.hProfile = INVALID_HANDLE_VALUE;
474 if (0 == (Session->Options & WLX_LOGON_OPT_NO_PROFILE))
475 {
476 if (Session->Profile == NULL
477 || (Session->Profile->dwType != WLX_PROFILE_TYPE_V1_0
478 && Session->Profile->dwType != WLX_PROFILE_TYPE_V2_0))
479 {
480 ERR("WL: Wrong profile\n");
481 goto cleanup;
482 }
483
484 /* Load the user profile */
485 ZeroMemory(&ProfileInfo, sizeof(PROFILEINFOW));
486 ProfileInfo.dwSize = sizeof(PROFILEINFOW);
487 ProfileInfo.dwFlags = 0;
488 ProfileInfo.lpUserName = Session->MprNotifyInfo.pszUserName;
489 ProfileInfo.lpProfilePath = Session->Profile->pszProfile;
490 if (Session->Profile->dwType >= WLX_PROFILE_TYPE_V2_0)
491 {
492 ProfileInfo.lpDefaultPath = Session->Profile->pszNetworkDefaultUserProfile;
493 ProfileInfo.lpServerName = Session->Profile->pszServerName;
494 ProfileInfo.lpPolicyPath = Session->Profile->pszPolicy;
495 }
496
497 if (!LoadUserProfileW(Session->UserToken, &ProfileInfo))
498 {
499 ERR("WL: LoadUserProfileW() failed\n");
500 goto cleanup;
501 }
502 }
503
504 /* Create environment block for the user */
505 if (!CreateUserEnvironment(Session))
506 {
507 WARN("WL: SetUserEnvironment() failed\n");
508 goto cleanup;
509 }
510
512
513 DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_APPLYINGYOURPERSONALSETTINGS);
515
516 /* Set default user language */
517 if (!SetDefaultLanguage(Session))
518 {
519 WARN("WL: SetDefaultLanguage() failed\n");
520 goto cleanup;
521 }
522
523 /* Allow winsta and desktop access for this session */
524 if (!AllowAccessOnSession(Session))
525 {
526 WARN("WL: AllowAccessOnSession() failed to give winsta & desktop access for this session\n");
527 goto cleanup;
528 }
529
530 /* Connect remote resources */
531 RestoreAllConnections(Session);
532
533 if (!StartUserShell(Session))
534 {
535 //WCHAR StatusMsg[256];
536 WARN("WL: WlxActivateUserShell() failed\n");
537 //LoadStringW(hAppInstance, IDS_FAILEDACTIVATEUSERSHELL, StatusMsg, sizeof(StatusMsg) / sizeof(StatusMsg[0]));
538 //MessageBoxW(0, StatusMsg, NULL, MB_ICONERROR);
539 goto cleanup;
540 }
541
543
544 if (!InitializeScreenSaver(Session))
545 WARN("WL: Failed to initialize screen saver\n");
546
547 Session->hProfileInfo = ProfileInfo.hProfile;
548
549 /* Logon has succeeded. Play sound. */
550 PlayLogonSound(Session);
551
552 ret = TRUE;
553
554cleanup:
555 if (Session->Profile)
556 {
557 HeapFree(GetProcessHeap(), 0, Session->Profile->pszProfile);
558 HeapFree(GetProcessHeap(), 0, Session->Profile);
559 }
560 Session->Profile = NULL;
561 if (!ret && ProfileInfo.hProfile != INVALID_HANDLE_VALUE)
562 {
563 UnloadUserProfile(Session->UserToken, ProfileInfo.hProfile);
564 }
565 RemoveStatusMessage(Session);
566 if (!ret)
567 {
568 SetWindowStationUser(Session->InteractiveWindowStation,
569 &LuidNone, NULL, 0);
570 CloseHandle(Session->UserToken);
571 Session->UserToken = NULL;
572 }
573
574 if (ret)
575 {
576 SwitchDesktop(Session->ApplicationDesktop);
577 Session->LogonState = STATE_LOGGED_ON;
578 }
579
580 return ret;
581}
582
583
584static
585DWORD
586WINAPI
589{
590 DWORD ret = 1;
592 UINT uFlags;
593
594 if (LSData->Session->UserToken != NULL &&
596 {
597 ERR("ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
598 return 0;
599 }
600
601 // FIXME: To be really fixed: need to check what needs to be kept and what needs to be removed there.
602 //
603 // uFlags = EWX_INTERNAL_KILL_USER_APPS | (LSData->Flags & EWX_FLAGS_MASK) |
604 // ((LSData->Flags & EWX_ACTION_MASK) == EWX_LOGOFF ? EWX_CALLER_WINLOGON_LOGOFF : 0);
605
606 uFlags = EWX_CALLER_WINLOGON | (LSData->Flags & 0x0F);
607
608 TRACE("In LogoffShutdownThread with uFlags == 0x%x; exit_in_progress == %s\n",
609 uFlags, ExitReactOSInProgress ? "true" : "false");
610
612
613 /* Close processes of the interactive user */
614 if (!ExitWindowsEx(uFlags, 0))
615 {
616 ERR("Unable to kill user apps, error %lu\n", GetLastError());
617 ret = 0;
618 }
619
620 /* Cancel all the user connections */
622
623 if (LSData->Session->UserToken)
624 RevertToSelf();
625
626 return ret;
627}
628
629static
630DWORD
631WINAPI
634{
635 DWORD ret = 1;
637
638 TRACE("In KillComProcesses\n");
639
640 if (LSData->Session->UserToken != NULL &&
642 {
643 ERR("ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
644 return 0;
645 }
646
647 /* Attempt to kill remaining processes. No notifications needed. */
649 {
650 ERR("Unable to kill COM apps, error %lu\n", GetLastError());
651 ret = 0;
652 }
653
654 if (LSData->Session->UserToken)
655 RevertToSelf();
656
657 return ret;
658}
659
660static
664{
665 /* The following code is not working yet and messy */
666 /* Still, it gives some ideas about data types and functions involved and */
667 /* required to set up a SECURITY_DESCRIPTOR for a SECURITY_ATTRIBUTES */
668 /* instance for a thread, to allow that thread to ImpersonateLoggedOnUser(). */
669 /* Specifically THREAD_SET_THREAD_TOKEN is required. */
672 BYTE* pMem;
673 PACL pACL;
674 EXPLICIT_ACCESS Access;
675 PSID pEveryoneSID = NULL;
677
678 *ppsa = NULL;
679
680 // Let's first try to enumerate what kind of data we need for this to ever work:
681 // 1. The Winlogon SID, to be able to give it THREAD_SET_THREAD_TOKEN.
682 // 2. The users SID (the user trying to logoff, or rather shut down the system).
683 // 3. At least two EXPLICIT_ACCESS instances:
684 // 3.1 One for Winlogon itself, giving it the rights
685 // required to THREAD_SET_THREAD_TOKEN (as it's needed to successfully call
686 // ImpersonateLoggedOnUser).
687 // 3.2 One for the user, to allow *that* thread to perform its work.
688 // 4. An ACL to hold the these EXPLICIT_ACCESS ACE's.
689 // 5. A SECURITY_DESCRIPTOR to hold the ACL, and finally.
690 // 6. A SECURITY_ATTRIBUTES instance to pull all of this required stuff
691 // together, to hand it to CreateThread.
692 //
693 // However, it seems struct LOGOFF_SHUTDOWN_DATA doesn't contain
694 // these required SID's, why they'd have to be added.
695 // The Winlogon's own SID should probably only be created once,
696 // while the user's SID obviously must be created for each new user.
697 // Might as well store it when the user logs on?
698
700 1,
702 0, 0, 0, 0, 0, 0, 0,
703 &pEveryoneSID))
704 {
705 ERR("Failed to initialize security descriptor for logoff thread!\n");
706 return STATUS_UNSUCCESSFUL;
707 }
708
709 /* set up the required security attributes to be able to shut down */
710 /* To save space and time, allocate a single block of memory holding */
711 /* both SECURITY_ATTRIBUTES and SECURITY_DESCRIPTOR */
712 pMem = HeapAlloc(GetProcessHeap(),
713 0,
714 sizeof(SECURITY_ATTRIBUTES) +
716 sizeof(ACL));
717 if (!pMem)
718 {
719 ERR("Failed to allocate memory for logoff security descriptor!\n");
720 return STATUS_NO_MEMORY;
721 }
722
723 /* Note that the security descriptor needs to be in _absolute_ format, */
724 /* meaning its members must be pointers to other structures, rather */
725 /* than the relative format using offsets */
729
730 // Initialize an EXPLICIT_ACCESS structure for an ACE.
731 // The ACE will allow this thread to log off (and shut down the system, currently).
732 ZeroMemory(&Access, sizeof(Access));
734 Access.grfAccessMode = SET_ACCESS; // GRANT_ACCESS?
738 Access.Trustee.ptstrName = pEveryoneSID;
739
740 if (SetEntriesInAcl(1, &Access, NULL, &pACL) != ERROR_SUCCESS)
741 {
742 ERR("Failed to set Access Rights for logoff thread. Logging out will most likely fail.\n");
743
744 HeapFree(GetProcessHeap(), 0, pMem);
745 return STATUS_UNSUCCESSFUL;
746 }
747
749 {
750 ERR("Failed to initialize security descriptor for logoff thread!\n");
751 HeapFree(GetProcessHeap(), 0, pMem);
752 return STATUS_UNSUCCESSFUL;
753 }
754
756 TRUE, // bDaclPresent flag
757 pACL,
758 FALSE)) // not a default DACL
759 {
760 ERR("SetSecurityDescriptorDacl Error %lu\n", GetLastError());
761 HeapFree(GetProcessHeap(), 0, pMem);
762 return STATUS_UNSUCCESSFUL;
763 }
764
765 psa->nLength = sizeof(SECURITY_ATTRIBUTES);
766 psa->lpSecurityDescriptor = SecurityDescriptor;
767 psa->bInheritHandle = FALSE;
768
769 *ppsa = psa;
770
771 return STATUS_SUCCESS;
772}
773
774static
775VOID
778{
779 if (psa)
780 {
782 }
783}
784
785
786static
789 IN OUT PWLSESSION Session,
790 IN UINT Flags)
791{
795 DWORD exitCode;
797
798 /* Prepare data for logoff thread */
799 LSData = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGOFF_SHUTDOWN_DATA));
800 if (!LSData)
801 {
802 ERR("Failed to allocate mem for thread data\n");
803 return STATUS_NO_MEMORY;
804 }
805 LSData->Flags = Flags;
806 LSData->Session = Session;
807
809 if (!NT_SUCCESS(Status))
810 {
811 ERR("Failed to create a required security descriptor. Status 0x%08lx\n", Status);
812 HeapFree(GetProcessHeap(), 0, LSData);
813 return Status;
814 }
815
816 /* Run logoff thread */
818 if (!hThread)
819 {
820 ERR("Unable to create logoff thread, error %lu\n", GetLastError());
822 HeapFree(GetProcessHeap(), 0, LSData);
823 return STATUS_UNSUCCESSFUL;
824 }
826 if (!GetExitCodeThread(hThread, &exitCode))
827 {
828 ERR("Unable to get exit code of logoff thread (error %lu)\n", GetLastError());
831 HeapFree(GetProcessHeap(), 0, LSData);
832 return STATUS_UNSUCCESSFUL;
833 }
835 if (exitCode == 0)
836 {
837 ERR("Logoff thread returned failure\n");
839 HeapFree(GetProcessHeap(), 0, LSData);
840 return STATUS_UNSUCCESSFUL;
841 }
842
843 SwitchDesktop(Session->WinlogonDesktop);
844
845 PlayLogoffSound(Session);
846
847 SetWindowStationUser(Session->InteractiveWindowStation,
848 &LuidNone, NULL, 0);
849
850 // DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_LOGGINGOFF);
851
852 // FIXME: Closing network connections!
853 // DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_CLOSINGNETWORKCONNECTIONS);
854
855 /* Kill remaining COM apps. Only at logoff! */
857 if (hThread)
858 {
861 }
862
863 /* We're done with the SECURITY_DESCRIPTOR */
865 psa = NULL;
866
867 HeapFree(GetProcessHeap(), 0, LSData);
868
869 DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_SAVEYOURSETTINGS);
870
871 UnloadUserProfile(Session->UserToken, Session->hProfileInfo);
872
874
875 CloseHandle(Session->UserToken);
877 Session->LogonState = STATE_LOGGED_OFF;
878 Session->UserToken = NULL;
879
880 return STATUS_SUCCESS;
881}
882
883static
887 IN HWND hwndDlg,
888 IN UINT uMsg,
891{
893
894 switch (uMsg)
895 {
896 case WM_COMMAND:
897 {
898 switch (LOWORD(wParam))
899 {
902 return TRUE;
903 }
904 break;
905 }
906 case WM_INITDIALOG:
907 {
910 return TRUE;
911 }
912 }
913 return FALSE;
914}
915
916static
917VOID
919 IN OUT PWLSESSION Session)
920{
921 if (Session->SASWindow)
922 {
923 DestroyWindow(Session->SASWindow);
924 Session->SASWindow = NULL;
925 }
926 if (Session->hEndOfScreenSaverThread)
927 SetEvent(Session->hEndOfScreenSaverThread);
929}
930
933 IN OUT PWLSESSION Session,
934 IN DWORD wlxAction)
935{
938 DWORD exitCode;
939 BOOLEAN Old;
940
941 // SwitchDesktop(Session->WinlogonDesktop);
942
943 /* If the system is rebooting, show the appropriate string */
944 if (wlxAction == WLX_SAS_ACTION_SHUTDOWN_REBOOT)
945 DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_REACTOSISRESTARTING);
946 else
947 DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_REACTOSISSHUTTINGDOWN);
948
949 /* Prepare data for shutdown thread */
950 LSData = HeapAlloc(GetProcessHeap(), 0, sizeof(LOGOFF_SHUTDOWN_DATA));
951 if (!LSData)
952 {
953 ERR("Failed to allocate mem for thread data\n");
954 return STATUS_NO_MEMORY;
955 }
956 if (wlxAction == WLX_SAS_ACTION_SHUTDOWN_POWER_OFF)
957 LSData->Flags = EWX_POWEROFF;
958 else if (wlxAction == WLX_SAS_ACTION_SHUTDOWN_REBOOT)
959 LSData->Flags = EWX_REBOOT;
960 else
961 LSData->Flags = EWX_SHUTDOWN;
962 LSData->Session = Session;
963
964 // FIXME: We may need to specify this flag to really force application kill
965 // (we are shutting down ReactOS, not just logging off so no hangs, etc...
966 // should be allowed).
967 // LSData->Flags |= EWX_FORCE;
968
969 /* Run shutdown thread */
971 if (!hThread)
972 {
973 ERR("Unable to create shutdown thread, error %lu\n", GetLastError());
974 HeapFree(GetProcessHeap(), 0, LSData);
975 return STATUS_UNSUCCESSFUL;
976 }
978 HeapFree(GetProcessHeap(), 0, LSData);
979 if (!GetExitCodeThread(hThread, &exitCode))
980 {
981 ERR("Unable to get exit code of shutdown thread (error %lu)\n", GetLastError());
983 return STATUS_UNSUCCESSFUL;
984 }
986 if (exitCode == 0)
987 {
988 ERR("Shutdown thread returned failure\n");
989 return STATUS_UNSUCCESSFUL;
990 }
991
993
994 /* Destroy SAS window */
995 UninitializeSAS(Session);
996
997 /* Now we can shut down NT */
998 ERR("Shutting down NT...\n");
1000 if (wlxAction == WLX_SAS_ACTION_SHUTDOWN_REBOOT)
1001 {
1003 }
1004 else
1005 {
1006 if (FALSE)
1007 {
1008 /* FIXME - only show this dialog if it's a shutdown and the computer doesn't support APM */
1011 }
1013 }
1015 return STATUS_SUCCESS;
1016}
1017
1018static
1019VOID
1021 IN OUT PWLSESSION Session,
1022 IN DWORD wlxAction)
1023{
1024 switch (wlxAction)
1025 {
1026 case WLX_SAS_ACTION_LOGON: /* 0x01 */
1027 if (Session->LogonState == STATE_LOGGED_OFF_SAS)
1028 {
1029 if (!HandleLogon(Session))
1030 {
1031 Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context);
1033 }
1034 }
1035 break;
1036 case WLX_SAS_ACTION_NONE: /* 0x02 */
1037 if (Session->LogonState == STATE_LOGGED_OFF_SAS)
1038 {
1039 Session->LogonState = STATE_LOGGED_OFF;
1040 Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context);
1041 }
1042 else if (Session->LogonState == STATE_LOGGED_ON_SAS)
1043 {
1044 Session->LogonState = STATE_LOGGED_ON;
1045 }
1046 else if (Session->LogonState == STATE_LOCKED_SAS)
1047 {
1048 Session->LogonState = STATE_LOCKED;
1049 Session->Gina.Functions.WlxDisplayLockedNotice(Session->Gina.Context);
1050 }
1051 break;
1052 case WLX_SAS_ACTION_LOCK_WKSTA: /* 0x03 */
1053 if (Session->Gina.Functions.WlxIsLockOk(Session->Gina.Context))
1054 {
1055 SwitchDesktop(Session->WinlogonDesktop);
1056 Session->LogonState = STATE_LOCKED;
1057 Session->Gina.Functions.WlxDisplayLockedNotice(Session->Gina.Context);
1059 }
1060 break;
1061 case WLX_SAS_ACTION_LOGOFF: /* 0x04 */
1062 case WLX_SAS_ACTION_SHUTDOWN: /* 0x05 */
1063 case WLX_SAS_ACTION_FORCE_LOGOFF: /* 0x09 */
1064 case WLX_SAS_ACTION_SHUTDOWN_POWER_OFF: /* 0x0a */
1065 case WLX_SAS_ACTION_SHUTDOWN_REBOOT: /* 0x0b */
1066 if (Session->LogonState != STATE_LOGGED_OFF)
1067 {
1068 UINT LogOffFlags = EWX_LOGOFF;
1069 if (wlxAction == WLX_SAS_ACTION_FORCE_LOGOFF)
1070 LogOffFlags |= EWX_FORCE;
1071 if (!Session->Gina.Functions.WlxIsLogoffOk(Session->Gina.Context))
1072 break;
1073 if (!NT_SUCCESS(HandleLogoff(Session, LogOffFlags)))
1074 {
1075 RemoveStatusMessage(Session);
1076 break;
1077 }
1078 Session->Gina.Functions.WlxLogoff(Session->Gina.Context);
1079 }
1080 if (WLX_SHUTTINGDOWN(wlxAction))
1081 {
1082 // FIXME: WlxShutdown should be done from inside HandleShutdown,
1083 // after having displayed "ReactOS is shutting down" message.
1084 Session->Gina.Functions.WlxShutdown(Session->Gina.Context, wlxAction);
1085 if (!NT_SUCCESS(HandleShutdown(Session, wlxAction)))
1086 {
1087 RemoveStatusMessage(Session);
1088 Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context);
1089 }
1090 }
1091 else
1092 {
1093 RemoveStatusMessage(Session);
1094 Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context);
1095 }
1096 break;
1097 case WLX_SAS_ACTION_TASKLIST: /* 0x07 */
1098 SwitchDesktop(Session->ApplicationDesktop);
1099 Session->LogonState = STATE_LOGGED_ON;
1100 StartTaskManager(Session);
1101 break;
1102 case WLX_SAS_ACTION_UNLOCK_WKSTA: /* 0x08 */
1103 SwitchDesktop(Session->ApplicationDesktop);
1104 Session->LogonState = STATE_LOGGED_ON;
1106 break;
1107 default:
1108 WARN("Unknown SAS action 0x%lx\n", wlxAction);
1109 }
1110}
1111
1112static
1113VOID
1115 IN OUT PWLSESSION Session,
1116 IN DWORD dwSasType)
1117{
1118 DWORD wlxAction = WLX_SAS_ACTION_NONE;
1119 PSID LogonSid = NULL; /* FIXME */
1120 BOOL bSecure = TRUE;
1121
1122 switch (dwSasType)
1123 {
1125 switch (Session->LogonState)
1126 {
1127 case STATE_INIT:
1128 Session->LogonState = STATE_LOGGED_OFF;
1129 Session->Gina.Functions.WlxDisplaySASNotice(Session->Gina.Context);
1130 return;
1131
1132 case STATE_LOGGED_OFF:
1133 Session->LogonState = STATE_LOGGED_OFF_SAS;
1134
1136
1137 Session->Options = 0;
1138
1139 wlxAction = (DWORD)Session->Gina.Functions.WlxLoggedOutSAS(
1140 Session->Gina.Context,
1141 Session->SASAction,
1142 &Session->LogonId,
1143 LogonSid,
1144 &Session->Options,
1145 &Session->UserToken,
1146 &Session->MprNotifyInfo,
1147 (PVOID*)&Session->Profile);
1148 break;
1149
1151 /* Ignore SAS if we are already in an SAS state */
1152 return;
1153
1154 case STATE_LOGGED_ON:
1155 Session->LogonState = STATE_LOGGED_ON_SAS;
1156 wlxAction = (DWORD)Session->Gina.Functions.WlxLoggedOnSAS(Session->Gina.Context, dwSasType, NULL);
1157 break;
1158
1160 /* Ignore SAS if we are already in an SAS state */
1161 return;
1162
1163 case STATE_LOCKED:
1164 Session->LogonState = STATE_LOCKED_SAS;
1165
1167
1168 wlxAction = (DWORD)Session->Gina.Functions.WlxWkstaLockedSAS(Session->Gina.Context, dwSasType);
1169 break;
1170
1171 case STATE_LOCKED_SAS:
1172 /* Ignore SAS if we are already in an SAS state */
1173 return;
1174
1175 default:
1176 return;
1177 }
1178 break;
1179
1181 return;
1182
1184 if (!Session->Gina.Functions.WlxScreenSaverNotify(Session->Gina.Context, &bSecure))
1185 {
1186 /* Skip start of screen saver */
1187 SetEvent(Session->hEndOfScreenSaver);
1188 }
1189 else
1190 {
1191 StartScreenSaver(Session);
1192 if (bSecure)
1193 {
1194 wlxAction = WLX_SAS_ACTION_LOCK_WKSTA;
1195// DoGenericAction(Session, WLX_SAS_ACTION_LOCK_WKSTA);
1196 }
1197 }
1198 break;
1199
1201 SetEvent(Session->hUserActivity);
1202 break;
1203 }
1204
1205 DoGenericAction(Session, wlxAction);
1206}
1207
1208static
1209BOOL
1211 IN PWLSESSION Session,
1212 IN HWND hwndSAS)
1213{
1214 /* Register Ctrl+Alt+Del Hotkey */
1216 {
1217 ERR("WL: Unable to register Ctrl+Alt+Del hotkey!\n");
1218 return FALSE;
1219 }
1220
1221 /* Register Ctrl+Shift+Esc (optional) */
1223 if (!Session->TaskManHotkey)
1224 WARN("WL: Warning: Unable to register Ctrl+Alt+Esc hotkey!\n");
1225 return TRUE;
1226}
1227
1228static
1229BOOL
1231 IN PWLSESSION Session,
1232 IN HWND hwndSAS)
1233{
1234 /* Unregister hotkeys */
1236
1237 if (Session->TaskManHotkey)
1239
1240 return TRUE;
1241}
1242
1243static
1244BOOL
1246 _In_ PWLSESSION Session,
1247 _In_ UINT uType)
1248{
1249 LPWSTR EventName;
1250
1251 switch (uType)
1252 {
1253 case 0xFFFFFFFF:
1254 EventName = NULL;
1255 break;
1256 case MB_OK:
1257 EventName = L"SystemDefault";
1258 break;
1259 case MB_ICONASTERISK:
1260 EventName = L"SystemAsterisk";
1261 break;
1262 case MB_ICONEXCLAMATION:
1263 EventName = L"SystemExclamation";
1264 break;
1265 case MB_ICONHAND:
1266 EventName = L"SystemHand";
1267 break;
1268 case MB_ICONQUESTION:
1269 EventName = L"SystemQuestion";
1270 break;
1271 default:
1272 WARN("Unhandled type %d\n", uType);
1273 EventName = L"SystemDefault";
1274 }
1275
1276 return PlayEventSound(Session, EventName);
1277}
1278
1279static
1280LRESULT
1283 IN HWND hwndDlg,
1284 IN UINT uMsg,
1287{
1289
1290 switch (uMsg)
1291 {
1292 case WM_HOTKEY:
1293 {
1294 switch (lParam)
1295 {
1297 {
1298 TRACE("SAS: CONTROL+ALT+DELETE\n");
1299 if (!Session->Gina.UseCtrlAltDelete)
1300 break;
1302 return TRUE;
1303 }
1305 {
1306 TRACE("SAS: CONTROL+SHIFT+ESCAPE\n");
1307 if (Session->LogonState == STATE_LOGGED_ON)
1309 return TRUE;
1310 }
1311 }
1312 break;
1313 }
1314 case WM_CREATE:
1315 {
1316 /* Get the session pointer from the create data */
1317 Session = (PWLSESSION)((LPCREATESTRUCT)lParam)->lpCreateParams;
1318
1319 /* Save the Session pointer */
1320 SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (LONG_PTR)Session);
1321 if (GetSetupType())
1322 return TRUE;
1323 return RegisterHotKeys(Session, hwndDlg);
1324 }
1325 case WM_DESTROY:
1326 {
1327 if (!GetSetupType())
1328 UnregisterHotKeys(Session, hwndDlg);
1329 return TRUE;
1330 }
1331 case WM_SETTINGCHANGE:
1332 {
1333 UINT uiAction = (UINT)wParam;
1334 if (uiAction == SPI_SETSCREENSAVETIMEOUT
1335 || uiAction == SPI_SETSCREENSAVEACTIVE)
1336 {
1338 }
1339 return TRUE;
1340 }
1341 case WM_LOGONNOTIFY:
1342 {
1343 switch(wParam)
1344 {
1345 case LN_MESSAGE_BEEP:
1346 {
1347 return HandleMessageBeep(Session, lParam);
1348 }
1349 case LN_SHELL_EXITED:
1350 {
1351 /* lParam is the exit code */
1352 if (lParam != 1 &&
1353 Session->LogonState != STATE_LOGGED_OFF &&
1354 Session->LogonState != STATE_LOGGED_OFF_SAS)
1355 {
1356 SetTimer(hwndDlg, 1, 1000, NULL);
1357 }
1358 break;
1359 }
1361 {
1363 break;
1364 }
1366 {
1368 break;
1369 }
1370 case LN_LOGOFF:
1371 {
1372 UINT Flags = (UINT)lParam;
1374 DWORD wlxAction;
1375
1376 TRACE("\tFlags : 0x%lx\n", lParam);
1377
1378 /*
1379 * Our caller (USERSRV) should have added the shutdown flag
1380 * when setting also poweroff or reboot.
1381 */
1382 if (Action & (EWX_POWEROFF | EWX_REBOOT))
1383 {
1384 if ((Action & EWX_SHUTDOWN) == 0)
1385 {
1386 ERR("Missing EWX_SHUTDOWN flag for poweroff or reboot; action 0x%x\n", Action);
1388 }
1389
1390 /* Now we can locally remove it for performing checks */
1391 Action &= ~EWX_SHUTDOWN;
1392 }
1393
1394 /* Check parameters */
1395 if (Action & EWX_FORCE)
1396 {
1397 // FIXME!
1398 ERR("FIXME: EWX_FORCE present for Winlogon, what to do?\n");
1399 Action &= ~EWX_FORCE;
1400 }
1401 switch (Action)
1402 {
1403 case EWX_LOGOFF:
1404 wlxAction = WLX_SAS_ACTION_LOGOFF;
1405 break;
1406 case EWX_SHUTDOWN:
1407 wlxAction = WLX_SAS_ACTION_SHUTDOWN;
1408 break;
1409 case EWX_REBOOT:
1411 break;
1412 case EWX_POWEROFF:
1414 break;
1415
1416 default:
1417 {
1418 ERR("Invalid ExitWindows action 0x%x\n", Action);
1420 }
1421 }
1422
1423 TRACE("In LN_LOGOFF, exit_in_progress == %s\n",
1424 ExitReactOSInProgress ? "true" : "false");
1425
1426 /*
1427 * In case a parallel shutdown request is done (while we are
1428 * being to shut down) and it was not done by Winlogon itself,
1429 * then just stop here.
1430 */
1431#if 0
1432// This code is commented at the moment (even if it's correct) because
1433// our log-offs do not really work: the shell is restarted, no app is killed
1434// etc... and as a result you just get explorer opening "My Documents". And
1435// if you try now a shut down, it won't work because winlogon thinks it is
1436// still in the middle of a shutdown.
1437// Maybe we also need to reset ExitReactOSInProgress somewhere else??
1439 {
1440 break;
1441 }
1442#endif
1443 /* Now do the shutdown action proper */
1444 DoGenericAction(Session, wlxAction);
1445 return 1;
1446 }
1447 case LN_LOGOFF_CANCELED:
1448 {
1449 ERR("Logoff canceled!!, before: exit_in_progress == %s, after will be false\n",
1450 ExitReactOSInProgress ? "true" : "false");
1451
1453 return 1;
1454 }
1455 default:
1456 {
1457 ERR("WM_LOGONNOTIFY case %d is unimplemented\n", wParam);
1458 }
1459 }
1460 return 0;
1461 }
1462 case WM_TIMER:
1463 {
1464 if (wParam == 1)
1465 {
1466 KillTimer(hwndDlg, 1);
1467 StartUserShell(Session);
1468 }
1469 break;
1470 }
1471 case WLX_WM_SAS:
1472 {
1473 DispatchSAS(Session, (DWORD)wParam);
1474 return TRUE;
1475 }
1476 }
1477
1478 return DefWindowProc(hwndDlg, uMsg, wParam, lParam);
1479}
1480
1481BOOL
1483 IN OUT PWLSESSION Session)
1484{
1485 WNDCLASSEXW swc;
1486 BOOL ret = FALSE;
1487
1488 if (!SwitchDesktop(Session->WinlogonDesktop))
1489 {
1490 ERR("WL: Failed to switch to winlogon desktop\n");
1491 goto cleanup;
1492 }
1493
1494 /* Register SAS window class */
1495 swc.cbSize = sizeof(WNDCLASSEXW);
1496 swc.style = CS_SAVEBITS;
1498 swc.cbClsExtra = 0;
1499 swc.cbWndExtra = 0;
1500 swc.hInstance = hAppInstance;
1501 swc.hIcon = NULL;
1502 swc.hCursor = NULL;
1503 swc.hbrBackground = NULL;
1504 swc.lpszMenuName = NULL;
1506 swc.hIconSm = NULL;
1507 if (RegisterClassExW(&swc) == 0)
1508 {
1509 ERR("WL: Failed to register SAS window class\n");
1510 goto cleanup;
1511 }
1512
1513 /* Create invisible SAS window */
1514 Session->SASWindow = CreateWindowExW(
1515 0,
1518 WS_POPUP,
1519 0, 0, 0, 0, 0, 0,
1520 hAppInstance, Session);
1521 if (!Session->SASWindow)
1522 {
1523 ERR("WL: Failed to create SAS window\n");
1524 goto cleanup;
1525 }
1526
1527 /* Register SAS window to receive SAS notifications */
1528 if (!SetLogonNotifyWindow(Session->SASWindow))
1529 {
1530 ERR("WL: Failed to register SAS window\n");
1531 goto cleanup;
1532 }
1533
1535 return FALSE;
1536
1537 ret = TRUE;
1538
1539cleanup:
1540 if (!ret)
1541 UninitializeSAS(Session);
1542 return ret;
1543}
DWORD WINAPI UpdatePerUserSystemParameters(DWORD dw1, DWORD dw2)
unsigned char BOOLEAN
@ 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 VOID
Definition: acefi.h:82
#define SetEntriesInAcl
Definition: aclapi.h:240
LONG NTSTATUS
Definition: precomp.h:26
HINSTANCE hAppInstance
Definition: mmc.c:23
void quit(int argc, const char *argv[])
Definition: cmds.c:1606
BOOL CreateUserEnvironment(IN PWLSESSION Session)
Definition: environment.c:128
VOID CallNotificationDlls(PWLSESSION pSession, NOTIFICATION_TYPE Type)
Definition: notify.c:390
#define IDS_APPLYINGYOURPERSONALSETTINGS
Definition: resource.h:26
#define IDC_BTNSHTDOWNCOMPUTER
Definition: resource.h:10
#define IDS_REACTOSISSHUTTINGDOWN
Definition: resource.h:31
#define IDD_SHUTDOWNCOMPUTER
Definition: resource.h:7
#define IDS_REACTOSISRESTARTING
Definition: resource.h:38
#define IDS_SAVEYOURSETTINGS
Definition: resource.h:34
#define IDS_LOADINGYOURPERSONALSETTINGS
Definition: resource.h:29
BOOL InitializeScreenSaver(IN OUT PWLSESSION Session)
Definition: screensaver.c:204
VOID StartScreenSaver(IN PWLSESSION Session)
Definition: screensaver.c:257
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
DWORD GetSetupType(VOID)
Definition: setup.c:16
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
#define RegCloseKey(hKey)
Definition: registry.h:49
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
HMODULE hLibrary
Definition: odbccp32.c:12
#define ERROR_SUCCESS
Definition: deptool.c:10
BOOL WINAPI Beep(IN DWORD dwFreq, IN DWORD dwDuration)
Definition: deviceio.c:48
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegOpenCurrentUser(IN REGSAM samDesired, OUT PHKEY phkResult)
Definition: reg.c:3209
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
BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
Definition: misc.c:152
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
UINT uFlags
Definition: api.c:59
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define FreeLibrary(x)
Definition: compat.h:748
#define GENERIC_READ
Definition: compat.h:135
struct _SECURITY_ATTRIBUTES * PSECURITY_ATTRIBUTES
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CALLBACK
Definition: compat.h:35
#define LoadLibraryW(x)
Definition: compat.h:747
static void cleanup(void)
Definition: main.c:1335
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 GetExitCodeThread(IN HANDLE hThread, OUT LPDWORD lpExitCode)
Definition: thread.c:541
static SID_IDENTIFIER_AUTHORITY WorldAuthority
Definition: security.c:14
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
BOOL WINAPI LoadUserProfileW(_In_ HANDLE hToken, _Inout_ LPPROFILEINFOW lpProfileInfo)
Definition: profile.c:2005
BOOL WINAPI UnloadUserProfile(_In_ HANDLE hToken, _In_ HANDLE hProfile)
Definition: profile.c:2184
#define INFINITE
Definition: serial.h:102
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define _SEH2_LEAVE
Definition: filesup.c:20
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
Status
Definition: gdiplustypes.h:25
#define MOD_ALT
Definition: imm.h:184
#define MOD_SHIFT
Definition: imm.h:186
#define MOD_CONTROL
Definition: imm.h:185
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define THREAD_SET_THREAD_TOKEN
Definition: pstypes.h:150
#define REG_SZ
Definition: layer.c:22
#define SND_ALIAS
Definition: mmsystem.h:160
#define SND_ASYNC
Definition: mmsystem.h:154
#define SND_NODEFAULT
Definition: mmsystem.h:155
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
#define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
Definition: security.c:657
#define SE_SHUTDOWN_PRIVILEGE
Definition: security.c:673
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
#define _In_
Definition: ms_sal.h:308
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned int UINT
Definition: ndis.h:50
@ ShutdownReboot
Definition: extypes.h:177
@ ShutdownNoReboot
Definition: extypes.h:176
NTSYSAPI NTSTATUS NTAPI RtlAdjustPrivilege(_In_ ULONG Privilege, _In_ BOOLEAN NewValue, _In_ BOOLEAN ForThread, _Out_ PBOOLEAN OldValue)
HANDLE hThread
Definition: wizard.c:28
#define BOOL
Definition: nt_native.h:43
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
#define DWORD
Definition: nt_native.h:44
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
NTSTATUS NTAPI NtSetDefaultLocale(IN BOOLEAN UserProfile, IN LCID DefaultLocaleId)
Definition: locale.c:437
NTSTATUS NTAPI NtShutdownSystem(IN SHUTDOWN_ACTION Action)
Definition: shutdown.c:43
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
HWND hwndSAS
Definition: winsta.c:24
#define L(x)
Definition: ntvdm.h:50
#define LOWORD(l)
Definition: pedump.c:82
BYTE * PBYTE
Definition: pedump.c:66
#define WS_POPUP
Definition: pedump.c:616
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define DefWindowProc
Definition: ros2win.h:31
static VOID PlayLogonSound(IN OUT PWLSESSION Session)
Definition: sas.c:358
static NTSTATUS CreateLogoffSecurityAttributes(OUT PSECURITY_ATTRIBUTES *ppsa)
Definition: sas.c:662
#define WINLOGON_SAS_TITLE
Definition: sas.c:27
static BOOL StartUserShell(IN OUT PWLSESSION Session)
Definition: sas.c:80
static BOOL RegisterHotKeys(IN PWLSESSION Session, IN HWND hwndSAS)
Definition: sas.c:1210
struct tagLOGOFF_SHUTDOWN_DATA LOGOFF_SHUTDOWN_DATA
static DWORD WINAPI KillComProcesses(LPVOID Parameter)
Definition: sas.c:632
#define WINLOGON_SAS_CLASS
Definition: sas.c:26
static NTSTATUS HandleLogoff(IN OUT PWLSESSION Session, IN UINT Flags)
Definition: sas.c:788
static LRESULT CALLBACK SASWindowProc(IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam)
Definition: sas.c:1282
static INT_PTR CALLBACK ShutdownComputerWindowProc(IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam)
Definition: sas.c:886
BOOL SetDefaultLanguage(IN PWLSESSION Session)
Definition: sas.c:111
static VOID DispatchSAS(IN OUT PWLSESSION Session, IN DWORD dwSasType)
Definition: sas.c:1114
LUID LuidNone
Definition: sas.c:47
NTSTATUS HandleShutdown(IN OUT PWLSESSION Session, IN DWORD wlxAction)
Definition: sas.c:932
static VOID UninitializeSAS(IN OUT PWLSESSION Session)
Definition: sas.c:918
static VOID DoGenericAction(IN OUT PWLSESSION Session, IN DWORD wlxAction)
Definition: sas.c:1020
static BOOL StartTaskManager(IN OUT PWLSESSION Session)
Definition: sas.c:52
static BOOL HandleMessageBeep(_In_ PWLSESSION Session, _In_ UINT uType)
Definition: sas.c:1245
#define HK_CTRL_SHIFT_ESC
Definition: sas.c:30
#define EWX_ACTION_MASK
Definition: sas.c:37
static BOOL PlayEventSound(_In_ PWLSESSION Session, _In_ LPCWSTR EventName)
Definition: sas.c:383
static BOOL HandleLogon(IN OUT PWLSESSION Session)
Definition: sas.c:465
struct tagLOGOFF_SHUTDOWN_DATA * PLOGOFF_SHUTDOWN_DATA
static VOID DestroyLogoffSecurityAttributes(IN PSECURITY_ATTRIBUTES psa)
Definition: sas.c:776
BOOL InitializeSAS(IN OUT PWLSESSION Session)
Definition: sas.c:1482
static VOID RestoreAllConnections(PWLSESSION Session)
Definition: sas.c:401
static DWORD WINAPI LogoffShutdownThread(LPVOID Parameter)
Definition: sas.c:587
DWORD WINAPI PlayLogonSoundThread(IN LPVOID lpParameter)
Definition: sas.c:290
BOOL PlaySoundRoutine(IN LPCWSTR FileName, IN UINT bLogon, IN UINT Flags)
Definition: sas.c:240
#define HK_CTRL_ALT_DEL
Definition: sas.c:29
static BOOL UnregisterHotKeys(IN PWLSESSION Session, IN HWND hwndSAS)
Definition: sas.c:1230
static VOID PlayLogoffSound(_In_ PWLSESSION Session)
Definition: sas.c:370
static BOOL ExitReactOSInProgress
Definition: sas.c:45
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:2887
SC_HANDLE WINAPI OpenServiceW(SC_HANDLE hSCManager, LPCWSTR lpServiceName, DWORD dwDesiredAccess)
Definition: scm.c:2160
BOOL WINAPI CloseServiceHandle(SC_HANDLE hSCObject)
Definition: scm.c:580
DWORD LCID
Definition: nls.h:13
#define memset(x, y, z)
Definition: compat.h:39
BOOL WINAPI SetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR pSecurityDescriptor, BOOL bDaclPresent, PACL pDacl, BOOL bDaclDefaulted)
Definition: sec.c:262
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE(s)
Definition: solgame.cpp:4
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
BOOL UseCtrlAltDelete
Definition: winlogon.h:131
LPSTR lpLocalName
Definition: winnetwk.h:171
LPSTR lpRemoteName
Definition: winnetwk.h:172
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
TRUSTEE_TYPE TrusteeType
Definition: accctrl.h:207
TRUSTEE_FORM TrusteeForm
Definition: accctrl.h:206
LPSTR ptstrName
Definition: accctrl.h:208
USHORT MaximumLength
Definition: env_spec_w32.h:370
HANDLE hScreenSaverParametersChanged
Definition: winlogon.h:243
HANDLE UserToken
Definition: winlogon.h:232
LOGON_STATE LogonState
Definition: winlogon.h:234
HWND SASWindow
Definition: winlogon.h:225
GINAINSTANCE Gina
Definition: winlogon.h:221
LPCWSTR lpszClassName
Definition: winuser.h:3226
LPCWSTR lpszMenuName
Definition: winuser.h:3225
HBRUSH hbrBackground
Definition: winuser.h:3224
WNDPROC lpfnWndProc
Definition: winuser.h:3218
UINT cbSize
Definition: winuser.h:3216
int cbWndExtra
Definition: winuser.h:3220
HCURSOR hCursor
Definition: winuser.h:3223
HICON hIconSm
Definition: winuser.h:3227
HINSTANCE hInstance
Definition: winuser.h:3221
UINT style
Definition: winuser.h:3217
int cbClsExtra
Definition: winuser.h:3219
HICON hIcon
Definition: winuser.h:3222
PWLSESSION Session
Definition: sas.c:42
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
#define GetWindowLongPtr
Definition: treelist.c:73
#define GWLP_USERDATA
Definition: treelist.c:63
int32_t INT_PTR
Definition: typedefs.h:64
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char * LPBYTE
Definition: typedefs.h:53
#define IN
Definition: typedefs.h:39
#define MAKELONG(a, b)
Definition: typedefs.h:249
HANDLE HMODULE
Definition: typedefs.h:77
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define LN_SHELL_EXITED
Definition: undocuser.h:116
#define EWX_NONOTIFY
Definition: undocuser.h:135
#define LN_LOCK_WORKSTATION
Definition: undocuser.h:118
BOOL WINAPI SetLogonNotifyWindow(HWND Wnd)
Definition: logon.c:91
#define WM_LOGONNOTIFY
Definition: undocuser.h:37
#define EWX_CALLER_WINLOGON
Definition: undocuser.h:129
#define LN_START_SCREENSAVE
Definition: undocuser.h:121
#define LN_MESSAGE_BEEP
Definition: undocuser.h:120
#define LN_LOGOFF
Definition: undocuser.h:115
#define LN_LOGOFF_CANCELED
Definition: undocuser.h:122
struct _PROFILEINFOW PROFILEINFOW
int ret
_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
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510
_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
#define ZeroMemory
Definition: winbase.h:1712
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
BOOL WINAPI RevertToSelf(void)
Definition: security.c:1608
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
#define WINAPI
Definition: msvc.h:6
BOOL DisplayStatusMessage(IN PWLSESSION Session, IN HDESK hDesktop, IN UINT ResourceId)
Definition: winlogon.c:349
BOOL RemoveStatusMessage(IN PWLSESSION Session)
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_SHUTTINGDOWN(Status)
Definition: winlogon.h:276
struct _WLSESSION * PWLSESSION
@ STATE_LOGGED_ON
Definition: winlogon.h:206
@ STATE_LOGGED_OFF_SAS
Definition: winlogon.h:205
@ STATE_LOCKED_SAS
Definition: winlogon.h:209
@ STATE_INIT
Definition: winlogon.h:203
@ STATE_LOGGED_OFF
Definition: winlogon.h:204
@ STATE_LOGGED_ON_SAS
Definition: winlogon.h:207
@ STATE_LOCKED
Definition: winlogon.h:208
VOID CloseAllDialogWindows(VOID)
Definition: wlx.c:95
@ LogonHandler
Definition: winlogon.h:258
@ LogoffHandler
Definition: winlogon.h:259
@ StartShellHandler
Definition: winlogon.h:268
@ UnlockHandler
Definition: winlogon.h:261
@ LockHandler
Definition: winlogon.h:260
@ ShutdownHandler
Definition: winlogon.h:263
UINT WINAPI waveOutGetNumDevs(void)
Definition: winmm.c:2137
#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
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#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
#define EWX_POWEROFF
Definition: winuser.h:637
#define EWX_SHUTDOWN
Definition: winuser.h:639
#define MF_BYCOMMAND
Definition: winuser.h:202
BOOL WINAPI SwitchDesktop(_In_ HDESK)
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define MB_ICONHAND
Definition: winuser.h:788
#define WM_CREATE
Definition: winuser.h:1608
BOOL WINAPI UnregisterHotKey(_In_opt_ HWND, _In_ int)
#define WM_COMMAND
Definition: winuser.h:1740
#define SPI_SETSCREENSAVEACTIVE
Definition: winuser.h:1366
#define EWX_LOGOFF
Definition: winuser.h:636
#define WM_INITDIALOG
Definition: winuser.h:1739
HMENU WINAPI GetSystemMenu(_In_ HWND, _In_ BOOL)
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:656
#define WM_SETTINGCHANGE
Definition: winuser.h:1629
#define EWX_REBOOT
Definition: winuser.h:638
BOOL WINAPI RegisterHotKey(_In_opt_ HWND, _In_ int, _In_ UINT, _In_ UINT)
HWND WINAPI SetFocus(_In_opt_ HWND)
#define WM_TIMER
Definition: winuser.h:1742
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)
BOOL WINAPI RemoveMenu(_In_ HMENU, _In_ UINT, _In_ UINT)
ATOM WINAPI RegisterClassExW(_In_ CONST WNDCLASSEXW *)
#define EWX_FORCE
Definition: winuser.h:635
#define SC_CLOSE
Definition: winuser.h:2592
#define MB_ICONEXCLAMATION
Definition: winuser.h:785
#define MB_OK
Definition: winuser.h:790
#define MB_ICONQUESTION
Definition: winuser.h:789
#define CS_SAVEBITS
Definition: winuser.h:657
BOOL WINAPI ExitWindowsEx(_In_ UINT, _In_ DWORD)
#define WM_HOTKEY
Definition: winuser.h:1879
struct _WNDCLASSEXW WNDCLASSEXW
#define VK_DELETE
Definition: winuser.h:2233
#define WM_DESTROY
Definition: winuser.h:1609
BOOL WINAPI UnregisterClassW(_In_ LPCWSTR, HINSTANCE)
#define MB_ICONASTERISK
Definition: winuser.h:784
BOOL WINAPI KillTimer(_In_opt_ HWND, _In_ UINT_PTR)
#define SetWindowLongPtrW
Definition: winuser.h:5346
#define VK_ESCAPE
Definition: winuser.h:2214
BOOL WINAPI DestroyWindow(_In_ HWND)
#define MAKEINTRESOURCE
Definition: winuser.h:591
#define SPI_SETSCREENSAVETIMEOUT
Definition: winuser.h:1364
#define DialogBox
Definition: winuser.h:5761
BOOL WINAPI EndDialog(_In_ HWND, _In_ INT_PTR)
#define WLX_SAS_TYPE_TIMEOUT
Definition: winwlx.h:35
#define WLX_SAS_ACTION_NONE
Definition: winwlx.h:54
#define WLX_PROFILE_TYPE_V1_0
Definition: winwlx.h:50
#define WLX_SAS_ACTION_FORCE_LOGOFF
Definition: winwlx.h:61
#define WLX_SAS_ACTION_UNLOCK_WKSTA
Definition: winwlx.h:60
#define WLX_SAS_TYPE_CTRL_ALT_DEL
Definition: winwlx.h:36
#define WLX_PROFILE_TYPE_V2_0
Definition: winwlx.h:51
#define WLX_WM_SAS
Definition: winwlx.h:71
#define WLX_SAS_ACTION_LOGON
Definition: winwlx.h:53
#define WLX_SAS_ACTION_TASKLIST
Definition: winwlx.h:59
#define WLX_SAS_ACTION_SHUTDOWN_POWER_OFF
Definition: winwlx.h:62
#define WLX_SAS_TYPE_SCRNSVR_TIMEOUT
Definition: winwlx.h:37
#define WLX_SAS_ACTION_SHUTDOWN
Definition: winwlx.h:57
#define WLX_SAS_TYPE_SCRNSVR_ACTIVITY
Definition: winwlx.h:38
#define WLX_LOGON_OPT_NO_PROFILE
Definition: winwlx.h:48
#define WLX_SAS_ACTION_SHUTDOWN_REBOOT
Definition: winwlx.h:63
#define WLX_SAS_ACTION_LOCK_WKSTA
Definition: winwlx.h:55
#define WLX_SAS_ACTION_LOGOFF
Definition: winwlx.h:56
DWORD WINAPI WNetClearConnections(HWND owner)
Definition: wnet.c:2825
DWORD WINAPI WNetCloseEnum(HANDLE hEnum)
Definition: wnet.c:1760
_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
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_In_ CONST DEVPROPKEY _In_ LCID Lcid
Definition: iofuncs.h:2415
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:323
#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:815
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193