ReactOS  0.4.14-dev-98-gb0d4763
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 }
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
#define WARN(fmt,...)
Definition: debug.h:111
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
#define WH_MOUSE_LL
Definition: winuser.h:44
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:136
smooth NULL
Definition: ftsmooth.c:416
#define WH_KEYBOARD_LL
Definition: winuser.h:43
#define SetWindowsHookEx
Definition: winuser.h:5757
#define ERR(fmt,...)
Definition: debug.h:109
static DWORD WINAPI ScreenSaverThreadMain(IN LPVOID lpParameter)
Definition: screensaver.c:76
HINSTANCE hAppInstance
Definition: mmc.c:23

Referenced by HandleLogon().

◆ LoadScreenSaverParameters()

static VOID LoadScreenSaverParameters ( OUT LPDWORD  Timeout)
static

Definition at line 45 of file screensaver.c.

47 {
48  BOOL Enabled;
49 
51  {
52  WARN("WL: Unable to get screen saver timeout (error %lu). Disabling it\n", GetLastError());
53  *Timeout = INFINITE;
54  }
56  {
57  WARN("WL: Unable to check if screen saver is enabled (error %lu). Disabling it\n", GetLastError());
58  *Timeout = INFINITE;
59  }
60  else if (!Enabled)
61  {
62  TRACE("WL: Screen saver is disabled\n");
63  *Timeout = INFINITE;
64  }
65  else
66  {
67  TRACE("WL: Screen saver timeout: %lu seconds\n", *Timeout);
68  *Timeout *= 1000;
69  }
70 }
#define WARN(fmt,...)
Definition: debug.h:111
#define SPI_GETSCREENSAVETIMEOUT
Definition: winuser.h:1345
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL WINAPI SystemParametersInfoW(_In_ UINT, _In_ UINT, _Inout_opt_ PVOID, _In_ UINT)
#define TRACE(s)
Definition: solgame.cpp:4
static ULONG Timeout
Definition: ping.c:61
#define SPI_GETSCREENSAVEACTIVE
Definition: winuser.h:1347
#define INFINITE
Definition: serial.h:102

Referenced by ScreenSaverThreadMain().

◆ ScreenSaverThreadMain()

static DWORD WINAPI ScreenSaverThreadMain ( IN LPVOID  lpParameter)
static

Definition at line 76 of file screensaver.c.

