// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// 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 <sddl.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#define STRSAFE_NO_DEPRECATE
#include <windows.h>
#include <objbase.h>
#include <strsafe.h>
#include <tlhelp32.h>
#include <wrl/client.h>

#include <cstdlib>
#include <iterator>
#include <limits>
#include <set>
#include <string>

#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/process/launch.h"
#include "base/stl_util.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/time/time.h"
#include "base/win/registry.h"
#include "base/win/scoped_com_initializer.h"
#include "base/win/scoped_handle.h"
#include "base/win/wmi.h"
#include "chrome/installer/gcapi/gcapi_omaha_experiment.h"
#include "chrome/installer/gcapi/gcapi_reactivation.h"
#include "chrome/installer/gcapi/google_update_util.h"
#include "chrome/installer/launcher_support/chrome_launcher_support.h"
#include "chrome/installer/util/google_update_constants.h"
#include "chrome/installer/util/util_constants.h"
#include "google_update/google_update_idl.h"

using Microsoft::WRL::ComPtr;
using base::Time;
using base::TimeDelta;
using base::win::RegKey;
using base::win::ScopedCOMInitializer;
using base::win::ScopedHandle;

namespace {

const wchar_t kGCAPITempKey[] = L"Software\\Google\\GCAPITemp";

const wchar_t kChromeRegVersion[] = L"pv";
const wchar_t kNoChromeOfferUntil[] =
    L"SOFTWARE\\Google\\No Chrome Offer Until";

const wchar_t kC1FPendingKey[] =
    L"Software\\Google\\Common\\Rlz\\Events\\C";
const wchar_t kC1FSentKey[] =
    L"Software\\Google\\Common\\Rlz\\StatefulEvents\\C";
const wchar_t kC1FKey[] = L"C1F";

const wchar_t kRelaunchBrandcodeValue[] = L"RelaunchBrandcode";
const wchar_t kRelaunchAllowedAfterValue[] = L"RelaunchAllowedAfter";

// Prefix used to match the window class for Chrome windows.
const wchar_t kChromeWindowClassPrefix[] = L"Chrome_WidgetWin_";

// Return the company name specified in the file version info resource.
bool GetCompanyName(const wchar_t* filename, wchar_t* buffer, DWORD out_len) {
  wchar_t file_version_info[8192];
  DWORD handle = 0;
  DWORD buffer_size = 0;

  buffer_size = ::GetFileVersionInfoSize(filename, &handle);
  // Cannot stats the file or our buffer size is too small (very unlikely).
  if (buffer_size == 0 || buffer_size > _countof(file_version_info))
    return false;

  buffer_size = _countof(file_version_info);
  memset(file_version_info, 0, buffer_size);
  if (!::GetFileVersionInfo(filename, handle, buffer_size, file_version_info))
    return false;

  DWORD data_len = 0;
  LPVOID data = NULL;
  // Retrieve the language and codepage code if exists.
  buffer_size = 0;
  if (!::VerQueryValue(file_version_info, TEXT("\\VarFileInfo\\Translation"),
      reinterpret_cast<LPVOID *>(&data), reinterpret_cast<UINT *>(&data_len)))
    return false;
  if (data_len != 4)
    return false;

  wchar_t info_name[256];
  DWORD lang = 0;
  // Formulate the string to retrieve the company name of the specific
  // language codepage.
  memcpy(&lang, data, 4);
  ::StringCchPrintf(info_name, _countof(info_name),
      L"\\StringFileInfo\\%02X%02X%02X%02X\\CompanyName",
      (lang & 0xff00)>>8, (lang & 0xff), (lang & 0xff000000)>>24,
      (lang & 0xff0000)>>16);

  data_len = 0;
  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 / sizeof(wchar_t)))
    return false;

  memset(buffer, 0, out_len);
  ::StringCchCopyN(buffer,
                   (out_len / sizeof(wchar_t)),
                   reinterpret_cast<const wchar_t*>(data),
                   data_len);
  return true;
}

