Chromium Code Reviews| 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()) |
|
robertshield
2015/09/01 14:20:12
FYI, I've seen two ways of building such reg key p
grt (UTC plus 2)
2015/09/03 18:12:05
Thanks for pointing that out. The other way doesn'
robertshield
2015/09/05 03:23:24
I reckon not, though for cases that don't store pr
|
| + .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 |