1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 // All Rights Reserved. 5 6 #ifndef BASE_REGISTRY_H__ 7 #define BASE_REGISTRY_H__ 8 9 #include <windows.h> 10 #include <tchar.h> 11 #include <shlwapi.h> 12 #include <string> 13 14 // The shared file uses a bunch of header files that define types that we don't. 15 // To avoid changing much code from the standard version, and also to avoid 16 // polluting our namespace with extra types we don't want, we define these types 17 // here with the preprocessor and undefine them at the end of the file. 18 #define tchar TCHAR 19 #define CTP const tchar* 20 #define tstr std::basic_string<tchar> 21 22 // RegKey 23 // Utility class to read from and manipulate the registry. 24 // Registry vocabulary primer: a "key" is like a folder, in which there 25 // are "values", which are <name,data> pairs, with an associated data type. 26 27 class RegKey { 28 public: 29 RegKey(HKEY rootkey = NULL, CTP subkey = NULL, REGSAM access = KEY_READ); 30 // start there 31 32 ~RegKey() { this->Close(); } 33 34 bool Create(HKEY rootkey, CTP subkey, REGSAM access = KEY_READ); 35 36 bool CreateWithDisposition(HKEY rootkey, CTP subkey, DWORD* disposition, 37 REGSAM access = KEY_READ); 38 39 bool Open(HKEY rootkey, CTP subkey, REGSAM access = KEY_READ); 40 41 // Create a subkey (or open if exists) 42 bool CreateKey(CTP name, REGSAM access); 43 44 // Open a subkey 45 bool OpenKey(CTP name, REGSAM access); 46 47 // all done, eh? 48 void Close(); 49 50 DWORD ValueCount(); // Count of the number of value extant 51 52 bool ReadName(int index, tstr* name); // Determine the Nth value's name 53 54 // True while the key is valid 55 bool Valid() const { return NULL != key_; } 56 57 // Kill key and everything that liveth below it; please be careful out there 58 bool DeleteKey(CTP name); 59 60 // Delete a single value within the key 61 bool DeleteValue(CTP name); 62 63 bool ValueExists(CTP name); 64 bool ReadValue(CTP name, void * data, DWORD * dsize, DWORD * dtype = NULL); 65 bool ReadValue(CTP name, tstr * value); 66 bool ReadValueDW(CTP name, DWORD * value); // Named to differ from tstr* 67 68 bool WriteValue(CTP name, const void * data, DWORD dsize, 69 DWORD dtype = REG_BINARY); 70 bool WriteValue(CTP name, CTP value); 71 bool WriteValue(CTP name, DWORD value); 72 73 // StartWatching() 74 // Start watching the key to see if any of its values have changed. 75 // The key must have been opened with the KEY_NOTIFY access 76 // privelege. 77 bool StartWatching(); 78 79 // HasChanged() 80 // If StartWatching hasn't been called, always returns false. 81 // Otherwise, returns true if anything under the key has changed. 82 // This can't be const because the watch_event_ may be refreshed. 83 bool HasChanged(); 84 85 // StopWatching() 86 // Will automatically be called by destructor if not manually called 87 // beforehand. Returns true if it was watching, false otherwise. 88 bool StopWatching(); 89 90 inline bool IsWatching() const { return watch_event_ != 0; } 91 HANDLE watch_event() const { return watch_event_; } 92 HKEY Handle() const { return key_; } 93 94 private: 95 HKEY key_; // the registry key being iterated 96 HANDLE watch_event_; 97 }; 98 99 100 // Standalone registry functions -- sorta deprecated, they now map to 101 // using RegKey 102 103 104 // Add a raw data to the registry -- you can pass NULL for the data if 105 // you just want to create a key 106 inline bool AddToRegistry(HKEY root_key, CTP key, CTP value_name, 107 void const * data, DWORD dsize, 108 DWORD dtype = REG_BINARY) { 109 return RegKey(root_key, key, KEY_WRITE).WriteValue(value_name, data, dsize, 110 dtype); 111 } 112 113 // Convenience routine to add a string value to the registry 114 inline bool AddToRegistry(HKEY root_key, CTP key, CTP value_name, CTP value) { 115 return AddToRegistry(root_key, key, value_name, value, 116 sizeof(*value) * (lstrlen(value) + 1), REG_SZ); 117 } 118 119 // Read raw data from the registry -- pass something as the dtype 120 // parameter if you care to learn what type the value was stored as 121 inline bool ReadFromRegistry(HKEY root_key, CTP key, CTP value_name, 122 void* data, DWORD* dsize, DWORD* dtype = NULL) { 123 return RegKey(root_key, key).ReadValue(value_name, data, dsize, dtype); 124 } 125 126 127 // Delete a value or a key from the registry 128 inline bool DeleteFromRegistry(HKEY root_key, CTP subkey, CTP value_name) { 129 if (value_name) 130 return ERROR_SUCCESS == ::SHDeleteValue(root_key, subkey, value_name); 131 else 132 return ERROR_SUCCESS == ::SHDeleteKey(root_key, subkey); 133 } 134 135 136 137 // delete a key and all subkeys from the registry 138 inline bool DeleteKeyFromRegistry(HKEY root_key, CTP key_path, CTP key_name) { 139 RegKey key; 140 return key.Open(root_key, key_path, KEY_WRITE) 141 && key.DeleteKey(key_name); 142 } 143 144 145 // Iterates the entries found in a particular folder on the registry. 146 // For this application I happen to know I wont need data size larger 147 // than MAX_PATH, but in real life this wouldn't neccessarily be 148 // adequate. 149 class RegistryValueIterator { 150 public: 151 // Specify a key in construction 152 RegistryValueIterator(HKEY root_key, LPCTSTR folder_key); 153 154 ~RegistryValueIterator(); 155 156 DWORD ValueCount() const; // count of the number of subkeys extant 157 158 bool Valid() const; // true while the iterator is valid 159 160 void operator++(); // advance to the next entry in the folder 161 162 // The pointers returned by these functions are statics owned by the 163 // Name and Value functions 164 CTP Name() const { return name_; } 165 CTP Value() const { return value_; } 166 DWORD ValueSize() const { return value_size_; } 167 DWORD Type() const { return type_; } 168 169 int Index() const { return index_; } 170 171 private: 172 bool Read(); // read in the current values 173 174 HKEY key_; // the registry key being iterated 175 int index_; // current index of the iteration 176 177 // Current values 178 TCHAR name_[MAX_PATH]; 179 TCHAR value_[MAX_PATH]; 180 DWORD value_size_; 181 DWORD type_; 182 }; 183 184 185 class RegistryKeyIterator { 186 public: 187 // Specify a parent key in construction 188 RegistryKeyIterator(HKEY root_key, LPCTSTR folder_key); 189 190 ~RegistryKeyIterator(); 191 192 DWORD SubkeyCount() const; // count of the number of subkeys extant 193 194 bool Valid() const; // true while the iterator is valid 195 196 void operator++(); // advance to the next entry in the folder 197 198 // The pointer returned by Name() is a static owned by the function 199 CTP Name() const { return name_; } 200 201 int Index() const { return index_; } 202 203 private: 204 bool Read(); // read in the current values 205 206 HKEY key_; // the registry key being iterated 207 int index_; // current index of the iteration 208 209 // Current values 210 TCHAR name_[MAX_PATH]; 211 }; 212 213 214 // Register a COM object with the most usual properties. 215 bool RegisterCOMServer(const tchar* guid, const tchar* name, 216 const tchar* modulepath); 217 bool RegisterCOMServer(const tchar* guid, const tchar* name, HINSTANCE module); 218 bool UnregisterCOMServer(const tchar* guid); 219 220 // undo the local types defined above 221 #undef tchar 222 #undef CTP 223 #undef tstr 224 225 #endif // BASE_REGISTRY_H__ 226