// Offsets the current date by |months|. |months| must be between 0 and 12.
// The returned date is in the YYYYMMDD format.
DWORD FormatDateOffsetByMonths(int months) {
  DCHECK(months >= 0 && months <= 12);

  SYSTEMTIME now;
  GetLocalTime(&now);
  now.wMonth += months;
  if (now.wMonth > 12) {
    now.wMonth -= 12;
    now.wYear += 1;
  }

  return now.wYear * 10000 + now.wMonth * 100 + now.wDay;
}

// Return true if we can re-offer Chrome; false, otherwise.
// Each partner can only offer Chrome once every six months.
bool CanReOfferChrome(BOOL set_flag) {
  wchar_t filename[MAX_PATH+1];
  wchar_t company[MAX_PATH];

  // If we cannot retrieve the version info of the executable or company
  // name, we allow the Chrome to be offered because there is no past
  // history to be found.
  if (::GetModuleFileName(NULL, filename, MAX_PATH) == 0)
    return true;
  if (!GetCompanyName(filename, company, sizeof(company)))
    return true;

  bool can_re_offer = true;
  DWORD disposition = 0;
  HKEY key = NULL;
  if (::RegCreateKeyEx(HKEY_LOCAL_MACHINE, kNoChromeOfferUntil,
      0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE,
      NULL, &key, &disposition) == ERROR_SUCCESS) {
    // Get today's date, and format it as YYYYMMDD numeric value.
    DWORD today = FormatDateOffsetByMonths(0);

    // Cannot re-offer, if the timer already exists and is not expired yet.
    DWORD value_type = REG_DWORD;
    DWORD value_data = 0;
    DWORD value_length = sizeof(DWORD);
    if (::RegQueryValueEx(key, company, 0, &value_type,
                          reinterpret_cast<LPBYTE>(&value_data),
                          &value_length) == ERROR_SUCCESS &&
        REG_DWORD == value_type &&
        value_data > today) {
      // The time has not expired, we cannot offer Chrome.
      can_re_offer = false;
    } else {
      // Delete the old or invalid value.
      ::RegDeleteValue(key, company);
      if (set_flag) {
        // Set expiration date for offer as six months from today,
        // represented as a YYYYMMDD numeric value.
        DWORD value = FormatDateOffsetByMonths(6);
        ::RegSetValueEx(key, company, 0, REG_DWORD, (LPBYTE)&value,
                        sizeof(DWORD));
      }
    }

    ::RegCloseKey(key);
  }

  return can_re_offer;
}

bool IsChromeInstalled(HKEY root_key) {
  RegKey key;
  return key.Open(root_key, gcapi_internals::kChromeRegClientsKey,
                  KEY_READ | KEY_WOW64_32KEY) == ERROR_SUCCESS &&
         key.HasValue(kChromeRegVersion);
}

// Returns true if the |subkey| in |root| has the kC1FKey entry set to 1.
bool RegKeyHasC1F(HKEY root, const wchar_t* subkey) {
  RegKey key;
  DWORD value;
  return key.Open(root, subkey, KEY_READ | KEY_WOW64_32KEY) == ERROR_SUCCESS &&
      key.ReadValueDW(kC1FKey, &value) == ERROR_SUCCESS &&
      value == static_cast<DWORD>(1);
}

bool IsC1FSent() {
  // The C1F RLZ key can either be in HKCU or in HKLM (the HKLM RLZ key is made
  // readable to all-users via rlz_lib::CreateMachineState()) and can either be
  // in sent or pending state. Return true if there is a match for any of these
  // 4 states.
  return RegKeyHasC1F(HKEY_CURRENT_USER, kC1FSentKey) ||
      RegKeyHasC1F(HKEY_CURRENT_USER, kC1FPendingKey) ||
      RegKeyHasC1F(HKEY_LOCAL_MACHINE, kC1FSentKey) ||
      RegKeyHasC1F(HKEY_LOCAL_MACHINE, kC1FPendingKey);
}

