147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/*
247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Copyright 2003 The WebRTC Project Authors. All rights reserved.
347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *
447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Use of this source code is governed by a BSD-style license
547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  that can be found in the LICENSE file in the root of the source
647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  tree. An additional intellectual property rights grant can be found
747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  in the file PATENTS.  All contributing project authors may
847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */
1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Registry configuration wrapers class implementation
1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//
1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Change made by S. Ganesh - ganesh@google.com:
1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//   Use SHQueryValueEx instead of RegQueryValueEx throughout.
1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//   A call to the SHLWAPI function is essentially a call to the standard
1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//   function but with post-processing:
1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//   * to fix REG_SZ or REG_EXPAND_SZ data that is not properly null-terminated;
1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//   * to expand REG_EXPAND_SZ data.
1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/win32regkey.h"
2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <shlwapi.h>
2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/common.h"
2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/logging.h"
2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/scoped_ptr.h"
2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc {
2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgRegKey::RegKey() {
3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  h_key_ = NULL;
3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgRegKey::~RegKey() {
3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Close();
3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::Create(HKEY parent_key, const wchar_t* key_name) {
3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return Create(parent_key,
4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                key_name,
4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                REG_NONE,
4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                REG_OPTION_NON_VOLATILE,
4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                KEY_ALL_ACCESS,
4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                NULL,
4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                NULL);
4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::Open(HKEY parent_key, const wchar_t* key_name) {
4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return Open(parent_key, key_name, KEY_ALL_ACCESS);
5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool RegKey::HasValue(const TCHAR* value_name) const {
5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return (ERROR_SUCCESS == ::RegQueryValueEx(h_key_, value_name, NULL,
5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                             NULL, NULL, NULL));
5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::SetValue(const wchar_t* full_key_name,
5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         const wchar_t* value_name,
5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         DWORD value) {
6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return SetValueStaticHelper(full_key_name, value_name, REG_DWORD, &value);
6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::SetValue(const wchar_t* full_key_name,
6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         const wchar_t* value_name,
6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         DWORD64 value) {
6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return SetValueStaticHelper(full_key_name, value_name, REG_QWORD, &value);
7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::SetValue(const wchar_t* full_key_name,
7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         const wchar_t* value_name,
7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         float value) {
7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return SetValueStaticHelper(full_key_name, value_name,
7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                              REG_BINARY, &value, sizeof(value));
8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::SetValue(const wchar_t* full_key_name,
8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         const wchar_t* value_name,
8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         double value) {
8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return SetValueStaticHelper(full_key_name, value_name,
8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                              REG_BINARY, &value, sizeof(value));
8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::SetValue(const wchar_t* full_key_name,
9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         const wchar_t* value_name,
9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         const TCHAR* value) {
9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(value != NULL);
9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return SetValueStaticHelper(full_key_name, value_name,
9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                              REG_SZ, const_cast<wchar_t*>(value));
9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::SetValue(const wchar_t* full_key_name,
10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         const wchar_t* value_name,
10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         const uint8* value,
10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         DWORD byte_count) {
10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return SetValueStaticHelper(full_key_name, value_name, REG_BINARY,
10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                              const_cast<uint8*>(value), byte_count);
10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::SetValueMultiSZ(const wchar_t* full_key_name,
11247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                const wchar_t* value_name,
11347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                const uint8* value,
11447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                DWORD byte_count) {
11547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return SetValueStaticHelper(full_key_name, value_name, REG_MULTI_SZ,
11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                              const_cast<uint8*>(value), byte_count);
11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::GetValue(const wchar_t* full_key_name,
12247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         const wchar_t* value_name,
12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         DWORD* value) {
12447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
12547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(value != NULL);
12647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return GetValueStaticHelper(full_key_name, value_name, REG_DWORD, value);
12847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
12947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
13047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::GetValue(const wchar_t* full_key_name,
13147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         const wchar_t* value_name,
13247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         DWORD64* value) {
13347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
13447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(value != NULL);
13547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
13647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return GetValueStaticHelper(full_key_name, value_name, REG_QWORD, value);
13747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
13847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
13947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::GetValue(const wchar_t* full_key_name,
14047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         const wchar_t* value_name,
14147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         float* value) {
14247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(value != NULL);
14347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
14447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
14547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD byte_count = 0;
14647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<byte[]> buffer;
14747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = GetValueStaticHelper(full_key_name, value_name,
14847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                    REG_BINARY, buffer.accept(), &byte_count);
14947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (SUCCEEDED(hr)) {
15047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(byte_count == sizeof(*value));
15147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (byte_count == sizeof(*value)) {
15247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      *value = *reinterpret_cast<float*>(buffer.get());
15347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
15447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
15547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return hr;
15647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
15747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
15847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::GetValue(const wchar_t* full_key_name,
15947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         const wchar_t* value_name,
16047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         double* value) {
16147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(value != NULL);
16247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
16347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
16447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD byte_count = 0;
16547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<byte[]> buffer;
16647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = GetValueStaticHelper(full_key_name, value_name,
16747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                    REG_BINARY, buffer.accept(), &byte_count);
16847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (SUCCEEDED(hr)) {
16947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(byte_count == sizeof(*value));
17047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (byte_count == sizeof(*value)) {
17147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      *value = *reinterpret_cast<double*>(buffer.get());
17247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
17347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
17447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return hr;
17547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
17647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
17747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::GetValue(const wchar_t* full_key_name,
17847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         const wchar_t* value_name,
17947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         wchar_t** value) {
18047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
18147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(value != NULL);
18247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
18347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return GetValueStaticHelper(full_key_name, value_name, REG_SZ, value);
18447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
18547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
18647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::GetValue(const wchar_t* full_key_name,
18747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         const wchar_t* value_name,
18847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         std::wstring* value) {
18947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
19047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(value != NULL);
19147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
19247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<wchar_t[]> buffer;
19347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = RegKey::GetValue(full_key_name, value_name, buffer.accept());
19447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (SUCCEEDED(hr)) {
19547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    value->assign(buffer.get());
19647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
19747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return hr;
19847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
19947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
20047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::GetValue(const wchar_t* full_key_name,
20147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         const wchar_t* value_name,
20247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         std::vector<std::wstring>* value) {
20347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
20447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(value != NULL);
20547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
20647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return GetValueStaticHelper(full_key_name, value_name, REG_MULTI_SZ, value);
20747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
20847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
20947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::GetValue(const wchar_t* full_key_name,
21047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         const wchar_t* value_name,
21147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         uint8** value,
21247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         DWORD* byte_count) {
21347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
21447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(value != NULL);
21547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(byte_count != NULL);
21647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
21747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return GetValueStaticHelper(full_key_name, value_name,
21847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                              REG_BINARY, value, byte_count);
21947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
22047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
22147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::DeleteSubKey(const wchar_t* key_name) {
22247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(key_name != NULL);
22347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(h_key_ != NULL);
22447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
22547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LONG res = ::RegDeleteKey(h_key_, key_name);
22647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = HRESULT_FROM_WIN32(res);
22747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) ||
22847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)) {
22947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    hr = S_FALSE;
23047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
23147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return hr;
23247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
23347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
23447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::DeleteValue(const wchar_t* value_name) {
23547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(h_key_ != NULL);
23647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
23747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LONG res = ::RegDeleteValue(h_key_, value_name);
23847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = HRESULT_FROM_WIN32(res);
23947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) ||
24047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)) {
24147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    hr = S_FALSE;
24247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
24347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return hr;
24447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
24547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
24647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::Close() {
24747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = S_OK;
24847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (h_key_ != NULL) {
24947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LONG res = ::RegCloseKey(h_key_);
25047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    hr = HRESULT_FROM_WIN32(res);
25147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    h_key_ = NULL;
25247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
25347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return hr;
25447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
25547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
25647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::Create(HKEY parent_key,
25747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                       const wchar_t* key_name,
25847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                       wchar_t* lpszClass,
25947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                       DWORD options,
26047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                       REGSAM sam_desired,
26147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                       LPSECURITY_ATTRIBUTES lpSecAttr,
26247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                       LPDWORD lpdwDisposition) {
26347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(key_name != NULL);
26447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(parent_key != NULL);
26547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
26647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD dw = 0;
26747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HKEY h_key = NULL;
26847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LONG res = ::RegCreateKeyEx(parent_key, key_name, 0, lpszClass, options,
26947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                              sam_desired, lpSecAttr, &h_key, &dw);
27047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = HRESULT_FROM_WIN32(res);
27147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
27247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (lpdwDisposition) {
27347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *lpdwDisposition = dw;
27447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
27547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
27647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // we have to close the currently opened key
27747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // before replacing it with the new one
27847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (hr == S_OK) {
27947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    hr = Close();
28047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(hr == S_OK);
28147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    h_key_ = h_key;
28247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
28347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return hr;
28447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
28547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
28647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::Open(HKEY parent_key,
28747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                     const wchar_t* key_name,
28847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                     REGSAM sam_desired) {
28947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(key_name != NULL);
29047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(parent_key != NULL);
29147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
29247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HKEY h_key = NULL;
29347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LONG res = ::RegOpenKeyEx(parent_key, key_name, 0, sam_desired, &h_key);
29447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = HRESULT_FROM_WIN32(res);
29547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
29647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // we have to close the currently opened key
29747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // before replacing it with the new one
29847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (hr == S_OK) {
29947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // close the currently opened key if any
30047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    hr = Close();
30147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(hr == S_OK);
30247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    h_key_ = h_key;
30347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
30447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return hr;
30547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
30647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
30747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// save the key and all of its subkeys and values to a file
30847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::Save(const wchar_t* full_key_name, const wchar_t* file_name) {
30947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
31047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(file_name != NULL);
31147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
31247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::wstring key_name(full_key_name);
31347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HKEY h_key = GetRootKeyInfo(&key_name);
31447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!h_key) {
31547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return E_FAIL;
31647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
31747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
31847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  RegKey key;
31947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = key.Open(h_key, key_name.c_str(), KEY_READ);
32047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (FAILED(hr)) {
32147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return hr;
32247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
32347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
32447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  AdjustCurrentProcessPrivilege(SE_BACKUP_NAME, true);
32547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LONG res = ::RegSaveKey(key.h_key_, file_name, NULL);
32647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  AdjustCurrentProcessPrivilege(SE_BACKUP_NAME, false);
32747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
32847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return HRESULT_FROM_WIN32(res);
32947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
33047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
33147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// restore the key and all of its subkeys and values which are saved into a file
33247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::Restore(const wchar_t* full_key_name,
33347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                        const wchar_t* file_name) {
33447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
33547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(file_name != NULL);
33647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
33747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::wstring key_name(full_key_name);
33847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HKEY h_key = GetRootKeyInfo(&key_name);
33947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!h_key) {
34047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return E_FAIL;
34147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
34247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
34347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  RegKey key;
34447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = key.Open(h_key, key_name.c_str(), KEY_WRITE);
34547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (FAILED(hr)) {
34647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return hr;
34747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
34847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
34947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  AdjustCurrentProcessPrivilege(SE_RESTORE_NAME, true);
35047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LONG res = ::RegRestoreKey(key.h_key_, file_name, REG_FORCE_RESTORE);
35147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  AdjustCurrentProcessPrivilege(SE_RESTORE_NAME, false);
35247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
35347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return HRESULT_FROM_WIN32(res);
35447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
35547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
35647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// check if the current key has the specified subkey
35747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool RegKey::HasSubkey(const wchar_t* key_name) const {
35847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(key_name != NULL);
35947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
36047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  RegKey key;
36147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = key.Open(h_key_, key_name, KEY_READ);
36247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  key.Close();
36347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return hr == S_OK;
36447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
36547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
36647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// static flush key
36747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::FlushKey(const wchar_t* full_key_name) {
36847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
36947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
37047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND);
37147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // get the root HKEY
37247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::wstring key_name(full_key_name);
37347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HKEY h_key = GetRootKeyInfo(&key_name);
37447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
37547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (h_key != NULL) {
37647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LONG res = ::RegFlushKey(h_key);
37747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    hr = HRESULT_FROM_WIN32(res);
37847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
37947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return hr;
38047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
38147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
38247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// static SET helper
38347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::SetValueStaticHelper(const wchar_t* full_key_name,
38447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                     const wchar_t* value_name,
38547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                     DWORD type,
38647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                     LPVOID value,
38747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                     DWORD byte_count) {
38847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
38947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
39047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND);
39147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // get the root HKEY
39247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::wstring key_name(full_key_name);
39347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HKEY h_key = GetRootKeyInfo(&key_name);
39447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
39547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (h_key != NULL) {
39647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    RegKey key;
39747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    hr = key.Create(h_key, key_name.c_str());
39847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (hr == S_OK) {
39947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      switch (type) {
40047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        case REG_DWORD:
40147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          hr = key.SetValue(value_name, *(static_cast<DWORD*>(value)));
40247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          break;
40347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        case REG_QWORD:
40447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          hr = key.SetValue(value_name, *(static_cast<DWORD64*>(value)));
40547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          break;
40647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        case REG_SZ:
40747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          hr = key.SetValue(value_name, static_cast<const wchar_t*>(value));
40847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          break;
40947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        case REG_BINARY:
41047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          hr = key.SetValue(value_name, static_cast<const uint8*>(value),
41147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                            byte_count);
41247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          break;
41347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        case REG_MULTI_SZ:
41447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          hr = key.SetValue(value_name, static_cast<const uint8*>(value),
41547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                            byte_count, type);
41647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          break;
41747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        default:
41847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          ASSERT(false);
41947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          hr = HRESULT_FROM_WIN32(ERROR_DATATYPE_MISMATCH);
42047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          break;
42147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
42247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // close the key after writing
42347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      HRESULT temp_hr = key.Close();
42447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (hr == S_OK) {
42547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        hr = temp_hr;
42647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
42747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
42847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
42947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return hr;
43047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
43147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
43247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// static GET helper
43347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::GetValueStaticHelper(const wchar_t* full_key_name,
43447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                     const wchar_t* value_name,
43547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                     DWORD type,
43647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                     LPVOID value,
43747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                     DWORD* byte_count) {
43847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
43947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
44047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND);
44147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // get the root HKEY
44247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::wstring key_name(full_key_name);
44347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HKEY h_key = GetRootKeyInfo(&key_name);
44447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
44547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (h_key != NULL) {
44647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    RegKey key;
44747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    hr = key.Open(h_key, key_name.c_str(), KEY_READ);
44847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (hr == S_OK) {
44947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      switch (type) {
45047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        case REG_DWORD:
45147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          hr = key.GetValue(value_name, reinterpret_cast<DWORD*>(value));
45247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          break;
45347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        case REG_QWORD:
45447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          hr = key.GetValue(value_name, reinterpret_cast<DWORD64*>(value));
45547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          break;
45647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        case REG_SZ:
45747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          hr = key.GetValue(value_name, reinterpret_cast<wchar_t**>(value));
45847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          break;
45947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        case REG_MULTI_SZ:
46047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          hr = key.GetValue(value_name, reinterpret_cast<
46147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                            std::vector<std::wstring>*>(value));
46247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          break;
46347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        case REG_BINARY:
46447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          hr = key.GetValue(value_name, reinterpret_cast<uint8**>(value),
46547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                            byte_count);
46647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          break;
46747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        default:
46847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          ASSERT(false);
46947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          hr = HRESULT_FROM_WIN32(ERROR_DATATYPE_MISMATCH);
47047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          break;
47147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
47247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // close the key after writing
47347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      HRESULT temp_hr = key.Close();
47447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (hr == S_OK) {
47547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        hr = temp_hr;
47647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
47747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
47847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
47947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return hr;
48047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
48147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
48247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// GET helper
48347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::GetValueHelper(const wchar_t* value_name,
48447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                               DWORD* type,
48547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                               uint8** value,
48647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                               DWORD* byte_count) const {
48747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(byte_count != NULL);
48847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(value != NULL);
48947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(type != NULL);
49047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
49147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // init return buffer
49247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  *value = NULL;
49347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
49447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // get the size of the return data buffer
49547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LONG res = ::SHQueryValueEx(h_key_, value_name, NULL, type, NULL, byte_count);
49647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = HRESULT_FROM_WIN32(res);
49747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
49847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (hr == S_OK) {
49947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // if the value length is 0, nothing to do
50047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (*byte_count != 0) {
50147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // allocate the buffer
50247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      *value = new byte[*byte_count];
50347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ASSERT(*value != NULL);
50447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
50547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // make the call again to get the data
50647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      res = ::SHQueryValueEx(h_key_, value_name, NULL,
50747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                             type, *value, byte_count);
50847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      hr = HRESULT_FROM_WIN32(res);
50947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ASSERT(hr == S_OK);
51047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
51147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
51247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return hr;
51347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
51447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
51547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Int32 Get
51647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::GetValue(const wchar_t* value_name, DWORD* value) const {
51747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(value != NULL);
51847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
51947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD type = 0;
52047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD byte_count = sizeof(DWORD);
52147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LONG res = ::SHQueryValueEx(h_key_, value_name, NULL, &type,
52247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                              value, &byte_count);
52347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = HRESULT_FROM_WIN32(res);
52447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT((hr != S_OK) || (type == REG_DWORD));
52547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT((hr != S_OK) || (byte_count == sizeof(DWORD)));
52647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return hr;
52747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
52847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
52947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Int64 Get
53047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::GetValue(const wchar_t* value_name, DWORD64* value) const {
53147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(value != NULL);
53247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
53347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD type = 0;
53447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD byte_count = sizeof(DWORD64);
53547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LONG res = ::SHQueryValueEx(h_key_, value_name, NULL, &type,
53647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                              value, &byte_count);
53747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = HRESULT_FROM_WIN32(res);
53847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT((hr != S_OK) || (type == REG_QWORD));
53947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT((hr != S_OK) || (byte_count == sizeof(DWORD64)));
54047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return hr;
54147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
54247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
54347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// String Get
54447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::GetValue(const wchar_t* value_name, wchar_t** value) const {
54547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(value != NULL);
54647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
54747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD byte_count = 0;
54847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD type = 0;
54947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
55047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // first get the size of the string buffer
55147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LONG res = ::SHQueryValueEx(h_key_, value_name, NULL,
55247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                              &type, NULL, &byte_count);
55347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = HRESULT_FROM_WIN32(res);
55447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
55547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (hr == S_OK) {
55647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // allocate room for the string and a terminating \0
55747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *value = new wchar_t[(byte_count / sizeof(wchar_t)) + 1];
55847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
55947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if ((*value) != NULL) {
56047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (byte_count != 0) {
56147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        // make the call again
56247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        res = ::SHQueryValueEx(h_key_, value_name, NULL, &type,
56347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                               *value, &byte_count);
56447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        hr = HRESULT_FROM_WIN32(res);
56547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      } else {
56647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        (*value)[0] = L'\0';
56747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
56847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
56947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ASSERT((hr != S_OK) || (type == REG_SZ) ||
57047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org             (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ));
57147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } else {
57247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      hr = E_OUTOFMEMORY;
57347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
57447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
57547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
57647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return hr;
57747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
57847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
57947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// get a string value
58047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::GetValue(const wchar_t* value_name, std::wstring* value) const {
58147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(value != NULL);
58247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
58347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD byte_count = 0;
58447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD type = 0;
58547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
58647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // first get the size of the string buffer
58747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LONG res = ::SHQueryValueEx(h_key_, value_name, NULL,
58847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                              &type, NULL, &byte_count);
58947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = HRESULT_FROM_WIN32(res);
59047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
59147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (hr == S_OK) {
59247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (byte_count != 0) {
59347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // Allocate some memory and make the call again
59447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      value->resize(byte_count / sizeof(wchar_t) + 1);
59547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      res = ::SHQueryValueEx(h_key_, value_name, NULL, &type,
59647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                             &value->at(0), &byte_count);
59747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      hr = HRESULT_FROM_WIN32(res);
59847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      value->resize(wcslen(value->data()));
59947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } else {
60047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      value->clear();
60147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
60247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
60347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT((hr != S_OK) || (type == REG_SZ) ||
60447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org           (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ));
60547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
60647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
60747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return hr;
60847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
60947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
61047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// convert REG_MULTI_SZ bytes to string array
61147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::MultiSZBytesToStringArray(const uint8* buffer,
61247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                          DWORD byte_count,
61347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                          std::vector<std::wstring>* value) {
61447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(buffer != NULL);
61547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(value != NULL);
61647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
61747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const wchar_t* data = reinterpret_cast<const wchar_t*>(buffer);
61847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD data_len = byte_count / sizeof(wchar_t);
61947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  value->clear();
62047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (data_len > 1) {
62147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // must be terminated by two null characters
62247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (data[data_len - 1] != 0 || data[data_len - 2] != 0) {
62347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return E_INVALIDARG;
62447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
62547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
62647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // put null-terminated strings into arrays
62747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    while (*data) {
62847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      std::wstring str(data);
62947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      value->push_back(str);
63047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      data += str.length() + 1;
63147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
63247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
63347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return S_OK;
63447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
63547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
63647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// get a std::vector<std::wstring> value from REG_MULTI_SZ type
63747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::GetValue(const wchar_t* value_name,
63847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         std::vector<std::wstring>* value) const {
63947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(value != NULL);
64047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
64147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD byte_count = 0;
64247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD type = 0;
64347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  uint8* buffer = 0;
64447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
64547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // first get the size of the buffer
64647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = GetValueHelper(value_name, &type, &buffer, &byte_count);
64747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT((hr != S_OK) || (type == REG_MULTI_SZ));
64847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
64947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (SUCCEEDED(hr)) {
65047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    hr = MultiSZBytesToStringArray(buffer, byte_count, value);
65147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
65247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
65347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return hr;
65447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
65547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
65647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Binary data Get
65747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::GetValue(const wchar_t* value_name,
65847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         uint8** value,
65947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         DWORD* byte_count) const {
66047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(byte_count != NULL);
66147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(value != NULL);
66247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
66347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD type = 0;
66447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = GetValueHelper(value_name, &type, value, byte_count);
66547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT((hr != S_OK) || (type == REG_MULTI_SZ) || (type == REG_BINARY));
66647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return hr;
66747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
66847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
66947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Raw data get
67047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::GetValue(const wchar_t* value_name,
67147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         uint8** value,
67247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         DWORD* byte_count,
67347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         DWORD*type) const {
67447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(type != NULL);
67547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(byte_count != NULL);
67647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(value != NULL);
67747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
67847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return GetValueHelper(value_name, type, value, byte_count);
67947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
68047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
68147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Int32 set
68247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::SetValue(const wchar_t* value_name, DWORD value) const {
68347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(h_key_ != NULL);
68447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
68547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LONG res = ::RegSetValueEx(h_key_, value_name, NULL, REG_DWORD,
68647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                             reinterpret_cast<const uint8*>(&value),
68747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                             sizeof(DWORD));
68847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return HRESULT_FROM_WIN32(res);
68947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
69047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
69147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Int64 set
69247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::SetValue(const wchar_t* value_name, DWORD64 value) const {
69347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(h_key_ != NULL);
69447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
69547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LONG res = ::RegSetValueEx(h_key_, value_name, NULL, REG_QWORD,
69647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                             reinterpret_cast<const uint8*>(&value),
69747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                             sizeof(DWORD64));
69847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return HRESULT_FROM_WIN32(res);
69947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
70047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
70147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// String set
70247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::SetValue(const wchar_t* value_name,
70347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         const wchar_t* value) const {
70447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(value != NULL);
70547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(h_key_ != NULL);
70647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
70747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LONG res = ::RegSetValueEx(h_key_, value_name, NULL, REG_SZ,
70847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                             reinterpret_cast<const uint8*>(value),
70947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                             (lstrlen(value) + 1) * sizeof(wchar_t));
71047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return HRESULT_FROM_WIN32(res);
71147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
71247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
71347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Binary data set
71447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::SetValue(const wchar_t* value_name,
71547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         const uint8* value,
71647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         DWORD byte_count) const {
71747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(h_key_ != NULL);
71847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
71947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // special case - if 'value' is NULL make sure byte_count is zero
72047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (value == NULL) {
72147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    byte_count = 0;
72247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
72347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
72447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LONG res = ::RegSetValueEx(h_key_, value_name, NULL,
72547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                             REG_BINARY, value, byte_count);
72647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return HRESULT_FROM_WIN32(res);
72747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
72847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
72947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Raw data set
73047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::SetValue(const wchar_t* value_name,
73147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         const uint8* value,
73247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         DWORD byte_count,
73347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         DWORD type) const {
73447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(value != NULL);
73547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(h_key_ != NULL);
73647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
73747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LONG res = ::RegSetValueEx(h_key_, value_name, NULL, type, value, byte_count);
73847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return HRESULT_FROM_WIN32(res);
73947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
74047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
74147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool RegKey::HasKey(const wchar_t* full_key_name) {
74247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
74347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
74447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // get the root HKEY
74547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::wstring key_name(full_key_name);
74647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HKEY h_key = GetRootKeyInfo(&key_name);
74747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
74847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (h_key != NULL) {
74947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    RegKey key;
75047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    HRESULT hr = key.Open(h_key, key_name.c_str(), KEY_READ);
75147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    key.Close();
75247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return S_OK == hr;
75347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
75447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return false;
75547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
75647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
75747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// static version of HasValue
75847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool RegKey::HasValue(const wchar_t* full_key_name, const wchar_t* value_name) {
75947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
76047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
76147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool has_value = false;
76247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // get the root HKEY
76347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::wstring key_name(full_key_name);
76447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HKEY h_key = GetRootKeyInfo(&key_name);
76547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
76647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (h_key != NULL) {
76747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    RegKey key;
76847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (key.Open(h_key, key_name.c_str(), KEY_READ) == S_OK) {
76947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      has_value = key.HasValue(value_name);
77047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      key.Close();
77147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
77247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
77347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return has_value;
77447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
77547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
77647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::GetValueType(const wchar_t* full_key_name,
77747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                             const wchar_t* value_name,
77847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                             DWORD* value_type) {
77947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
78047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(value_type != NULL);
78147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
78247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  *value_type = REG_NONE;
78347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
78447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::wstring key_name(full_key_name);
78547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HKEY h_key = GetRootKeyInfo(&key_name);
78647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
78747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  RegKey key;
78847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = key.Open(h_key, key_name.c_str(), KEY_READ);
78947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (SUCCEEDED(hr)) {
79047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LONG res = ::SHQueryValueEx(key.h_key_, value_name, NULL, value_type,
79147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                NULL, NULL);
79247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (res != ERROR_SUCCESS) {
79347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      hr = HRESULT_FROM_WIN32(res);
79447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
79547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
79647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
79747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return hr;
79847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
79947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
80047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::DeleteKey(const wchar_t* full_key_name) {
80147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
80247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
80347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return DeleteKey(full_key_name, true);
80447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
80547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
80647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::DeleteKey(const wchar_t* full_key_name, bool recursively) {
80747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
80847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
80947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // need to open the parent key first
81047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // get the root HKEY
81147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::wstring key_name(full_key_name);
81247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HKEY h_key = GetRootKeyInfo(&key_name);
81347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
81447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // get the parent key
81547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::wstring parent_key(GetParentKeyInfo(&key_name));
81647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
81747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  RegKey key;
81847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = key.Open(h_key, parent_key.c_str());
81947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
82047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (hr == S_OK) {
82147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    hr = recursively ? key.RecurseDeleteSubKey(key_name.c_str())
82247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                     : key.DeleteSubKey(key_name.c_str());
82347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) ||
82447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org             hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)) {
82547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    hr = S_FALSE;
82647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
82747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
82847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  key.Close();
82947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return hr;
83047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
83147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
83247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::DeleteValue(const wchar_t* full_key_name,
83347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                            const wchar_t* value_name) {
83447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
83547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
83647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND);
83747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // get the root HKEY
83847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::wstring key_name(full_key_name);
83947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HKEY h_key = GetRootKeyInfo(&key_name);
84047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
84147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (h_key != NULL) {
84247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    RegKey key;
84347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    hr = key.Open(h_key, key_name.c_str());
84447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (hr == S_OK) {
84547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      hr = key.DeleteValue(value_name);
84647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      key.Close();
84747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
84847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
84947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return hr;
85047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
85147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
85247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::RecurseDeleteSubKey(const wchar_t* key_name) {
85347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(key_name != NULL);
85447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
85547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  RegKey key;
85647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = key.Open(h_key_, key_name);
85747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
85847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (hr == S_OK) {
85947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // enumerate all subkeys of this key and recursivelly delete them
86047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    FILETIME time = {0};
86147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    wchar_t key_name_buf[kMaxKeyNameChars] = {0};
86247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    DWORD key_name_buf_size = kMaxKeyNameChars;
86347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    while (hr == S_OK &&
86447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        ::RegEnumKeyEx(key.h_key_, 0, key_name_buf, &key_name_buf_size,
86547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                       NULL, NULL, NULL,  &time) == ERROR_SUCCESS) {
86647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      hr = key.RecurseDeleteSubKey(key_name_buf);
86747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
86847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // restore the buffer size
86947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      key_name_buf_size = kMaxKeyNameChars;
87047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
87147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // close the top key
87247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    key.Close();
87347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
87447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
87547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (hr == S_OK) {
87647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // the key has no more children keys
87747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // delete the key and all of its values
87847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    hr = DeleteSubKey(key_name);
87947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
88047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
88147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return hr;
88247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
88347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
88447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHKEY RegKey::GetRootKeyInfo(std::wstring* full_key_name) {
88547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
88647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
88747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HKEY h_key = NULL;
88847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // get the root HKEY
88947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t index = full_key_name->find(L'\\');
89047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::wstring root_key;
89147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
89247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (index == -1) {
89347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    root_key = *full_key_name;
89447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *full_key_name = L"";
89547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else {
89647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    root_key = full_key_name->substr(0, index);
89747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *full_key_name = full_key_name->substr(index + 1,
89847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                           full_key_name->length() - index - 1);
89947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
90047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
90147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  for (std::wstring::iterator iter = root_key.begin();
90247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org       iter != root_key.end(); ++iter) {
90347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *iter = toupper(*iter);
90447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
90547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
90647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!root_key.compare(L"HKLM") ||
90747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      !root_key.compare(L"HKEY_LOCAL_MACHINE")) {
90847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    h_key = HKEY_LOCAL_MACHINE;
90947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else if (!root_key.compare(L"HKCU") ||
91047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org             !root_key.compare(L"HKEY_CURRENT_USER")) {
91147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    h_key = HKEY_CURRENT_USER;
91247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else if (!root_key.compare(L"HKU") ||
91347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org             !root_key.compare(L"HKEY_USERS")) {
91447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    h_key = HKEY_USERS;
91547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else if (!root_key.compare(L"HKCR") ||
91647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org             !root_key.compare(L"HKEY_CLASSES_ROOT")) {
91747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    h_key = HKEY_CLASSES_ROOT;
91847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
91947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
92047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return h_key;
92147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
92247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
92347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
92447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Returns true if this key name is 'safe' for deletion
92547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// (doesn't specify a key root)
92647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool RegKey::SafeKeyNameForDeletion(const wchar_t* key_name) {
92747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(key_name != NULL);
92847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::wstring key(key_name);
92947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
93047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HKEY root_key = GetRootKeyInfo(&key);
93147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
93247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!root_key) {
93347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    key = key_name;
93447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
93547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (key.empty()) {
93647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
93747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
93847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool found_subkey = false, backslash_found = false;
93947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  for (size_t i = 0 ; i < key.length() ; ++i) {
94047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (key[i] == L'\\') {
94147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      backslash_found = true;
94247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } else if (backslash_found) {
94347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      found_subkey = true;
94447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      break;
94547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
94647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
94747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return (root_key == HKEY_USERS) ? found_subkey : true;
94847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
94947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
95047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstd::wstring RegKey::GetParentKeyInfo(std::wstring* key_name) {
95147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(key_name != NULL);
95247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
95347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // get the parent key
95447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t index = key_name->rfind(L'\\');
95547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::wstring parent_key;
95647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (index == -1) {
95747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    parent_key = L"";
95847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else {
95947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    parent_key = key_name->substr(0, index);
96047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *key_name = key_name->substr(index + 1, key_name->length() - index - 1);
96147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
96247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
96347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return parent_key;
96447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
96547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
96647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// get the number of values for this key
96747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orguint32 RegKey::GetValueCount() {
96847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD num_values = 0;
96947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
97047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (ERROR_SUCCESS != ::RegQueryInfoKey(
97147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        h_key_,  // key handle
97247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        NULL,  // buffer for class name
97347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        NULL,  // size of class string
97447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        NULL,  // reserved
97547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        NULL,  // number of subkeys
97647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        NULL,  // longest subkey size
97747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        NULL,  // longest class string
97847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        &num_values,  // number of values for this key
97947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        NULL,  // longest value name
98047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        NULL,  // longest value data
98147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        NULL,  // security descriptor
98247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        NULL)) {  // last write time
98347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(false);
98447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
98547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return num_values;
98647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
98747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
98847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Enumerators for the value_names for this key
98947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
99047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Called to get the value name for the given value name index
99147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Use GetValueCount() to get the total value_name count for this key
99247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Returns failure if no key at the specified index
99347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::GetValueNameAt(int index, std::wstring* value_name,
99447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                               DWORD* type) {
99547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(value_name != NULL);
99647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
99747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LONG res = ERROR_SUCCESS;
99847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  wchar_t value_name_buf[kMaxValueNameChars] = {0};
99947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD value_name_buf_size = kMaxValueNameChars;
100047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  res = ::RegEnumValue(h_key_, index, value_name_buf, &value_name_buf_size,
100147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                       NULL, type, NULL, NULL);
100247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
100347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (res == ERROR_SUCCESS) {
100447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    value_name->assign(value_name_buf);
100547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
100647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
100747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return HRESULT_FROM_WIN32(res);
100847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
100947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
101047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orguint32 RegKey::GetSubkeyCount() {
101147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // number of values for key
101247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD num_subkeys = 0;
101347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
101447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (ERROR_SUCCESS != ::RegQueryInfoKey(
101547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          h_key_,  // key handle
101647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          NULL,  // buffer for class name
101747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          NULL,  // size of class string
101847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          NULL,  // reserved
101947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          &num_subkeys,  // number of subkeys
102047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          NULL,  // longest subkey size
102147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          NULL,  // longest class string
102247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          NULL,  // number of values for this key
102347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          NULL,  // longest value name
102447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          NULL,  // longest value data
102547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          NULL,  // security descriptor
102647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          NULL)) { // last write time
102747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(false);
102847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
102947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return num_subkeys;
103047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
103147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
103247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgHRESULT RegKey::GetSubkeyNameAt(int index, std::wstring* key_name) {
103347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(key_name != NULL);
103447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
103547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LONG res = ERROR_SUCCESS;
103647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  wchar_t key_name_buf[kMaxKeyNameChars] = {0};
103747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD key_name_buf_size = kMaxKeyNameChars;
103847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
103947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  res = ::RegEnumKeyEx(h_key_, index, key_name_buf, &key_name_buf_size,
104047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                       NULL, NULL, NULL, NULL);
104147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
104247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (res == ERROR_SUCCESS) {
104347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    key_name->assign(key_name_buf);
104447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
104547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
104647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return HRESULT_FROM_WIN32(res);
104747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
104847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
104947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Is the key empty: having no sub-keys and values
105047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool RegKey::IsKeyEmpty(const wchar_t* full_key_name) {
105147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(full_key_name != NULL);
105247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
105347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool is_empty = true;
105447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
105547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Get the root HKEY
105647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::wstring key_name(full_key_name);
105747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HKEY h_key = GetRootKeyInfo(&key_name);
105847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
105947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Open the key to check
106047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (h_key != NULL) {
106147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    RegKey key;
106247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    HRESULT hr = key.Open(h_key, key_name.c_str(), KEY_READ);
106347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (SUCCEEDED(hr)) {
106447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      is_empty = key.GetSubkeyCount() == 0 && key.GetValueCount() == 0;
106547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      key.Close();
106647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
106747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
106847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
106947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return is_empty;
107047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
107147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
107247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool AdjustCurrentProcessPrivilege(const TCHAR* privilege, bool to_enable) {
107347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(privilege != NULL);
107447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
107547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool ret = false;
107647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HANDLE token;
107747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (::OpenProcessToken(::GetCurrentProcess(),
107847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) {
107947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LUID luid;
108047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    memset(&luid, 0, sizeof(luid));
108147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (::LookupPrivilegeValue(NULL, privilege, &luid)) {
108247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      TOKEN_PRIVILEGES privs;
108347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      privs.PrivilegeCount = 1;
108447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      privs.Privileges[0].Luid = luid;
108547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      privs.Privileges[0].Attributes = to_enable ? SE_PRIVILEGE_ENABLED : 0;
108647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (::AdjustTokenPrivileges(token, FALSE, &privs, 0, NULL, 0)) {
108747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        ret = true;
108847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      } else {
108947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        LOG_GLE(LS_ERROR) << "AdjustTokenPrivileges failed";
109047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
109147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } else {
109247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      LOG_GLE(LS_ERROR) << "LookupPrivilegeValue failed";
109347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
109447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    CloseHandle(token);
109547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else {
109647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG_GLE(LS_ERROR) << "OpenProcessToken(GetCurrentProcess) failed";
109747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
109847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
109947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return ret;
110047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
110147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
110247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}  // namespace rtc
1103