mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
981 lines
25 KiB
981 lines
25 KiB
/****************************** Module Header ******************************\
|
|
* Module Name: scrnsave.c
|
|
*
|
|
* Copyright (c) 1991, Microsoft Corporation
|
|
*
|
|
* Support routines to implement screen-saver-invokation
|
|
*
|
|
* History:
|
|
* 01-23-91 Davidc Created.
|
|
\***************************************************************************/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
#define LPTSTR LPWSTR
|
|
|
|
//
|
|
// Define the structure used to pass data into the screen-saver control dialog
|
|
//
|
|
typedef struct {
|
|
PGLOBALS pGlobals;
|
|
BOOL fSecure;
|
|
BOOL fEnabled;
|
|
LPTSTR ScreenSaverName;
|
|
DWORD ProcessId; // Screen-saver process id
|
|
DWORD SasInterrupt; // Sas interrupt, if any
|
|
BOOL WeKilledIt;
|
|
HANDLE hProcess;
|
|
POBJECT_MONITOR Monitor;
|
|
int ReturnValue;
|
|
} SCREEN_SAVER_DATA;
|
|
typedef SCREEN_SAVER_DATA *PSCREEN_SAVER_DATA;
|
|
|
|
// Parameters added to screen saver command line
|
|
TCHAR Parameters[] = TEXT(" /s");
|
|
|
|
//
|
|
// Private prototypes
|
|
//
|
|
|
|
BOOL WINAPI
|
|
ScreenSaverDlgProc(
|
|
HWND hDlg,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
);
|
|
|
|
BOOL
|
|
ScreenSaverDlgInit(
|
|
HWND hDlg
|
|
);
|
|
|
|
BOOL
|
|
StartScreenSaver(
|
|
PSCREEN_SAVER_DATA ScreenSaverData
|
|
);
|
|
|
|
BOOL
|
|
KillScreenSaver(
|
|
PSCREEN_SAVER_DATA ScreenSaverData,
|
|
int ReturnValue
|
|
);
|
|
|
|
BOOL
|
|
StartScreenSaverMonitor(
|
|
HWND hDlg
|
|
);
|
|
|
|
VOID
|
|
DeleteScreenSaverMonitor(
|
|
HWND hDlg
|
|
);
|
|
|
|
DWORD ScreenSaverMonitorThread(
|
|
LPVOID lpThreadParameter
|
|
);
|
|
|
|
BOOL
|
|
GetScreenSaverInfo(
|
|
PSCREEN_SAVER_DATA ScreenSaverData
|
|
);
|
|
|
|
VOID
|
|
DeleteScreenSaverInfo(
|
|
PSCREEN_SAVER_DATA ScreenSaverData
|
|
);
|
|
|
|
// Message sent by the monitor thread to main thread window
|
|
#define WM_SCREEN_SAVER_ENDED (WM_USER + 10)
|
|
|
|
|
|
/***************************************************************************\
|
|
* ScreenSaverEnabled
|
|
*
|
|
* Checks that a screen-saver is enabled for the current logged-on user.
|
|
*
|
|
* Returns : TRUE if the current user has an enabled screen-saver, otherwise FALSE
|
|
*
|
|
* 10-15-92 Davidc Created.
|
|
\***************************************************************************/
|
|
|
|
BOOL
|
|
ScreenSaverEnabled(
|
|
PGLOBALS pGlobals)
|
|
{
|
|
SCREEN_SAVER_DATA ScreenSaverData;
|
|
BOOL Enabled;
|
|
|
|
ScreenSaverData.pGlobals = pGlobals;
|
|
GetScreenSaverInfo(&ScreenSaverData);
|
|
|
|
Enabled = ScreenSaverData.fEnabled;
|
|
|
|
DeleteScreenSaverInfo(&ScreenSaverData);
|
|
|
|
return(Enabled);
|
|
}
|
|
|
|
/***************************************************************************\
|
|
* ValidateScreenSaver
|
|
*
|
|
* Confirm that the screen saver executable exists and it enabled.
|
|
*
|
|
* Returns :
|
|
* TRUE - the screen-saver is ready.
|
|
* FALSE - the screen-saver does not exist or is not enabled.
|
|
*
|
|
* 01-23-91 ericflo Created.
|
|
\***************************************************************************/
|
|
BOOL
|
|
ValidateScreenSaver(
|
|
PSCREEN_SAVER_DATA ssd)
|
|
{
|
|
WIN32_FIND_DATA fd;
|
|
HANDLE hFile;
|
|
BOOL Enabled;
|
|
LPTSTR lpTempSS, lpEnd;
|
|
WCHAR szFake[2];
|
|
LPTSTR lpFake;
|
|
|
|
|
|
//
|
|
// Check if the screen saver enabled
|
|
//
|
|
|
|
Enabled = ssd->fEnabled;
|
|
|
|
//
|
|
// If the screen saver is enabled, confirm that the executable exists.
|
|
//
|
|
|
|
if (Enabled) {
|
|
|
|
//
|
|
// The screen save executable name contains some parameters after
|
|
// it. We need to allocate a temporary buffer, remove the arguments
|
|
// and test if the executable exists.
|
|
//
|
|
|
|
lpTempSS = (LPTSTR) GlobalAlloc (GPTR,
|
|
sizeof (TCHAR) * (lstrlen (ssd->ScreenSaverName) + 1));
|
|
|
|
if (!lpTempSS) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Copy the filename to the temp buffer.
|
|
//
|
|
|
|
lstrcpy (lpTempSS, ssd->ScreenSaverName);
|
|
|
|
|
|
//
|
|
// Since we know how many arguments were added to the executable,
|
|
// we can get the string length, move that many characters in from
|
|
// the right and insert a NULL.
|
|
//
|
|
|
|
lpEnd = lpTempSS + lstrlen (lpTempSS);
|
|
*(lpEnd - lstrlen (Parameters)) = TEXT('\0');
|
|
|
|
//
|
|
// Test to see if the executable exists.
|
|
//
|
|
|
|
if (SearchPath(NULL, lpTempSS, NULL, 2, szFake, &lpFake) == 0)
|
|
{
|
|
Enabled = FALSE;
|
|
|
|
DebugLog((DEB_TRACE, "Screen Saver <%S> does not exist. Error is %d",
|
|
lpTempSS, GetLastError()));
|
|
|
|
}
|
|
|
|
//
|
|
// Clean up.
|
|
//
|
|
|
|
GlobalFree (lpTempSS);
|
|
}
|
|
|
|
return (Enabled);
|
|
}
|
|
|
|
/***************************************************************************\
|
|
* RunScreenSaver
|
|
*
|
|
* Starts the appropriate screen-saver for the current user in the correct
|
|
* context and waits for it to complete.
|
|
* If the user presses the SAS, we kill the screen-saver and return.
|
|
* If a logoff notification comes in, we kill the screen-saver and return.
|
|
*
|
|
* Returns :
|
|
* DLG_SUCCESS - the screen-saver completed successfully.
|
|
* DLG_FAILURE - unable to run the screen-saver
|
|
* DLG_LOCK_WORKSTATION - the screen-saver completed successfully and
|
|
* was designated secure.
|
|
* DLG_LOGOFF - the screen-saver was interrupted by a user logoff notification
|
|
*
|
|
* Normally the original desktop is switched back to and the desktop lock
|
|
* returned to its original state on exit.
|
|
* If the return value is DLG_LOCK_WORKSTATION or DLG_LOGOFF - the winlogon
|
|
* desktop has been switched to and the desktop lock retained.
|
|
*
|
|
* 01-23-91 Davidc Created.
|
|
\***************************************************************************/
|
|
|
|
int
|
|
RunScreenSaver(
|
|
PGLOBALS pGlobals,
|
|
BOOL WindowStationLocked,
|
|
BOOL AllowFastUnlock)
|
|
{
|
|
HDESK hdeskPrevious;
|
|
int Result;
|
|
SCREEN_SAVER_DATA ScreenSaverData;
|
|
BOOL Success;
|
|
WinstaState PriorState;
|
|
DWORD BeginTime;
|
|
DWORD EndTime;
|
|
|
|
|
|
|
|
//
|
|
// If no one is logged on, make SYSTEM the user.
|
|
//
|
|
if (!pGlobals->UserLoggedOn)
|
|
{
|
|
|
|
|
|
//
|
|
// Toggle the locks, in case the OPENLOCK is still set from
|
|
// a prior logoff.
|
|
//
|
|
|
|
UnlockWindowStation(pGlobals->WindowStation.hwinsta);
|
|
LockWindowStation(pGlobals->WindowStation.hwinsta);
|
|
}
|
|
//
|
|
// Create and open the app desktop.
|
|
//
|
|
if (!(pGlobals->WindowStation.hdeskScreenSaver =
|
|
CreateDesktop((LPTSTR)SCREENSAVER_DESKTOP_NAME,
|
|
NULL, NULL, 0, MAXIMUM_ALLOWED, NULL))) {
|
|
DebugLog((DEB_TRACE, "Failed to create screen saver desktop\n"));
|
|
return(DLG_FAILURE);
|
|
}
|
|
|
|
//
|
|
// Fill in screen-saver data structure
|
|
//
|
|
ZeroMemory( &ScreenSaverData, sizeof( ScreenSaverData ) );
|
|
|
|
ScreenSaverData.pGlobals = pGlobals;
|
|
|
|
if (GetScreenSaverInfo(&ScreenSaverData)) {
|
|
if (!ValidateScreenSaver(&ScreenSaverData)) {
|
|
|
|
DeleteScreenSaverInfo(&ScreenSaverData);
|
|
|
|
CloseDesktop(pGlobals->WindowStation.hdeskScreenSaver);
|
|
|
|
return (DLG_FAILURE);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Update windowstation lock so screen saver can start
|
|
//
|
|
|
|
if (!pGlobals->pGina->pWlxScreenSaverNotify(
|
|
pGlobals->pGina->pGinaContext,
|
|
&ScreenSaverData.fSecure ))
|
|
{
|
|
DebugLog((DEB_TRACE, "GINA DLL rejected screen saver\n"));
|
|
|
|
DeleteScreenSaverInfo( &ScreenSaverData );
|
|
CloseDesktop( pGlobals->WindowStation.hdeskScreenSaver );
|
|
|
|
//
|
|
// If no one is logged on, remove SYSTEM as the user.
|
|
//
|
|
return(DLG_FAILURE);
|
|
}
|
|
|
|
|
|
pGlobals->ScreenSaverActive = TRUE;
|
|
|
|
if ( ScreenSaverData.fSecure )
|
|
{
|
|
|
|
PriorState = pGlobals->WinlogonState;
|
|
pGlobals->WinlogonState = Winsta_Locked;
|
|
|
|
DebugLog((DEB_TRACE_STATE, "RunScreenSaver: Setting state to %s\n",
|
|
GetState(Winsta_Locked)));
|
|
}
|
|
|
|
//
|
|
// Switch to screen-saver desktop
|
|
//
|
|
if (!SetActiveDesktop(&pGlobals->WindowStation, Desktop_ScreenSaver)) {
|
|
|
|
DebugLog((DEB_TRACE, "Failed to switch to screen saver desktop\n"));
|
|
|
|
pGlobals->ScreenSaverActive = FALSE;
|
|
|
|
DeleteScreenSaverInfo(&ScreenSaverData);
|
|
CloseDesktop(pGlobals->WindowStation.hdeskScreenSaver);
|
|
|
|
//
|
|
// If no one is logged on, remove SYSTEM as the user.
|
|
//
|
|
return(DLG_FAILURE);
|
|
}
|
|
|
|
//
|
|
// Stash begin time
|
|
//
|
|
|
|
BeginTime = GetTickCount();
|
|
|
|
//
|
|
// Start the screen-saver
|
|
//
|
|
if (!StartScreenSaver(&ScreenSaverData)) {
|
|
|
|
DebugLog((DEB_TRACE, "Failed to start screen-saver\n"));
|
|
|
|
if (ScreenSaverData.fSecure && pGlobals->UserLoggedOn)
|
|
{
|
|
Result = WLX_SAS_ACTION_LOCK_WKSTA;
|
|
}
|
|
else
|
|
{
|
|
Result = DLG_FAILURE;
|
|
}
|
|
DeleteScreenSaverInfo(&ScreenSaverData);
|
|
SetActiveDesktop(&pGlobals->WindowStation, pGlobals->WindowStation.PreviousDesktop);
|
|
pGlobals->ScreenSaverActive = FALSE;
|
|
CloseDesktop(pGlobals->WindowStation.hdeskScreenSaver);
|
|
|
|
//
|
|
// If no one is logged on, remove SYSTEM as the user.
|
|
//
|
|
return(Result);
|
|
}
|
|
|
|
//
|
|
// Initialize the sas type to report
|
|
//
|
|
|
|
ScreenSaverData.SasInterrupt = WLX_SAS_TYPE_SCRNSVR_ACTIVITY;
|
|
|
|
//
|
|
// Summon the dialog that monitors the screen-saver
|
|
//
|
|
Result = WlxSetTimeout( pGlobals, TIMEOUT_NONE);
|
|
|
|
Result = WlxDialogBoxParam( pGlobals,
|
|
pGlobals->hInstance,
|
|
(LPTSTR)IDD_CONTROL,
|
|
NULL, ScreenSaverDlgProc,
|
|
(LONG)&ScreenSaverData);
|
|
|
|
EndTime = GetTickCount();
|
|
|
|
|
|
if (EndTime <= BeginTime)
|
|
{
|
|
//
|
|
// TickCount must have wrapped around:
|
|
//
|
|
|
|
EndTime += (0xFFFFFFFF - BeginTime);
|
|
}
|
|
else
|
|
{
|
|
EndTime -= BeginTime;
|
|
}
|
|
|
|
//
|
|
// If the screen saver ran for less than the default period, don't enforce
|
|
// the lock.
|
|
//
|
|
if (ScreenSaverData.fSecure && pGlobals->UserLoggedOn)
|
|
{
|
|
|
|
if (AllowFastUnlock &&
|
|
(EndTime < (GetProfileInt( APPLICATION_NAME,
|
|
LOCK_GRACE_PERIOD_KEY,
|
|
LOCK_DEFAULT_VALUE) * 1000)))
|
|
{
|
|
Result = WLX_SAS_ACTION_NONE;
|
|
pGlobals->WinlogonState = PriorState;
|
|
}
|
|
else
|
|
{
|
|
Result = WLX_SAS_ACTION_LOCK_WKSTA;
|
|
}
|
|
|
|
}
|
|
|
|
DebugLog((DEB_TRACE, "Screensaver completed, SasInterrupt == %d\n",
|
|
ScreenSaverData.SasInterrupt));
|
|
|
|
|
|
|
|
//
|
|
// Set up desktop and windowstation lock appropriately. If we got a logoff,
|
|
// or we're supposed to lock the workstation, switch back to the winlogon
|
|
// desktop. Otherwise, go back to the users current desktop.
|
|
//
|
|
|
|
if ((ScreenSaverData.SasInterrupt == WLX_SAS_TYPE_USER_LOGOFF) ||
|
|
(Result == WLX_SAS_ACTION_LOCK_WKSTA) ) {
|
|
|
|
//
|
|
// Switch to the winlogon desktop and retain windowstation lock
|
|
//
|
|
Success = SetActiveDesktop(&pGlobals->WindowStation, Desktop_Winlogon);
|
|
|
|
} else {
|
|
|
|
//
|
|
// Switch to previous desktop and retore lock to previous state
|
|
//
|
|
SetActiveDesktop(&pGlobals->WindowStation, pGlobals->WindowStation.PreviousDesktop);
|
|
|
|
|
|
//
|
|
// Tickle the messenger so it will display any queue'd messages.
|
|
// (This call is a kind of NoOp).
|
|
//
|
|
TickleMessenger();
|
|
}
|
|
|
|
//
|
|
// We are no longer active (our knowledge of the desktop state is correct),
|
|
// let SASRouter know, so any future SAS's will be sent correctly.
|
|
//
|
|
|
|
pGlobals->ScreenSaverActive = FALSE;
|
|
//
|
|
// If we killed it, it means we got a SAS and killed the screen saver.
|
|
// we need to repost the SAS so that whomever invoked the screen saver
|
|
// can catch it and pass it off to the gina. Note, we special case
|
|
// WLX_SAS_TYPE_USER_LOGOFF below, because WlxSasNotify filters it out,
|
|
// and we really need to return as the result code...
|
|
//
|
|
if ( ScreenSaverData.WeKilledIt &&
|
|
(ScreenSaverData.SasInterrupt != WLX_SAS_TYPE_SCRNSVR_ACTIVITY) )
|
|
{
|
|
if ( ScreenSaverData.SasInterrupt == WLX_SAS_TYPE_USER_LOGOFF )
|
|
{
|
|
//
|
|
// So HandleLoggedOn() will know what to do:
|
|
//
|
|
|
|
pGlobals->SasType = WLX_SAS_TYPE_USER_LOGOFF ;
|
|
Result = WLX_SAS_ACTION_LOGOFF ;
|
|
}
|
|
else
|
|
{
|
|
WlxSasNotify( pGlobals, ScreenSaverData.SasInterrupt );
|
|
}
|
|
}
|
|
|
|
DeleteScreenSaverInfo(&ScreenSaverData);
|
|
|
|
if (!CloseDesktop(pGlobals->WindowStation.hdeskScreenSaver)) {
|
|
DebugLog((DEB_TRACE, "Failed to close screen saver desktop!\n\n"));
|
|
} else
|
|
pGlobals->WindowStation.hdeskScreenSaver = NULL;
|
|
|
|
//
|
|
// Update windowstation locks to reflect correct state.
|
|
//
|
|
|
|
|
|
return(Result);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: ScreenSaverDlgProc
|
|
*
|
|
* PURPOSE: Processes messages for the screen-saver control dialog
|
|
*
|
|
* DIALOG RETURNS : DLG_FAILURE if dialog could not be created
|
|
* DLG_SUCCESS if the screen-saver ran correctly and
|
|
* has now completed.
|
|
* DLG_LOGOFF() if the screen-saver was interrupted by
|
|
* a logoff notification.
|
|
* HISTORY:
|
|
*
|
|
* 12-09-91 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
BOOL WINAPI
|
|
ScreenSaverDlgProc(
|
|
HWND hDlg,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
PSCREEN_SAVER_DATA pScreenSaverData = (PSCREEN_SAVER_DATA)GetWindowLong(hDlg, GWL_USERDATA);
|
|
|
|
switch (message) {
|
|
|
|
case WM_INITDIALOG:
|
|
SetWindowLong(hDlg, GWL_USERDATA, lParam);
|
|
|
|
if (!ScreenSaverDlgInit(hDlg)) {
|
|
EndDialog(hDlg, DLG_FAILURE);
|
|
|
|
}
|
|
|
|
//
|
|
// Tell the mapping layer that we're a winlogon window, so we
|
|
// can handle our own timeouts.
|
|
//
|
|
|
|
SetMapperFlag(hDlg, MAPPERFLAG_WINLOGON);
|
|
|
|
EnableSasMessages( hDlg );
|
|
|
|
return(TRUE);
|
|
|
|
case WLX_WM_SAS:
|
|
//
|
|
// Just kill the screen-saver, the monitor thread will notice that
|
|
// the process has ended and send us a message
|
|
//
|
|
|
|
//
|
|
// Actually, stash the Sas code away, so that who ever invoked us
|
|
// can use it.
|
|
|
|
|
|
pScreenSaverData->SasInterrupt = wParam;
|
|
pScreenSaverData->WeKilledIt = TRUE;
|
|
|
|
KillScreenSaver(pScreenSaverData, DLG_SUCCESS);
|
|
|
|
DisableSasMessages();
|
|
|
|
return(TRUE);
|
|
|
|
|
|
case WM_OBJECT_NOTIFY:
|
|
|
|
DeleteScreenSaverMonitor(hDlg);
|
|
|
|
EndDialog(hDlg, pScreenSaverData->ReturnValue);
|
|
return(TRUE);
|
|
}
|
|
|
|
// We didn't process this message
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: ScreenSaverDlgInit
|
|
*
|
|
* PURPOSE: Handles initialization of screen-saver control dialog
|
|
* Actually starts the screen-saver and puts the id of the
|
|
* screen-saver process in the screen-saver data structure.
|
|
*
|
|
* RETURNS: TRUE on success, FALSE on failure
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 12-09-91 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
BOOL
|
|
ScreenSaverDlgInit(
|
|
HWND hDlg
|
|
)
|
|
{
|
|
PSCREEN_SAVER_DATA ScreenSaverData = (PSCREEN_SAVER_DATA)GetWindowLong(hDlg, GWL_USERDATA);
|
|
|
|
//
|
|
// Initialize our return value
|
|
//
|
|
ScreenSaverData->ReturnValue = DLG_SUCCESS;
|
|
|
|
|
|
//
|
|
// Start the thread that will wait for the screen-saver to finish
|
|
//
|
|
if (!StartScreenSaverMonitor(hDlg)) {
|
|
|
|
DebugLog((DEB_TRACE, "Failed to start screen-saver monitor thread\n"));
|
|
KillScreenSaver(ScreenSaverData, DLG_FAILURE);
|
|
return(FALSE);
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: StartScreenSaver
|
|
*
|
|
* PURPOSE: Creates the screen-saver process
|
|
*
|
|
* RETURNS: TRUE on success, FALSE on failure
|
|
*
|
|
* On successful return, the ProcessId field in our global data structure
|
|
* is set to the screen-saver process id
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 12-09-91 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
BOOL
|
|
StartScreenSaver(
|
|
PSCREEN_SAVER_DATA ScreenSaverData
|
|
)
|
|
{
|
|
HANDLE hThread;
|
|
HANDLE hProcess;
|
|
|
|
|
|
//
|
|
// Try and exec the screen-saver app
|
|
//
|
|
if (!StartSystemProcess(ScreenSaverData->ScreenSaverName,
|
|
SCREENSAVER_DESKTOP_PATH,
|
|
CREATE_SUSPENDED | CREATE_SEPARATE_WOW_VDM |
|
|
IDLE_PRIORITY_CLASS,
|
|
STARTF_SCREENSAVER,
|
|
ScreenSaverData->pGlobals->UserProcessData.pEnvironment,
|
|
FALSE,
|
|
&hProcess,
|
|
&hThread) )
|
|
{
|
|
DebugLog((DEB_ERROR, "Failed to start screen saver %ws, %d\n",
|
|
ScreenSaverData->ScreenSaverName, GetLastError()));
|
|
return(FALSE);
|
|
}
|
|
|
|
if (ScreenSaverData->pGlobals->UserLoggedOn)
|
|
{
|
|
WlxAssignShellProtection(
|
|
ScreenSaverData->pGlobals,
|
|
ScreenSaverData->pGlobals->UserProcessData.UserToken,
|
|
hProcess,
|
|
hThread);
|
|
|
|
}
|
|
|
|
ResumeThread(hThread);
|
|
CloseHandle(hThread);
|
|
|
|
ScreenSaverData->hProcess = hProcess;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: KillScreenSaver
|
|
*
|
|
* PURPOSE: Terminates the screen-saver process
|
|
*
|
|
* RETURNS: TRUE on success, FALSE on failure
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 12-09-91 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
BOOL
|
|
KillScreenSaver(
|
|
PSCREEN_SAVER_DATA ScreenSaverData,
|
|
int ReturnValue
|
|
)
|
|
{
|
|
HANDLE hProcess;
|
|
BOOL bRet;
|
|
|
|
//
|
|
// Store the return value to be used by the dlg proc when the notification
|
|
// arrives from the monitor thread that the SS has ended.
|
|
//
|
|
|
|
ScreenSaverData->ReturnValue = ReturnValue;
|
|
|
|
if (ScreenSaverData->hProcess != INVALID_HANDLE_VALUE)
|
|
{
|
|
bRet = TerminateProcess(ScreenSaverData->hProcess, STATUS_SUCCESS);
|
|
if (!bRet)
|
|
{
|
|
DebugLog((DEB_TRACE, "Failed to terminate screen-saver process, error = %d\n", GetLastError()));
|
|
}
|
|
|
|
CloseObjectMonitorObject( ScreenSaverData->Monitor );
|
|
|
|
}
|
|
|
|
// if (ScreenSaverData->Monitor)
|
|
// {
|
|
// DeleteObjectMonitor( ScreenSaverData->Monitor, FALSE );
|
|
// }
|
|
|
|
ScreenSaverData->hProcess = INVALID_HANDLE_VALUE;
|
|
|
|
return(bRet);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: StartScreenSaverMonitor
|
|
*
|
|
* PURPOSE: Creates a thread that waits for the screen-saver to terminate
|
|
*
|
|
* RETURNS: TRUE on success, FALSE on failure
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 12-09-91 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
BOOL
|
|
StartScreenSaverMonitor(
|
|
HWND hDlg
|
|
)
|
|
{
|
|
PSCREEN_SAVER_DATA ScreenSaverData = (PSCREEN_SAVER_DATA)GetWindowLong(hDlg, GWL_USERDATA);
|
|
|
|
//
|
|
// Create a monitor object to watch the screen-saver process
|
|
//
|
|
|
|
ScreenSaverData->Monitor = CreateObjectMonitor(ScreenSaverData->hProcess,
|
|
hDlg, 0);
|
|
|
|
if (ScreenSaverData->Monitor == NULL) {
|
|
DebugLog((DEB_TRACE, "Failed to create screen-saver monitor object\n"));
|
|
return(FALSE);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: DeleteScreenSaverMonitor
|
|
*
|
|
* PURPOSE: Cleans up resources used by screen-saver monitor
|
|
*
|
|
* RETURNS: Nothing
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 01-11-93 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
VOID
|
|
DeleteScreenSaverMonitor(
|
|
HWND hDlg
|
|
)
|
|
{
|
|
PSCREEN_SAVER_DATA ScreenSaverData = (PSCREEN_SAVER_DATA)GetWindowLong(hDlg, GWL_USERDATA);
|
|
POBJECT_MONITOR Monitor = ScreenSaverData->Monitor;
|
|
|
|
//
|
|
// Delete the object monitor
|
|
//
|
|
|
|
CloseObjectMonitorObject( Monitor );
|
|
|
|
DeleteObjectMonitor(Monitor, FALSE);
|
|
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: GetScreenSaverInfo
|
|
*
|
|
* PURPOSE: Gets the name of the screen-saver that should be run. Also whether
|
|
* the user wanted the screen-saver to be secure. These values are
|
|
* filled in in the ScreenSaver data structure on return.
|
|
*
|
|
* If there is no current user logged on or if we fail to get the
|
|
* user's preferred screen-saver info, we default to the system
|
|
* secure screen-saver.
|
|
*
|
|
* RETURNS: TRUE on success
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 12-09-91 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
BOOL
|
|
GetScreenSaverInfo(
|
|
PSCREEN_SAVER_DATA ScreenSaverData
|
|
)
|
|
{
|
|
BOOL Success = FALSE;
|
|
TCHAR SystemScreenSaverName[MAX_STRING_BYTES];
|
|
WCHAR ExpandedName[MAX_PATH];
|
|
DWORD ScreenSaverLength;
|
|
DWORD ExpandedSize;
|
|
|
|
|
|
//
|
|
// Get the default system screen-saver name
|
|
//
|
|
LoadString(NULL, IDS_SYSTEM_SCREEN_SAVER_NAME, SystemScreenSaverName, sizeof(SystemScreenSaverName));
|
|
|
|
|
|
//
|
|
// Open the ini file mapping layer in the current user's context
|
|
//
|
|
|
|
if (!OpenIniFileUserMapping(ScreenSaverData->pGlobals))
|
|
{
|
|
DebugLog((DEB_ERROR, "Failed to open user profile mapping!\n"));
|
|
}
|
|
|
|
//
|
|
// Try and get the user screen-saver program name
|
|
//
|
|
|
|
ScreenSaverData->ScreenSaverName = AllocAndGetPrivateProfileString(
|
|
SCREEN_SAVER_INI_SECTION,
|
|
SCREEN_SAVER_FILENAME_KEY,
|
|
SystemScreenSaverName, // default
|
|
SCREEN_SAVER_INI_FILE);
|
|
|
|
if (ScreenSaverData->ScreenSaverName == NULL) {
|
|
DebugLog((DEB_TRACE, "Failed to get screen-saver name\n"));
|
|
goto Exit;
|
|
}
|
|
|
|
ScreenSaverLength = lstrlen(ScreenSaverData->ScreenSaverName);
|
|
|
|
//
|
|
// Figure out how big based on the expanded environment variables, if any.
|
|
// subtract one, since Expand returns the # characters, plus the \0.
|
|
//
|
|
ExpandedSize = ExpandEnvironmentStrings(ScreenSaverData->ScreenSaverName,
|
|
ExpandedName,
|
|
MAX_PATH) - 1;
|
|
|
|
if (ExpandedSize != ScreenSaverLength )
|
|
{
|
|
//
|
|
// Well, we expanded to something other than what we had originally.
|
|
// So, alloc anew and do the parameter thing right now.
|
|
//
|
|
|
|
Free(ScreenSaverData->ScreenSaverName);
|
|
ScreenSaverData->ScreenSaverName = Alloc( (ExpandedSize +
|
|
lstrlen(Parameters) + 1) *
|
|
sizeof(WCHAR) );
|
|
|
|
if (!ScreenSaverData->ScreenSaverName)
|
|
{
|
|
DebugLog((DEB_WARN, "No memory for screensaver\n"));
|
|
goto Exit;
|
|
}
|
|
|
|
wcscpy( ScreenSaverData->ScreenSaverName,
|
|
ExpandedName);
|
|
wcscpy( &ScreenSaverData->ScreenSaverName[ExpandedSize],
|
|
Parameters);
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Always add some fixed screen-saver parameters
|
|
//
|
|
|
|
ScreenSaverData->ScreenSaverName = ReAlloc(
|
|
ScreenSaverData->ScreenSaverName,
|
|
(lstrlen(ScreenSaverData->ScreenSaverName) +
|
|
lstrlen(Parameters) + 1)
|
|
* sizeof(TCHAR));
|
|
if (ScreenSaverData->ScreenSaverName == NULL) {
|
|
DebugLog((DEB_TRACE, "Realloc of screen-saver name failed\n"));
|
|
goto Exit;
|
|
}
|
|
|
|
lstrcat(ScreenSaverData->ScreenSaverName, Parameters);
|
|
|
|
}
|
|
|
|
//
|
|
// Find out if the screen-saver should be secure
|
|
//
|
|
|
|
ScreenSaverData->fSecure = (GetPrivateProfileInt(
|
|
SCREEN_SAVER_INI_SECTION,
|
|
SCREEN_SAVER_SECURE_KEY,
|
|
(DWORD)FALSE, // default to non-secure
|
|
SCREEN_SAVER_INI_FILE) != 0);
|
|
|
|
//
|
|
// Find out if the screen-saver is enabled
|
|
//
|
|
ScreenSaverData->fEnabled = (GetProfileInt(
|
|
WINDOWS_INI_SECTION,
|
|
SCREEN_SAVER_ENABLED_KEY,
|
|
(DWORD)FALSE // default to not-enabled
|
|
) != 0);
|
|
|
|
Success = TRUE;
|
|
|
|
Exit:
|
|
|
|
//
|
|
// Close the ini file mapping - this closes the user registry key
|
|
//
|
|
|
|
(VOID)CloseIniFileUserMapping(ScreenSaverData->pGlobals);
|
|
|
|
return(Success);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: DeleteScreenSaverInfo
|
|
*
|
|
* PURPOSE: Frees up any space allocate by screen-saver data structure
|
|
*
|
|
* RETURNS: Nothing
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 11-17-92 Davidc Created.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
VOID
|
|
DeleteScreenSaverInfo(
|
|
PSCREEN_SAVER_DATA ScreenSaverData
|
|
)
|
|
{
|
|
if (ScreenSaverData->ScreenSaverName != NULL) {
|
|
Free(ScreenSaverData->ScreenSaverName);
|
|
}
|
|
}
|