bool IsWindowsVersionSupported() {
  OSVERSIONINFOEX version_info = { sizeof version_info };
  GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&version_info));

  // Windows 7 is version 6.1.
  if (version_info.dwMajorVersion > 6 ||
      (version_info.dwMajorVersion == 6 && version_info.dwMinorVersion > 0))
    return true;

  return false;
}

// Note this function should not be called on old Windows versions where these
// Windows API are not available. We always invoke this function after checking
// that current OS is Vista or later.
bool VerifyAdminGroup() {
  SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
  PSID Group;
  BOOL check = ::AllocateAndInitializeSid(&NtAuthority, 2,
                                          SECURITY_BUILTIN_DOMAIN_RID,
                                          DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0,
                                          0, 0, 0,
                                          &Group);
  if (check) {
    if (!::CheckTokenMembership(NULL, Group, &check))
      check = FALSE;
  }
  ::FreeSid(Group);
  return (check == TRUE);
}

bool VerifyHKLMAccess() {
  wchar_t str[] = L"test";
  bool result = false;
  DWORD disposition = 0;
  HKEY key = NULL;

  if (::RegCreateKeyEx(HKEY_LOCAL_MACHINE, kGCAPITempKey, 0, NULL,
                       REG_OPTION_NON_VOLATILE,
                       KEY_READ | KEY_WRITE | KEY_WOW64_32KEY, NULL,
                       &key, &disposition) == ERROR_SUCCESS) {
    if (::RegSetValueEx(key, str, 0, REG_SZ, (LPBYTE)str,
        (DWORD)lstrlen(str)) == ERROR_SUCCESS) {
      result = true;
      RegDeleteValue(key, str);
    }

    RegCloseKey(key);

    //  If we create the main key, delete the entire key.
    if (disposition == REG_CREATED_NEW_KEY)
      RegDeleteKey(HKEY_LOCAL_MACHINE, kGCAPITempKey);
  }

  return result;
}

bool IsRunningElevated() {
  // This method should be called only for Vista or later.
  if (!IsWindowsVersionSupported() || !VerifyAdminGroup())
    return false;

  HANDLE process_token;
  if (!::OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &process_token))
    return false;

  TOKEN_ELEVATION_TYPE elevation_type = TokenElevationTypeDefault;
  DWORD size_returned = 0;
  if (!::GetTokenInformation(process_token, TokenElevationType,
                             &elevation_type, sizeof(elevation_type),
                             &size_returned)) {
    ::CloseHandle(process_token);
    return false;
  }

  ::CloseHandle(process_token);
  return (elevation_type == TokenElevationTypeFull);
}

bool GetUserIdForProcess(size_t pid, wchar_t** user_sid) {
  HANDLE process_handle =
      ::OpenProcess(PROCESS_QUERY_INFORMATION, TRUE, static_cast<DWORD>(pid));
  if (process_handle == NULL)
    return false;

  HANDLE process_token;
  bool result = false;
  if (::OpenProcessToken(process_handle, TOKEN_QUERY, &process_token)) {
    DWORD size = 0;
    ::GetTokenInformation(process_token, TokenUser, NULL, 0, &size);
    if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
        ::GetLastError() == ERROR_SUCCESS) {
      DWORD actual_size = 0;
      BYTE* token_user = new BYTE[size];
      if ((::GetTokenInformation(process_token, TokenUser, token_user, size,
                                &actual_size)) &&
          (actual_size <= size)) {
        PSID sid = reinterpret_cast<TOKEN_USER*>(token_user)->User.Sid;
        if (::ConvertSidToStringSid(sid, user_sid))
          result = true;
      }
      delete[] token_user;
    }
    ::CloseHandle(process_token);
  }
  ::CloseHandle(process_handle);
  return result;
}

struct SetWindowPosParams {
  int x;
  int y;
  int width;
  int height;
  DWORD flags;
  HWND window_insert_after;
  bool success;
  std::set<HWND> shunted_hwnds;
};

