ReactOS 0.4.15-dev-8102-g108db8f
screensaver.c File Reference
#include "winlogon.h"
Include dependency graph for screensaver.c:

Go to the source code of this file.

Functions

static VOID LoadScreenSaverParameters (OUT LPDWORD Timeout)
 
static DWORD WINAPI ScreenSaverThreadMain (IN LPVOID lpParameter)
 
BOOL InitializeScreenSaver (IN OUT PWLSESSION Session)
 
VOID StartScreenSaver (IN PWLSESSION Session)
 

Function Documentation

◆ InitializeScreenSaver()

BOOL InitializeScreenSaver ( IN OUT PWLSESSION  Session)

Definition at line 204 of file screensaver.c.

206{
207 HANDLE ScreenSaverThread;
208
209#ifndef USE_GETLASTINPUTINFO
210 /* Register hooks to detect keyboard and mouse activity */
211 Session->KeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardActivityProc, hAppInstance, 0);
212 if (!Session->KeyboardHook)
213 {
214 ERR("WL: Unable to register keyboard hook\n");
215 return FALSE;
216 }
217
218 Session->MouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseActivityProc, hAppInstance, 0);
219 if (!Session->MouseHook)
220 {
221 ERR("WL: Unable to register mouse hook\n");
222 return FALSE;
223 }
224#endif
225
226 Session->hScreenSaverParametersChanged = CreateEventW(NULL, FALSE, FALSE, NULL);
227 if (!Session->hScreenSaverParametersChanged)
228 {
229 WARN("WL: Unable to create screen saver event (error %lu)\n", GetLastError());
230 return TRUE;
231 }
232
233 Session->hEndOfScreenSaverThread = CreateEventW(NULL, FALSE, FALSE, NULL);
234 if (!Session->hEndOfScreenSaverThread)
235 {
236 WARN("WL: Unable to create screen saver event (error %lu)\n", GetLastError());
237 CloseHandle(Session->hScreenSaverParametersChanged);
238 return TRUE;
239 }
240
241 ScreenSaverThread = CreateThread(NULL,
242 0,
244 Session,
245 0,
246 NULL);
247 if (ScreenSaverThread)
248 CloseHandle(ScreenSaverThread);
249 else
250 ERR("WL: Unable to start screen saver thread\n");
251
252 return TRUE;
253}
HINSTANCE hAppInstance
Definition: mmc.c:23
static DWORD WINAPI ScreenSaverThreadMain(IN LPVOID lpParameter)
Definition: screensaver.c:76
#define WARN(fmt,...)
Definition: debug.h:115
#define ERR(fmt,...)
Definition: debug.h:113
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#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
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define SetWindowsHookEx
Definition: winuser.h:5856
#define WH_MOUSE_LL
Definition: winuser.h:44
#define WH_KEYBOARD_LL
Definition: winuser.h:43

Referenced by HandleLogon().

◆ LoadScreenSaverParameters()

static VOID LoadScreenSaverParameters ( OUT LPDWORD  Timeout)
static

Definition at line 45 of file screensaver.c.

47{
49
51 {
52 WARN("WL: Unable to get screen saver timeout (error %lu). Disabling it\n", GetLastError());
54 }
56 {
57 WARN("WL: Unable to check if screen saver is enabled (error %lu). Disabling it\n", GetLastError());
59 }
60 else if (!Enabled)
61 {
62 TRACE("WL: Screen saver is disabled\n");
64 }
65 else
66 {
67 TRACE("WL: Screen saver timeout: %lu seconds\n", *Timeout);
68 *Timeout *= 1000;
69 }
70}
#define INFINITE
Definition: serial.h:102
unsigned int BOOL
Definition: ntddk_ex.h:94
@ Enabled
Definition: mountmgr.h:159
static ULONG Timeout
Definition: ping.c:61
#define TRACE(s)
Definition: solgame.cpp:4
BOOL WINAPI SystemParametersInfoW(_In_ UINT uiAction, _In_ UINT uiParam, _Inout_opt_ PVOID pvParam, _In_ UINT fWinIni)
#define SPI_GETSCREENSAVETIMEOUT
Definition: winuser.h:1363
#define SPI_GETSCREENSAVEACTIVE
Definition: winuser.h:1365

