Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(218)

Side by Side Diff: chrome/installer/gcapi/gcapi.cc

Issue 8508060: Add functionality to the GCAPI to detect when Chrome was last run. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
21 #include <algorithm>
15 #include <cstdlib> 22 #include <cstdlib>
23 #include <limits>
24 #include <string>
16 25
17 #include "google_update_idl.h" 26 #include "base/basictypes.h"
27 #include "base/string_number_conversions.h"
28 #include "base/time.h"
29 #include "base/win/registry.h"
30 #include "chrome/installer/util/google_update_constants.h"
31
32 #include "google_update_idl.h" // NOLINT
18 33
19 namespace { 34 namespace {
20 35
21 const wchar_t kChromeRegClientsKey[] = 36 const wchar_t kChromeRegClientsKey[] =
22 L"Software\\Google\\Update\\Clients\\" 37 L"Software\\Google\\Update\\Clients\\"
23 L"{8A69D345-D564-463c-AFF1-A69D9E530F96}"; 38 L"{8A69D345-D564-463c-AFF1-A69D9E530F96}";
24 const wchar_t kChromeRegClientStateKey[] = 39 const wchar_t kChromeRegClientStateKey[] =
25 L"Software\\Google\\Update\\ClientState\\" 40 L"Software\\Google\\Update\\ClientState\\"
26 L"{8A69D345-D564-463c-AFF1-A69D9E530F96}"; 41 L"{8A69D345-D564-463c-AFF1-A69D9E530F96}";
42 const wchar_t kChromeRegClientStateMediumKey[] =
43 L"Software\\Google\\Update\\ClientStateMedium\\"
44 L"{8A69D345-D564-463c-AFF1-A69D9E530F96}";
45
27 const wchar_t kChromeRegLaunchCmd[] = L"InstallerSuccessLaunchCmdLine"; 46 const wchar_t kChromeRegLaunchCmd[] = L"InstallerSuccessLaunchCmdLine";
28 const wchar_t kChromeRegLastLaunchCmd[] = L"LastInstallerSuccessLaunchCmdLine"; 47 const wchar_t kChromeRegLastLaunchCmd[] = L"LastInstallerSuccessLaunchCmdLine";
29 const wchar_t kChromeRegVersion[] = L"pv"; 48 const wchar_t kChromeRegVersion[] = L"pv";
30 const wchar_t kNoChromeOfferUntil[] = 49 const wchar_t kNoChromeOfferUntil[] =
31 L"SOFTWARE\\Google\\No Chrome Offer Until"; 50 L"SOFTWARE\\Google\\No Chrome Offer Until";
32 51
33 // Return the company name specified in the file version info resource. 52 // Return the company name specified in the file version info resource.
34 bool GetCompanyName(const wchar_t* filename, wchar_t* buffer, DWORD out_len) { 53 bool GetCompanyName(const wchar_t* filename, wchar_t* buffer, DWORD out_len) {
35 wchar_t file_version_info[8192]; 54 wchar_t file_version_info[8192];
36 DWORD handle = 0; 55 DWORD handle = 0;
(...skipping 26 matching lines...) Expand all
63 memcpy(&lang, data, 4); 82 memcpy(&lang, data, 4);
64 ::StringCchPrintf(info_name, _countof(info_name), 83 ::StringCchPrintf(info_name, _countof(info_name),
65 L"\\StringFileInfo\\%02X%02X%02X%02X\\CompanyName", 84 L"\\StringFileInfo\\%02X%02X%02X%02X\\CompanyName",
66 (lang & 0xff00)>>8, (lang & 0xff), (lang & 0xff000000)>>24, 85 (lang & 0xff00)>>8, (lang & 0xff), (lang & 0xff000000)>>24,
67 (lang & 0xff0000)>>16); 86 (lang & 0xff0000)>>16);
68 87
69 data_len = 0; 88 data_len = 0;
70 if (!::VerQueryValue(file_version_info, info_name, 89 if (!::VerQueryValue(file_version_info, info_name,
71 reinterpret_cast<LPVOID *>(&data), reinterpret_cast<UINT *>(&data_len))) 90 reinterpret_cast<LPVOID *>(&data), reinterpret_cast<UINT *>(&data_len)))
72 return false; 91 return false;
73 if (data_len <= 0 || data_len >= out_len) 92 if (data_len <= 0 || data_len >= (out_len / sizeof(wchar_t)))
74 return false; 93 return false;
75 94
76 memset(buffer, 0, out_len); 95 memset(buffer, 0, out_len);
77 ::StringCchCopyN(buffer, out_len, (const wchar_t*)data, data_len); 96 ::StringCchCopyN(buffer,
97 (out_len / sizeof(wchar_t)),
98 reinterpret_cast<const wchar_t*>(data),
99 data_len);
78 return true; 100 return true;
79 } 101 }
80 102
81 // Return true if we can re-offer Chrome; false, otherwise. 103 // Return true if we can re-offer Chrome; false, otherwise.
82 // Each partner can only offer Chrome once every six months. 104 // Each partner can only offer Chrome once every six months.
83 bool CanReOfferChrome(BOOL set_flag) { 105 bool CanReOfferChrome(BOOL set_flag) {
84 wchar_t filename[MAX_PATH+1]; 106 wchar_t filename[MAX_PATH+1];
85 wchar_t company[MAX_PATH]; 107 wchar_t company[MAX_PATH];
86 108
87 // If we cannot retrieve the version info of the executable or company 109 // If we cannot retrieve the version info of the executable or company
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 } 155 }
134 156
135 ::RegCloseKey(key); 157 ::RegCloseKey(key);
136 } 158 }
137 159
138 return can_re_offer; 160 return can_re_offer;
139 } 161 }
140 162
141 // Helper function to read a value from registry. Returns true if value 163 // Helper function to read a value from registry. Returns true if value
142 // is read successfully and stored in parameter value. Returns false otherwise. 164 // is read successfully and stored in parameter value. Returns false otherwise.
143 bool ReadValueFromRegistry(HKEY root_key, const wchar_t *sub_key, 165 bool ReadValueFromRegistry(HKEY root_key, const wchar_t* sub_key,
144 const wchar_t *value_name, wchar_t *value, 166 const wchar_t* value_name, wchar_t* value,
145 size_t *size) { 167 size_t* size) {
146 HKEY key; 168 HKEY key;
147 if ((::RegOpenKeyEx(root_key, sub_key, NULL, 169 if ((::RegOpenKeyEx(root_key, sub_key, NULL,
148 KEY_READ, &key) == ERROR_SUCCESS) && 170 KEY_READ, &key) == ERROR_SUCCESS) &&
149 (::RegQueryValueEx(key, value_name, NULL, NULL, 171 (::RegQueryValueEx(key, value_name, NULL, NULL,
150 reinterpret_cast<LPBYTE>(value), 172 reinterpret_cast<LPBYTE>(value),
151 reinterpret_cast<LPDWORD>(size)) == ERROR_SUCCESS)) { 173 reinterpret_cast<LPDWORD>(size)) == ERROR_SUCCESS)) {
152 ::RegCloseKey(key); 174 ::RegCloseKey(key);
153 return true; 175 return true;
154 } 176 }
155 return false; 177 return false;
156 } 178 }
157 179
158 bool IsChromeInstalled(HKEY root_key) { 180 bool IsChromeInstalled(HKEY root_key) {
159 wchar_t version[64]; 181 wchar_t version[64];
160 size_t size = _countof(version); 182 size_t size = _countof(version);
161 return ReadValueFromRegistry(root_key, kChromeRegClientsKey, 183 return ReadValueFromRegistry(root_key, kChromeRegClientsKey,
162 kChromeRegVersion, version, &size); 184 kChromeRegVersion, version, &size);
163 } 185 }
164 186
165 enum WindowsVersion { 187 enum WindowsVersion {
166 VERSION_BELOW_XP_SP2, 188 VERSION_BELOW_XP_SP2,
167 VERSION_XP_SP2_UP_TO_VISTA, // "but not including" 189 VERSION_XP_SP2_UP_TO_VISTA, // "but not including"
168 VERSION_VISTA_OR_HIGHER, 190 VERSION_VISTA_OR_HIGHER,
169 }; 191 };
170 WindowsVersion GetWindowsVersion() { 192 WindowsVersion GetWindowsVersion() {
171 OSVERSIONINFOEX version_info = { sizeof version_info }; 193 OSVERSIONINFOEX version_info = { sizeof version_info };
172 GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&version_info)); 194 GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&version_info));
173 195
174 // Windows Vista is version 6.0. 196 // Windows Vista is version 6.0.
175 if (version_info.dwMajorVersion >= 6) 197 if (version_info.dwMajorVersion >= 6)
176 return VERSION_VISTA_OR_HIGHER; 198 return VERSION_VISTA_OR_HIGHER;
177 199
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 } 298 }
277 delete[] token_user; 299 delete[] token_user;
278 } 300 }
279 ::CloseHandle(process_token); 301 ::CloseHandle(process_token);
280 } 302 }
281 ::CloseHandle(process_handle); 303 ::CloseHandle(process_handle);
282 return result; 304 return result;
283 } 305 }
284 } // namespace 306 } // namespace
285 307
286 #pragma comment(linker, "/EXPORT:GoogleChromeCompatibilityCheck=_GoogleChromeCom patibilityCheck@8,PRIVATE") 308 BOOL __stdcall GoogleChromeCompatibilityCheck(BOOL set_flag, DWORD* reasons) {
287 DLLEXPORT BOOL __stdcall GoogleChromeCompatibilityCheck(BOOL set_flag,
288 DWORD *reasons) {
289 DWORD local_reasons = 0; 309 DWORD local_reasons = 0;
290 310
291 WindowsVersion windows_version = GetWindowsVersion(); 311 WindowsVersion windows_version = GetWindowsVersion();
292 // System requirements? 312 // System requirements?
293 if (windows_version == VERSION_BELOW_XP_SP2) 313 if (windows_version == VERSION_BELOW_XP_SP2)
294 local_reasons |= GCCC_ERROR_OSNOTSUPPORTED; 314 local_reasons |= GCCC_ERROR_OSNOTSUPPORTED;
295 315
296 if (IsChromeInstalled(HKEY_LOCAL_MACHINE)) 316 if (IsChromeInstalled(HKEY_LOCAL_MACHINE))
297 local_reasons |= GCCC_ERROR_SYSTEMLEVELALREADYPRESENT; 317 local_reasons |= GCCC_ERROR_SYSTEMLEVELALREADYPRESENT;
298 318
(...skipping 13 matching lines...) Expand all
312 if (local_reasons == 0 && !CanReOfferChrome(set_flag)) 332 if (local_reasons == 0 && !CanReOfferChrome(set_flag))
313 local_reasons |= GCCC_ERROR_ALREADYOFFERED; 333 local_reasons |= GCCC_ERROR_ALREADYOFFERED;
314 334
315 // Done. Copy/return results. 335 // Done. Copy/return results.
316 if (reasons != NULL) 336 if (reasons != NULL)
317 *reasons = local_reasons; 337 *reasons = local_reasons;
318 338
319 return (local_reasons == 0); 339 return (local_reasons == 0);
320 } 340 }
321 341
322 #pragma comment(linker, "/EXPORT:LaunchGoogleChrome=_LaunchGoogleChrome@0,PRIVAT E") 342 BOOL __stdcall LaunchGoogleChrome() {
323 DLLEXPORT BOOL __stdcall LaunchGoogleChrome() {
324 wchar_t launch_cmd[MAX_PATH]; 343 wchar_t launch_cmd[MAX_PATH];
325 size_t size = _countof(launch_cmd); 344 size_t size = _countof(launch_cmd);
326 if (!ReadValueFromRegistry(HKEY_LOCAL_MACHINE, kChromeRegClientStateKey, 345 if (!ReadValueFromRegistry(HKEY_LOCAL_MACHINE, kChromeRegClientStateKey,
327 kChromeRegLastLaunchCmd, launch_cmd, &size)) { 346 kChromeRegLastLaunchCmd, launch_cmd, &size)) {
328 size = _countof(launch_cmd); 347 size = _countof(launch_cmd);
329 if (!ReadValueFromRegistry(HKEY_LOCAL_MACHINE, kChromeRegClientStateKey, 348 if (!ReadValueFromRegistry(HKEY_LOCAL_MACHINE, kChromeRegClientStateKey,
330 kChromeRegLaunchCmd, launch_cmd, &size)) { 349 kChromeRegLaunchCmd, launch_cmd, &size)) {
331 return false; 350 return false;
332 } 351 }
333 } 352 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 ret = true; 425 ret = true;
407 ipl.Release(); 426 ipl.Release();
408 } 427 }
409 428
410 if (impersonation_success) 429 if (impersonation_success)
411 ::RevertToSelf(); 430 ::RevertToSelf();
412 ::CoUninitialize(); 431 ::CoUninitialize();
413 return ret; 432 return ret;
414 } 433 }
415 434
416 #pragma comment(linker, "/EXPORT:LaunchGoogleChromeWithDimensions=_LaunchGoogleC hromeWithDimensions@16,PRIVATE") 435 BOOL __stdcall LaunchGoogleChromeWithDimensions(int x,
417 DLLEXPORT BOOL __stdcall LaunchGoogleChromeWithDimensions(int x, 436 int y,
418 int y, 437 int width,
419 int width, 438 int height) {
420 int height) {
421 if (!LaunchGoogleChrome()) 439 if (!LaunchGoogleChrome())
422 return false; 440 return false;
423 441
424 HWND handle = NULL; 442 HWND handle = NULL;
425 int seconds_elapsed = 0; 443 int seconds_elapsed = 0;
426 444
427 // Chrome may have been launched, but the window may not have appeared 445 // 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 446 // yet. Wait for it to appear for 10 seconds, but exit if it takes longer
429 // than that. 447 // than that.
430 while (!handle && seconds_elapsed < 10) { 448 while (!handle && seconds_elapsed < 10) {
(...skipping 13 matching lines...) Expand all
444 // This loop iterates through all of the top-level Windows named 462 // This loop iterates through all of the top-level Windows named
445 // Chrome_WindowImpl_0, and looks for the first one with any children. 463 // Chrome_WindowImpl_0, and looks for the first one with any children.
446 while (handle && !FindWindowEx(handle, NULL, L"Chrome_WindowImpl_0", NULL)) { 464 while (handle && !FindWindowEx(handle, NULL, L"Chrome_WindowImpl_0", NULL)) {
447 // Get the next top-level Chrome window. 465 // Get the next top-level Chrome window.
448 handle = FindWindowEx(NULL, handle, L"Chrome_WindowImpl_0", NULL); 466 handle = FindWindowEx(NULL, handle, L"Chrome_WindowImpl_0", NULL);
449 } 467 }
450 468
451 return (handle && 469 return (handle &&
452 SetWindowPos(handle, 0, x, y, width, height, SWP_NOZORDER)); 470 SetWindowPos(handle, 0, x, y, width, height, SWP_NOZORDER));
453 } 471 }
472
473 int __stdcall GoogleChromeDaysSinceLastRun() {
474 using base::win::RegKey;
475 using base::Time;
476 using base::TimeDelta;
477
478 int days_since_last_run = std::numeric_limits<int>::max();
479
480 struct {
481 HKEY hive;
482 const wchar_t* path;
483 } reg_data[] = {
484 { HKEY_LOCAL_MACHINE, kChromeRegClientStateMediumKey },
485 { HKEY_CURRENT_USER, kChromeRegClientStateKey }
486 };
487
488 for (int i = 0; i < arraysize(reg_data); ++i) {
489 RegKey client_state(reg_data[i].hive, reg_data[i].path, KEY_QUERY_VALUE);
grt (UTC plus 2) 2011/11/14 14:24:09 i think this is prone to flakiness since it doesn'
robertshield 2011/11/14 15:13:49 Done.
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) {
grt (UTC plus 2) 2011/11/14 14:24:09 heh. now that you need this check anyway, i'd get
robertshield 2011/11/14 15:13:49 Done.
503 days_since_last_run = std::min(days_since_last_run,
504 new_days_since_last_run);
505 }
506 }
507 }
508 }
509
510 if (days_since_last_run == std::numeric_limits<int>::max()) {
511 days_since_last_run = -1;
512 }
513
514 return days_since_last_run;
515 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698