|
|
//----------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997
//
// File: idle.cpp
//
// Contents: user idle detection
//
// Classes:
//
// Functions:
//
// History: 05-14-1997 darrenmi (Darren Mitchell) Created
//
//----------------------------------------------------------------------------
#include "private.h"
#include "throttle.h"
typedef void (WINAPI* _IDLECALLBACK) (DWORD dwState); typedef DWORD (WINAPI* _BEGINIDLEDETECTION) (_IDLECALLBACK, DWORD, DWORD); typedef BOOL (WINAPI* _ENDIDLEDETECTION) (DWORD);
#define TF_THISMODULE TF_WEBCHECKCORE
HINSTANCE g_hinstMSIDLE = NULL; _BEGINIDLEDETECTION g_pfnBegin = NULL; _ENDIDLEDETECTION g_pfnEnd = NULL;
//
// extra stuff so we don't need msidle.dll on win95
//
BOOL g_fWin95PerfWin = FALSE; // using msidle.dll or not?
UINT_PTR g_uIdleTimer = 0; // timer handle if not
HANDLE g_hSageVxd = INVALID_HANDLE_VALUE; // vxd handle if not
DWORD g_dwIdleMin = 3; // inactivity mins before idle
BOOL g_fIdle = FALSE; // are we idle?
DWORD g_dwIdleBeginTicks = 0; // when did idle begin?
VOID CALLBACK OnIdleTimer(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
//
// A little code copied from msidle.dll. We use this on Win95 with sage.vxd
// so we don't have to load msidle.dll.
//
//
// SetIdleTimer - decide how often to poll and set the timer appropriately
//
void SetIdleTimer(void) { UINT uInterval = 1000 * 60;
//
// If we're idle and looking for busy, check every 2 seconds
//
if(g_fIdle) { uInterval = 1000 * 4; }
//
// kill off the old timer
//
if(g_uIdleTimer) { KillTimer(NULL, g_uIdleTimer); }
//
// Set the timer
//
TraceMsg(TF_THISMODULE,"SetIdleTimer uInterval=%d", uInterval); g_uIdleTimer = SetTimer(NULL, 0, uInterval, OnIdleTimer); } //
// OnIdleTimer - idle timer has gone off
//
VOID CALLBACK OnIdleTimer(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { DWORD dwDiff, dwLastActivityTicks;
//
// get last activity ticks from sage
//
DeviceIoControl(g_hSageVxd, 2, &dwLastActivityTicks, sizeof(DWORD), NULL, 0, NULL, NULL);
//
// check to see if we've changed state
//
if(g_fIdle) { //
// currently in idle state
//
if(dwLastActivityTicks != g_dwIdleBeginTicks) { // activity since we became idle - stop being idle!
g_fIdle = FALSE;
// set timer
SetIdleTimer();
// call back client
CThrottler::OnIdleStateChange(STATE_USER_IDLE_END); }
} else { //
// currently not in idle state
//
dwDiff = GetTickCount() - dwLastActivityTicks;
if(dwDiff > 1000 * 60 * g_dwIdleMin) { // Nothing's happened for our threshold time. We're now idle.
g_fIdle = TRUE;
// save time we became idle
g_dwIdleBeginTicks = dwLastActivityTicks;
// set timer
SetIdleTimer();
// call back client
CThrottler::OnIdleStateChange(STATE_USER_IDLE_BEGIN); } } }
BOOL LoadSageVxd(void) { int inpVXD[3];
if(INVALID_HANDLE_VALUE != g_hSageVxd) return TRUE;
g_hSageVxd = CreateFile(TEXT("\\\\.\\sage.vxd"), 0, 0, NULL, 0, FILE_FLAG_DELETE_ON_CLOSE, NULL);
// can't open it? can't use it
if(INVALID_HANDLE_VALUE == g_hSageVxd) return FALSE;
// start it monitoring
inpVXD[0] = -1; // no window - will query
inpVXD[1] = 0; // unused
inpVXD[2] = 0; // post delay - not used without a window
DeviceIoControl(g_hSageVxd, 1, &inpVXD, sizeof(inpVXD), NULL, 0, NULL, NULL);
return TRUE; }
BOOL UnloadSageVxd(void) { if(INVALID_HANDLE_VALUE != g_hSageVxd) { CloseHandle(g_hSageVxd); g_hSageVxd = INVALID_HANDLE_VALUE; }
return TRUE; }
void IdleBegin(HWND hwndParent) { DWORD dwValue;
// Override idle minutes with reg value if present
if(ReadRegValue(HKEY_CURRENT_USER, c_szRegKey, TEXT("IdleMinutes"), &dwValue, sizeof(DWORD)) && dwValue) {
g_dwIdleMin = dwValue; }
if(FALSE == g_fIsWinNT && LoadSageVxd()) { // using optimal win95 configuration
g_fWin95PerfWin = TRUE; SetIdleTimer(); return; }
// Bail out if the DebuggerFriendly registry value is set on NT4.
OSVERSIONINFOA vi; vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); GetVersionExA(&vi);
if( vi.dwPlatformId == VER_PLATFORM_WIN32_NT && vi.dwMajorVersion == 4 && ReadRegValue(HKEY_CURRENT_USER, c_szRegKey, TEXT("DebuggerFriendly"), &dwValue, sizeof(DWORD)) && dwValue) { return; }
// load msidle.dll
g_hinstMSIDLE = LoadLibrary(TEXT("msidle.dll"));
// get begin and end functions
if(g_hinstMSIDLE) { g_pfnBegin = (_BEGINIDLEDETECTION)GetProcAddress(g_hinstMSIDLE, (LPSTR)3); g_pfnEnd = (_ENDIDLEDETECTION)GetProcAddress(g_hinstMSIDLE, (LPSTR)4);
// call start monitoring
if(g_pfnBegin) (g_pfnBegin)(CThrottler::OnIdleStateChange, g_dwIdleMin, 0); } }
void IdleEnd(void) { if(g_fWin95PerfWin) { // clean up timer
KillTimer(NULL, g_uIdleTimer); UnloadSageVxd(); } else { // clean up msidle.dll
if(g_pfnEnd) { (g_pfnEnd)(0); FreeLibrary(g_hinstMSIDLE); g_hinstMSIDLE = NULL; g_pfnBegin = NULL; g_pfnEnd = NULL; } } }
|