/****************************************************************************** * * 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 } 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; } }