Referenced by ScreenSaverThreadMain().

◆ ScreenSaverThreadMain()

static DWORD WINAPI ScreenSaverThreadMain ( IN LPVOID  lpParameter)
static

Definition at line 76 of file screensaver.c.

78{
79 PWLSESSION Session = (PWLSESSION)lpParameter;
80 HANDLE HandleArray[3];
81#ifdef USE_GETLASTINPUTINFO
82 LASTINPUTINFO lastInputInfo;
83#else
84 DWORD LastActivity;
85#endif
86 DWORD TimeToWait;
87 DWORD Timeout; /* Timeout before screen saver starts, in milliseconds */
88 DWORD ret;
89
91 {
92 ERR("ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
93 return 0;
94 }
95
97 if (!Session->hUserActivity)
98 {
99 ERR("WL: Unable to create event (error %lu)\n", GetLastError());
100 goto cleanup;
101 }
102
104 if (!Session->hEndOfScreenSaver)
105 {
106 ERR("WL: Unable to create event (error %lu)\n", GetLastError());
107 goto cleanup;
108 }
109
110 HandleArray[0] = Session->hEndOfScreenSaverThread;
111 HandleArray[1] = Session->hScreenSaverParametersChanged;
112 HandleArray[2] = Session->hEndOfScreenSaver;
113
115
116#ifndef USE_GETLASTINPUTINFO
117 InterlockedExchange((LONG*)&Session->LastActivity, GetTickCount());
118#else
119 lastInputInfo.cbSize = sizeof(LASTINPUTINFO);
120#endif
121 for (;;)
122 {
123 /* See the time of last activity and calculate a timeout */
124#ifndef USE_GETLASTINPUTINFO
125 LastActivity = InterlockedCompareExchange((LONG*)&Session->LastActivity, 0, 0);
126 TimeToWait = Timeout - (GetTickCount() - LastActivity);
127#else
128 if (GetLastInputInfo(&lastInputInfo))
129 TimeToWait = Timeout - (GetTickCount() - lastInputInfo.dwTime);
130 else
131 {
132 WARN("GetLastInputInfo() failed with error %lu\n", GetLastError());
133 TimeToWait = 10; /* Try again in 10 ms */
134 }
135#endif
136
137 if (TimeToWait > Timeout)
138 {
139 /* GetTickCount() got back to 0 */
140 TimeToWait = Timeout;
141 }
142
143 /* Wait for the timeout, or the end of this thread */
144 ret = WaitForMultipleObjects(2, HandleArray, FALSE, TimeToWait);
145 if (ret == WAIT_OBJECT_0)
146 break;
147 else if (ret == WAIT_OBJECT_0 + 1)
149
150 /* Check if we didn't had recent activity */
151#ifndef USE_GETLASTINPUTINFO
152 LastActivity = InterlockedCompareExchange((LONG*)&Session->LastActivity, 0, 0);
153 if (LastActivity + Timeout > GetTickCount())
154 continue;
155#else
156 if (!GetLastInputInfo(&lastInputInfo))
157 {
158 WARN("GetLastInputInfo() failed with error %lu\n", GetLastError());
159 continue;
160 }
161
162 if (lastInputInfo.dwTime + Timeout > GetTickCount())
163 continue;
164#endif
165
166 /* Run screen saver */
168
169 /* Wait for the end of this thread or of the screen saver */
170 ret = WaitForMultipleObjects(3, HandleArray, FALSE, INFINITE);
171 if (ret == WAIT_OBJECT_0)
172 break;
173 else if (ret == WAIT_OBJECT_0 + 1)
175 else if (ret == WAIT_OBJECT_0 + 2)
176 SystemParametersInfoW(SPI_SETSCREENSAVERRUNNING, FALSE, NULL, 0);
177 }
178
179cleanup:
180 if (Session->hUserActivity)
181 CloseHandle(Session->hUserActivity);
182
183 if (Session->hEndOfScreenSaver)
185
186 RevertToSelf();
187
188#ifndef USE_GETLASTINPUTINFO
189 if (Session->KeyboardHook)
190 UnhookWindowsHookEx(Session->KeyboardHook);
191
192 if (Session->MouseHook)
193 UnhookWindowsHookEx(Session->MouseHook);
194#endif
195
198
199 return 0;
200}
#define InterlockedExchange
Definition: armddk.h:54
static VOID LoadScreenSaverParameters(OUT LPDWORD Timeout)
Definition: screensaver.c:45
BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
Definition: misc.c:152
static void cleanup(void)
Definition: main.c:1335
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
unsigned long DWORD
Definition: ntddk_ex.h:95
#define InterlockedCompareExchange
Definition: interlocked.h:104
long LONG
Definition: pedump.c:60
HANDLE hUserActivity
Definition: winlogon.h:244
HANDLE hScreenSaverParametersChanged
Definition: winlogon.h:243
HANDLE hEndOfScreenSaver
Definition: winlogon.h:245
HANDLE UserToken
Definition: winlogon.h:232
HANDLE hEndOfScreenSaverThread
Definition: winlogon.h:242
HWND SASWindow
Definition: winlogon.h:225
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
int ret
#define WAIT_OBJECT_0
Definition: winbase.h:406
BOOL WINAPI RevertToSelf(void)
Definition: security.c:1608
struct _WLSESSION * PWLSESSION
BOOL WINAPI GetLastInputInfo(_Out_ PLASTINPUTINFO)
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI UnhookWindowsHookEx(_In_ HHOOK)
struct tagLASTINPUTINFO LASTINPUTINFO
#define WLX_WM_SAS
Definition: winwlx.h:71
#define WLX_SAS_TYPE_SCRNSVR_TIMEOUT
Definition: winwlx.h:37

Referenced by InitializeScreenSaver().

◆ StartScreenSaver()

VOID StartScreenSaver ( IN PWLSESSION  Session)

Definition at line 257 of file screensaver.c.

259{
260 HKEY hKey = NULL, hCurrentUser = NULL;
261 WCHAR szApplicationName[MAX_PATH];
262 WCHAR szCommandLine[MAX_PATH + 3];
263 DWORD bufferSize = sizeof(szApplicationName) - sizeof(WCHAR);
264 DWORD dwType;
265 STARTUPINFOW StartupInfo;
266 PROCESS_INFORMATION ProcessInformation;
267 HANDLE HandleArray[2];
268 LONG rc;
270 BOOL ret = FALSE;
271
272 if (!ImpersonateLoggedOnUser(Session->UserToken))
273 {
274 ERR("WL: ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
275 goto cleanup;
276 }
277
279 &hCurrentUser);
280 if (rc != ERROR_SUCCESS)
281 {
282 ERR("WL: RegOpenCurrentUser error %lu\n", rc);
283 goto cleanup;
284 }
285
286 rc = RegOpenKeyExW(hCurrentUser,
287 L"Control Panel\\Desktop",
288 0,
290 &hKey);
291 if (rc != ERROR_SUCCESS)
292 {
293 ERR("WL: RegOpenKeyEx error %lu\n", rc);
294 goto cleanup;
295 }
296
298 L"SCRNSAVE.EXE",
299 0,
300 &dwType,
301 (LPBYTE)szApplicationName,
302 &bufferSize);
303 if (rc != ERROR_SUCCESS || dwType != REG_SZ)
304 {
305 if (rc != ERROR_FILE_NOT_FOUND)
306 ERR("WL: RegQueryValueEx error %lu\n", rc);
307 goto cleanup;
308 }
309
310 if (bufferSize == 0)
311 {
312 ERR("WL: Buffer size is NULL!\n");
313 goto cleanup;
314 }
315
316 szApplicationName[bufferSize / sizeof(WCHAR)] = 0; /* Terminate the string */
317
318 if (wcslen(szApplicationName) == 0)
319 {
320 ERR("WL: Application Name length is zero!\n");
321 goto cleanup;
322 }
323
324 wsprintfW(szCommandLine, L"%s /s", szApplicationName);
325 TRACE("WL: Executing %S\n", szCommandLine);
326
327 ZeroMemory(&StartupInfo, sizeof(STARTUPINFOW));
328 ZeroMemory(&ProcessInformation, sizeof(PROCESS_INFORMATION));
329 StartupInfo.cb = sizeof(STARTUPINFOW);
330 StartupInfo.dwFlags = STARTF_SCREENSAVER;
331
332 /* FIXME: Run the screen saver on the secure screen saver desktop if required */
333 StartupInfo.lpDesktop = L"WinSta0\\Default";
334
335 ret = CreateProcessAsUserW(Session->UserToken,
336 szApplicationName,
337 szCommandLine,
338 NULL,
339 NULL,
340 FALSE,
342 NULL,
343 NULL,
344 &StartupInfo,
345 &ProcessInformation);
346 if (!ret)
347 {
348 ERR("WL: Unable to start %S, error %lu\n", szApplicationName, GetLastError());
349 goto cleanup;
350 }
351
352 CloseHandle(ProcessInformation.hThread);
353
354 SystemParametersInfoW(SPI_SETSCREENSAVERRUNNING, TRUE, NULL, 0);
355
357
358 /* Wait the end of the process or some other activity */
359 ResetEvent(Session->hUserActivity);
360 HandleArray[0] = ProcessInformation.hProcess;
361 HandleArray[1] = Session->hUserActivity;
362 Status = WaitForMultipleObjects(2, HandleArray, FALSE, INFINITE);
363 if (Status == WAIT_OBJECT_0 + 1)
364 {
365 /* Kill the screen saver */
366 TerminateProcess(ProcessInformation.hProcess, 0);
367 }
368
369 SetEvent(Session->hEndOfScreenSaver);
370
371 CloseHandle(ProcessInformation.hProcess);
372
374
375cleanup:
376 if (hKey)
378
379 if (hCurrentUser)
380 RegCloseKey(hCurrentUser);
381
382 RevertToSelf();
383
384 if (!ret)
385 {
387#ifndef USE_GETLASTINPUTINFO
388 InterlockedExchange((LONG*)&Session->LastActivity, GetTickCount());
389#endif
390 }
391}
VOID CallNotificationDlls(PWLSESSION pSession, NOTIFICATION_TYPE Type)
Definition: notify.c:390
#define RegCloseKey(hKey)
Definition: registry.h:49
#define ERROR_SUCCESS
Definition: deptool.c:10
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessAsUserW(_In_opt_ HANDLE hToken, _In_opt_ LPCWSTR lpApplicationName, _Inout_opt_ LPWSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags, _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCWSTR lpCurrentDirectory, _In_ LPSTARTUPINFOW lpStartupInfo, _Out_ LPPROCESS_INFORMATION lpProcessInformation)
Definition: logon.c:993
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
#define MAX_PATH
Definition: compat.h:34
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1532
FxAutoRegKey hKey
size_t bufferSize
Status
Definition: gdiplustypes.h:25
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define REG_SZ
Definition: layer.c:22
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define KEY_READ
Definition: nt_native.h:1023
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define L(x)
Definition: ntvdm.h:50
LPWSTR lpDesktop
Definition: winbase.h:854
DWORD cb
Definition: winbase.h:852
DWORD dwFlags
Definition: winbase.h:863
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:714
unsigned char * LPBYTE
Definition: typedefs.h:53
#define STARTF_SCREENSAVER
Definition: undocuser.h:165
#define ZeroMemory
Definition: winbase.h:1712
#define IDLE_PRIORITY_CLASS
Definition: winbase.h:182
struct _STARTUPINFOW STARTUPINFOW
@ StopScreenSaverHandler
Definition: winlogon.h:265
@ StartScreenSaverHandler
Definition: winlogon.h:264
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
#define WLX_SAS_TYPE_SCRNSVR_ACTIVITY
Definition: winwlx.h:38
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by DispatchSAS().