windows-nt/Source/XPSP1/NT/admin/pchealth/sr/service/srconfig.cpp
2020-09-26 16:20:57 +08:00

696 lines
18 KiB
C++

/******************************************************************************
*
* Copyright (c) 2000 Microsoft Corporation
*
* Module Name:
* srconfig.cpp
*
* Abstract:
* CSRConfig methods
*
* Revision History:
* Brijesh Krishnaswami (brijeshk) 04/15/2000
* created
*
*****************************************************************************/
#include "precomp.h"
extern "C"
{
#include <powrprof.h>
}
CSRConfig *g_pSRConfig; // the global instance
CSRConfig::CSRConfig()
{
m_hSRInitEvent = m_hSRStopEvent = m_hIdleRequestEvent = NULL;
m_hIdleStartEvent = m_hIdleStopEvent = NULL;
m_hFilter = NULL;
::GetSystemDrive(m_szSystemDrive);
m_fCleanup = FALSE;
m_fSafeMode = FALSE;
m_fReset = FALSE;
m_dwFifoDisabledNum = 0;
m_dwFreezeThawLogCount = 0;
lstrcpy(m_szGuid, L"");
}
CSRConfig::~CSRConfig()
{
if (m_hSRInitEvent)
CloseHandle(m_hSRInitEvent);
if (m_hSRStopEvent)
CloseHandle(m_hSRStopEvent);
if (m_hIdleRequestEvent)
CloseHandle(m_hIdleRequestEvent);
CloseFilter();
}
void
CSRConfig::SetDefaults()
{
m_dwDisableSR = FALSE;
m_dwDisableSR_GroupPolicy = 0xFFFFFFFF; // not configured
m_dwFirstRun = SR_FIRSTRUN_NO;
m_dwTimerInterval = SR_DEFAULT_TIMERINTERVAL;
m_dwIdleInterval = SR_DEFAULT_IDLEINTERVAL;
m_dwCompressionBurst = SR_DEFAULT_COMPRESSIONBURST;
m_dwRPSessionInterval = SR_DEFAULT_RPSESSIONINTERVAL;
m_dwDSMax = SR_DEFAULT_DSMAX;
m_dwDSMin = SR_DEFAULT_DSMIN;
m_dwRPGlobalInterval = SR_DEFAULT_RPGLOBALINTERVAL;
m_dwRPLifeInterval = SR_DEFAULT_RPLIFEINTERVAL;
m_dwThawInterval = SR_DEFAULT_THAW_INTERVAL;
m_dwDiskPercent = SR_DEFAULT_DISK_PERCENT;
m_dwTestBroadcast = 0;
m_dwCreateFirstRunRp = 1;
}
void
CSRConfig::ReadAll()
{
HKEY hKeyCur = NULL, hKeyCfg = NULL, hKeyFilter = NULL, hKey = NULL;
HKEY hKeyGP = NULL;
DWORD dwRc;
POWER_POLICY pp;
GLOBAL_POWER_POLICY gpp;
UINT uiPowerScheme = 0;
TENTER("CSRConfig::ReadAll");
// open the group policy key, ignore failures if key doesn't exist
RegOpenKeyEx (HKEY_LOCAL_MACHINE,
s_cszGroupPolicy,
0,
KEY_READ,
&hKeyGP);
// open SystemRestore regkeys
dwRc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
s_cszSRRegKey,
0,
KEY_READ,
&hKeyCur);
if (ERROR_SUCCESS != dwRc)
{
TRACE(0, "! RegOpenKeyEx on %S : %ld", s_cszSRRegKey, dwRc);
goto done;
}
dwRc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
s_cszSRCfgRegKey,
0,
KEY_READ,
&hKeyCfg);
if (ERROR_SUCCESS != dwRc)
{
TRACE(0, "! RegOpenKeyEx on %S : %ld", s_cszSRCfgRegKey, dwRc);
goto done;
}
// open the filter regkey
dwRc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
s_cszFilterRegKey,
0,
KEY_READ,
&hKeyFilter);
if (ERROR_SUCCESS != dwRc)
{
TRACE(0, "! RegOpenKeyEx on %S : %ld", s_cszFilterRegKey, dwRc);
goto done;
}
RegReadDWORD(hKeyCur, s_cszDisableSR, &m_dwDisableSR);
RegReadDWORD(hKeyCur, s_cszTestBroadcast, &m_dwTestBroadcast);
// read the group policy values to be enforced
// read the corresponding local setting also
if (hKeyGP != NULL)
RegReadDWORD(hKeyGP, s_cszDisableSR, &m_dwDisableSR_GroupPolicy);
// read firstrun - 1 means firstrun, 0 means not
RegReadDWORD(hKeyFilter, s_cszFirstRun, &m_dwFirstRun);
// if firstrun, read other values from Cfg subkey
// else read other values from main regkey
hKey = (m_dwFirstRun == SR_FIRSTRUN_YES) ? hKeyCfg : hKeyCur;
RegReadDWORD(hKey, s_cszDSMin, &m_dwDSMin);
RegReadDWORD(hKey, s_cszDSMax, &m_dwDSMax);
RegReadDWORD(hKey, s_cszRPSessionInterval, &m_dwRPSessionInterval);
RegReadDWORD(hKey, s_cszRPGlobalInterval, &m_dwRPGlobalInterval);
RegReadDWORD(hKey, s_cszRPLifeInterval, &m_dwRPLifeInterval);
RegReadDWORD(hKey, s_cszCompressionBurst, &m_dwCompressionBurst);
RegReadDWORD(hKey, s_cszTimerInterval, &m_dwTimerInterval);
RegReadDWORD(hKey, s_cszDiskPercent, &m_dwDiskPercent);
RegReadDWORD(hKey, s_cszThawInterval, &m_dwThawInterval);
if (GetCurrentPowerPolicies (&gpp, &pp))
{
m_dwIdleInterval = max(pp.user.IdleTimeoutAc, pp.user.IdleTimeoutDc);
m_dwIdleInterval = max(SR_DEFAULT_IDLEINTERVAL, m_dwIdleInterval*2);
}
done:
if (hKeyCur)
RegCloseKey(hKeyCur);
if (hKeyCfg)
RegCloseKey(hKeyCfg);
if (hKeyFilter)
RegCloseKey(hKeyFilter);
if (hKeyGP)
RegCloseKey (hKeyGP);
TLEAVE();
}
// upon firstrun, write the current values to the current location
void
CSRConfig::WriteAll()
{
TENTER("CSRConfig::WriteAll");
HKEY hKey = NULL;
HKEY hKeyCfg = NULL;
DWORD dwRc;
// open SystemRestore regkey
dwRc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
s_cszSRRegKey,
0,
KEY_WRITE,
&hKey);
if (ERROR_SUCCESS != dwRc)
{
TRACE(0, "! RegOpenKeyEx on %S : %ld", s_cszSRRegKey, dwRc);
goto done;
}
RegWriteDWORD(hKey, s_cszDisableSR, &m_dwDisableSR);
RegWriteDWORD(hKey, s_cszDSMin, &m_dwDSMin);
RegWriteDWORD(hKey, s_cszDSMax, &m_dwDSMax);
RegWriteDWORD(hKey, s_cszRPSessionInterval, &m_dwRPSessionInterval);
RegWriteDWORD(hKey, s_cszRPGlobalInterval, &m_dwRPGlobalInterval);
RegWriteDWORD(hKey, s_cszRPLifeInterval, &m_dwRPLifeInterval);
RegWriteDWORD(hKey, s_cszCompressionBurst, &m_dwCompressionBurst);
RegWriteDWORD(hKey, s_cszTimerInterval, &m_dwTimerInterval);
RegWriteDWORD(hKey, s_cszDiskPercent, &m_dwDiskPercent);
RegWriteDWORD(hKey, s_cszThawInterval, &m_dwThawInterval);
// secure our keys from other users
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
s_cszSRCfgRegKey,
0,
KEY_WRITE,
&hKeyCfg))
{
dwRc = SetAclInObject(hKeyCfg, SE_REGISTRY_KEY,KEY_ALL_ACCESS,KEY_READ, TRUE);
RegCloseKey (hKeyCfg);
hKeyCfg = NULL;
if (ERROR_SUCCESS != dwRc)
{
TRACE(0, "! SetAclInObject %S : %ld", s_cszSRCfgRegKey, dwRc);
goto done;
}
}
dwRc = SetAclInObject(hKey, SE_REGISTRY_KEY, KEY_ALL_ACCESS, KEY_READ, TRUE);
if (ERROR_SUCCESS != dwRc)
{
TRACE(0, "! SetAclInObject %S : %ld", s_cszSRRegKey, dwRc);
goto done;
}
done:
TLEAVE();
if (hKey)
RegCloseKey(hKey);
}
DWORD
CSRConfig::SetMachineGuid()
{
TENTER("CSRConfig::SetMachineGuid");
HKEY hKey = NULL;
DWORD dwErr, dwType, dwSize;
WCHAR szGuid[GUID_STRLEN];
LPWSTR pszGuid = NULL;
// read the machine guid from the cfg regkey
pszGuid = GetMachineGuid();
if (! pszGuid)
{
GUID guid;
UuidCreate(&guid);
dwErr = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
s_cszSRCfgRegKey, 0,
KEY_WRITE, &hKey);
if (dwErr != ERROR_SUCCESS)
goto Err;
if (0 == StringFromGUID2 (guid, szGuid, sizeof(szGuid)/sizeof(WCHAR)))
goto Err;
dwErr = RegSetValueEx (hKey, s_cszSRMachineGuid,
0, REG_SZ, (BYTE *) szGuid,
(lstrlen(szGuid) + 1) * sizeof(WCHAR));
if (dwErr != ERROR_SUCCESS)
goto Err;
pszGuid = (LPWSTR) szGuid;
}
RegCloseKey(hKey);
hKey = NULL;
// then copy it to the filter regkey
dwErr = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
s_cszFilterRegKey, 0,
KEY_WRITE, &hKey);
if (dwErr != ERROR_SUCCESS)
goto Err;
dwErr = RegSetValueEx (hKey, s_cszSRMachineGuid,
0, REG_SZ, (BYTE *) pszGuid,
(lstrlen(pszGuid) + 1) * sizeof(WCHAR));
Err:
if (hKey)
RegCloseKey(hKey);
TLEAVE();
return dwErr;
}
// method to set firstrun key in the registry and update member
DWORD
CSRConfig::SetFirstRun(DWORD dwValue)
{
HKEY hKeyFilter = NULL;
DWORD dwRc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
s_cszFilterRegKey,
0,
KEY_WRITE,
&hKeyFilter);
if (ERROR_SUCCESS != dwRc)
goto done;
dwRc = RegWriteDWORD(hKeyFilter, s_cszFirstRun, &dwValue);
if (ERROR_SUCCESS != dwRc)
goto done;
m_dwFirstRun = dwValue;
done:
if (hKeyFilter)
RegCloseKey(hKeyFilter);
return dwRc;
}
DWORD
CSRConfig::SetDisableFlag(DWORD dwValue)
{
HKEY hKeySR = NULL;
DWORD dwRc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
s_cszSRRegKey,
0,
KEY_WRITE,
&hKeySR);
if (ERROR_SUCCESS != dwRc)
goto done;
dwRc = RegWriteDWORD(hKeySR, s_cszDisableSR, &dwValue);
if (ERROR_SUCCESS != dwRc)
goto done;
m_dwDisableSR = dwValue;
done:
if (hKeySR)
RegCloseKey(hKeySR);
return dwRc;
}
DWORD
CSRConfig::SetCreateFirstRunRp(DWORD dwValue)
{
HKEY hKeySR = NULL;
DWORD dwRc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
s_cszSRRegKey,
0,
KEY_WRITE,
&hKeySR);
if (ERROR_SUCCESS != dwRc)
goto done;
dwRc = RegWriteDWORD(hKeySR, s_cszCreateFirstRunRp, &dwValue);
if (ERROR_SUCCESS != dwRc)
goto done;
m_dwCreateFirstRunRp = dwValue;
done:
if (hKeySR)
RegCloseKey(hKeySR);
return dwRc;
}
DWORD
CSRConfig::GetCreateFirstRunRp()
{
HKEY hKeySR = NULL;
DWORD dwRc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
s_cszSRRegKey,
0,
KEY_READ,
&hKeySR);
if (ERROR_SUCCESS != dwRc)
goto done;
dwRc = RegReadDWORD(hKeySR, s_cszCreateFirstRunRp, &m_dwCreateFirstRunRp);
done:
if (hKeySR)
RegCloseKey(hKeySR);
return m_dwCreateFirstRunRp;
}
// add datastore to regkey backup exclude list
DWORD
CSRConfig::AddBackupRegKey()
{
HKEY hKey = NULL;
WCHAR szPath[MAX_PATH];
DWORD dwRc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
L"System\\CurrentControlSet\\Control\\BackupRestore\\FilesNotToBackup",
0,
KEY_WRITE,
&hKey);
if (ERROR_SUCCESS != dwRc)
goto done;
MakeRestorePath(szPath, L"\\", L"* /s");
szPath[lstrlen(szPath)+1] = L'\0'; // second null terminator for multi sz
dwRc = RegSetValueEx (hKey,
L"System Restore",
0,
REG_MULTI_SZ,
(LPBYTE) szPath,
(lstrlen(szPath) + 2) * sizeof(WCHAR));
if (ERROR_SUCCESS != dwRc)
goto done;
done:
if (hKey)
RegCloseKey(hKey);
return dwRc;
}
void
CSRConfig::RegisterTestMessages()
{
HWINSTA hwinstaUser = NULL;
HDESK hdeskUser = NULL;
DWORD dwThreadId;
HWINSTA hwinstaSave = NULL;
HDESK hdeskSave = NULL;
DWORD dwRc;
TENTER("RegisterTestMessages");
//
// save current values
//
GetDesktopWindow();
hwinstaSave = GetProcessWindowStation();
dwThreadId = GetCurrentThreadId();
hdeskSave = GetThreadDesktop(dwThreadId);
//
// change desktop and winstation to interactive user
//
hwinstaUser = OpenWindowStation(L"WinSta0", FALSE, MAXIMUM_ALLOWED);
if (hwinstaUser == NULL)
{
dwRc = GetLastError();
trace(0, "! OpenWindowStation : %ld", dwRc);
goto done;
}
SetProcessWindowStation(hwinstaUser);
hdeskUser = OpenDesktop(L"Default", 0, FALSE, MAXIMUM_ALLOWED);
if (hdeskUser == NULL)
{
dwRc = GetLastError();
trace(0, "! OpenDesktop : %ld", dwRc);
goto done;
}
SetThreadDesktop(hdeskUser);
//
// register the test messages
//
m_uiTMFreeze = RegisterWindowMessage(s_cszTM_Freeze);
m_uiTMThaw = RegisterWindowMessage(s_cszTM_Thaw);
m_uiTMFifoStart = RegisterWindowMessage(s_cszTM_FifoStart);
m_uiTMFifoStop = RegisterWindowMessage(s_cszTM_FifoStop);
m_uiTMEnable = RegisterWindowMessage(s_cszTM_Enable);
m_uiTMDisable = RegisterWindowMessage(s_cszTM_Disable);
m_uiTMCompressStart = RegisterWindowMessage(s_cszTM_CompressStart);
m_uiTMCompressStop = RegisterWindowMessage(s_cszTM_CompressStop);
done:
//
// restore old values
//
if (hdeskSave)
SetThreadDesktop(hdeskSave);
if (hwinstaSave)
SetProcessWindowStation(hwinstaSave);
//
// close opened handles
//
if (hdeskUser)
CloseDesktop(hdeskUser);
if (hwinstaUser)
CloseWindowStation(hwinstaUser);
TLEAVE();
}
DWORD
CSRConfig::Initialize()
{
DWORD dwRc = ERROR_INTERNAL_ERROR;
WCHAR szDat[MAX_PATH];
TENTER("CSRConfig::Initialize");
// read all config values from registry
// use default if not able to read value
SetDefaults();
ReadAll();
// is this safe mode?
if (0 != GetSystemMetrics(SM_CLEANBOOT))
{
TRACE(0, "This is safemode");
m_fSafeMode = TRUE;
}
// if _filelst.cfg does not exist, then consider this firstrun
MakeRestorePath(szDat, GetSystemDrive(), s_cszFilelistDat);
if (-1 == GetFileAttributes(szDat))
{
TRACE(0, "%S does not exist", s_cszFilelistDat);
SetFirstRun(SR_FIRSTRUN_YES);
}
if (m_dwFirstRun == SR_FIRSTRUN_YES)
{
SetMachineGuid();
WriteAll();
AddBackupRegKey();
}
TRACE(0, "%SFirstRun", m_dwFirstRun == SR_FIRSTRUN_YES ? L"" : L"Not ");
// create events
// give read access to everyone so that clients can wait on them
// SR init
m_hSRInitEvent = CreateEvent(NULL, FALSE, FALSE, s_cszSRInitEvent);
if (! m_hSRInitEvent)
{
TRACE(0, "! CreateEvent on %S : %ld", s_cszSRInitEvent, GetLastError());
goto done;
}
dwRc = SetAclInObject(m_hSRInitEvent,
SE_KERNEL_OBJECT,
STANDARD_RIGHTS_ALL | GENERIC_ALL,
STANDARD_RIGHTS_READ | GENERIC_READ | SYNCHRONIZE,
FALSE);
if (dwRc != ERROR_SUCCESS)
{
TRACE(0, "! SetAclInObject : %ld", dwRc);
goto done;
}
// SR stop
m_hSRStopEvent = CreateEvent(NULL, TRUE, FALSE, s_cszSRStopEvent);
if (! m_hSRStopEvent)
{
TRACE(0, "! CreateEvent on %S : %ld", s_cszSRStopEvent, GetLastError());
goto done;
}
else if (GetLastError() == ERROR_ALREADY_EXISTS)
{
TRACE(0, "Stop Event already exists!");
ResetEvent (m_hSRStopEvent);
}
dwRc = SetAclInObject(m_hSRStopEvent,
SE_KERNEL_OBJECT,
STANDARD_RIGHTS_ALL | GENERIC_ALL,
STANDARD_RIGHTS_READ | GENERIC_READ | SYNCHRONIZE,
FALSE);
if (dwRc != ERROR_SUCCESS)
{
TRACE(0, "! SetAclInObject : %ld", dwRc);
goto done;
}
// idle request
m_hIdleRequestEvent = CreateEvent(NULL, FALSE, FALSE, s_cszIdleRequestEvent);
if (! m_hIdleRequestEvent)
{
TRACE(0, "! CreateEvent on %S : %ld", s_cszIdleRequestEvent, GetLastError());
goto done;
}
dwRc = SetAclInObject(m_hIdleRequestEvent,
SE_KERNEL_OBJECT,
STANDARD_RIGHTS_ALL | GENERIC_ALL,
STANDARD_RIGHTS_READ | GENERIC_READ | SYNCHRONIZE,
FALSE);
if (dwRc != ERROR_SUCCESS)
{
TRACE(0, "! SetAclInObject : %ld", dwRc);
goto done;
}
//
// register test messages
//
if (m_dwTestBroadcast)
{
RegisterTestMessages();
}
dwRc = ERROR_SUCCESS;
done:
TLEAVE();
return dwRc;
}
//
// function to check if system is running on battery
//
BOOL CSRConfig::IsSystemOnBattery()
{
tenter("CSRConfig::IsSystemOnBattery");
BOOL fRc = FALSE;
SYSTEM_POWER_STATUS sps;
if (FALSE == GetSystemPowerStatus(&sps))
{
trace(0, "! GetSystemPowerStatus : %ld", GetLastError());
goto done;
}
fRc = (sps.ACLineStatus == 0);
done:
trace(0, "System %S battery", fRc ? L"on" : L"not on");
tleave();
return fRc;
}
DWORD CSRConfig::OpenFilter()
{
return SrCreateControlHandle(SR_OPTION_OVERLAPPED, &m_hFilter);
}
void CSRConfig::CloseFilter()
{
if (m_hFilter)
{
CloseHandle(m_hFilter);
m_hFilter = NULL;
}
}