ReactOS 0.4.16-dev-1946-g52006dd
screensaver.c File Reference
#include "winlogon.h"
#include <winbase_undoc.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 205 of file screensaver.c.

207{
208 HANDLE ScreenSaverThread;
209
210#ifndef USE_GETLASTINPUTINFO
211 /* Register hooks to detect keyboard and mouse activity */
212 Session->KeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardActivityProc, hAppInstance, 0);
213 if (!Session->KeyboardHook)
214 {
215 ERR("WL: Unable to register keyboard hook\n");
216 return FALSE;
217 }
218
219 Session->MouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseActivityProc, hAppInstance, 0);
220 if (!Session->MouseHook)
221 {
222 ERR("WL: Unable to register mouse hook\n");
223 return FALSE;
224 }
225#endif
226
227 Session->hScreenSaverParametersChanged = CreateEventW(NULL, FALSE, FALSE, NULL);
228 if (!Session->hScreenSaverParametersChanged)
229 {
230 WARN("WL: Unable to create screen saver event (error %lu)\n", GetLastError());
231 return TRUE;
232 }
233
234 Session->hEndOfScreenSaverThread = CreateEventW(NULL, FALSE, FALSE, NULL);
235 if (!Session->hEndOfScreenSaverThread)
236 {
237 WARN("WL: Unable to create screen saver event (error %lu)\n", GetLastError());
238 CloseHandle(Session->hScreenSaverParametersChanged);
239 return TRUE;
240 }
241
242 ScreenSaverThread = CreateThread(NULL,
243 0,
245 Session,
246 0,
247 NULL);
248 if (ScreenSaverThread)
249 CloseHandle(ScreenSaverThread);
250 else
251 ERR("WL: Unable to start screen saver thread\n");
252
253 return TRUE;
254}
HINSTANCE hAppInstance
Definition: mmc.c:23
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
static DWORD WINAPI ScreenSaverThreadMain(IN LPVOID lpParameter)
Definition: screensaver.c:77
#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:5967
#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 46 of file screensaver.c.

48{
50
52 {
53 WARN("WL: Unable to get screen saver timeout (error %lu). Disabling it\n", GetLastError());
55 }
57 {
58 WARN("WL: Unable to check if screen saver is enabled (error %lu). Disabling it\n", GetLastError());
60 }
61 else if (!Enabled)
62 {
63 TRACE("WL: Screen saver is disabled\n");
65 }
66 else
67 {
68 TRACE("WL: Screen saver timeout: %lu seconds\n", *Timeout);
69 *Timeout *= 1000;
70 }
71}
#define INFINITE
Definition: serial.h:102
unsigned int BOOL
Definition: ntddk_ex.h:94
@ Enabled
Definition: mountmgr.h:179
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:1374
#define SPI_GETSCREENSAVEACTIVE
Definition: winuser.h:1376

Referenced by ScreenSaverThreadMain().

◆ ScreenSaverThreadMain()

static DWORD WINAPI ScreenSaverThreadMain ( IN LPVOID  lpParameter)
static

Definition at line 77 of file screensaver.c.

