OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 // NOTE: This code is a legacy utility API for partners to check whether |
| 6 // Chrome can be installed and launched. Recent updates are being made |
| 7 // to add new functionality. These updates use code from Chromium, the old |
| 8 // coded against the win32 api directly. If you have an itch to shave a |
| 9 // yak, feel free to re-write the old code too. |
| 10 |
5 #include "chrome/installer/gcapi/gcapi.h" | 11 #include "chrome/installer/gcapi/gcapi.h" |
6 | 12 |
7 #include <atlbase.h> | 13 #include <atlbase.h> |
8 #include <atlcom.h> | 14 #include <atlcom.h> |
9 #include <windows.h> | |
10 #include <sddl.h> | 15 #include <sddl.h> |
11 #define STRSAFE_NO_DEPRECATE | 16 #define STRSAFE_NO_DEPRECATE |
12 #include <strsafe.h> | 17 #include <strsafe.h> |
13 #include <tlhelp32.h> | 18 #include <tlhelp32.h> |
| 19 #include <windows.h> |
14 | 20 |
15 #include <cstdlib> | 21 #include <cstdlib> |
| 22 #include <limits> |
| 23 #include <string> |
16 | 24 |
17 #include "google_update_idl.h" | 25 #include "base/basictypes.h" |
| 26 #include "base/string_number_conversions.h" |
| 27 #include "base/time.h" |
| 28 #include "base/win/registry.h" |
| 29 #include "chrome/installer/util/google_update_constants.h" |
| 30 |
| 31 #include "google_update_idl.h" // NOLINT |
18 | 32 |
19 namespace { | 33 namespace { |
20 | 34 |
21 const wchar_t kChromeRegClientsKey[] = | 35 const wchar_t kChromeRegClientsKey[] = |
22 L"Software\\Google\\Update\\Clients\\" | 36 L"Software\\Google\\Update\\Clients\\" |
23 L"{8A69D345-D564-463c-AFF1-A69D9E530F96}"; | 37 L"{8A69D345-D564-463c-AFF1-A69D9E530F96}"; |
24 const wchar_t kChromeRegClientStateKey[] = | 38 const wchar_t kChromeRegClientStateKey[] = |
25 L"Software\\Google\\Update\\ClientState\\" | 39 L"Software\\Google\\Update\\ClientState\\" |
26 L"{8A69D345-D564-463c-AFF1-A69D9E530F96}"; | 40 L"{8A69D345-D564-463c-AFF1-A69D9E530F96}"; |
| 41 const wchar_t kChromeRegClientStateMediumKey[] = |
| 42 L"Software\\Google\\Update\\ClientStateMedium\\" |
| 43 L"{8A69D345-D564-463c-AFF1-A69D9E530F96}"; |
| 44 |
27 const wchar_t kChromeRegLaunchCmd[] = L"InstallerSuccessLaunchCmdLine"; | 45 const wchar_t kChromeRegLaunchCmd[] = L"InstallerSuccessLaunchCmdLine"; |
28 const wchar_t kChromeRegLastLaunchCmd[] = L"LastInstallerSuccessLaunchCmdLine"; | 46 const wchar_t kChromeRegLastLaunchCmd[] = L"LastInstallerSuccessLaunchCmdLine"; |
29 const wchar_t kChromeRegVersion[] = L"pv"; | 47 const wchar_t kChromeRegVersion[] = L"pv"; |
30 const wchar_t kNoChromeOfferUntil[] = | 48 const wchar_t kNoChromeOfferUntil[] = |
31 L"SOFTWARE\\Google\\No Chrome Offer Until"; | 49 L"SOFTWARE\\Google\\No Chrome Offer Until"; |
32 | 50 |
33 // Return the company name specified in the file version info resource. | 51 // Return the company name specified in the file version info resource. |
34 bool GetCompanyName(const wchar_t* filename, wchar_t* buffer, DWORD out_len) { | 52 bool GetCompanyName(const wchar_t* filename, wchar_t* buffer, DWORD out_len) { |
35 wchar_t file_version_info[8192]; | 53 wchar_t file_version_info[8192]; |
36 DWORD handle = 0; | 54 DWORD handle = 0; |
(...skipping 26 matching lines...) Expand all Loading... |
63 memcpy(&lang, data, 4); | 81 memcpy(&lang, data, 4); |
64 ::StringCchPrintf(info_name, _countof(info_name), | 82 ::StringCchPrintf(info_name, _countof(info_name), |
65 L"\\StringFileInfo\\%02X%02X%02X%02X\\CompanyName", | 83 L"\\StringFileInfo\\%02X%02X%02X%02X\\CompanyName", |
66 (lang & 0xff00)>>8, (lang & 0xff), (lang & 0xff000000)>>24, | 84 (lang & 0xff00)>>8, (lang & 0xff), (lang & 0xff000000)>>24, |
67 (lang & 0xff0000)>>16); | 85 (lang & 0xff0000)>>16); |
68 | 86 |
69 data_len = 0; | 87 data_len = 0; |
70 if (!::VerQueryValue(file_version_info, info_name, | 88 if (!::VerQueryValue(file_version_info, info_name, |
71 reinterpret_cast<LPVOID *>(&data), reinterpret_cast<UINT *>(&data_len))) | 89 reinterpret_cast<LPVOID *>(&data), reinterpret_cast<UINT *>(&data_len))) |
72 return false; | 90 return false; |
73 if (data_len <= 0 || data_len >= out_len) | 91 if (data_len <= 0 || data_len >= (out_len / sizeof(wchar_t))) |
74 return false; | 92 return false; |
75 | 93 |
76 memset(buffer, 0, out_len); | 94 memset(buffer, 0, out_len); |
77 ::StringCchCopyN(buffer, out_len, (const wchar_t*)data, data_len); | 95 ::StringCchCopyN(buffer, |
| 96 (out_len / sizeof(wchar_t)), |
| 97 reinterpret_cast<const wchar_t*>(data), |
| 98 data_len); |
78 return true; | 99 return true; |
79 } | 100 } |
80 | 101 |
81 // Return true if we can re-offer Chrome; false, otherwise. | 102 // Return true if we can re-offer Chrome; false, otherwise. |
82 // Each partner can only offer Chrome once every six months. | 103 // Each partner can only offer Chrome once every six months. |
83 bool CanReOfferChrome(BOOL set_flag) { | 104 bool CanReOfferChrome(BOOL set_flag) { |
84 wchar_t filename[MAX_PATH+1]; | 105 wchar_t filename[MAX_PATH+1]; |
85 wchar_t company[MAX_PATH]; | 106 wchar_t company[MAX_PATH]; |
86 | 107 |
87 // If we cannot retrieve the version info of the executable or company | 108 // If we cannot retrieve the version info of the executable or company |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 } | 154 } |
134 | 155 |
135 ::RegCloseKey(key); | 156 ::RegCloseKey(key); |
136 } | 157 } |
137 | 158 |
138 return can_re_offer; | 159 return can_re_offer; |
139 } | 160 } |
140 | 161 |
141 // Helper function to read a value from registry. Returns true if value | 162 // Helper function to read a value from registry. Returns true if value |
142 // is read successfully and stored in parameter value. Returns false otherwise. | 163 // is read successfully and stored in parameter value. Returns false otherwise. |
143 bool ReadValueFromRegistry(HKEY root_key, const wchar_t *sub_key, | 164 bool ReadValueFromRegistry(HKEY root_key, const wchar_t* sub_key, |
144 const wchar_t *value_name, wchar_t *value, | 165 const wchar_t* value_name, wchar_t* value, |
145 size_t *size) { | 166 size_t* size) { |
146 HKEY key; | 167 HKEY key; |
147 if ((::RegOpenKeyEx(root_key, sub_key, NULL, | 168 if ((::RegOpenKeyEx(root_key, sub_key, NULL, |
148 KEY_READ, &key) == ERROR_SUCCESS) && | 169 KEY_READ, &key) == ERROR_SUCCESS) && |
149 (::RegQueryValueEx(key, value_name, NULL, NULL, | 170 (::RegQueryValueEx(key, value_name, NULL, NULL, |
150 reinterpret_cast<LPBYTE>(value), | 171 reinterpret_cast<LPBYTE>(value), |
151 reinterpret_cast<LPDWORD>(size)) == ERROR_SUCCESS)) { | 172 reinterpret_cast<LPDWORD>(size)) == ERROR_SUCCESS)) { |
152 ::RegCloseKey(key); | 173 ::RegCloseKey(key); |
153 return true; | 174 return true; |
154 } | 175 } |
155 return false; | 176 return false; |
156 } | 177 } |
157 | 178 |
158 bool IsChromeInstalled(HKEY root_key) { | 179 bool IsChromeInstalled(HKEY root_key) { |
159 wchar_t version[64]; | 180 wchar_t version[64]; |
160 size_t size = _countof(version); | 181 size_t size = _countof(version); |
161 return ReadValueFromRegistry(root_key, kChromeRegClientsKey, | 182 return ReadValueFromRegistry(root_key, kChromeRegClientsKey, |
162 kChromeRegVersion, version, &size); | 183 kChromeRegVersion, version, &size); |
163 } | 184 } |
164 | 185 |
165 enum WindowsVersion { | 186 enum WindowsVersion { |
166 VERSION_BELOW_XP_SP2, | 187 VERSION_BELOW_XP_SP2, |
167 VERSION_XP_SP2_UP_TO_VISTA, // "but not including" | 188 VERSION_XP_SP2_UP_TO_VISTA, // "but not including" |
168 VERSION_VISTA_OR_HIGHER, | 189 VERSION_VISTA_OR_HIGHER, |
169 }; | 190 }; |
170 WindowsVersion GetWindowsVersion() { | 191 WindowsVersion GetWindowsVersion() { |
171 OSVERSIONINFOEX version_info = { sizeof version_info }; | 192 OSVERSIONINFOEX version_info = { sizeof version_info }; |
172 GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&version_info)); | 193 GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&version_info)); |
173 | 194 |
174 // Windows Vista is version 6.0. | 195 // Windows Vista is version 6.0. |
175 if (version_info.dwMajorVersion >= 6) | 196 if (version_info.dwMajorVersion >= 6) |
176 return VERSION_VISTA_OR_HIGHER; | 197 return VERSION_VISTA_OR_HIGHER; |
177 | 198 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 } | 297 } |
277 delete[] token_user; | 298 delete[] token_user; |
278 } | 299 } |
279 ::CloseHandle(process_token); | 300 ::CloseHandle(process_token); |
280 } | 301 } |
281 ::CloseHandle(process_handle); | 302 ::CloseHandle(process_handle); |
282 return result; | 303 return result; |
283 } | 304 } |
284 } // namespace | 305 } // namespace |
285 | 306 |
286 #pragma comment(linker, "/EXPORT:GoogleChromeCompatibilityCheck=_GoogleChromeCom
patibilityCheck@8,PRIVATE") | 307 BOOL __stdcall GoogleChromeCompatibilityCheck(BOOL set_flag, DWORD* reasons) { |
287 DLLEXPORT BOOL __stdcall GoogleChromeCompatibilityCheck(BOOL set_flag, | |
288 DWORD *reasons) { | |
289 DWORD local_reasons = 0; | 308 DWORD local_reasons = 0; |
290 | 309 |
291 WindowsVersion windows_version = GetWindowsVersion(); | 310 WindowsVersion windows_version = GetWindowsVersion(); |
292 // System requirements? | 311 // System requirements? |
293 if (windows_version == VERSION_BELOW_XP_SP2) | 312 if (windows_version == VERSION_BELOW_XP_SP2) |
294 local_reasons |= GCCC_ERROR_OSNOTSUPPORTED; | 313 local_reasons |= GCCC_ERROR_OSNOTSUPPORTED; |
295 | 314 |
296 if (IsChromeInstalled(HKEY_LOCAL_MACHINE)) | 315 if (IsChromeInstalled(HKEY_LOCAL_MACHINE)) |
297 local_reasons |= GCCC_ERROR_SYSTEMLEVELALREADYPRESENT; | 316 local_reasons |= GCCC_ERROR_SYSTEMLEVELALREADYPRESENT; |
298 | 317 |
(...skipping 13 matching lines...) Expand all Loading... |
312 if (local_reasons == 0 && !CanReOfferChrome(set_flag)) | 331 if (local_reasons == 0 && !CanReOfferChrome(set_flag)) |
313 local_reasons |= GCCC_ERROR_ALREADYOFFERED; | 332 local_reasons |= GCCC_ERROR_ALREADYOFFERED; |
314 | 333 |
315 // Done. Copy/return results. | 334 // Done. Copy/return results. |
316 if (reasons != NULL) | 335 if (reasons != NULL) |
317 *reasons = local_reasons; | 336 *reasons = local_reasons; |
318 | 337 |
319 return (local_reasons == 0); | 338 return (local_reasons == 0); |
320 } | 339 } |
321 | 340 |
322 #pragma comment(linker, "/EXPORT:LaunchGoogleChrome=_LaunchGoogleChrome@0,PRIVAT
E") | 341 BOOL __stdcall LaunchGoogleChrome() { |
323 DLLEXPORT BOOL __stdcall LaunchGoogleChrome() { | |
324 wchar_t launch_cmd[MAX_PATH]; | 342 wchar_t launch_cmd[MAX_PATH]; |
325 size_t size = _countof(launch_cmd); | 343 size_t size = _countof(launch_cmd); |
326 if (!ReadValueFromRegistry(HKEY_LOCAL_MACHINE, kChromeRegClientStateKey, | 344 if (!ReadValueFromRegistry(HKEY_LOCAL_MACHINE, kChromeRegClientStateKey, |
327 kChromeRegLastLaunchCmd, launch_cmd, &size)) { | 345 kChromeRegLastLaunchCmd, launch_cmd, &size)) { |
328 size = _countof(launch_cmd); | 346 size = _countof(launch_cmd); |
329 if (!ReadValueFromRegistry(HKEY_LOCAL_MACHINE, kChromeRegClientStateKey, | 347 if (!ReadValueFromRegistry(HKEY_LOCAL_MACHINE, kChromeRegClientStateKey, |
330 kChromeRegLaunchCmd, launch_cmd, &size)) { | 348 kChromeRegLaunchCmd, launch_cmd, &size)) { |
331 return false; | 349 return false; |
332 } | 350 } |
333 } | 351 } |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 ret = true; | 424 ret = true; |
407 ipl.Release(); | 425 ipl.Release(); |
408 } | 426 } |
409 | 427 |
410 if (impersonation_success) | 428 if (impersonation_success) |
411 ::RevertToSelf(); | 429 ::RevertToSelf(); |
412 ::CoUninitialize(); | 430 ::CoUninitialize(); |
413 return ret; | 431 return ret; |
414 } | 432 } |
415 | 433 |
416 #pragma comment(linker, "/EXPORT:LaunchGoogleChromeWithDimensions=_LaunchGoogleC
hromeWithDimensions@16,PRIVATE") | 434 BOOL __stdcall LaunchGoogleChromeWithDimensions(int x, |
417 DLLEXPORT BOOL __stdcall LaunchGoogleChromeWithDimensions(int x, | 435 int y, |
418 int y, | 436 int width, |
419 int width, | 437 int height) { |
420 int height) { | |
421 if (!LaunchGoogleChrome()) | 438 if (!LaunchGoogleChrome()) |
422 return false; | 439 return false; |
423 | 440 |
424 HWND handle = NULL; | 441 HWND handle = NULL; |
425 int seconds_elapsed = 0; | 442 int seconds_elapsed = 0; |
426 | 443 |
427 // Chrome may have been launched, but the window may not have appeared | 444 // Chrome may have been launched, but the window may not have appeared |
428 // yet. Wait for it to appear for 10 seconds, but exit if it takes longer | 445 // yet. Wait for it to appear for 10 seconds, but exit if it takes longer |
429 // than that. | 446 // than that. |
430 while (!handle && seconds_elapsed < 10) { | 447 while (!handle && seconds_elapsed < 10) { |
(...skipping 13 matching lines...) Expand all Loading... |
444 // This loop iterates through all of the top-level Windows named | 461 // This loop iterates through all of the top-level Windows named |
445 // Chrome_WindowImpl_0, and looks for the first one with any children. | 462 // Chrome_WindowImpl_0, and looks for the first one with any children. |
446 while (handle && !FindWindowEx(handle, NULL, L"Chrome_WindowImpl_0", NULL)) { | 463 while (handle && !FindWindowEx(handle, NULL, L"Chrome_WindowImpl_0", NULL)) { |
447 // Get the next top-level Chrome window. | 464 // Get the next top-level Chrome window. |
448 handle = FindWindowEx(NULL, handle, L"Chrome_WindowImpl_0", NULL); | 465 handle = FindWindowEx(NULL, handle, L"Chrome_WindowImpl_0", NULL); |
449 } | 466 } |
450 | 467 |
451 return (handle && | 468 return (handle && |
452 SetWindowPos(handle, 0, x, y, width, height, SWP_NOZORDER)); | 469 SetWindowPos(handle, 0, x, y, width, height, SWP_NOZORDER)); |
453 } | 470 } |
| 471 |
| 472 int __stdcall GoogleChromeDaysSinceLastRun() { |
| 473 using base::win::RegKey; |
| 474 using base::Time; |
| 475 using base::TimeDelta; |
| 476 |
| 477 int days_since_last_run = std::numeric_limits<int>::max(); |
| 478 |
| 479 struct { |
| 480 HKEY hive; |
| 481 const wchar_t* path; |
| 482 } reg_data[] = { |
| 483 { HKEY_LOCAL_MACHINE, kChromeRegClientStateMediumKey }, |
| 484 { HKEY_CURRENT_USER, kChromeRegClientStateKey } |
| 485 }; |
| 486 |
| 487 for (int i = 0; i < arraysize(reg_data); ++i) { |
| 488 if (IsChromeInstalled(reg_data[i].hive)) { |
| 489 RegKey client_state(reg_data[i].hive, reg_data[i].path, KEY_QUERY_VALUE); |
| 490 if (client_state.Valid()) { |
| 491 std::wstring last_run; |
| 492 int64 last_run_value = 0; |
| 493 if (client_state.ReadValue(google_update::kRegLastRunTimeField, |
| 494 &last_run) == ERROR_SUCCESS && |
| 495 base::StringToInt64(last_run, &last_run_value)) { |
| 496 Time last_run_time = Time::FromInternalValue(last_run_value); |
| 497 TimeDelta difference = Time::NowFromSystemTime() - last_run_time; |
| 498 |
| 499 // We can end up with negative numbers here, given changes in system |
| 500 // clock time or due to TimeDelta's int64 -> int truncation. |
| 501 int new_days_since_last_run = difference.InDays(); |
| 502 if (new_days_since_last_run >= 0 && |
| 503 new_days_since_last_run < days_since_last_run) { |
| 504 days_since_last_run = new_days_since_last_run; |
| 505 } |
| 506 } |
| 507 } |
| 508 } |
| 509 } |
| 510 |
| 511 if (days_since_last_run == std::numeric_limits<int>::max()) { |
| 512 days_since_last_run = -1; |
| 513 } |
| 514 |
| 515 return days_since_last_run; |
| 516 } |
OLD | NEW |