ipc/chromium/src/base/registry.cc

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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.
     6 #include "base/registry.h"
     8 #include <assert.h>
     9 #include <shlwapi.h>
    10 #include <windows.h>
    12 #pragma comment(lib, "shlwapi.lib")  // for SHDeleteKey
    14 // local types (see the same declarations in the header file)
    15 #define tchar TCHAR
    16 #define CTP const tchar*
    17 #define tstr std::basic_string<tchar>
    19 //
    20 // RegistryValueIterator
    21 //
    23 RegistryValueIterator::RegistryValueIterator(HKEY root_key,
    24                                              LPCTSTR folder_key) {
    25   LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_);
    26   if (result != ERROR_SUCCESS) {
    27     key_ = NULL;
    28   } else {
    29     DWORD count = 0;
    30     result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL, &count,
    31                                NULL, NULL, NULL, NULL);
    33     if (result != ERROR_SUCCESS) {
    34       ::RegCloseKey(key_);
    35       key_ = NULL;
    36     } else {
    37       index_ = count - 1;
    38     }
    39   }
    41   Read();
    42 }
    44 RegistryValueIterator::~RegistryValueIterator() {
    45   if (key_)
    46     ::RegCloseKey(key_);
    47 }
    49 bool RegistryValueIterator::Valid() const {
    50   // true while the iterator is valid
    51   return key_ != NULL && index_ >= 0;
    52 }
    54 void RegistryValueIterator::operator ++ () {
    55   // advance to the next entry in the folder
    56   --index_;
    57   Read();
    58 }
    60 bool RegistryValueIterator::Read() {
    61   if (Valid()) {
    62     DWORD ncount = sizeof(name_)/sizeof(*name_);
    63     value_size_ = sizeof(value_);
    64     LRESULT r = ::RegEnumValue(key_, index_, name_, &ncount, NULL, &type_,
    65                                reinterpret_cast<BYTE*>(value_), &value_size_);
    66     if (ERROR_SUCCESS == r)
    67       return true;
    68   }
    70   name_[0] = '\0';
    71   value_[0] = '\0';
    72   value_size_ = 0;
    73   return false;
    74 }
    76 DWORD RegistryValueIterator::ValueCount() const {
    78   DWORD count = 0;
    79   HRESULT result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL, NULL,
    80                                      &count, NULL, NULL, NULL, NULL);
    82   if (result != ERROR_SUCCESS)
    83     return 0;
    85   return count;
    86 }
    88 //
    89 // RegistryKeyIterator
    90 //
    92 RegistryKeyIterator::RegistryKeyIterator(HKEY root_key,
    93                                          LPCTSTR folder_key) {
    94   LONG result = RegOpenKeyEx(root_key, folder_key, 0, KEY_READ, &key_);
    95   if (result != ERROR_SUCCESS) {
    96     key_ = NULL;
    97   } else {
    98     DWORD count = 0;
    99     HRESULT result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL,
   100                                        NULL, NULL, NULL, NULL, NULL);
   102     if (result != ERROR_SUCCESS) {
   103       ::RegCloseKey(key_);
   104       key_ = NULL;
   105     } else {
   106       index_ = count - 1;
   107     }
   108   }
   110   Read();
   111 }
   113 RegistryKeyIterator::~RegistryKeyIterator() {
   114   if (key_)
   115     ::RegCloseKey(key_);
   116 }
   118 bool RegistryKeyIterator::Valid() const {
   119   // true while the iterator is valid
   120   return key_ != NULL && index_ >= 0;
   121 }
   123 void RegistryKeyIterator::operator ++ () {
   124   // advance to the next entry in the folder
   125   --index_;
   126   Read();
   127 }
   129 bool RegistryKeyIterator::Read() {
   130   if (Valid()) {
   131     DWORD ncount = sizeof(name_)/sizeof(*name_);
   132     FILETIME written;
   133     LRESULT r = ::RegEnumKeyEx(key_, index_, name_, &ncount, NULL, NULL,
   134                                NULL, &written);
   135     if (ERROR_SUCCESS == r)
   136       return true;
   137   }
   139   name_[0] = '\0';
   140   return false;
   141 }
   143 DWORD RegistryKeyIterator::SubkeyCount() const {
   145   DWORD count = 0;
   146   HRESULT result = ::RegQueryInfoKey(key_, NULL, 0, NULL, &count, NULL, NULL,
   147                                      NULL, NULL, NULL, NULL, NULL);
   149   if (result != ERROR_SUCCESS)
   150     return 0;
   152   return count;
   153 }
   155 //
   156 // RegKey
   157 //
   159 RegKey::RegKey(HKEY rootkey, const tchar* subkey, REGSAM access)
   160   : key_(NULL), watch_event_(0) {
   161   if (rootkey) {
   162     if (access & (KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_CREATE_LINK))
   163       this->Create(rootkey, subkey, access);
   164     else
   165       this->Open(rootkey, subkey, access);
   166   }
   167   else assert(!subkey);
   168 }
   170 void RegKey::Close() {
   171   StopWatching();
   172   if (key_) {
   173     ::RegCloseKey(key_);
   174     key_ = NULL;
   175   }
   176 }
   178 bool RegKey::Create(HKEY rootkey, const tchar* subkey, REGSAM access) {
   179   DWORD disposition_value;
   180   return CreateWithDisposition(rootkey, subkey, &disposition_value, access);
   181 }
   183 bool RegKey::CreateWithDisposition(HKEY rootkey, const tchar* subkey,
   184                                    DWORD* disposition, REGSAM access) {
   185   assert(rootkey && subkey && access && disposition);
   186   this->Close();
   188   LONG const result = RegCreateKeyEx(rootkey,
   189                                      subkey,
   190                                      0,
   191                                      NULL,
   192                                      REG_OPTION_NON_VOLATILE,
   193                                      access,
   194                                      NULL,
   195                                      &key_,
   196                                      disposition );
   197   if (result != ERROR_SUCCESS) {
   198     key_ = NULL;
   199     return false;
   200   }
   201   else return true;
   202 }
   204 bool RegKey::Open(HKEY rootkey, const tchar* subkey, REGSAM access) {
   205   assert(rootkey && subkey && access);
   206   this->Close();
   208   LONG const result = RegOpenKeyEx(rootkey, subkey, 0,
   209                                    access, &key_ );
   210   if (result != ERROR_SUCCESS) {
   211     key_ = NULL;
   212     return false;
   213   }
   214   else return true;
   215 }
   217 bool RegKey::CreateKey(const tchar* name, REGSAM access) {
   218   assert(name && access);
   220   HKEY subkey = NULL;
   221   LONG const result = RegCreateKeyEx(key_, name, 0, NULL,
   222                                      REG_OPTION_NON_VOLATILE,
   223                                      access, NULL, &subkey, NULL);
   224   this->Close();
   226   key_ = subkey;
   227   return (result == ERROR_SUCCESS);
   228 }
   230 bool RegKey::OpenKey(const tchar* name, REGSAM access) {
   231   assert(name && access);
   233   HKEY subkey = NULL;
   234   LONG const result = RegOpenKeyEx(key_, name, 0, access, &subkey);
   236   this->Close();
   238   key_ = subkey;
   239   return (result == ERROR_SUCCESS);
   240 }
   242 DWORD RegKey::ValueCount() {
   243   DWORD count = 0;
   244   HRESULT const result = ::RegQueryInfoKey(key_, NULL, 0, NULL, NULL, NULL,
   245                                      NULL, &count, NULL, NULL, NULL, NULL);
   246   return (result != ERROR_SUCCESS) ? 0 : count;
   247 }
   249 bool RegKey::ReadName(int index, tstr* name) {
   250   tchar buf[256];
   251   DWORD bufsize = sizeof(buf)/sizeof(*buf);
   252   LRESULT r = ::RegEnumValue(key_, index, buf, &bufsize, NULL, NULL,
   253                              NULL, NULL);
   254   if (r != ERROR_SUCCESS)
   255     return false;
   256   if (name)
   257     *name = buf;
   258   return true;
   259 }
   261 bool RegKey::ValueExists(const tchar* name) {
   262   if (!key_) return false;
   263   const HRESULT result = RegQueryValueEx(key_, name, 0, NULL, NULL, NULL);
   264   return (result == ERROR_SUCCESS);
   265 }
   267 bool RegKey::ReadValue(const tchar* name, void* data,
   268                        DWORD* dsize, DWORD* dtype) {
   269   if (!key_) return false;
   270   HRESULT const result = RegQueryValueEx(key_, name, 0, dtype,
   271                                          reinterpret_cast<LPBYTE>(data),
   272                                          dsize);
   273   return (result == ERROR_SUCCESS);
   274 }
   276 bool RegKey::ReadValue(const tchar* name, tstr * value) {
   277   assert(value);
   278   static const size_t kMaxStringLength = 1024;  // This is after expansion.
   279   // Use the one of the other forms of ReadValue if 1024 is too small for you.
   280   TCHAR raw_value[kMaxStringLength];
   281   DWORD type = REG_SZ, size = sizeof(raw_value);
   282   if (this->ReadValue(name, raw_value, &size, &type)) {
   283     if (type == REG_SZ) {
   284       *value = raw_value;
   285     } else if (type == REG_EXPAND_SZ) {
   286       TCHAR expanded[kMaxStringLength];
   287       size = ExpandEnvironmentStrings(raw_value, expanded, kMaxStringLength);
   288       // Success: returns the number of TCHARs copied
   289       // Fail: buffer too small, returns the size required
   290       // Fail: other, returns 0
   291       if (size == 0 || size > kMaxStringLength)
   292         return false;
   293       *value = expanded;
   294     } else {
   295       // Not a string. Oops.
   296       return false;
   297     }
   298     return true;
   299   }
   300   else return false;
   301 }
   303 bool RegKey::ReadValueDW(const tchar* name, DWORD * value) {
   304   assert(value);
   305   DWORD type = REG_DWORD, size = sizeof(DWORD), result = 0;
   306   if (this->ReadValue(name, &result, &size, &type)
   307      && (type == REG_DWORD || type == REG_BINARY)
   308      && size == sizeof(DWORD)) {
   309     *value = result;
   310     return true;
   311   }
   312   else return false;
   313 }
   315 bool RegKey::WriteValue(const tchar* name,
   316                         const void * data,
   317                         DWORD dsize,
   318                         DWORD dtype) {
   319   assert(data);
   320   if (!key_) return false;
   321   HRESULT const result = RegSetValueEx(
   322       key_,
   323       name,
   324       0,
   325       dtype,
   326       reinterpret_cast<LPBYTE>(const_cast<void*>(data)),
   327       dsize);
   328   return (result == ERROR_SUCCESS);
   329 }
   331 bool RegKey::WriteValue(const tchar * name, const tchar * value) {
   332   return this->WriteValue(name, value,
   333     static_cast<DWORD>(sizeof(*value) * (_tcslen(value) + 1)), REG_SZ);
   334 }
   336 bool RegKey::WriteValue(const tchar * name, DWORD value) {
   337   return this->WriteValue(name, &value,
   338     static_cast<DWORD>(sizeof(value)), REG_DWORD);
   339 }
   341 bool RegKey::DeleteKey(const tchar * name) {
   342   if (!key_) return false;
   343   return (ERROR_SUCCESS == SHDeleteKey(key_, name));
   344 }
   347 bool RegKey::DeleteValue(const tchar * value_name) {
   348   assert(value_name);
   349   HRESULT const result = RegDeleteValue(key_, value_name);
   350   return (result == ERROR_SUCCESS);
   351 }
   353 bool RegKey::StartWatching() {
   354   if (!watch_event_)
   355     watch_event_ = CreateEvent(NULL, TRUE, FALSE, NULL);
   357   DWORD filter = REG_NOTIFY_CHANGE_NAME |
   358                  REG_NOTIFY_CHANGE_ATTRIBUTES |
   359                  REG_NOTIFY_CHANGE_LAST_SET |
   360                  REG_NOTIFY_CHANGE_SECURITY;
   362   // Watch the registry key for a change of value.
   363   HRESULT result = RegNotifyChangeKeyValue(key_, TRUE, filter,
   364                                            watch_event_, TRUE);
   365   if (SUCCEEDED(result)) {
   366     return true;
   367   } else {
   368     CloseHandle(watch_event_);
   369     watch_event_ = 0;
   370     return false;
   371   }
   372 }
   374 bool RegKey::StopWatching() {
   375   if (watch_event_) {
   376     CloseHandle(watch_event_);
   377     watch_event_ = 0;
   378     return true;
   379   }
   380   return false;
   381 }
   383 bool RegKey::HasChanged() {
   384   if (watch_event_) {
   385     if (WaitForSingleObject(watch_event_, 0) == WAIT_OBJECT_0) {
   386       StartWatching();
   387       return true;
   388     }
   389   }
   390   return false;
   391 }
   393 // Register a COM object with the most usual properties.
   394 bool RegisterCOMServer(const tchar* guid,
   395                        const tchar* name,
   396                        const tchar* path) {
   397   RegKey key(HKEY_CLASSES_ROOT, _T("CLSID"), KEY_WRITE);
   398   key.CreateKey(guid, KEY_WRITE);
   399   key.WriteValue(NULL, name);
   400   key.CreateKey(_T("InprocServer32"), KEY_WRITE);
   401   key.WriteValue(NULL, path);
   402   key.WriteValue(_T("ThreadingModel"), _T("Apartment"));
   403   return true;
   404 }
   406 bool RegisterCOMServer(const tchar* guid, const tchar* name, HINSTANCE module) {
   407   tchar module_path[MAX_PATH];
   408   ::GetModuleFileName(module, module_path, MAX_PATH);
   409   _tcslwr_s(module_path, MAX_PATH);
   410   return RegisterCOMServer(guid, name, module_path);
   411 }
   413 bool UnregisterCOMServer(const tchar* guid) {
   414   RegKey key(HKEY_CLASSES_ROOT, _T("CLSID"), KEY_WRITE);
   415   key.DeleteKey(guid);
   416   return true;
   417 }

mercurial