172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/win/registry.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <shlwapi.h> 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/logging.h" 103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread_restrictions.h" 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma comment(lib, "shlwapi.lib") // for SHDeleteKey 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 14731df977c0511bca2206b5f333555b1205ff1f43Iain Merricknamespace base { 15731df977c0511bca2206b5f333555b1205ff1f43Iain Merricknamespace win { 16731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// RegKey ---------------------------------------------------------------------- 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 193345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickRegKey::RegKey() 203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : key_(NULL), 213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick watch_event_(0) { 223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 243345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickRegKey::RegKey(HKEY rootkey, const wchar_t* subkey, REGSAM access) 253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : key_(NULL), 263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick watch_event_(0) { 27513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rootkey) { 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (access & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_CREATE_LINK)) 303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Create(rootkey, subkey, access); 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott else 323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Open(rootkey, subkey, access); 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(!subkey); 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 383345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickRegKey::~RegKey() { 393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Close(); 403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenLONG RegKey::Create(HKEY rootkey, const wchar_t* subkey, REGSAM access) { 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD disposition_value; 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return CreateWithDisposition(rootkey, subkey, &disposition_value, access); 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenLONG RegKey::CreateWithDisposition(HKEY rootkey, const wchar_t* subkey, 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD* disposition, REGSAM access) { 49513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(rootkey && subkey && access && disposition); 513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Close(); 523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LONG result = RegCreateKeyEx(rootkey, subkey, 0, NULL, 5472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen REG_OPTION_NON_VOLATILE, access, NULL, &key_, 553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick disposition); 5672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return result; 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenLONG RegKey::Open(HKEY rootkey, const wchar_t* subkey, REGSAM access) { 60513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(rootkey && subkey && access); 623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Close(); 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LONG result = RegOpenKeyEx(rootkey, subkey, 0, access, &key_); 6572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return result; 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 6872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenLONG RegKey::CreateKey(const wchar_t* name, REGSAM access) { 69513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(name && access); 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HKEY subkey = NULL; 733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LONG result = RegCreateKeyEx(key_, name, 0, NULL, REG_OPTION_NON_VOLATILE, 743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick access, NULL, &subkey, NULL); 753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Close(); 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott key_ = subkey; 7872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return result; 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 8172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenLONG RegKey::OpenKey(const wchar_t* name, REGSAM access) { 82513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(name && access); 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HKEY subkey = NULL; 863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LONG result = RegOpenKeyEx(key_, name, 0, access, &subkey); 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Close(); 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott key_ = subkey; 9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return result; 9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid RegKey::Close() { 9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::ThreadRestrictions::AssertIOAllowed(); 9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen StopWatching(); 9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (key_) { 9872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ::RegCloseKey(key_); 9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen key_ = NULL; 10072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 10321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenDWORD RegKey::ValueCount() const { 104513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD count = 0; 10672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LONG result = RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, &count, 10772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NULL, NULL, NULL, NULL); 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (result != ERROR_SUCCESS) ? 0 : count; 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 11172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenLONG RegKey::ReadName(int index, std::wstring* name) const { 112513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 1133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick wchar_t buf[256]; 1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DWORD bufsize = arraysize(buf); 11572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LONG r = ::RegEnumValue(key_, index, buf, &bufsize, NULL, NULL, NULL, NULL); 11672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (r == ERROR_SUCCESS) 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *name = buf; 11872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 11972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return r; 12072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 12172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 12272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenLONG RegKey::DeleteKey(const wchar_t* name) { 12372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::ThreadRestrictions::AssertIOAllowed(); 12472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(key_); 12572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(name); 12672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LONG result = SHDeleteKey(key_, name); 12772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return result; 12872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 12972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 13072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenLONG RegKey::DeleteValue(const wchar_t* value_name) { 13172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::ThreadRestrictions::AssertIOAllowed(); 13272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(key_); 13372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(value_name); 13472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LONG result = RegDeleteValue(key_, value_name); 13572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return result; 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 13872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool RegKey::ValueExists(const wchar_t* name) const { 139513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 14072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LONG result = RegQueryValueEx(key_, name, 0, NULL, NULL, NULL); 14172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return result == ERROR_SUCCESS; 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 14472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenLONG RegKey::ReadValue(const wchar_t* name, void* data, DWORD* dsize, 14572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DWORD* dtype) const { 146513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 14772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LONG result = RegQueryValueEx(key_, name, 0, dtype, 14872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen reinterpret_cast<LPBYTE>(data), dsize); 14972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return result; 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 15272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenLONG RegKey::ReadValue(const wchar_t* name, std::wstring* value) const { 153513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 1543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(value); 1553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const size_t kMaxStringLength = 1024; // This is after expansion. 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Use the one of the other forms of ReadValue if 1024 is too small for you. 1573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick wchar_t raw_value[kMaxStringLength]; 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD type = REG_SZ, size = sizeof(raw_value); 15972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LONG result = ReadValue(name, raw_value, &size, &type); 16072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (result == ERROR_SUCCESS) { 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (type == REG_SZ) { 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *value = raw_value; 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else if (type == REG_EXPAND_SZ) { 1643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick wchar_t expanded[kMaxStringLength]; 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size = ExpandEnvironmentStrings(raw_value, expanded, kMaxStringLength); 1663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Success: returns the number of wchar_t's copied 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Fail: buffer too small, returns the size required 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Fail: other, returns 0 16972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (size == 0 || size > kMaxStringLength) { 17072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen result = ERROR_MORE_DATA; 17172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else { 17272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen *value = expanded; 17372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Not a string. Oops. 17672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen result = ERROR_CANTREAD; 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 18072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return result; 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 18372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenLONG RegKey::ReadValueDW(const wchar_t* name, DWORD* value) const { 1843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(value); 1853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DWORD type = REG_DWORD; 1863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DWORD size = sizeof(DWORD); 18772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DWORD local_value = 0; 18872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LONG result = ReadValue(name, &local_value, &size, &type); 18972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (result == ERROR_SUCCESS) { 19072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if ((type == REG_DWORD || type == REG_BINARY) && size == sizeof(DWORD)) { 19172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen *value = local_value; 19272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else { 19372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen result = ERROR_CANTREAD; 19472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return result; 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 20072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenLONG RegKey::ReadInt64(const wchar_t* name, int64* value) const { 20172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(value); 20272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DWORD type = REG_QWORD; 20372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int64 local_value = 0; 20472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DWORD size = sizeof(local_value); 20572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LONG result = ReadValue(name, &local_value, &size, &type); 20672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (result == ERROR_SUCCESS) { 20772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if ((type == REG_QWORD || type == REG_BINARY) && 20872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen size == sizeof(local_value)) { 20972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen *value = local_value; 21072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else { 21172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen result = ERROR_CANTREAD; 21272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 21372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 21472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 21572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return result; 21672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 21772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 21872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenLONG RegKey::WriteValue(const wchar_t* name, const void * data, 2193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DWORD dsize, DWORD dtype) { 220513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::AssertIOAllowed(); 22172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(data || !dsize); 2223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 22372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LONG result = RegSetValueEx(key_, name, 0, dtype, 22472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen reinterpret_cast<LPBYTE>(const_cast<void*>(data)), dsize); 22572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return result; 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 22872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenLONG RegKey::WriteValue(const wchar_t * name, const wchar_t* value) { 2293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return WriteValue(name, value, 2303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static_cast<DWORD>(sizeof(*value) * (wcslen(value) + 1)), REG_SZ); 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 23372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenLONG RegKey::WriteValue(const wchar_t* name, DWORD value) { 23472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return WriteValue(name, &value, static_cast<DWORD>(sizeof(value)), REG_DWORD); 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 23772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenLONG RegKey::StartWatching() { 23872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DCHECK(key_); 239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!watch_event_) 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott watch_event_ = CreateEvent(NULL, TRUE, FALSE, NULL); 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD filter = REG_NOTIFY_CHANGE_NAME | 243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott REG_NOTIFY_CHANGE_ATTRIBUTES | 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott REG_NOTIFY_CHANGE_LAST_SET | 245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott REG_NOTIFY_CHANGE_SECURITY; 246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Watch the registry key for a change of value. 24872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LONG result = RegNotifyChangeKeyValue(key_, TRUE, filter, watch_event_, TRUE); 24972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (result != ERROR_SUCCESS) { 250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CloseHandle(watch_event_); 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott watch_event_ = 0; 252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 25372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 25472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return result; 255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 25772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool RegKey::HasChanged() { 258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (watch_event_) { 25972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (WaitForSingleObject(watch_event_, 0) == WAIT_OBJECT_0) { 26072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen StartWatching(); 26172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 26272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 26772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenLONG RegKey::StopWatching() { 26872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LONG result = ERROR_INVALID_HANDLE; 269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (watch_event_) { 27072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen CloseHandle(watch_event_); 27172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen watch_event_ = 0; 27272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen result = ERROR_SUCCESS; 27372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 27472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return result; 27572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 27672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 27772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// RegistryValueIterator ------------------------------------------------------ 27872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 27972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenRegistryValueIterator::RegistryValueIterator(HKEY root_key, 28072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const wchar_t* folder_key) { 28172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::ThreadRestrictions::AssertIOAllowed(); 28272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 28372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_); 28472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (result != ERROR_SUCCESS) { 28572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen key_ = NULL; 28672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else { 28772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DWORD count = 0; 28872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, &count, 28972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NULL, NULL, NULL, NULL); 29072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 29172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (result != ERROR_SUCCESS) { 29272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ::RegCloseKey(key_); 29372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen key_ = NULL; 29472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else { 29572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen index_ = count - 1; 29672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 29772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 29872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 29972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen Read(); 30072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 30172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 30272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenRegistryValueIterator::~RegistryValueIterator() { 30372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::ThreadRestrictions::AssertIOAllowed(); 30472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (key_) 30572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ::RegCloseKey(key_); 30672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 30772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 30872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenDWORD RegistryValueIterator::ValueCount() const { 30972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::ThreadRestrictions::AssertIOAllowed(); 31072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DWORD count = 0; 31172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, 31272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &count, NULL, NULL, NULL, NULL); 31372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (result != ERROR_SUCCESS) 31472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return 0; 31572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 31672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return count; 31772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 31872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 31972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool RegistryValueIterator::Valid() const { 32072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return key_ != NULL && index_ >= 0; 32172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 32272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 32372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid RegistryValueIterator::operator++() { 32472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen --index_; 32572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen Read(); 32672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 32772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 32872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool RegistryValueIterator::Read() { 32972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::ThreadRestrictions::AssertIOAllowed(); 33072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (Valid()) { 33172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DWORD ncount = arraysize(name_); 33272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen value_size_ = sizeof(value_); 33372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LONG r = ::RegEnumValue(key_, index_, name_, &ncount, NULL, &type_, 33472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen reinterpret_cast<BYTE*>(value_), &value_size_); 33572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (ERROR_SUCCESS == r) 336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 33772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 33872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 33972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen name_[0] = '\0'; 34072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen value_[0] = '\0'; 34172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen value_size_ = 0; 34272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 34372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 34472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 34572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// RegistryKeyIterator -------------------------------------------------------- 34672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 34772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenRegistryKeyIterator::RegistryKeyIterator(HKEY root_key, 34872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const wchar_t* folder_key) { 34972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::ThreadRestrictions::AssertIOAllowed(); 35072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_); 35172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (result != ERROR_SUCCESS) { 35272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen key_ = NULL; 35372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else { 35472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DWORD count = 0; 35572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL, 35672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NULL, NULL, NULL, NULL, NULL); 35772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 35872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (result != ERROR_SUCCESS) { 35972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ::RegCloseKey(key_); 36072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen key_ = NULL; 36172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } else { 36272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen index_ = count - 1; 363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 36572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 36672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen Read(); 36772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 36872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 36972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenRegistryKeyIterator::~RegistryKeyIterator() { 37072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::ThreadRestrictions::AssertIOAllowed(); 37172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (key_) 37272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ::RegCloseKey(key_); 37372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 37472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 37572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenDWORD RegistryKeyIterator::SubkeyCount() const { 37672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::ThreadRestrictions::AssertIOAllowed(); 37772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DWORD count = 0; 37872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LONG result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL, 37972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NULL, NULL, NULL, NULL, NULL); 38072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (result != ERROR_SUCCESS) 38172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return 0; 38272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 38372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return count; 38472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 38572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 38672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool RegistryKeyIterator::Valid() const { 38772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return key_ != NULL && index_ >= 0; 38872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 38972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 39072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid RegistryKeyIterator::operator++() { 39172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen --index_; 39272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen Read(); 39372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 39472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 39572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool RegistryKeyIterator::Read() { 39672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::ThreadRestrictions::AssertIOAllowed(); 39772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (Valid()) { 39872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DWORD ncount = arraysize(name_); 39972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen FILETIME written; 40072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LONG r = ::RegEnumKeyEx(key_, index_, name_, &ncount, NULL, NULL, 40172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NULL, &written); 40272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (ERROR_SUCCESS == r) 40372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return true; 40472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 40572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 40672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen name_[0] = '\0'; 407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 409731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 410731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} // namespace win 411731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} // namespace base 412