| Index: chrome/browser/safe_browsing/incident_reporting/platform_state_store_win.cc
|
| diff --git a/chrome/browser/safe_browsing/incident_reporting/platform_state_store_win.cc b/chrome/browser/safe_browsing/incident_reporting/platform_state_store_win.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..da2e2f50a5cb63d79462e4ea9d2f8865805fc4b1
|
| --- /dev/null
|
| +++ b/chrome/browser/safe_browsing/incident_reporting/platform_state_store_win.cc
|
| @@ -0,0 +1,103 @@
|
| +// Copyright 2015 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.
|
| +
|
| +// State is stored in the Windows registry in a value of the key
|
| +// HKEY_CURRENT_USER\Software\<browser>\IncidentsSent for each profile. The
|
| +// value names are profile directory BaseNames.
|
| +
|
| +#include "chrome/browser/safe_browsing/incident_reporting/platform_state_store.h"
|
| +
|
| +#include <windows.h>
|
| +
|
| +#include "base/numerics/safe_conversions.h"
|
| +#include "base/win/registry.h"
|
| +#include "chrome/browser/profiles/profile.h"
|
| +#include "chrome/installer/util/browser_distribution.h"
|
| +
|
| +namespace safe_browsing {
|
| +namespace platform_state_store {
|
| +
|
| +namespace {
|
| +
|
| +// Returns the path to the registry key holding profile-specific state values.
|
| +base::string16 GetStateStoreKeyName() {
|
| + base::string16 key_name(L"Software\\");
|
| + return key_name.append(
|
| + BrowserDistribution::GetDistribution()->GetInstallSubDir())
|
| + .append(L"\\IncidentsSent");
|
| +}
|
| +
|
| +// Returns the name of the registry value for |profile|'s state.
|
| +base::string16 GetValueNameForProfile(Profile* profile) {
|
| + return profile->GetPath().BaseName().value();
|
| +}
|
| +
|
| +// Clears |profile|'s state.
|
| +PlatformStateStoreLoadResult ClearStoreData(Profile* profile) {
|
| + base::win::RegKey key;
|
| +
|
| + if (key.Open(HKEY_CURRENT_USER, GetStateStoreKeyName().c_str(),
|
| + KEY_QUERY_VALUE | KEY_SET_VALUE | KEY_WOW64_32KEY) ==
|
| + ERROR_SUCCESS) {
|
| + base::string16 value_name(GetValueNameForProfile(profile));
|
| + if (key.HasValue(value_name.c_str())) {
|
| + if (key.DeleteValue(value_name.c_str()) == ERROR_SUCCESS)
|
| + return PlatformStateStoreLoadResult::CLEARED_DATA;
|
| + return PlatformStateStoreLoadResult::DATA_CLEAR_FAILED;
|
| + }
|
| + }
|
| + return PlatformStateStoreLoadResult::CLEARED_NO_DATA;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +PlatformStateStoreLoadResult ReadStoreData(Profile* profile,
|
| + std::string* data) {
|
| + // Clear any old state if this is a new profile.
|
| + if (profile->IsNewProfile()) {
|
| + data->clear();
|
| + return ClearStoreData(profile);
|
| + }
|
| +
|
| + base::string16 value_name(GetValueNameForProfile(profile));
|
| + base::win::RegKey key;
|
| + if (key.Open(HKEY_CURRENT_USER, GetStateStoreKeyName().c_str(),
|
| + KEY_QUERY_VALUE | KEY_WOW64_32KEY) == ERROR_SUCCESS) {
|
| + while (true) {
|
| + void* buffer = data->empty() ? nullptr : &(*data)[0];
|
| + DWORD buffer_size = base::saturated_cast<DWORD, size_t>(data->size());
|
| + LONG result =
|
| + key.ReadValue(value_name.c_str(), buffer, &buffer_size, nullptr);
|
| + // Trim the output string and return if all data was read.
|
| + if (result == ERROR_SUCCESS && buffer_size <= data->size()) {
|
| + data->resize(buffer_size);
|
| + return PlatformStateStoreLoadResult::SUCCESS;
|
| + }
|
| + // Increase the buffer and retry if more space was needed. Otherwise bail.
|
| + if (buffer_size > data->size())
|
| + data->resize(buffer_size);
|
| + else
|
| + return PlatformStateStoreLoadResult::READ_FAILED;
|
| + }
|
| + }
|
| +
|
| + return PlatformStateStoreLoadResult::OPEN_FAILED;
|
| +}
|
| +
|
| +void WriteStoreData(Profile* profile, const std::string& data) {
|
| + base::win::RegKey key;
|
| + if (key.Create(HKEY_CURRENT_USER, GetStateStoreKeyName().c_str(),
|
| + KEY_SET_VALUE | KEY_WOW64_32KEY) == ERROR_SUCCESS) {
|
| + if (data.empty()) {
|
| + key.DeleteValue(GetValueNameForProfile(profile).c_str());
|
| + } else {
|
| + key.WriteValue(GetValueNameForProfile(profile).c_str(), &data[0],
|
| + base::saturated_cast<DWORD, size_t>(data.size()),
|
| + REG_BINARY);
|
| + }
|
| + }
|
| +}
|
| +
|
| +} // namespace platform_state_store
|
| +} // namespace safe_browsing
|
|
|