tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Registry.cpp (10036B)


      1 // Windows/Registry.cpp
      2 
      3 #include "StdAfx.h"
      4 
      5 #include <wchar.h>
      6 
      7 #ifndef _UNICODE
      8 #include "../Common/StringConvert.h"
      9 #endif
     10 #include "Registry.h"
     11 
     12 #ifndef _UNICODE
     13 extern bool g_IsNT;
     14 #endif
     15 
     16 namespace NWindows {
     17 namespace NRegistry {
     18 
     19 #define MYASSERT(expr) // _ASSERTE(expr)
     20 
     21 LONG CKey::Create(HKEY parentKey, LPCTSTR keyName,
     22    LPTSTR keyClass, DWORD options, REGSAM accessMask,
     23    LPSECURITY_ATTRIBUTES securityAttributes, LPDWORD disposition) throw()
     24 {
     25  MYASSERT(parentKey != NULL);
     26  DWORD dispositionReal;
     27  HKEY key = NULL;
     28  LONG res = RegCreateKeyEx(parentKey, keyName, 0, keyClass,
     29      options, accessMask, securityAttributes, &key, &dispositionReal);
     30  if (disposition != NULL)
     31    *disposition = dispositionReal;
     32  if (res == ERROR_SUCCESS)
     33  {
     34    res = Close();
     35    _object = key;
     36  }
     37  return res;
     38 }
     39 
     40 LONG CKey::Open(HKEY parentKey, LPCTSTR keyName, REGSAM accessMask) throw()
     41 {
     42  MYASSERT(parentKey != NULL);
     43  HKEY key = NULL;
     44  LONG res = RegOpenKeyEx(parentKey, keyName, 0, accessMask, &key);
     45  if (res == ERROR_SUCCESS)
     46  {
     47    res = Close();
     48    MYASSERT(res == ERROR_SUCCESS);
     49    _object = key;
     50  }
     51  return res;
     52 }
     53 
     54 LONG CKey::Close() throw()
     55 {
     56  LONG res = ERROR_SUCCESS;
     57  if (_object != NULL)
     58  {
     59    res = RegCloseKey(_object);
     60    _object = NULL;
     61  }
     62  return res;
     63 }
     64 
     65 // win95, win98: deletes sunkey and all its subkeys
     66 // winNT to be deleted must not have subkeys
     67 LONG CKey::DeleteSubKey(LPCTSTR subKeyName) throw()
     68 {
     69  MYASSERT(_object != NULL);
     70  return RegDeleteKey(_object, subKeyName);
     71 }
     72 
     73 LONG CKey::RecurseDeleteKey(LPCTSTR subKeyName) throw()
     74 {
     75  CKey key;
     76  LONG res = key.Open(_object, subKeyName, KEY_READ | KEY_WRITE);
     77  if (res != ERROR_SUCCESS)
     78    return res;
     79  FILETIME fileTime;
     80  const UInt32 kBufSize = MAX_PATH + 1; // 256 in ATL
     81  DWORD size = kBufSize;
     82  TCHAR buffer[kBufSize];
     83  while (RegEnumKeyEx(key._object, 0, buffer, &size, NULL, NULL, NULL, &fileTime) == ERROR_SUCCESS)
     84  {
     85    res = key.RecurseDeleteKey(buffer);
     86    if (res != ERROR_SUCCESS)
     87      return res;
     88    size = kBufSize;
     89  }
     90  key.Close();
     91  return DeleteSubKey(subKeyName);
     92 }
     93 
     94 
     95 /////////////////////////
     96 // Value Functions
     97 
     98 static inline UInt32 BoolToUINT32(bool value) {  return (value ? 1: 0); }
     99 static inline bool UINT32ToBool(UInt32 value) {  return (value != 0); }
    100 
    101 
    102 LONG CKey::DeleteValue(LPCTSTR name) throw()
    103 {
    104  MYASSERT(_object != NULL);
    105  return ::RegDeleteValue(_object, name);
    106 }
    107 
    108 #ifndef _UNICODE
    109 LONG CKey::DeleteValue(LPCWSTR name)
    110 {
    111  MYASSERT(_object != NULL);
    112  if (g_IsNT)
    113    return ::RegDeleteValueW(_object, name);
    114  return DeleteValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name));
    115 }
    116 #endif
    117 
    118 LONG CKey::SetValue(LPCTSTR name, UInt32 value) throw()
    119 {
    120  MYASSERT(_object != NULL);
    121  return RegSetValueEx(_object, name, 0, REG_DWORD,
    122      (BYTE * const)&value, sizeof(UInt32));
    123 }
    124 
    125 LONG CKey::SetValue(LPCTSTR name, bool value) throw()
    126 {
    127  return SetValue(name, BoolToUINT32(value));
    128 }
    129 
    130 LONG CKey::SetValue(LPCTSTR name, LPCTSTR value) throw()
    131 {
    132  MYASSERT(value != NULL);
    133  MYASSERT(_object != NULL);
    134  return RegSetValueEx(_object, name, 0, REG_SZ,
    135      (const BYTE * )value, (lstrlen(value) + 1) * sizeof(TCHAR));
    136 }
    137 
    138 /*
    139 LONG CKey::SetValue(LPCTSTR name, const CSysString &value)
    140 {
    141  MYASSERT(value != NULL);
    142  MYASSERT(_object != NULL);
    143  return RegSetValueEx(_object, name, NULL, REG_SZ,
    144      (const BYTE *)(const TCHAR *)value, (value.Len() + 1) * sizeof(TCHAR));
    145 }
    146 */
    147 
    148 #ifndef _UNICODE
    149 
    150 LONG CKey::SetValue(LPCWSTR name, LPCWSTR value)
    151 {
    152  MYASSERT(value != NULL);
    153  MYASSERT(_object != NULL);
    154  if (g_IsNT)
    155    return RegSetValueExW(_object, name, 0, REG_SZ,
    156      (const BYTE * )value, (DWORD)((wcslen(value) + 1) * sizeof(wchar_t)));
    157  return SetValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name),
    158    value == 0 ? 0 : (LPCSTR)GetSystemString(value));
    159 }
    160 
    161 #endif
    162 
    163 
    164 LONG CKey::SetValue(LPCTSTR name, const void *value, UInt32 size) throw()
    165 {
    166  MYASSERT(value != NULL);
    167  MYASSERT(_object != NULL);
    168  return RegSetValueEx(_object, name, 0, REG_BINARY,
    169      (const BYTE *)value, size);
    170 }
    171 
    172 LONG SetValue(HKEY parentKey, LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value)
    173 {
    174  MYASSERT(value != NULL);
    175  CKey key;
    176  LONG res = key.Create(parentKey, keyName);
    177  if (res == ERROR_SUCCESS)
    178    res = key.SetValue(valueName, value);
    179  return res;
    180 }
    181 
    182 LONG CKey::SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value) throw()
    183 {
    184  MYASSERT(value != NULL);
    185  CKey key;
    186  LONG res = key.Create(_object, keyName);
    187  if (res == ERROR_SUCCESS)
    188    res = key.SetValue(valueName, value);
    189  return res;
    190 }
    191 
    192 LONG CKey::QueryValue(LPCTSTR name, UInt32 &value) throw()
    193 {
    194  DWORD type = 0;
    195  DWORD count = sizeof(DWORD);
    196  LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type,
    197    (LPBYTE)&value, &count);
    198  MYASSERT((res != ERROR_SUCCESS) || (type == REG_DWORD));
    199  MYASSERT((res != ERROR_SUCCESS) || (count == sizeof(UInt32)));
    200  return res;
    201 }
    202 
    203 LONG CKey::QueryValue(LPCTSTR name, bool &value) throw()
    204 {
    205  UInt32 uintValue = BoolToUINT32(value);
    206  LONG res = QueryValue(name, uintValue);
    207  value = UINT32ToBool(uintValue);
    208  return res;
    209 }
    210 
    211 LONG CKey::GetValue_IfOk(LPCTSTR name, UInt32 &value) throw()
    212 {
    213  UInt32 newVal;
    214  LONG res = QueryValue(name, newVal);
    215  if (res == ERROR_SUCCESS)
    216    value = newVal;
    217  return res;
    218 }
    219 
    220 LONG CKey::GetValue_IfOk(LPCTSTR name, bool &value) throw()
    221 {
    222  bool newVal;
    223  LONG res = QueryValue(name, newVal);
    224  if (res == ERROR_SUCCESS)
    225    value = newVal;
    226  return res;
    227 }
    228 
    229 LONG CKey::QueryValue(LPCTSTR name, LPTSTR value, UInt32 &count) throw()
    230 {
    231  DWORD type = 0;
    232  LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, (LPBYTE)value, (DWORD *)&count);
    233  MYASSERT((res != ERROR_SUCCESS) || (type == REG_SZ) || (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ));
    234  return res;
    235 }
    236 
    237 LONG CKey::QueryValue(LPCTSTR name, CSysString &value)
    238 {
    239  value.Empty();
    240  DWORD type = 0;
    241  UInt32 curSize = 0;
    242  LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, NULL, (DWORD *)&curSize);
    243  if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
    244    return res;
    245  UInt32 curSize2 = curSize;
    246  res = QueryValue(name, value.GetBuf(curSize), curSize2);
    247  if (curSize > curSize2)
    248    curSize = curSize2;
    249  value.ReleaseBuf_CalcLen(curSize / sizeof(TCHAR));
    250  return res;
    251 }
    252 
    253 
    254 #ifndef _UNICODE
    255 
    256 LONG CKey::QueryValue(LPCWSTR name, LPWSTR value, UInt32 &count)
    257 {
    258  DWORD type = 0;
    259  LONG res = RegQueryValueExW(_object, name, NULL, &type, (LPBYTE)value, (DWORD *)&count);
    260  MYASSERT((res != ERROR_SUCCESS) || (type == REG_SZ) || (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ));
    261  return res;
    262 }
    263 
    264 LONG CKey::QueryValue(LPCWSTR name, UString &value)
    265 {
    266  value.Empty();
    267  DWORD type = 0;
    268  UInt32 curSize = 0;
    269 
    270  LONG res;
    271 
    272  if (g_IsNT)
    273  {
    274    res = RegQueryValueExW(_object, name, NULL, &type, NULL, (DWORD *)&curSize);
    275    if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
    276      return res;
    277    UInt32 curSize2 = curSize;
    278    res = QueryValue(name, value.GetBuf(curSize), curSize2);
    279    if (curSize > curSize2)
    280      curSize = curSize2;
    281    value.ReleaseBuf_CalcLen(curSize / sizeof(wchar_t));
    282  }
    283  else
    284  {
    285    AString vTemp;
    286    res = QueryValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name), vTemp);
    287    value = GetUnicodeString(vTemp);
    288  }
    289  
    290  return res;
    291 }
    292 
    293 #endif
    294 
    295 
    296 LONG CKey::QueryValue(LPCTSTR name, void *value, UInt32 &count) throw()
    297 {
    298  DWORD type = 0;
    299  LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, (LPBYTE)value, (DWORD *)&count);
    300  MYASSERT((res != ERROR_SUCCESS) || (type == REG_BINARY));
    301  return res;
    302 }
    303 
    304 
    305 LONG CKey::QueryValue(LPCTSTR name, CByteBuffer &value, UInt32 &dataSize)
    306 {
    307  DWORD type = 0;
    308  dataSize = 0;
    309  LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, NULL, (DWORD *)&dataSize);
    310  if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
    311    return res;
    312  value.Alloc(dataSize);
    313  return QueryValue(name, (BYTE *)value, dataSize);
    314 }
    315 
    316 LONG CKey::EnumKeys(CSysStringVector &keyNames)
    317 {
    318  keyNames.Clear();
    319  CSysString keyName;
    320  for (DWORD index = 0; ; index++)
    321  {
    322    const unsigned kBufSize = MAX_PATH + 1; // 256 in ATL
    323    FILETIME lastWriteTime;
    324    UInt32 nameSize = kBufSize;
    325    LONG result = ::RegEnumKeyEx(_object, index, keyName.GetBuf(kBufSize),
    326        (DWORD *)&nameSize, NULL, NULL, NULL, &lastWriteTime);
    327    keyName.ReleaseBuf_CalcLen(kBufSize);
    328    if (result == ERROR_NO_MORE_ITEMS)
    329      break;
    330    if (result != ERROR_SUCCESS)
    331      return result;
    332    keyNames.Add(keyName);
    333  }
    334  return ERROR_SUCCESS;
    335 }
    336 
    337 LONG CKey::SetValue_Strings(LPCTSTR valueName, const UStringVector &strings)
    338 {
    339  size_t numChars = 0;
    340  
    341  unsigned i;
    342  
    343  for (i = 0; i < strings.Size(); i++)
    344    numChars += strings[i].Len() + 1;
    345  
    346  CObjArray<wchar_t> buffer(numChars);
    347  size_t pos = 0;
    348  
    349  for (i = 0; i < strings.Size(); i++)
    350  {
    351    const UString &s = strings[i];
    352    size_t size = s.Len() + 1;
    353    wmemcpy(buffer + pos, s, size);
    354    pos += size;
    355  }
    356  return SetValue(valueName, buffer, (UInt32)numChars * sizeof(wchar_t));
    357 }
    358 
    359 LONG CKey::GetValue_Strings(LPCTSTR valueName, UStringVector &strings)
    360 {
    361  strings.Clear();
    362  CByteBuffer buffer;
    363  UInt32 dataSize = 0;
    364  LONG res = QueryValue(valueName, buffer, dataSize);
    365  if (res != ERROR_SUCCESS)
    366    return res;
    367  if (dataSize > buffer.Size())
    368    return E_FAIL;
    369  if (dataSize % sizeof(wchar_t) != 0)
    370    return E_FAIL;
    371 
    372  const wchar_t *data = (const wchar_t *)(const Byte  *)buffer;
    373  size_t numChars = dataSize / sizeof(wchar_t);
    374  size_t prev = 0;
    375  UString s;
    376  
    377  for (size_t i = 0; i < numChars; i++)
    378  {
    379    if (data[i] == 0)
    380    {
    381      s = data + prev;
    382      strings.Add(s);
    383      prev = i + 1;
    384    }
    385  }
    386  
    387  return res;
    388 }
    389 
    390 }}