BOOL CALLBACK ChromeWindowEnumProc(HWND hwnd, LPARAM lparam) {
  wchar_t window_class[MAX_PATH] = {};
  SetWindowPosParams* params = reinterpret_cast<SetWindowPosParams*>(lparam);

  if (!params->shunted_hwnds.count(hwnd) &&
      ::GetClassName(hwnd, window_class, base::size(window_class)) &&
      base::StartsWith(window_class, kChromeWindowClassPrefix,
                       base::CompareCase::INSENSITIVE_ASCII) &&
      ::SetWindowPos(hwnd, params->window_insert_after, params->x, params->y,
                     params->width, params->height, params->flags)) {
    params->shunted_hwnds.insert(hwnd);
    params->success = true;
  }

  // Return TRUE to ensure we hit all possible top-level Chrome windows as per
  // http://msdn.microsoft.com/en-us/library/windows/desktop/ms633498.aspx
  return TRUE;
}

// Returns true and populates |chrome_exe_path| with the path to chrome.exe if
// a valid installation can be found.
bool GetGoogleChromePath(base::FilePath* chrome_exe_path) {
  HKEY install_key = HKEY_LOCAL_MACHINE;
  if (!IsChromeInstalled(install_key)) {
    install_key = HKEY_CURRENT_USER;
    if (!IsChromeInstalled(install_key)) {
      return false;
    }
  }

  // Now grab the uninstall string from the appropriate ClientState key
  // and use that as the base for a path to chrome.exe.
  *chrome_exe_path = chrome_launcher_support::GetChromePathForInstallationLevel(
      install_key == HKEY_LOCAL_MACHINE
          ? chrome_launcher_support::SYSTEM_LEVEL_INSTALLATION
          : chrome_launcher_support::USER_LEVEL_INSTALLATION,
      false /* is_sxs */);
  return !chrome_exe_path->empty();
}

}  // namespace

BOOL __stdcall GoogleChromeCompatibilityCheck(BOOL set_flag,
                                              int shell_mode,
                                              DWORD* reasons) {
  DWORD local_reasons = 0;

  bool is_windows_version_supported = IsWindowsVersionSupported();
  // System requirements?
  if (!is_windows_version_supported)
    local_reasons |= GCCC_ERROR_OSNOTSUPPORTED;

  if (IsChromeInstalled(HKEY_LOCAL_MACHINE))
    local_reasons |= GCCC_ERROR_SYSTEMLEVELALREADYPRESENT;

  if (IsChromeInstalled(HKEY_CURRENT_USER))
    local_reasons |= GCCC_ERROR_USERLEVELALREADYPRESENT;

  if (shell_mode == GCAPI_INVOKED_UAC_ELEVATION) {
    // Only check that we have HKLM write permissions if we specify that
    // GCAPI is being invoked from an elevated shell, or in admin mode
    if (!VerifyHKLMAccess()) {
    local_reasons |= GCCC_ERROR_ACCESSDENIED;
    } else if (is_windows_version_supported && !VerifyAdminGroup()) {
      // For Vista or later check for elevation since even for admin user we
      // could be running in non-elevated mode. We require integrity level High.
      local_reasons |= GCCC_ERROR_INTEGRITYLEVEL;
    }
  }

  // Then only check whether we can re-offer, if everything else is OK.
  if (local_reasons == 0 && !CanReOfferChrome(set_flag))
    local_reasons |= GCCC_ERROR_ALREADYOFFERED;

  // Done. Copy/return results.
  if (reasons != NULL)
    *reasons = local_reasons;

  return (local_reasons == 0);
}

