Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2727)

Unified Diff: base/win/registry.cc

Issue 275103012: Add WOW64 support and DeleteEmptyKey to base::win::registry. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: separate the wow64 code from the bug fixes Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: base/win/registry.cc
diff --git a/base/win/registry.cc b/base/win/registry.cc
index 7330d08aa277e0ab5a67d84492176556bdd9dde0..17969275f42bfc079acee2afb3d1ca39d0233b18 100644
--- a/base/win/registry.cc
+++ b/base/win/registry.cc
@@ -10,8 +10,7 @@
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/threading/thread_restrictions.h"
-
-#pragma comment(lib, "shlwapi.lib") // for SHDeleteKey
grt (UTC plus 2) 2014/05/16 15:44:43 w00t!
Will Harris 2014/05/16 22:55:45 :D
+#include "base/win/windows_version.h"
namespace base {
namespace win {
@@ -76,6 +75,7 @@ LONG RegKey::CreateWithDisposition(HKEY rootkey, const wchar_t* subkey,
if (result == ERROR_SUCCESS) {
Close();
key_ = subhkey;
+ wow64access_ = access & KEY_WOW64_RES;
grt (UTC plus 2) 2014/05/16 15:44:43 looks like this is an undocumented constant in win
Will Harris 2014/05/16 22:55:44 Done.
}
return result;
@@ -86,10 +86,10 @@ LONG RegKey::CreateKey(const wchar_t* name, REGSAM access) {
HKEY subkey = NULL;
LONG result = RegCreateKeyEx(key_, name, 0, NULL, REG_OPTION_NON_VOLATILE,
access, NULL, &subkey, NULL);
- if (result == ERROR_SUCCESS) {
- Close();
-
- key_ = subkey;
+ if (result == ERROR_SUCCESS) {
+ Close();
+ key_ = subkey;
+ wow64access_ = access & KEY_WOW64_RES;
}
return result;
@@ -103,6 +103,7 @@ LONG RegKey::Open(HKEY rootkey, const wchar_t* subkey, REGSAM access) {
if (result == ERROR_SUCCESS) {
Close();
key_ = subhkey;
+ wow64access_ = access & KEY_WOW64_RES;
}
return result;
@@ -118,6 +119,7 @@ LONG RegKey::OpenKey(const wchar_t* relative_key_name, REGSAM access) {
if (result == ERROR_SUCCESS) {
Close();
key_ = subkey;
+ wow64access_ = access & KEY_WOW64_RES;
}
return result;
}
@@ -168,8 +170,19 @@ LONG RegKey::GetValueNameAt(int index, std::wstring* name) const {
LONG RegKey::DeleteKey(const wchar_t* name) {
DCHECK(key_);
DCHECK(name);
- LONG result = SHDeleteKey(key_, name);
- return result;
+ HKEY subkey;
+
+ // Verify the key exists before attempting delete to replicate previous
+ // behavior.
+ LONG result = RegOpenKeyEx(key_, name, 0, KEY_READ | wow64access_, &subkey);
grt (UTC plus 2) 2014/05/16 15:44:43 if this is just an existence test, i think READ_CO
Will Harris 2014/05/16 22:55:44 Done.
+ if (result == ERROR_SUCCESS) {
grt (UTC plus 2) 2014/05/16 15:44:43 suggestion: if (result != ERROR_SUCCESS) ret
Will Harris 2014/05/16 22:55:44 Done.
+ RegCloseKey(subkey);
+ std::wstring keyname(name);
grt (UTC plus 2) 2014/05/16 15:44:43 new code should use string16. would you mind switc
Will Harris 2014/05/16 22:55:44 will do in another CL
+
+ return RegKey::RegDelRecurse(key_, keyname, wow64access_);
grt (UTC plus 2) 2014/05/16 15:44:43 remove RegKey::
Will Harris 2014/05/16 22:55:44 Done.
+ } else {
+ return result;
+ }
}
LONG RegKey::DeleteValue(const wchar_t* value_name) {
@@ -342,6 +355,84 @@ LONG RegKey::StopWatching() {
return result;
}
+// static
+LONG RegKey::RegDeleteKeyExWrapper(HKEY hKey,
grt (UTC plus 2) 2014/05/16 15:44:43 use chromium naming style rather than hungarian
Will Harris 2014/05/16 22:55:44 Was intentionally using these since it's a wrapper
+ const wchar_t* lpSubKey,
+ REGSAM samDesired,
+ DWORD Reserved) {
+ typedef LSTATUS(WINAPI *RegDeleteKeyExPtr)(
+ HKEY hKey, LPCWSTR lpSubKey, REGSAM samDesired, DWORD Reserved);
+
+ if (base::win::GetVersion() >= VERSION_VISTA) {
grt (UTC plus 2) 2014/05/16 15:44:43 some versions prior to vista have RegDeleteKeyEx,
Will Harris 2014/05/16 22:55:44 Done. We need to support these Windows XP 64-bit
+ RegDeleteKeyExPtr reg_delete_key_ex_func =
+ reinterpret_cast<RegDeleteKeyExPtr>(
+ GetProcAddress(GetModuleHandleA("advapi32.dll"),
+ "RegDeleteKeyExW"));
+ if (reg_delete_key_ex_func)
+ return reg_delete_key_ex_func(hKey, lpSubKey, samDesired, Reserved);
+ } else {
+ // Windows XP does not support RegDeleteKeyEx.
+ return RegDeleteKey(hKey, lpSubKey);
+ }
+
+ return ERROR_GEN_FAILURE;
+}
+
+// static
grt (UTC plus 2) 2014/05/16 15:44:43 this isn't a static method according to the header
Will Harris 2014/05/16 22:55:44 Good spot - the static keyword was accidently drop
+LONG RegKey::RegDelRecurse(HKEY root_key, std::wstring name, REGSAM access) {
grt (UTC plus 2) 2014/05/16 15:44:43 pass name by const ref
Will Harris 2014/05/16 22:55:44 Done.
+ LONG result;
+ DWORD key_size;
+ wchar_t key_name[MAX_PATH];
+ HKEY hKey;
grt (UTC plus 2) 2014/05/16 15:44:43 no hungarians allowed. i suggest target_key or som
Will Harris 2014/05/16 22:55:44 Done.
+ FILETIME ft;
grt (UTC plus 2) 2014/05/16 15:44:43 is this needed? msdn says that the last param to E
Will Harris 2014/05/16 22:55:44 Done.
+
+ // First, see if the key can be deleted without having to recurse.
+ result = RegDeleteKeyExWrapper(root_key, name.c_str(), access, 0);
+
+ if (result == ERROR_SUCCESS)
+ return result;
+
+ result = RegOpenKeyEx(root_key, name.c_str(), 0, KEY_READ | access, &hKey);
grt (UTC plus 2) 2014/05/16 15:44:43 request the least required access: KEY_READ -> KEY
Will Harris 2014/05/16 22:55:45 Done.
+
+ if (result != ERROR_SUCCESS) {
grt (UTC plus 2) 2014/05/16 15:44:43 if (result == ERROR_FILE_NOT_FOUND) return ERR
Will Harris 2014/05/16 22:55:44 Done.
+ if (result == ERROR_FILE_NOT_FOUND) {
+ return ERROR_SUCCESS;
+ } else {
+ return result;
+ }
+ }
+
+ // Check for an ending slash and add one if it is missing.
+ if (name[name.length() - 1] != L'\\')
grt (UTC plus 2) 2014/05/16 15:44:43 what if |name| is empty? perhaps the top of the fu
Will Harris 2014/05/16 22:55:45 Done.
+ name += L"\\";
+
+ // Enumerate the keys
+ key_size = MAX_PATH;
+ result = RegEnumKeyEx(hKey, 0, key_name, &key_size, NULL, NULL, NULL, &ft);
grt (UTC plus 2) 2014/05/16 15:44:43 i think cpu already mentioned this, but do somethi
Will Harris 2014/05/16 22:55:45 Done.
+
+ if (result == ERROR_SUCCESS) {
grt (UTC plus 2) 2014/05/16 15:44:43 can you get rid of if { do { with: for (; result
Will Harris 2014/05/16 22:55:44 Done.
+ do {
+ std::wstring full_name(name);
grt (UTC plus 2) 2014/05/16 15:44:43 pull full_name's definition out of the loop
Will Harris 2014/05/16 22:55:44 Done.
+
+ full_name += key_name;
+
+ if (RegDelRecurse(root_key, full_name, access) != ERROR_SUCCESS)
+ break;
+
+ key_size = MAX_PATH;
+ result = RegEnumKeyEx(hKey, 0, key_name, &key_size, NULL,
+ NULL, NULL, &ft);
grt (UTC plus 2) 2014/05/16 15:44:43 shouldn't this be aligned with hKey above? did "gi
Will Harris 2014/05/16 22:55:44 Done.
+ } while (result == ERROR_SUCCESS);
+ }
+
+ RegCloseKey(hKey);
+
+ // Try again to delete the key.
+ result = RegDeleteKeyExWrapper(root_key, name.c_str(), access, 0);
+
+ return result;
+}
+
// RegistryValueIterator ------------------------------------------------------
RegistryValueIterator::RegistryValueIterator(HKEY root_key,

Powered by Google App Engine
This is Rietveld 408576698