78 {
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 
90  if (!ImpersonateLoggedOnUser(Session->UserToken))
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 
179 cleanup:
180  if (Session->hUserActivity)
181  CloseHandle(Session->hUserActivity);
182 
183  if (Session->hEndOfScreenSaver)
184  CloseHandle(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 WLX_WM_SAS
Definition: winwlx.h:71
struct _WLSESSION * PWLSESSION
#define CloseHandle
Definition: compat.h:398
HANDLE hScreenSaverParametersChanged
Definition: winlogon.h:238
struct tagLASTINPUTINFO LASTINPUTINFO
BOOL WINAPI RevertToSelf(VOID)
Definition: security.c:1487
HWND SASWindow
Definition: winlogon.h:220
#define WARN(fmt,...)
Definition: debug.h:111
HANDLE UserToken
Definition: winlogon.h:227
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:445
#define InterlockedCompareExchange
Definition: interlocked.h:104
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
HANDLE hEndOfScreenSaver
Definition: winlogon.h:240
#define WLX_SAS_TYPE_SCRNSVR_TIMEOUT
Definition: winwlx.h:37
HANDLE hUserActivity
Definition: winlogon.h:239
long LONG
Definition: pedump.c:60
smooth NULL
Definition: ftsmooth.c:416
BOOL WINAPI GetLastInputInfo(_Out_ PLASTINPUTINFO)
BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
Definition: misc.c:152
BOOL WINAPI SystemParametersInfoW(_In_ UINT, _In_ UINT, _Inout_opt_ PVOID, _In_ UINT)
#define WAIT_OBJECT_0
Definition: winbase.h:387
unsigned long DWORD
Definition: ntddk_ex.h:95
int ret
LPVOID lpParameter
Definition: kernel32.h:241
#define InterlockedExchange
Definition: armddk.h:54
BOOL WINAPI UnhookWindowsHookEx(_In_ HHOOK)
#define ERR(fmt,...)
Definition: debug.h:109
HANDLE hEndOfScreenSaverThread
Definition: winlogon.h:237
static ULONG Timeout
Definition: ping.c:61
static VOID LoadScreenSaverParameters(OUT LPDWORD Timeout)
Definition: screensaver.c:45
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
char * cleanup(char *str)
Definition: wpickclick.c:99
#define INFINITE
Definition: serial.h:102

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;
269  DWORD Status;
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 
297  rc = RegQueryValueExW(hKey,
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 screen saver desktop */
333  ret = CreateProcessW(szApplicationName,
334  szCommandLine,
335  NULL,
336  NULL,
337  FALSE,
338  0,
339  NULL,
340  NULL,
341  &StartupInfo,
342  &ProcessInformation);
343  if (!ret)
344  {
345  ERR("WL: Unable to start %S, error %lu\n", szApplicationName, GetLastError());
346  goto cleanup;
347  }
348 
349  CloseHandle(ProcessInformation.hThread);
350 
351  SystemParametersInfoW(SPI_SETSCREENSAVERRUNNING, TRUE, NULL, 0);
352 
354 
355  /* Wait the end of the process or some other activity */
356  ResetEvent(Session->hUserActivity);
357  HandleArray[0] = ProcessInformation.hProcess;
358  HandleArray[1] = Session->hUserActivity;
359  Status = WaitForMultipleObjects(2, HandleArray, FALSE, INFINITE);
360  if (Status == WAIT_OBJECT_0 + 1)
361  {
362  /* Kill the screen saver */
363  TerminateProcess(ProcessInformation.hProcess, 0);
364  }
365 
366  SetEvent(Session->hEndOfScreenSaver);
367 
368  CloseHandle(ProcessInformation.hProcess);
369 
371 
372 cleanup:
373  if (hKey)
374  RegCloseKey(hKey);
375 
376  if (hCurrentUser)
377  RegCloseKey(hCurrentUser);
378 
379  RevertToSelf();
380 
381  if (!ret)
382  {
383  PostMessageW(Session->SASWindow, WLX_WM_SAS, WLX_SAS_TYPE_SCRNSVR_ACTIVITY, 0);
384 #ifndef USE_GETLASTINPUTINFO
385  InterlockedExchange((LONG*)&Session->LastActivity, GetTickCount());
386 #endif
387  }
388 }
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
#define WLX_WM_SAS
Definition: winwlx.h:71
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
#define ERROR_SUCCESS
Definition: deptool.c:10
#define WLX_SAS_TYPE_SCRNSVR_ACTIVITY
Definition: winwlx.h:38
#define KEY_READ
Definition: nt_native.h:1023
BOOL WINAPI RevertToSelf(VOID)
Definition: security.c:1487
struct _STARTUPINFOW STARTUPINFOW
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:445
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1642
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:52
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
smooth NULL
Definition: ftsmooth.c:416
BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
Definition: misc.c:152
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4593
BOOL WINAPI SystemParametersInfoW(_In_ UINT, _In_ UINT, _Inout_opt_ PVOID, _In_ UINT)
#define TRACE(s)
Definition: solgame.cpp:4
#define WAIT_OBJECT_0
Definition: winbase.h:387
DWORD cb
Definition: winbase.h:824
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MAX_PATH
Definition: compat.h:26
unsigned long DWORD
Definition: ntddk_ex.h:95
int ret
static const WCHAR L[]
Definition: oid.c:1250
#define InterlockedExchange
Definition: armddk.h:54
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:109
VOID CallNotificationDlls(PWLSESSION pSession, NOTIFICATION_TYPE Type)
Definition: notify.c:304
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1532
#define STARTF_SCREENSAVER
Definition: undocuser.h:163
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:714
LONG WINAPI RegOpenCurrentUser(IN REGSAM samDesired, OUT PHKEY phkResult)
Definition: reg.c:3232
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
char * cleanup(char *str)
Definition: wpickclick.c:99
DWORD dwFlags
Definition: winbase.h:835
#define INFINITE
Definition: serial.h:102
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define REG_SZ
Definition: layer.c:22

Referenced by DispatchSAS().