OLD | NEW |
| (Empty) |
1 // Copyright 2007-2010 Google Inc. | |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 // ======================================================================== | |
15 | |
16 #include "omaha/common/config_manager.h" | |
17 #include <lm.h> | |
18 #include <shlobj.h> | |
19 #include <shlwapi.h> | |
20 #include <wininet.h> | |
21 #include <atlstr.h> | |
22 #include <atlsecurity.h> | |
23 #include <math.h> | |
24 #include "omaha/base/app_util.h" | |
25 #include "omaha/base/constants.h" | |
26 #include "omaha/base/const_addresses.h" | |
27 #include "omaha/base/debug.h" | |
28 #include "omaha/base/error.h" | |
29 #include "omaha/base/logging.h" | |
30 #include "omaha/base/scope_guard.h" | |
31 #include "omaha/base/string.h" | |
32 #include "omaha/base/time.h" | |
33 #include "omaha/base/utils.h" | |
34 #include "omaha/base/vistautil.h" | |
35 #include "omaha/common/app_registry_utils.h" | |
36 #include "omaha/common/const_group_policy.h" | |
37 #include "omaha/common/const_goopdate.h" | |
38 #include "omaha/common/oem_install_utils.h" | |
39 | |
40 namespace omaha { | |
41 | |
42 namespace { | |
43 | |
44 HRESULT GetDir(int csidl, | |
45 const CString& path_tail, | |
46 bool create_dir, | |
47 CString* dir) { | |
48 ASSERT1(dir); | |
49 | |
50 CString path; | |
51 HRESULT hr = GetFolderPath(csidl | CSIDL_FLAG_DONT_VERIFY, &path); | |
52 if (FAILED(hr)) { | |
53 CORE_LOG(LW, (_T("GetDir failed to find path][%d][0x%08x]"), csidl, hr)); | |
54 return hr; | |
55 } | |
56 if (!::PathAppend(CStrBuf(path, MAX_PATH), path_tail)) { | |
57 CORE_LOG(LW, (_T("GetDir failed to append path][%s][%s]"), path, path_tail))
; | |
58 return GOOPDATE_E_PATH_APPEND_FAILED; | |
59 } | |
60 dir->SetString(path); | |
61 | |
62 // Try to create the directory. Continue if the directory can't be created. | |
63 if (create_dir) { | |
64 hr = CreateDir(path, NULL); | |
65 if (FAILED(hr)) { | |
66 CORE_LOG(LW, (_T("[GetDir failed to create dir][%s][0x%08x]"), path, hr)); | |
67 } | |
68 } | |
69 return S_OK; | |
70 } | |
71 | |
72 // The app-specific value overrides the disable all value so read the former | |
73 // first. If it doesn't exist, read the "disable all" value. | |
74 bool GetEffectivePolicyForApp(const TCHAR* apps_default_value_name, | |
75 const TCHAR* app_prefix_name, | |
76 const GUID& app_guid, | |
77 DWORD* effective_policy) { | |
78 ASSERT1(apps_default_value_name); | |
79 ASSERT1(app_prefix_name); | |
80 ASSERT1(effective_policy); | |
81 | |
82 CString app_value_name(app_prefix_name); | |
83 app_value_name.Append(GuidToString(app_guid)); | |
84 | |
85 HRESULT hr = RegKey::GetValue(kRegKeyGoopdateGroupPolicy, | |
86 app_value_name, | |
87 effective_policy); | |
88 if (SUCCEEDED(hr)) { | |
89 return true; | |
90 } else { | |
91 CORE_LOG(L4, (_T("[Failed to read Group Policy value][%s]"), | |
92 app_value_name)); | |
93 } | |
94 | |
95 hr = RegKey::GetValue(kRegKeyGoopdateGroupPolicy, | |
96 apps_default_value_name, | |
97 effective_policy); | |
98 if (SUCCEEDED(hr)) { | |
99 return true; | |
100 } else { | |
101 CORE_LOG(L4, (_T("[Failed to read Group Policy value][%s]"), | |
102 apps_default_value_name)); | |
103 } | |
104 | |
105 return false; | |
106 } | |
107 | |
108 // Gets the raw update check period override value in seconds from the registry. | |
109 // The value must be processed for limits and overflow before using. | |
110 // Checks UpdateDev and Group Policy. | |
111 // Returns true if either override was successefully read. | |
112 bool GetLastCheckPeriodSecFromRegistry(DWORD* period_sec) { | |
113 ASSERT1(period_sec); | |
114 | |
115 DWORD update_dev_sec = 0; | |
116 if (SUCCEEDED(RegKey::GetValue(MACHINE_REG_UPDATE_DEV, | |
117 kRegValueLastCheckPeriodSec, | |
118 &update_dev_sec))) { | |
119 CORE_LOG(L5, (_T("['LastCheckPeriodSec' override %d]"), update_dev_sec)); | |
120 *period_sec = update_dev_sec; | |
121 return true; | |
122 } | |
123 | |
124 DWORD group_policy_minutes = 0; | |
125 if (SUCCEEDED(RegKey::GetValue(kRegKeyGoopdateGroupPolicy, | |
126 kRegValueAutoUpdateCheckPeriodOverrideMinutes, | |
127 &group_policy_minutes))) { | |
128 CORE_LOG(L5, (_T("[Group Policy check period override %d]"), | |
129 group_policy_minutes)); | |
130 | |
131 | |
132 *period_sec = (group_policy_minutes > UINT_MAX / 60) ? | |
133 UINT_MAX : | |
134 group_policy_minutes * 60; | |
135 | |
136 return true; | |
137 } | |
138 | |
139 return false; | |
140 } | |
141 | |
142 } // namespace | |
143 | |
144 LLock ConfigManager::lock_; | |
145 ConfigManager* ConfigManager::config_manager_ = NULL; | |
146 | |
147 ConfigManager* ConfigManager::Instance() { | |
148 __mutexScope(lock_); | |
149 if (!config_manager_) { | |
150 config_manager_ = new ConfigManager(); | |
151 } | |
152 return config_manager_; | |
153 } | |
154 | |
155 void ConfigManager::DeleteInstance() { | |
156 delete config_manager_; | |
157 } | |
158 | |
159 ConfigManager::ConfigManager() { | |
160 CString current_module_directory(app_util::GetCurrentModuleDirectory()); | |
161 | |
162 CString path; | |
163 HRESULT hr = GetDir(CSIDL_LOCAL_APPDATA, | |
164 CString(OMAHA_REL_GOOPDATE_INSTALL_DIR), | |
165 false, | |
166 &path); | |
167 | |
168 is_running_from_official_user_dir_ = | |
169 SUCCEEDED(hr) ? (String_StrNCmp(path, | |
170 current_module_directory, | |
171 path.GetLength(), | |
172 true) == 0) : | |
173 false; | |
174 | |
175 hr = GetDir(CSIDL_PROGRAM_FILES, | |
176 CString(OMAHA_REL_GOOPDATE_INSTALL_DIR), | |
177 false, | |
178 &path); | |
179 | |
180 is_running_from_official_machine_dir_ = | |
181 SUCCEEDED(hr) ? (String_StrNCmp(path, | |
182 current_module_directory, | |
183 path.GetLength(), | |
184 true) == 0) : | |
185 false; | |
186 } | |
187 | |
188 CString ConfigManager::GetUserDownloadStorageDir() const { | |
189 CString path; | |
190 VERIFY1(SUCCEEDED(GetDir(CSIDL_LOCAL_APPDATA, | |
191 CString(OMAHA_REL_DOWNLOAD_STORAGE_DIR), | |
192 true, | |
193 &path))); | |
194 return path; | |
195 } | |
196 | |
197 CString ConfigManager::GetUserInstallWorkingDir() const { | |
198 CString path; | |
199 VERIFY1(SUCCEEDED(GetDir(CSIDL_LOCAL_APPDATA, | |
200 CString(OMAHA_REL_INSTALL_WORKING_DIR), | |
201 true, | |
202 &path))); | |
203 return path; | |
204 } | |
205 | |
206 CString ConfigManager::GetUserOfflineStorageDir() const { | |
207 CString path; | |
208 VERIFY1(SUCCEEDED(GetDir(CSIDL_LOCAL_APPDATA, | |
209 CString(OMAHA_REL_OFFLINE_STORAGE_DIR), | |
210 true, | |
211 &path))); | |
212 return path; | |
213 } | |
214 | |
215 CString ConfigManager::GetUserGoopdateInstallDirNoCreate() const { | |
216 CString path; | |
217 VERIFY1(SUCCEEDED(GetDir(CSIDL_LOCAL_APPDATA, | |
218 CString(OMAHA_REL_GOOPDATE_INSTALL_DIR), | |
219 false, | |
220 &path))); | |
221 return path; | |
222 } | |
223 | |
224 CString ConfigManager::GetUserGoopdateInstallDir() const { | |
225 CString path; | |
226 VERIFY1(SUCCEEDED(GetDir(CSIDL_LOCAL_APPDATA, | |
227 CString(OMAHA_REL_GOOPDATE_INSTALL_DIR), | |
228 true, | |
229 &path))); | |
230 return path; | |
231 } | |
232 | |
233 bool ConfigManager::IsRunningFromUserGoopdateInstallDir() const { | |
234 return is_running_from_official_user_dir_; | |
235 } | |
236 | |
237 CString ConfigManager::GetUserCrashReportsDir() const { | |
238 CString path; | |
239 VERIFY1(SUCCEEDED(GetDir(CSIDL_LOCAL_APPDATA, | |
240 CString(OMAHA_REL_CRASH_DIR), | |
241 true, | |
242 &path))); | |
243 return path; | |
244 } | |
245 | |
246 CString ConfigManager::GetMachineCrashReportsDir() const { | |
247 CString path; | |
248 VERIFY1(SUCCEEDED(GetDir(CSIDL_PROGRAM_FILES, | |
249 CString(OMAHA_REL_CRASH_DIR), | |
250 true, | |
251 &path))); | |
252 return path; | |
253 } | |
254 | |
255 CString ConfigManager::GetMachineSecureDownloadStorageDir() const { | |
256 CString path; | |
257 VERIFY1(SUCCEEDED(GetDir(CSIDL_PROGRAM_FILES, | |
258 CString(OMAHA_REL_DOWNLOAD_STORAGE_DIR), | |
259 true, | |
260 &path))); | |
261 return path; | |
262 } | |
263 | |
264 CString ConfigManager::GetMachineInstallWorkingDir() const { | |
265 CString path; | |
266 VERIFY1(SUCCEEDED(GetDir(CSIDL_PROGRAM_FILES, | |
267 CString(OMAHA_REL_INSTALL_WORKING_DIR), | |
268 true, | |
269 &path))); | |
270 return path; | |
271 } | |
272 | |
273 CString ConfigManager::GetMachineSecureOfflineStorageDir() const { | |
274 CString path; | |
275 VERIFY1(SUCCEEDED(GetDir(CSIDL_PROGRAM_FILES, | |
276 CString(OMAHA_REL_OFFLINE_STORAGE_DIR), | |
277 true, | |
278 &path))); | |
279 return path; | |
280 } | |
281 | |
282 CString ConfigManager::GetTempDownloadDir() const { | |
283 CString temp_download_dir(app_util::GetTempDirForImpersonatedOrCurrentUser()); | |
284 ASSERT1(temp_download_dir); | |
285 HRESULT hr = CreateDir(temp_download_dir, NULL); | |
286 if (FAILED(hr)) { | |
287 CORE_LOG(LW, (_T("[GetDir failed to create dir][%s][0x%08x]"), | |
288 temp_download_dir, hr)); | |
289 } | |
290 return temp_download_dir; | |
291 } | |
292 | |
293 int ConfigManager::GetPackageCacheSizeLimitMBytes() const { | |
294 DWORD kDefaultCacheStorageLimit = 500; // 500 MB | |
295 DWORD kMaxCacheStorageLimit = 5000; // 5 GB | |
296 | |
297 DWORD cache_size_limit = 0; | |
298 if (FAILED(RegKey::GetValue(kRegKeyGoopdateGroupPolicy, | |
299 kRegValueCacheSizeLimitMBytes, | |
300 &cache_size_limit)) || | |
301 cache_size_limit > kMaxCacheStorageLimit || | |
302 cache_size_limit == 0) { | |
303 cache_size_limit = kDefaultCacheStorageLimit; | |
304 } | |
305 | |
306 return static_cast<int>(cache_size_limit); | |
307 } | |
308 | |
309 int ConfigManager::GetPackageCacheExpirationTimeDays() const { | |
310 DWORD kDefaultCacheLifeTimeInDays = 180; // 180 days. | |
311 DWORD kMaxCacheLifeTimeInDays = 1800; // Roughly 5 years. | |
312 | |
313 DWORD cache_life_limit = 0; | |
314 if (FAILED(RegKey::GetValue(kRegKeyGoopdateGroupPolicy, | |
315 kRegValueCacheLifeLimitDays, | |
316 &cache_life_limit)) || | |
317 cache_life_limit > kMaxCacheLifeTimeInDays || | |
318 cache_life_limit == 0) { | |
319 cache_life_limit = kDefaultCacheLifeTimeInDays; | |
320 } | |
321 | |
322 return static_cast<int>(cache_life_limit); | |
323 } | |
324 | |
325 CString ConfigManager::GetMachineGoopdateInstallDirNoCreate() const { | |
326 CString path; | |
327 VERIFY1(SUCCEEDED(GetDir(CSIDL_PROGRAM_FILES, | |
328 CString(OMAHA_REL_GOOPDATE_INSTALL_DIR), | |
329 false, | |
330 &path))); | |
331 return path; | |
332 } | |
333 | |
334 CString ConfigManager::GetMachineGoopdateInstallDir() const { | |
335 CString path; | |
336 VERIFY1(SUCCEEDED(GetDir(CSIDL_PROGRAM_FILES, | |
337 CString(OMAHA_REL_GOOPDATE_INSTALL_DIR), | |
338 true, | |
339 &path))); | |
340 return path; | |
341 } | |
342 | |
343 bool ConfigManager::IsRunningFromMachineGoopdateInstallDir() const { | |
344 return is_running_from_official_machine_dir_; | |
345 } | |
346 | |
347 HRESULT ConfigManager::GetPingUrl(CString* url) const { | |
348 ASSERT1(url); | |
349 | |
350 if (SUCCEEDED(RegKey::GetValue(MACHINE_REG_UPDATE_DEV, | |
351 kRegValueNamePingUrl, | |
352 url))) { | |
353 CORE_LOG(L5, (_T("['ping url' override %s]"), *url)); | |
354 return S_OK; | |
355 } | |
356 | |
357 *url = kUrlPing; | |
358 return S_OK; | |
359 } | |
360 | |
361 HRESULT ConfigManager::GetUpdateCheckUrl(CString* url) const { | |
362 ASSERT1(url); | |
363 | |
364 if (SUCCEEDED(RegKey::GetValue(MACHINE_REG_UPDATE_DEV, | |
365 kRegValueNameUrl, | |
366 url))) { | |
367 CORE_LOG(L5, (_T("['update check url' override %s]"), *url)); | |
368 return S_OK; | |
369 } | |
370 | |
371 *url = kUrlUpdateCheck; | |
372 return S_OK; | |
373 } | |
374 | |
375 HRESULT ConfigManager::GetCrashReportUrl(CString* url) const { | |
376 ASSERT1(url); | |
377 | |
378 if (SUCCEEDED(RegKey::GetValue(MACHINE_REG_UPDATE_DEV, | |
379 kRegValueNameCrashReportUrl, | |
380 url))) { | |
381 CORE_LOG(L5, (_T("['crash report url' override %s]"), *url)); | |
382 return S_OK; | |
383 } | |
384 | |
385 *url = kUrlCrashReport; | |
386 return S_OK; | |
387 } | |
388 | |
389 HRESULT ConfigManager::GetMoreInfoUrl(CString* url) const { | |
390 ASSERT1(url); | |
391 | |
392 if (SUCCEEDED(RegKey::GetValue(MACHINE_REG_UPDATE_DEV, | |
393 kRegValueNameGetMoreInfoUrl, | |
394 url))) { | |
395 CORE_LOG(L5, (_T("['more info url' override %s]"), *url)); | |
396 return S_OK; | |
397 } | |
398 | |
399 *url = kUrlMoreInfo; | |
400 return S_OK; | |
401 } | |
402 | |
403 HRESULT ConfigManager::GetUsageStatsReportUrl(CString* url) const { | |
404 ASSERT1(url); | |
405 | |
406 if (SUCCEEDED(RegKey::GetValue(MACHINE_REG_UPDATE_DEV, | |
407 kRegValueNameUsageStatsReportUrl, | |
408 url))) { | |
409 CORE_LOG(L5, (_T("['usage stats report url' override %s]"), *url)); | |
410 return S_OK; | |
411 } | |
412 | |
413 *url = kUrlUsageStatsReport; | |
414 return S_OK; | |
415 } | |
416 | |
417 // Returns the override from the registry locations if present. Otherwise, | |
418 // returns the default value. | |
419 // Default value is different value for internal users to make update checks | |
420 // more aggresive. | |
421 // Ensures returned value is between kMinLastCheckPeriodSec and INT_MAX except | |
422 // when the override is 0, which indicates updates are disabled. | |
423 int ConfigManager::GetLastCheckPeriodSec(bool* is_overridden) const { | |
424 ASSERT1(is_overridden); | |
425 DWORD registry_period_sec = 0; | |
426 *is_overridden = GetLastCheckPeriodSecFromRegistry(®istry_period_sec); | |
427 if (*is_overridden) { | |
428 if (0 == registry_period_sec) { | |
429 return 0; | |
430 } | |
431 const int period_sec = registry_period_sec > INT_MAX ? | |
432 INT_MAX : | |
433 static_cast<int>(registry_period_sec); | |
434 | |
435 if (period_sec < kMinLastCheckPeriodSec) { | |
436 return kMinLastCheckPeriodSec; | |
437 } | |
438 return period_sec; | |
439 } | |
440 | |
441 // Returns a lower value for internal users. | |
442 if (IsInternalUser()) { | |
443 return kLastCheckPeriodInternalUserSec; | |
444 } | |
445 | |
446 return kLastCheckPeriodSec; | |
447 } | |
448 | |
449 // All time values are in seconds. | |
450 int ConfigManager::GetTimeSinceLastCheckedSec(bool is_machine) const { | |
451 const uint32 now = Time64ToInt32(GetCurrent100NSTime()); | |
452 const uint32 last_checked = GetLastCheckedTime(is_machine); | |
453 if (now < last_checked) { | |
454 CORE_LOG(LW, (_T("[possible time warp detected]") | |
455 _T("[now %u][last checked %u]"), now, last_checked)); | |
456 } | |
457 const int time_difference = abs(static_cast<int>(now - last_checked)); | |
458 bool is_period_overridden = false; | |
459 CORE_LOG(L3, (_T("[now %u][last checked %u][update interval %u]") | |
460 _T("[time difference %u]"), | |
461 now, last_checked, GetLastCheckPeriodSec(&is_period_overridden), | |
462 time_difference)); | |
463 return time_difference; | |
464 } | |
465 | |
466 DWORD ConfigManager::GetLastCheckedTime(bool is_machine) const { | |
467 const TCHAR* reg_update_key = is_machine ? MACHINE_REG_UPDATE: | |
468 USER_REG_UPDATE; | |
469 DWORD last_checked_time = 0; | |
470 if (SUCCEEDED(RegKey::GetValue(reg_update_key, | |
471 kRegValueLastChecked, | |
472 &last_checked_time))) { | |
473 return last_checked_time; | |
474 } | |
475 return 0; | |
476 } | |
477 | |
478 HRESULT ConfigManager::SetLastCheckedTime(bool is_machine, DWORD time) const { | |
479 const TCHAR* reg_update_key = is_machine ? MACHINE_REG_UPDATE: | |
480 USER_REG_UPDATE; | |
481 return RegKey::SetValue(reg_update_key, kRegValueLastChecked, time); | |
482 } | |
483 | |
484 DWORD ConfigManager::GetInstallTime(bool is_machine) { | |
485 const CString client_state_key_name = | |
486 ConfigManager::Instance()->registry_client_state_goopdate(is_machine); | |
487 DWORD update_time(0); | |
488 if (SUCCEEDED(RegKey::GetValue(client_state_key_name, | |
489 kRegValueLastUpdateTimeSec, | |
490 &update_time))) { | |
491 return update_time; | |
492 } | |
493 | |
494 DWORD install_time(0); | |
495 if (SUCCEEDED(RegKey::GetValue(client_state_key_name, | |
496 kRegValueInstallTimeSec, | |
497 &install_time))) { | |
498 return install_time; | |
499 } | |
500 | |
501 return 0; | |
502 } | |
503 | |
504 bool ConfigManager::Is24HoursSinceInstall(bool is_machine) { | |
505 const int kDaySec = 24 * 60 * 60; | |
506 const uint32 now = Time64ToInt32(GetCurrent100NSTime()); | |
507 | |
508 const uint32 install_time = GetInstallTime(is_machine); | |
509 if (now < install_time) { | |
510 CORE_LOG(LW, (_T("[Incorrect clock time detected]") | |
511 _T("[now %u][install_time %u]"), now, install_time)); | |
512 } | |
513 const int time_difference = abs(static_cast<int>(now - install_time)); | |
514 return time_difference >= kDaySec; | |
515 } | |
516 | |
517 // Uses app_registry_utils because this needs to be called in the server and | |
518 // client and it is a best effort so locking isn't necessary. | |
519 bool ConfigManager::CanCollectStats(bool is_machine) const { | |
520 if (RegKey::HasValue(MACHINE_REG_UPDATE_DEV, kRegValueForceUsageStats)) { | |
521 return true; | |
522 } | |
523 | |
524 // TODO(omaha): This should actually be iterating over registered products | |
525 // rather than present ClientState keys. These are identical in most cases. | |
526 const TCHAR* state_key_name = registry_client_state(is_machine); | |
527 | |
528 RegKey state_key; | |
529 HRESULT hr = state_key.Open(state_key_name, KEY_READ); | |
530 if (FAILED(hr)) { | |
531 return false; | |
532 } | |
533 | |
534 int num_sub_keys = state_key.GetSubkeyCount(); | |
535 for (int i = 0; i < num_sub_keys; ++i) { | |
536 CString sub_key_name; | |
537 if (FAILED(state_key.GetSubkeyNameAt(i, &sub_key_name))) { | |
538 continue; | |
539 } | |
540 | |
541 if (app_registry_utils::AreAppUsageStatsEnabled(is_machine, sub_key_name)) { | |
542 return true; | |
543 } | |
544 } | |
545 | |
546 return false; | |
547 } | |
548 | |
549 // Overrides OverInstall in debug builds. | |
550 bool ConfigManager::CanOverInstall() const { | |
551 #ifdef DEBUG | |
552 DWORD value = 0; | |
553 if (SUCCEEDED(RegKey::GetValue(MACHINE_REG_UPDATE_DEV, | |
554 kRegValueNameOverInstall, | |
555 &value))) { | |
556 CORE_LOG(L5, (_T("['OverInstall' override %d]"), value)); | |
557 return value != 0; | |
558 } | |
559 #endif | |
560 return !OFFICIAL_BUILD; | |
561 } | |
562 | |
563 // Overrides AuCheckPeriodMs. Implements a lower bound value. Returns INT_MAX | |
564 // if the registry value exceeds INT_MAX. | |
565 int ConfigManager::GetAutoUpdateTimerIntervalMs() const { | |
566 DWORD interval(0); | |
567 if (SUCCEEDED(RegKey::GetValue(MACHINE_REG_UPDATE_DEV, | |
568 kRegValueAuCheckPeriodMs, | |
569 &interval))) { | |
570 int ret_val = 0; | |
571 if (interval > INT_MAX) { | |
572 ret_val = INT_MAX; | |
573 } else if (interval < kMinAUCheckPeriodMs) { | |
574 ret_val = kMinAUCheckPeriodMs; | |
575 } else { | |
576 ret_val = interval; | |
577 } | |
578 ASSERT1(ret_val >= kMinAUCheckPeriodMs); | |
579 CORE_LOG(L5, (_T("['AuCheckPeriodMs' override %d]"), interval)); | |
580 return ret_val; | |
581 } | |
582 | |
583 // Returns a lower value for internal users. | |
584 if (IsInternalUser()) { | |
585 return kAUCheckPeriodInternalUserMs; | |
586 } | |
587 | |
588 return kAUCheckPeriodMs; | |
589 } | |
590 | |
591 int ConfigManager::GetUpdateWorkerStartUpDelayMs() const { | |
592 int au_timer_interval_ms = GetAutoUpdateTimerIntervalMs(); | |
593 | |
594 // If the AuCheckPeriod is overriden then use that as the delay. | |
595 if (RegKey::HasValue(MACHINE_REG_UPDATE_DEV, kRegValueAuCheckPeriodMs)) { | |
596 return au_timer_interval_ms; | |
597 } | |
598 | |
599 int random_delay = 0; | |
600 if (!GenRandom(&random_delay, sizeof(random_delay))) { | |
601 return au_timer_interval_ms; | |
602 } | |
603 | |
604 // Scale the au_check_period number to be between | |
605 // kUpdateTimerStartupDelayMinMs and kUpdateTimerStartupDelayMaxMs. | |
606 int scale = kUpdateTimerStartupDelayMaxMs - kUpdateTimerStartupDelayMinMs; | |
607 ASSERT1(scale >= 0); | |
608 | |
609 int random_addition = abs(random_delay) % scale; | |
610 ASSERT1(random_addition < scale); | |
611 | |
612 au_timer_interval_ms = kUpdateTimerStartupDelayMinMs + random_addition; | |
613 ASSERT1(au_timer_interval_ms >= kUpdateTimerStartupDelayMinMs && | |
614 au_timer_interval_ms <= kUpdateTimerStartupDelayMaxMs); | |
615 | |
616 return au_timer_interval_ms; | |
617 } | |
618 | |
619 // Overrides CodeRedCheckPeriodMs. Implements a lower bound value. Returns | |
620 // INT_MAX if the registry value exceeds INT_MAX. | |
621 int ConfigManager::GetCodeRedTimerIntervalMs() const { | |
622 DWORD interval(0); | |
623 if (SUCCEEDED(RegKey::GetValue(MACHINE_REG_UPDATE_DEV, | |
624 kRegValueCrCheckPeriodMs, | |
625 &interval))) { | |
626 int ret_val = 0; | |
627 if (interval > INT_MAX) { | |
628 ret_val = INT_MAX; | |
629 } else if (interval < kMinCodeRedCheckPeriodMs) { | |
630 ret_val = kMinCodeRedCheckPeriodMs; | |
631 } else { | |
632 ret_val = interval; | |
633 } | |
634 ASSERT1(ret_val >= kMinCodeRedCheckPeriodMs); | |
635 CORE_LOG(L5, (_T("['CrCheckPeriodMs' override %d]"), interval)); | |
636 return ret_val; | |
637 } | |
638 return kCodeRedCheckPeriodMs; | |
639 } | |
640 | |
641 // Returns true if logging is enabled for the event type. | |
642 // Logging of errors and warnings is enabled by default. | |
643 bool ConfigManager::CanLogEvents(WORD event_type) const { | |
644 const TCHAR* reg_update_key = MACHINE_REG_UPDATE_DEV; | |
645 DWORD log_events_level = LOG_EVENT_LEVEL_NONE; | |
646 if (SUCCEEDED(RegKey::GetValue(reg_update_key, | |
647 kRegValueEventLogLevel, | |
648 &log_events_level))) { | |
649 switch (log_events_level) { | |
650 case LOG_EVENT_LEVEL_ALL: | |
651 return true; | |
652 case LOG_EVENT_LEVEL_WARN_AND_ERROR: | |
653 return event_type == EVENTLOG_ERROR_TYPE || | |
654 event_type == EVENTLOG_WARNING_TYPE; | |
655 case LOG_EVENT_LEVEL_NONE: | |
656 default: | |
657 return false; | |
658 } | |
659 } | |
660 | |
661 return event_type == EVENTLOG_ERROR_TYPE || | |
662 event_type == EVENTLOG_WARNING_TYPE; | |
663 } | |
664 | |
665 CString ConfigManager::GetTestSource() const { | |
666 CString test_source; | |
667 HRESULT hr = RegKey::GetValue(MACHINE_REG_UPDATE_DEV, | |
668 kRegValueTestSource, | |
669 &test_source); | |
670 if (SUCCEEDED(hr)) { | |
671 if (test_source.IsEmpty()) { | |
672 test_source = kRegValueTestSourceAuto; | |
673 } | |
674 return test_source; | |
675 } | |
676 | |
677 DWORD interval = 0; | |
678 hr = RegKey::GetValue(MACHINE_REG_UPDATE_DEV, | |
679 kRegValueAuCheckPeriodMs, | |
680 &interval); | |
681 if (SUCCEEDED(hr)) { | |
682 return kRegValueTestSourceAuto; | |
683 } | |
684 | |
685 #if defined(DEBUG) || !OFFICIAL_BUILD | |
686 test_source = kRegValueTestSourceAuto; | |
687 #endif | |
688 | |
689 return test_source; | |
690 } | |
691 | |
692 HRESULT ConfigManager::GetNetConfig(CString* net_config) { | |
693 ASSERT1(net_config); | |
694 CString val; | |
695 HRESULT hr = RegKey::GetValue(MACHINE_REG_UPDATE_DEV, | |
696 kRegValueNetConfig, | |
697 &val); | |
698 if (SUCCEEDED(hr)) { | |
699 *net_config = val; | |
700 } | |
701 return hr; | |
702 } | |
703 | |
704 // Returns false if running in the context of an OEM install or waiting for a | |
705 // EULA to be accepted. | |
706 bool ConfigManager::CanUseNetwork(bool is_machine) const { | |
707 DWORD eula_accepted(0); | |
708 HRESULT hr = RegKey::GetValue(registry_update(is_machine), | |
709 kRegValueOmahaEulaAccepted, | |
710 &eula_accepted); | |
711 if (SUCCEEDED(hr) && 0 == eula_accepted) { | |
712 CORE_LOG(L3, (_T("[CanUseNetwork][eulaaccepted=0][false]"))); | |
713 return false; | |
714 } | |
715 | |
716 if (oem_install_utils::IsOemInstalling(is_machine)) { | |
717 CORE_LOG(L3, (_T("[CanUseNetwork][OEM installing][false]"))); | |
718 return false; | |
719 } | |
720 | |
721 return true; | |
722 } | |
723 | |
724 // USE oem_install_utils::IsOemInstalling() INSTEAD in most cases. | |
725 bool ConfigManager::IsWindowsInstalling() const { | |
726 #if !OFFICIAL_BUILD | |
727 DWORD value = 0; | |
728 if (SUCCEEDED(RegKey::GetValue(MACHINE_REG_UPDATE_DEV, | |
729 kRegValueNameWindowsInstalling, | |
730 &value))) { | |
731 CORE_LOG(L3, (_T("['WindowsInstalling' override %d]"), value)); | |
732 return value != 0; | |
733 } | |
734 #endif | |
735 | |
736 return omaha::IsWindowsInstalling(); | |
737 } | |
738 | |
739 // Checks if the computer name ends with ".google.com" or the NetBIOS domain is | |
740 // "google". | |
741 bool ConfigManager::IsInternalUser() const { | |
742 CORE_LOG(L4, (_T("[ConfigManager::IsInternalUser]"))); | |
743 TCHAR dns_name[INTERNET_MAX_HOST_NAME_LENGTH] = {0}; | |
744 DWORD dns_name_size(arraysize(dns_name)); | |
745 if (::GetComputerNameEx(ComputerNameDnsFullyQualified, | |
746 dns_name, &dns_name_size)) { | |
747 CORE_LOG(L4, (_T("[dns name %s]"), dns_name)); | |
748 if (String_EndsWith(dns_name, kCompanyInternalDnsName, true)) { | |
749 return true; | |
750 } | |
751 } | |
752 | |
753 WKSTA_INFO_100* info = NULL; | |
754 int kInformationLevel = 100; | |
755 NET_API_STATUS status = ::NetWkstaGetInfo(NULL, | |
756 kInformationLevel, | |
757 reinterpret_cast<BYTE**>(&info)); | |
758 ON_SCOPE_EXIT(::NetApiBufferFree, info); | |
759 if (status == NERR_Success) { | |
760 CORE_LOG(L4, (_T("[netbios name %s]"), info->wki100_langroup)); | |
761 if (info->wki100_langroup && | |
762 _tcsicmp(info->wki100_langroup, kCompanyInternalLanGroupName) == 0) { | |
763 return true; | |
764 } | |
765 } | |
766 return false; | |
767 } | |
768 | |
769 bool ConfigManager::CanInstallApp(const GUID& app_guid) const { | |
770 // Google Update should never be checking whether it can install itself. | |
771 ASSERT1(!::IsEqualGUID(kGoopdateGuid, app_guid)); | |
772 | |
773 DWORD effective_policy = 0; | |
774 if (!GetEffectivePolicyForApp(kRegValueInstallAppsDefault, | |
775 kRegValueInstallAppPrefix, | |
776 app_guid, | |
777 &effective_policy)) { | |
778 return kInstallPolicyDefault; | |
779 } | |
780 | |
781 return kPolicyDisabled != effective_policy; | |
782 } | |
783 | |
784 // Self-updates cannot be disabled. | |
785 bool ConfigManager::CanUpdateApp(const GUID& app_guid, | |
786 bool is_manual) const { | |
787 if (::IsEqualGUID(kGoopdateGuid, app_guid)) { | |
788 return true; | |
789 } | |
790 | |
791 DWORD effective_policy = 0; | |
792 if (!GetEffectivePolicyForApp(kRegValueUpdateAppsDefault, | |
793 kRegValueUpdateAppPrefix, | |
794 app_guid, | |
795 &effective_policy)) { | |
796 return kUpdatePolicyDefault; | |
797 } | |
798 | |
799 if (kPolicyDisabled == effective_policy) { | |
800 return false; | |
801 } | |
802 if ((kPolicyManualUpdatesOnly == effective_policy) && !is_manual) { | |
803 return false; | |
804 } | |
805 | |
806 return kUpdatePolicyDefault; | |
807 } | |
808 | |
809 bool ConfigManager::AlwaysAllowCrashUploads() const { | |
810 DWORD always_allow_crash_uploads = 0; | |
811 RegKey::GetValue(MACHINE_REG_UPDATE_DEV, | |
812 kRegValueAlwaysAllowCrashUploads, | |
813 &always_allow_crash_uploads); | |
814 return always_allow_crash_uploads != 0; | |
815 } | |
816 | |
817 } // namespace omaha | |
OLD | NEW |