Chromium Code Reviews| Index: chrome/installer/gcapi/gcapi.cc |
| =================================================================== |
| --- chrome/installer/gcapi/gcapi.cc (revision 108839) |
| +++ chrome/installer/gcapi/gcapi.cc (working copy) |
| @@ -2,20 +2,35 @@ |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| +// NOTE: This code is a legacy utility API for partners to check whether |
| +// Chrome can be installed and launched. Recent updates are being made |
| +// to add new functionality. These updates use code from Chromium, the old |
| +// coded against the win32 api directly. If you have an itch to shave a |
| +// yak, feel free to re-write the old code too. |
| + |
| #include "chrome/installer/gcapi/gcapi.h" |
| #include <atlbase.h> |
| #include <atlcom.h> |
| -#include <windows.h> |
| #include <sddl.h> |
| #define STRSAFE_NO_DEPRECATE |
| #include <strsafe.h> |
| #include <tlhelp32.h> |
| +#include <windows.h> |
| +#include <algorithm> |
| #include <cstdlib> |
| +#include <limits> |
| +#include <string> |
| -#include "google_update_idl.h" |
| +#include "base/basictypes.h" |
| +#include "base/string_number_conversions.h" |
| +#include "base/time.h" |
| +#include "base/win/registry.h" |
| +#include "chrome/installer/util/google_update_constants.h" |
| +#include "google_update_idl.h" // NOLINT |
| + |
| namespace { |
| const wchar_t kChromeRegClientsKey[] = |
| @@ -24,6 +39,10 @@ |
| const wchar_t kChromeRegClientStateKey[] = |
| L"Software\\Google\\Update\\ClientState\\" |
| L"{8A69D345-D564-463c-AFF1-A69D9E530F96}"; |
| +const wchar_t kChromeRegClientStateMediumKey[] = |
| + L"Software\\Google\\Update\\ClientStateMedium\\" |
| + L"{8A69D345-D564-463c-AFF1-A69D9E530F96}"; |
| + |
| const wchar_t kChromeRegLaunchCmd[] = L"InstallerSuccessLaunchCmdLine"; |
| const wchar_t kChromeRegLastLaunchCmd[] = L"LastInstallerSuccessLaunchCmdLine"; |
| const wchar_t kChromeRegVersion[] = L"pv"; |
| @@ -70,11 +89,14 @@ |
| if (!::VerQueryValue(file_version_info, info_name, |
| reinterpret_cast<LPVOID *>(&data), reinterpret_cast<UINT *>(&data_len))) |
| return false; |
| - if (data_len <= 0 || data_len >= out_len) |
| + if (data_len <= 0 || data_len >= (out_len / sizeof(wchar_t))) |
| return false; |
| memset(buffer, 0, out_len); |
| - ::StringCchCopyN(buffer, out_len, (const wchar_t*)data, data_len); |
| + ::StringCchCopyN(buffer, |
| + (out_len / sizeof(wchar_t)), |
| + reinterpret_cast<const wchar_t*>(data), |
| + data_len); |
| return true; |
| } |
| @@ -140,9 +162,9 @@ |
| // Helper function to read a value from registry. Returns true if value |
| // is read successfully and stored in parameter value. Returns false otherwise. |
| -bool ReadValueFromRegistry(HKEY root_key, const wchar_t *sub_key, |
| - const wchar_t *value_name, wchar_t *value, |
| - size_t *size) { |
| +bool ReadValueFromRegistry(HKEY root_key, const wchar_t* sub_key, |
| + const wchar_t* value_name, wchar_t* value, |
| + size_t* size) { |
| HKEY key; |
| if ((::RegOpenKeyEx(root_key, sub_key, NULL, |
| KEY_READ, &key) == ERROR_SUCCESS) && |
| @@ -164,7 +186,7 @@ |
| enum WindowsVersion { |
| VERSION_BELOW_XP_SP2, |
| - VERSION_XP_SP2_UP_TO_VISTA, // "but not including" |
| + VERSION_XP_SP2_UP_TO_VISTA, // "but not including" |
| VERSION_VISTA_OR_HIGHER, |
| }; |
| WindowsVersion GetWindowsVersion() { |
| @@ -283,9 +305,7 @@ |
| } |
| } // namespace |
| -#pragma comment(linker, "/EXPORT:GoogleChromeCompatibilityCheck=_GoogleChromeCompatibilityCheck@8,PRIVATE") |
| -DLLEXPORT BOOL __stdcall GoogleChromeCompatibilityCheck(BOOL set_flag, |
| - DWORD *reasons) { |
| +BOOL __stdcall GoogleChromeCompatibilityCheck(BOOL set_flag, DWORD* reasons) { |
| DWORD local_reasons = 0; |
| WindowsVersion windows_version = GetWindowsVersion(); |
| @@ -319,8 +339,7 @@ |
| return (local_reasons == 0); |
| } |
| -#pragma comment(linker, "/EXPORT:LaunchGoogleChrome=_LaunchGoogleChrome@0,PRIVATE") |
| -DLLEXPORT BOOL __stdcall LaunchGoogleChrome() { |
| +BOOL __stdcall LaunchGoogleChrome() { |
| wchar_t launch_cmd[MAX_PATH]; |
| size_t size = _countof(launch_cmd); |
| if (!ReadValueFromRegistry(HKEY_LOCAL_MACHINE, kChromeRegClientStateKey, |
| @@ -413,11 +432,10 @@ |
| return ret; |
| } |
| -#pragma comment(linker, "/EXPORT:LaunchGoogleChromeWithDimensions=_LaunchGoogleChromeWithDimensions@16,PRIVATE") |
| -DLLEXPORT BOOL __stdcall LaunchGoogleChromeWithDimensions(int x, |
| - int y, |
| - int width, |
| - int height) { |
| +BOOL __stdcall LaunchGoogleChromeWithDimensions(int x, |
| + int y, |
| + int width, |
| + int height) { |
| if (!LaunchGoogleChrome()) |
| return false; |
| @@ -451,3 +469,47 @@ |
| return (handle && |
| SetWindowPos(handle, 0, x, y, width, height, SWP_NOZORDER)); |
| } |
| + |
| +int __stdcall GoogleChromeDaysSinceLastRun() { |
| + using base::win::RegKey; |
| + using base::Time; |
| + using base::TimeDelta; |
| + |
| + int days_since_last_run = std::numeric_limits<int>::max(); |
| + |
| + struct { |
| + HKEY hive; |
| + const wchar_t* path; |
| + } reg_data[] = { |
| + { HKEY_LOCAL_MACHINE, kChromeRegClientStateMediumKey }, |
| + { HKEY_CURRENT_USER, kChromeRegClientStateKey } |
| + }; |
| + |
| + for (int i = 0; i < arraysize(reg_data); ++i) { |
| + 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.
|
| + if (client_state.Valid()) { |
| + std::wstring last_run; |
| + int64 last_run_value = 0; |
| + if (client_state.ReadValue(google_update::kRegLastRunTimeField, |
| + &last_run) == ERROR_SUCCESS && |
| + base::StringToInt64(last_run, &last_run_value)) { |
| + Time last_run_time = Time::FromInternalValue(last_run_value); |
| + TimeDelta difference = Time::NowFromSystemTime() - last_run_time; |
| + |
| + // We can end up with negative numbers here, given changes in system |
| + // clock time or due to TimeDelta's int64 -> int truncation. |
| + int new_days_since_last_run = difference.InDays(); |
| + 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.
|
| + days_since_last_run = std::min(days_since_last_run, |
| + new_days_since_last_run); |
| + } |
| + } |
| + } |
| + } |
| + |
| + if (days_since_last_run == std::numeric_limits<int>::max()) { |
| + days_since_last_run = -1; |
| + } |
| + |
| + return days_since_last_run; |
| +} |