Index: chrome/installer/gcapi/gcapi.cc |
=================================================================== |
--- chrome/installer/gcapi/gcapi.cc (revision 108839) |
+++ chrome/installer/gcapi/gcapi.cc (working copy) |
@@ -2,20 +2,34 @@ |
// 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 <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 +38,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 +88,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 +161,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 +185,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 +304,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 +338,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 +431,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 +468,49 @@ |
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) { |
+ if (IsChromeInstalled(reg_data[i].hive)) { |
+ RegKey client_state(reg_data[i].hive, reg_data[i].path, KEY_QUERY_VALUE); |
+ 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 && |
+ new_days_since_last_run < days_since_last_run) { |
+ 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; |
+} |