BOOL __stdcall LaunchGoogleChrome() {
  base::FilePath chrome_exe_path;
  if (!GetGoogleChromePath(&chrome_exe_path))
    return false;

  ScopedCOMInitializer com_initializer;
  if (::CoInitializeSecurity(NULL, -1, NULL, NULL,
                             RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
                             RPC_C_IMP_LEVEL_IDENTIFY, NULL,
                             EOAC_DYNAMIC_CLOAKING, NULL) != S_OK) {
    return false;
  }

  bool impersonation_success = false;
  if (IsRunningElevated()) {
    wchar_t* curr_proc_sid;
    if (!GetUserIdForProcess(GetCurrentProcessId(), &curr_proc_sid)) {
      return false;
    }

    DWORD pid = 0;
    ::GetWindowThreadProcessId(::GetShellWindow(), &pid);
    if (pid <= 0) {
      ::LocalFree(curr_proc_sid);
      return false;
    }

    wchar_t* exp_proc_sid;
    if (GetUserIdForProcess(pid, &exp_proc_sid)) {
      if (_wcsicmp(curr_proc_sid, exp_proc_sid) == 0) {
        ScopedHandle process_handle(
            ::OpenProcess(PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION,
                          TRUE,
                          pid));
        if (process_handle.IsValid()) {
          HANDLE process_token = NULL;
          HANDLE user_token = NULL;
          if (::OpenProcessToken(process_handle.Get(),
                                 TOKEN_DUPLICATE | TOKEN_QUERY,
                                 &process_token) &&
              ::DuplicateTokenEx(process_token,
                                 TOKEN_IMPERSONATE | TOKEN_QUERY |
                                     TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE,
                                 NULL, SecurityImpersonation,
                                 TokenPrimary, &user_token) &&
              (::ImpersonateLoggedOnUser(user_token) != 0)) {
            impersonation_success = true;
          }
          if (user_token)
            ::CloseHandle(user_token);
          if (process_token)
            ::CloseHandle(process_token);
        }
      }
      ::LocalFree(exp_proc_sid);
    }

    ::LocalFree(curr_proc_sid);
    if (!impersonation_success) {
      return false;
    }
  }

  base::CommandLine chrome_command(chrome_exe_path);

  bool ret = false;
  ComPtr<IProcessLauncher> ipl;
  if (SUCCEEDED(::CoCreateInstance(__uuidof(ProcessLauncherClass), NULL,
                                   CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&ipl)))) {
    if (SUCCEEDED(ipl->LaunchCmdLine(
            chrome_command.GetCommandLineString().c_str())))
      ret = true;
    ipl.Reset();
  } else {
    // Couldn't get Omaha's process launcher, Omaha may not be installed at
    // system level. Try just running Chrome instead.
    ret = base::LaunchProcess(chrome_command.GetCommandLineString(),
                              base::LaunchOptions()).IsValid();
  }

  if (impersonation_success)
    ::RevertToSelf();
  return ret;
}

BOOL __stdcall LaunchGoogleChromeWithDimensions(int x,
                                                int y,
                                                int width,
                                                int height,
                                                bool in_background) {
  if (in_background) {
    base::FilePath chrome_exe_path;
    if (!GetGoogleChromePath(&chrome_exe_path))
      return false;

    // When launching in the background, use WMI to ensure that chrome.exe is
    // is not our child process. This prevents it from pushing itself to
    // foreground.
    base::CommandLine chrome_command(chrome_exe_path);

    ScopedCOMInitializer com_initializer;
    if (!base::win::WmiLaunchProcess(chrome_command.GetCommandLineString(),
                                     NULL)) {
      // For some reason WMI failed. Try and launch the old fashioned way,
      // knowing that visual glitches will occur when the window pops up.
      if (!LaunchGoogleChrome())
        return false;
    }

  } else {
    if (!LaunchGoogleChrome())
      return false;
  }

  HWND hwnd_insert_after = in_background ? HWND_BOTTOM : NULL;
  DWORD set_window_flags = in_background ? SWP_NOACTIVATE : SWP_NOZORDER;

  if (x == -1 && y == -1)
    set_window_flags |= SWP_NOMOVE;

  if (width == -1 && height == -1)
    set_window_flags |= SWP_NOSIZE;

  SetWindowPosParams enum_params = { x, y, width, height, set_window_flags,
                                     hwnd_insert_after, false };

  // Chrome may have been launched, but the window may not have appeared
  // yet. Wait for it to appear for 10 seconds, but exit if it takes longer
  // than that.
  int ms_elapsed = 0;
  int timeout = 10000;
  bool found_window = false;
  while (ms_elapsed < timeout) {
    // Enum all top-level windows looking for Chrome windows.
    ::EnumWindows(ChromeWindowEnumProc, reinterpret_cast<LPARAM>(&enum_params));

    // Give it five more seconds after finding the first window until we stop
    // shoving new windows into the background.
    if (!found_window && enum_params.success) {
      found_window = true;
      timeout = ms_elapsed + 5000;
    }

    Sleep(10);
    ms_elapsed += 10;
  }

  return found_window;
}