79{
80 PWLSESSION Session = (PWLSESSION)lpParameter;
81 HANDLE HandleArray[3];
82#ifdef USE_GETLASTINPUTINFO
83 LASTINPUTINFO lastInputInfo;
84#else
85 DWORD LastActivity;
86#endif
87 DWORD TimeToWait;
88 DWORD Timeout; /* Timeout before screen saver starts, in milliseconds */
89 DWORD ret;
90
92 {
93 ERR("ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
94 return 0;
95 }
96
98 if (!Session->hUserActivity)
99 {
100 ERR("WL: Unable to create event (error %lu)\n", GetLastError());
101 goto cleanup;
102 }
103
105 if (!Session->hEndOfScreenSaver)
106 {
107 ERR("WL: Unable to create event (error %lu)\n", GetLastError());
108 goto cleanup;
109 }
110
111 HandleArray[0] = Session->hEndOfScreenSaverThread;
112 HandleArray[1] = Session->hScreenSaverParametersChanged;
113 HandleArray[2] = Session->hEndOfScreenSaver;
114
116
117#ifndef USE_GETLASTINPUTINFO
118 InterlockedExchange((LONG*)&Session->LastActivity, GetTickCount());
119#else
120 lastInputInfo.cbSize = sizeof(LASTINPUTINFO);
121#endif
122 for (;;)
123 {
124 /* See the time of last activity and calculate a timeout */
125#ifndef USE_GETLASTINPUTINFO
126 LastActivity = InterlockedCompareExchange((LONG*)&Session->LastActivity, 0, 0);
127 TimeToWait = Timeout - (GetTickCount() - LastActivity);
128#else
129 if (GetLastInputInfo(&lastInputInfo))
130 TimeToWait = Timeout - (GetTickCount() - lastInputInfo.dwTime);
131 else
132 {
133 WARN("GetLastInputInfo() failed with error %lu\n", GetLastError());
134 TimeToWait = 10; /* Try again in 10 ms */
135 }
136#endif
137
138 if (TimeToWait > Timeout)
139 {
140 /* GetTickCount() got back to 0 */
141 TimeToWait = Timeout;
142 }
143
144 /* Wait for the timeout, or the end of this thread */
145 ret = WaitForMultipleObjects(2, HandleArray, FALSE, TimeToWait);
146 if (ret == WAIT_OBJECT_0)
147 break;
148 else if (ret == WAIT_OBJECT_0 + 1)
150
151 /* Check if we didn't had recent activity */
152#ifndef USE_GETLASTINPUTINFO
153 LastActivity = InterlockedCompareExchange((LONG*)&Session->LastActivity, 0, 0);
154 if (LastActivity + Timeout > GetTickCount())
155 continue;
156#else
157 if (!GetLastInputInfo(&lastInputInfo))
158 {
159 WARN("GetLastInputInfo() failed with error %lu\n", GetLastError());
160 continue;
161 }
162
163 if (lastInputInfo.dwTime + Timeout > GetTickCount())
164 continue;
165#endif
166
167 /* Run screen saver */
169
170 /* Wait for the end of this thread or of the screen saver */
171 ret = WaitForMultipleObjects(3, HandleArray, FALSE, INFINITE);
172 if (ret == WAIT_OBJECT_0)
173 break;
174 else if (ret == WAIT_OBJECT_0 + 1)
176 else if (ret == WAIT_OBJECT_0 + 2)
177 SystemParametersInfoW(SPI_SETSCREENSAVERRUNNING, FALSE, NULL, 0);
178 }
179
180cleanup:
181 if (Session->hUserActivity)
182 CloseHandle(Session->hUserActivity);
183
184 if (Session->hEndOfScreenSaver)
186
187 RevertToSelf();
188
189#ifndef USE_GETLASTINPUTINFO
190 if (Session->KeyboardHook)
191 UnhookWindowsHookEx(Session->KeyboardHook);
192
193 if (Session->MouseHook)
194 UnhookWindowsHookEx(Session->MouseHook);
195#endif
196
199
200 return 0;
201}
#define InterlockedExchange
Definition: armddk.h:54
static VOID LoadScreenSaverParameters(OUT LPDWORD Timeout)
Definition: screensaver.c:46
BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
Definition: misc.c:152
static void cleanup(void)
Definition: main.c:1335
BOOL WINAPI RevertToSelf(void)
Definition: security.c:855
ULONG WINAPI DECLSPEC_HOTPATCH GetTickCount(void)
Definition: sync.c:182
return ret
Definition: mutex.c:146
unsigned long DWORD
Definition: ntddk_ex.h:95
#define InterlockedCompareExchange
Definition: interlocked.h:119
long LONG
Definition: pedump.c:60
HANDLE hUserActivity
Definition: winlogon.h:250
HANDLE hScreenSaverParametersChanged
Definition: winlogon.h:249
HANDLE hEndOfScreenSaver
Definition: winlogon.h:251
HANDLE UserToken
Definition: winlogon.h:237
HANDLE hEndOfScreenSaverThread
Definition: winlogon.h:248
HWND SASWindow
Definition: winlogon.h:228
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
#define WAIT_OBJECT_0
Definition: winbase.h:383
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 258 of file screensaver.c.

260{
261 HKEY hKey = NULL, hCurrentUser = NULL;
262 WCHAR szApplicationName[MAX_PATH];
263 WCHAR szCommandLine[MAX_PATH + 3];
264 DWORD bufferSize = sizeof(szApplicationName) - sizeof(WCHAR);
265 DWORD dwType;
266 STARTUPINFOW StartupInfo;
267 PROCESS_INFORMATION ProcessInformation;
268 HANDLE HandleArray[2];
269 LONG rc;
271 BOOL ret = FALSE;
272
273 if (!ImpersonateLoggedOnUser(Session->UserToken))
274 {
275 ERR("WL: ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
276 goto cleanup;
277 }
278
280 &hCurrentUser);
281 if (rc != ERROR_SUCCESS)
282 {
283 ERR("WL: RegOpenCurrentUser error %lu\n", rc);
284 goto cleanup;
285 }
286
287 rc = RegOpenKeyExW(hCurrentUser,
288 L"Control Panel\\Desktop",
289 0,
291 &hKey);
292 if (rc != ERROR_SUCCESS)
293 {
294 ERR("WL: RegOpenKeyEx error %lu\n", rc);
295 goto cleanup;
296 }
297
299 L"SCRNSAVE.EXE",
300 0,
301 &dwType,
302 (LPBYTE)szApplicationName,
303 &bufferSize);
304 if (rc != ERROR_SUCCESS || dwType != REG_SZ)
305 {
306 if (rc != ERROR_FILE_NOT_FOUND)
307 ERR("WL: RegQueryValueEx error %lu\n", rc);
308 goto cleanup;
309 }
310
311 if (bufferSize == 0)
312 {
313 ERR("WL: Buffer size is NULL!\n");
314 goto cleanup;
315 }
316
317 szApplicationName[bufferSize / sizeof(WCHAR)] = 0; /* Terminate the string */
318
319 if (wcslen(szApplicationName) == 0)
320 {
321 ERR("WL: Application Name length is zero!\n");
322 goto cleanup;
323 }
324
325 wsprintfW(szCommandLine, L"%s /s", szApplicationName);
326 TRACE("WL: Executing %S\n", szCommandLine);
327
328 ZeroMemory(&StartupInfo, sizeof(STARTUPINFOW));
329 ZeroMemory(&ProcessInformation, sizeof(PROCESS_INFORMATION));
330 StartupInfo.cb = sizeof(STARTUPINFOW);
331 StartupInfo.dwFlags = STARTF_SCREENSAVER;
332
333 /* FIXME: Run the screen saver on the secure screen saver desktop if required */
334 StartupInfo.lpDesktop = L"WinSta0\\Default";
335
336 ret = CreateProcessAsUserW(Session->UserToken,
337 szApplicationName,
338 szCommandLine,
339 NULL,
340 NULL,
341 FALSE,
343 NULL,
344 NULL,
345 &StartupInfo,
346 &ProcessInformation);
347 if (!ret)
348 {
349 ERR("WL: Unable to start %S, error %lu\n", szApplicationName, GetLastError());
350 goto cleanup;
351 }
352
353 CloseHandle(ProcessInformation.hThread);
354
355 SystemParametersInfoW(SPI_SETSCREENSAVERRUNNING, TRUE, NULL, 0);
356
358
359 /* Wait the end of the process or some other activity */
360 ResetEvent(Session->hUserActivity);
361 HandleArray[0] = ProcessInformation.hProcess;
362 HandleArray[1] = Session->hUserActivity;
363 Status = WaitForMultipleObjects(2, HandleArray, FALSE, INFINITE);
364 if (Status == WAIT_OBJECT_0 + 1)
365 {
366 /* Kill the screen saver */
367 TerminateProcess(ProcessInformation.hProcess, 0);
368 }
369
370 SetEvent(Session->hEndOfScreenSaver);
371
372 CloseHandle(ProcessInformation.hProcess);
373
375
376cleanup:
377 if (hKey)
379
380 if (hCurrentUser)
381 RegCloseKey(hCurrentUser);
382
383 RevertToSelf();
384
385 if (!ret)
386 {
388#ifndef USE_GETLASTINPUTINFO
389 InterlockedExchange((LONG*)&Session->LastActivity, GetTickCount());
390#endif
391 }
392}
VOID CallNotificationDlls(PWLSESSION pSession, NOTIFICATION_TYPE Type)
Definition: notify.c:530
#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:987
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:1534
#define L(x)
Definition: resources.c:13
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 ZeroMemory
Definition: minwinbase.h:31
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define KEY_READ
Definition: nt_native.h:1026
#define KEY_QUERY_VALUE
Definition: nt_native.h:1019
struct _STARTUPINFOW STARTUPINFOW
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:167
#define IDLE_PRIORITY_CLASS
Definition: winbase.h:186
@ StopScreenSaverHandler
Definition: winlogon.h:271
@ StartScreenSaverHandler
Definition: winlogon.h:270
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().