BOOL __stdcall LaunchGoogleChromeInBackground() {
  return LaunchGoogleChromeWithDimensions(-1, -1, -1, -1, true);
}

int __stdcall GoogleChromeDaysSinceLastRun() {
  int days_since_last_run = std::numeric_limits<int>::max();

  if (IsChromeInstalled(HKEY_LOCAL_MACHINE) ||
      IsChromeInstalled(HKEY_CURRENT_USER)) {
    RegKey client_state(HKEY_CURRENT_USER,
                        gcapi_internals::kChromeRegClientStateKey,
                        KEY_QUERY_VALUE | KEY_WOW64_32KEY);
    if (client_state.Valid()) {
      base::string16 last_run;
      int64_t 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_t -> 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;
}

BOOL __stdcall CanOfferReactivation(const wchar_t* brand_code,
                                    int shell_mode,
                                    DWORD* error_code) {
  DCHECK(error_code);

  if (!brand_code) {
    if (error_code)
      *error_code = REACTIVATE_ERROR_INVALID_INPUT;
    return FALSE;
  }

  int days_since_last_run = GoogleChromeDaysSinceLastRun();
  if (days_since_last_run >= 0 &&
      days_since_last_run < kReactivationMinDaysDormant) {
    if (error_code)
      *error_code = REACTIVATE_ERROR_NOTDORMANT;
    return FALSE;
  }

  // Only run the code below when this function is invoked from a standard,
  // non-elevated cmd shell.  This is because this section of code looks at
  // values in HKEY_CURRENT_USER, and we only want to look at the logged-in
  // user's HKCU, not the admin user's HKCU.
  if (shell_mode == GCAPI_INVOKED_STANDARD_SHELL) {
    if (!IsChromeInstalled(HKEY_LOCAL_MACHINE) &&
        !IsChromeInstalled(HKEY_CURRENT_USER)) {
      if (error_code)
        *error_code = REACTIVATE_ERROR_NOTINSTALLED;
      return FALSE;
    }

    if (HasBeenReactivated()) {
      if (error_code)
        *error_code = REACTIVATE_ERROR_ALREADY_REACTIVATED;
      return FALSE;
    }
  }

  return TRUE;
}

BOOL __stdcall ReactivateChrome(const wchar_t* brand_code,
                                int shell_mode,
                                DWORD* error_code) {
  BOOL result = FALSE;
  if (CanOfferReactivation(brand_code,
                           shell_mode,
                           error_code)) {
    if (SetReactivationBrandCode(brand_code, shell_mode)) {
      // Currently set this as a best-effort thing. We return TRUE if
      // reactivation succeeded regardless of the experiment label result.
      SetReactivationExperimentLabels(brand_code, shell_mode);

      result = TRUE;
    } else {
      if (error_code)
        *error_code = REACTIVATE_ERROR_REACTIVATION_FAILED;
    }
  }

  return result;
}

BOOL __stdcall CanOfferRelaunch(const wchar_t** partner_brandcode_list,
                                int partner_brandcode_list_length,
                                int shell_mode,
                                DWORD* error_code) {
  DCHECK(error_code);

  if (!partner_brandcode_list || partner_brandcode_list_length <= 0) {
    if (error_code)
      *error_code = RELAUNCH_ERROR_INVALID_INPUT;
    return FALSE;
  }

  // These conditions need to be satisfied for relaunch:
  // a) Chrome should be installed;
  if (!IsChromeInstalled(HKEY_LOCAL_MACHINE) &&
      (shell_mode != GCAPI_INVOKED_STANDARD_SHELL ||
          !IsChromeInstalled(HKEY_CURRENT_USER))) {
    if (error_code)
      *error_code = RELAUNCH_ERROR_NOTINSTALLED;
    return FALSE;
  }

  // b) the installed brandcode should belong to that partner (in
  // brandcode_list);
  base::string16 installed_brandcode;
  bool valid_brandcode = false;
  if (gcapi_internals::GetBrand(&installed_brandcode)) {
    for (int i = 0; i < partner_brandcode_list_length; ++i) {
      if (!_wcsicmp(installed_brandcode.c_str(), partner_brandcode_list[i])) {
        valid_brandcode = true;
        break;
      }
    }
  }

  if (!valid_brandcode) {
    if (error_code)
      *error_code = RELAUNCH_ERROR_INVALID_PARTNER;
    return FALSE;
  }

  // c) C1F ping should not have been sent;
  if (IsC1FSent()) {
    if (error_code)
      *error_code = RELAUNCH_ERROR_PINGS_SENT;
    return FALSE;
  }

  // d) a minimum period (30 days) must have passed since Chrome was last used;
  int days_since_last_run = GoogleChromeDaysSinceLastRun();
  if (days_since_last_run >= 0 &&
      days_since_last_run < kRelaunchMinDaysDormant) {
    if (error_code)
      *error_code = RELAUNCH_ERROR_NOTDORMANT;
    return FALSE;
  }

  // e) a minimum period (6 months) must have passed since the previous
  // relaunch offer for the current user;
  RegKey key;
  DWORD min_relaunch_date;
  if (key.Open(HKEY_CURRENT_USER, gcapi_internals::kChromeRegClientStateKey,
               KEY_QUERY_VALUE | KEY_WOW64_32KEY) == ERROR_SUCCESS &&
      key.ReadValueDW(kRelaunchAllowedAfterValue, &min_relaunch_date) ==
          ERROR_SUCCESS &&
      FormatDateOffsetByMonths(0) < min_relaunch_date) {
    if (error_code)
      *error_code = RELAUNCH_ERROR_ALREADY_RELAUNCHED;
    return FALSE;
  }

  return TRUE;
}

BOOL __stdcall SetRelaunchOffered(const wchar_t** partner_brandcode_list,
                                  int partner_brandcode_list_length,
                                  const wchar_t* relaunch_brandcode,
                                  int shell_mode,
                                  DWORD* error_code) {
  if (!CanOfferRelaunch(partner_brandcode_list, partner_brandcode_list_length,
                        shell_mode, error_code))
    return FALSE;

  // Store the relaunched brand code and the minimum date for relaunch (6 months
  // from now), and set the Omaha experiment label.
  RegKey key;
  if (key.Create(HKEY_CURRENT_USER, gcapi_internals::kChromeRegClientStateKey,
                 KEY_SET_VALUE | KEY_WOW64_32KEY) != ERROR_SUCCESS ||
      key.WriteValue(kRelaunchBrandcodeValue, relaunch_brandcode) !=
          ERROR_SUCCESS ||
      key.WriteValue(kRelaunchAllowedAfterValue, FormatDateOffsetByMonths(6)) !=
          ERROR_SUCCESS ||
      !SetRelaunchExperimentLabels(relaunch_brandcode, shell_mode)) {
    if (error_code)
      *error_code = RELAUNCH_ERROR_RELAUNCH_FAILED;
    return FALSE;
  }

  return TRUE;
}
