| Index: webrtc/base/win32regkey.cc
|
| diff --git a/webrtc/base/win32regkey.cc b/webrtc/base/win32regkey.cc
|
| deleted file mode 100644
|
| index 447086aff5fcfffcaf544ec513004490a48e1204..0000000000000000000000000000000000000000
|
| --- a/webrtc/base/win32regkey.cc
|
| +++ /dev/null
|
| @@ -1,1106 +0,0 @@
|
| -/*
|
| - * Copyright 2003 The WebRTC Project Authors. All rights reserved.
|
| - *
|
| - * Use of this source code is governed by a BSD-style license
|
| - * that can be found in the LICENSE file in the root of the source
|
| - * tree. An additional intellectual property rights grant can be found
|
| - * in the file PATENTS. All contributing project authors may
|
| - * be found in the AUTHORS file in the root of the source tree.
|
| - */
|
| -
|
| -// Registry configuration wrapers class implementation
|
| -//
|
| -// Change made by S. Ganesh - ganesh@google.com:
|
| -// Use SHQueryValueEx instead of RegQueryValueEx throughout.
|
| -// A call to the SHLWAPI function is essentially a call to the standard
|
| -// function but with post-processing:
|
| -// * to fix REG_SZ or REG_EXPAND_SZ data that is not properly null-terminated;
|
| -// * to expand REG_EXPAND_SZ data.
|
| -
|
| -#include "webrtc/base/win32regkey.h"
|
| -
|
| -#include <shlwapi.h>
|
| -
|
| -#include <memory>
|
| -
|
| -#include "webrtc/base/common.h"
|
| -#include "webrtc/base/logging.h"
|
| -
|
| -namespace rtc {
|
| -
|
| -RegKey::RegKey() {
|
| - h_key_ = NULL;
|
| -}
|
| -
|
| -RegKey::~RegKey() {
|
| - Close();
|
| -}
|
| -
|
| -HRESULT RegKey::Create(HKEY parent_key, const wchar_t* key_name) {
|
| - return Create(parent_key,
|
| - key_name,
|
| - REG_NONE,
|
| - REG_OPTION_NON_VOLATILE,
|
| - KEY_ALL_ACCESS,
|
| - NULL,
|
| - NULL);
|
| -}
|
| -
|
| -HRESULT RegKey::Open(HKEY parent_key, const wchar_t* key_name) {
|
| - return Open(parent_key, key_name, KEY_ALL_ACCESS);
|
| -}
|
| -
|
| -bool RegKey::HasValue(const TCHAR* value_name) const {
|
| - return (ERROR_SUCCESS == ::RegQueryValueEx(h_key_, value_name, NULL,
|
| - NULL, NULL, NULL));
|
| -}
|
| -
|
| -HRESULT RegKey::SetValue(const wchar_t* full_key_name,
|
| - const wchar_t* value_name,
|
| - DWORD value) {
|
| - ASSERT(full_key_name != NULL);
|
| -
|
| - return SetValueStaticHelper(full_key_name, value_name, REG_DWORD, &value);
|
| -}
|
| -
|
| -HRESULT RegKey::SetValue(const wchar_t* full_key_name,
|
| - const wchar_t* value_name,
|
| - DWORD64 value) {
|
| - ASSERT(full_key_name != NULL);
|
| -
|
| - return SetValueStaticHelper(full_key_name, value_name, REG_QWORD, &value);
|
| -}
|
| -
|
| -HRESULT RegKey::SetValue(const wchar_t* full_key_name,
|
| - const wchar_t* value_name,
|
| - float value) {
|
| - ASSERT(full_key_name != NULL);
|
| -
|
| - return SetValueStaticHelper(full_key_name, value_name,
|
| - REG_BINARY, &value, sizeof(value));
|
| -}
|
| -
|
| -HRESULT RegKey::SetValue(const wchar_t* full_key_name,
|
| - const wchar_t* value_name,
|
| - double value) {
|
| - ASSERT(full_key_name != NULL);
|
| -
|
| - return SetValueStaticHelper(full_key_name, value_name,
|
| - REG_BINARY, &value, sizeof(value));
|
| -}
|
| -
|
| -HRESULT RegKey::SetValue(const wchar_t* full_key_name,
|
| - const wchar_t* value_name,
|
| - const TCHAR* value) {
|
| - ASSERT(full_key_name != NULL);
|
| - ASSERT(value != NULL);
|
| -
|
| - return SetValueStaticHelper(full_key_name, value_name,
|
| - REG_SZ, const_cast<wchar_t*>(value));
|
| -}
|
| -
|
| -HRESULT RegKey::SetValue(const wchar_t* full_key_name,
|
| - const wchar_t* value_name,
|
| - const uint8_t* value,
|
| - DWORD byte_count) {
|
| - ASSERT(full_key_name != NULL);
|
| -
|
| - return SetValueStaticHelper(full_key_name, value_name, REG_BINARY,
|
| - const_cast<uint8_t*>(value), byte_count);
|
| -}
|
| -
|
| -HRESULT RegKey::SetValueMultiSZ(const wchar_t* full_key_name,
|
| - const wchar_t* value_name,
|
| - const uint8_t* value,
|
| - DWORD byte_count) {
|
| - ASSERT(full_key_name != NULL);
|
| -
|
| - return SetValueStaticHelper(full_key_name, value_name, REG_MULTI_SZ,
|
| - const_cast<uint8_t*>(value), byte_count);
|
| -}
|
| -
|
| -HRESULT RegKey::GetValue(const wchar_t* full_key_name,
|
| - const wchar_t* value_name,
|
| - DWORD* value) {
|
| - ASSERT(full_key_name != NULL);
|
| - ASSERT(value != NULL);
|
| -
|
| - return GetValueStaticHelper(full_key_name, value_name, REG_DWORD, value);
|
| -}
|
| -
|
| -HRESULT RegKey::GetValue(const wchar_t* full_key_name,
|
| - const wchar_t* value_name,
|
| - DWORD64* value) {
|
| - ASSERT(full_key_name != NULL);
|
| - ASSERT(value != NULL);
|
| -
|
| - return GetValueStaticHelper(full_key_name, value_name, REG_QWORD, value);
|
| -}
|
| -
|
| -HRESULT RegKey::GetValue(const wchar_t* full_key_name,
|
| - const wchar_t* value_name,
|
| - float* value) {
|
| - ASSERT(value != NULL);
|
| - ASSERT(full_key_name != NULL);
|
| -
|
| - DWORD byte_count = 0;
|
| - byte* buffer_raw = nullptr;
|
| - HRESULT hr = GetValueStaticHelper(full_key_name, value_name,
|
| - REG_BINARY, &buffer_raw, &byte_count);
|
| - std::unique_ptr<byte[]> buffer(buffer_raw);
|
| - if (SUCCEEDED(hr)) {
|
| - ASSERT(byte_count == sizeof(*value));
|
| - if (byte_count == sizeof(*value)) {
|
| - *value = *reinterpret_cast<float*>(buffer.get());
|
| - }
|
| - }
|
| - return hr;
|
| -}
|
| -
|
| -HRESULT RegKey::GetValue(const wchar_t* full_key_name,
|
| - const wchar_t* value_name,
|
| - double* value) {
|
| - ASSERT(value != NULL);
|
| - ASSERT(full_key_name != NULL);
|
| -
|
| - DWORD byte_count = 0;
|
| - byte* buffer_raw = nullptr;
|
| - HRESULT hr = GetValueStaticHelper(full_key_name, value_name,
|
| - REG_BINARY, &buffer_raw, &byte_count);
|
| - std::unique_ptr<byte[]> buffer(buffer_raw);
|
| - if (SUCCEEDED(hr)) {
|
| - ASSERT(byte_count == sizeof(*value));
|
| - if (byte_count == sizeof(*value)) {
|
| - *value = *reinterpret_cast<double*>(buffer.get());
|
| - }
|
| - }
|
| - return hr;
|
| -}
|
| -
|
| -HRESULT RegKey::GetValue(const wchar_t* full_key_name,
|
| - const wchar_t* value_name,
|
| - wchar_t** value) {
|
| - ASSERT(full_key_name != NULL);
|
| - ASSERT(value != NULL);
|
| -
|
| - return GetValueStaticHelper(full_key_name, value_name, REG_SZ, value);
|
| -}
|
| -
|
| -HRESULT RegKey::GetValue(const wchar_t* full_key_name,
|
| - const wchar_t* value_name,
|
| - std::wstring* value) {
|
| - ASSERT(full_key_name != NULL);
|
| - ASSERT(value != NULL);
|
| -
|
| - wchar_t* buffer_raw = nullptr;
|
| - HRESULT hr = RegKey::GetValue(full_key_name, value_name, &buffer_raw);
|
| - std::unique_ptr<wchar_t[]> buffer(buffer_raw);
|
| - if (SUCCEEDED(hr)) {
|
| - value->assign(buffer.get());
|
| - }
|
| - return hr;
|
| -}
|
| -
|
| -HRESULT RegKey::GetValue(const wchar_t* full_key_name,
|
| - const wchar_t* value_name,
|
| - std::vector<std::wstring>* value) {
|
| - ASSERT(full_key_name != NULL);
|
| - ASSERT(value != NULL);
|
| -
|
| - return GetValueStaticHelper(full_key_name, value_name, REG_MULTI_SZ, value);
|
| -}
|
| -
|
| -HRESULT RegKey::GetValue(const wchar_t* full_key_name,
|
| - const wchar_t* value_name,
|
| - uint8_t** value,
|
| - DWORD* byte_count) {
|
| - ASSERT(full_key_name != NULL);
|
| - ASSERT(value != NULL);
|
| - ASSERT(byte_count != NULL);
|
| -
|
| - return GetValueStaticHelper(full_key_name, value_name,
|
| - REG_BINARY, value, byte_count);
|
| -}
|
| -
|
| -HRESULT RegKey::DeleteSubKey(const wchar_t* key_name) {
|
| - ASSERT(key_name != NULL);
|
| - ASSERT(h_key_ != NULL);
|
| -
|
| - LONG res = ::RegDeleteKey(h_key_, key_name);
|
| - HRESULT hr = HRESULT_FROM_WIN32(res);
|
| - if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) ||
|
| - hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)) {
|
| - hr = S_FALSE;
|
| - }
|
| - return hr;
|
| -}
|
| -
|
| -HRESULT RegKey::DeleteValue(const wchar_t* value_name) {
|
| - ASSERT(h_key_ != NULL);
|
| -
|
| - LONG res = ::RegDeleteValue(h_key_, value_name);
|
| - HRESULT hr = HRESULT_FROM_WIN32(res);
|
| - if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) ||
|
| - hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)) {
|
| - hr = S_FALSE;
|
| - }
|
| - return hr;
|
| -}
|
| -
|
| -HRESULT RegKey::Close() {
|
| - HRESULT hr = S_OK;
|
| - if (h_key_ != NULL) {
|
| - LONG res = ::RegCloseKey(h_key_);
|
| - hr = HRESULT_FROM_WIN32(res);
|
| - h_key_ = NULL;
|
| - }
|
| - return hr;
|
| -}
|
| -
|
| -HRESULT RegKey::Create(HKEY parent_key,
|
| - const wchar_t* key_name,
|
| - wchar_t* lpszClass,
|
| - DWORD options,
|
| - REGSAM sam_desired,
|
| - LPSECURITY_ATTRIBUTES lpSecAttr,
|
| - LPDWORD lpdwDisposition) {
|
| - ASSERT(key_name != NULL);
|
| - ASSERT(parent_key != NULL);
|
| -
|
| - DWORD dw = 0;
|
| - HKEY h_key = NULL;
|
| - LONG res = ::RegCreateKeyEx(parent_key, key_name, 0, lpszClass, options,
|
| - sam_desired, lpSecAttr, &h_key, &dw);
|
| - HRESULT hr = HRESULT_FROM_WIN32(res);
|
| -
|
| - if (lpdwDisposition) {
|
| - *lpdwDisposition = dw;
|
| - }
|
| -
|
| - // we have to close the currently opened key
|
| - // before replacing it with the new one
|
| - if (hr == S_OK) {
|
| - hr = Close();
|
| - ASSERT(hr == S_OK);
|
| - h_key_ = h_key;
|
| - }
|
| - return hr;
|
| -}
|
| -
|
| -HRESULT RegKey::Open(HKEY parent_key,
|
| - const wchar_t* key_name,
|
| - REGSAM sam_desired) {
|
| - ASSERT(key_name != NULL);
|
| - ASSERT(parent_key != NULL);
|
| -
|
| - HKEY h_key = NULL;
|
| - LONG res = ::RegOpenKeyEx(parent_key, key_name, 0, sam_desired, &h_key);
|
| - HRESULT hr = HRESULT_FROM_WIN32(res);
|
| -
|
| - // we have to close the currently opened key
|
| - // before replacing it with the new one
|
| - if (hr == S_OK) {
|
| - // close the currently opened key if any
|
| - hr = Close();
|
| - ASSERT(hr == S_OK);
|
| - h_key_ = h_key;
|
| - }
|
| - return hr;
|
| -}
|
| -
|
| -// save the key and all of its subkeys and values to a file
|
| -HRESULT RegKey::Save(const wchar_t* full_key_name, const wchar_t* file_name) {
|
| - ASSERT(full_key_name != NULL);
|
| - ASSERT(file_name != NULL);
|
| -
|
| - std::wstring key_name(full_key_name);
|
| - HKEY h_key = GetRootKeyInfo(&key_name);
|
| - if (!h_key) {
|
| - return E_FAIL;
|
| - }
|
| -
|
| - RegKey key;
|
| - HRESULT hr = key.Open(h_key, key_name.c_str(), KEY_READ);
|
| - if (FAILED(hr)) {
|
| - return hr;
|
| - }
|
| -
|
| - AdjustCurrentProcessPrivilege(SE_BACKUP_NAME, true);
|
| - LONG res = ::RegSaveKey(key.h_key_, file_name, NULL);
|
| - AdjustCurrentProcessPrivilege(SE_BACKUP_NAME, false);
|
| -
|
| - return HRESULT_FROM_WIN32(res);
|
| -}
|
| -
|
| -// restore the key and all of its subkeys and values which are saved into a file
|
| -HRESULT RegKey::Restore(const wchar_t* full_key_name,
|
| - const wchar_t* file_name) {
|
| - ASSERT(full_key_name != NULL);
|
| - ASSERT(file_name != NULL);
|
| -
|
| - std::wstring key_name(full_key_name);
|
| - HKEY h_key = GetRootKeyInfo(&key_name);
|
| - if (!h_key) {
|
| - return E_FAIL;
|
| - }
|
| -
|
| - RegKey key;
|
| - HRESULT hr = key.Open(h_key, key_name.c_str(), KEY_WRITE);
|
| - if (FAILED(hr)) {
|
| - return hr;
|
| - }
|
| -
|
| - AdjustCurrentProcessPrivilege(SE_RESTORE_NAME, true);
|
| - LONG res = ::RegRestoreKey(key.h_key_, file_name, REG_FORCE_RESTORE);
|
| - AdjustCurrentProcessPrivilege(SE_RESTORE_NAME, false);
|
| -
|
| - return HRESULT_FROM_WIN32(res);
|
| -}
|
| -
|
| -// check if the current key has the specified subkey
|
| -bool RegKey::HasSubkey(const wchar_t* key_name) const {
|
| - ASSERT(key_name != NULL);
|
| -
|
| - RegKey key;
|
| - HRESULT hr = key.Open(h_key_, key_name, KEY_READ);
|
| - key.Close();
|
| - return hr == S_OK;
|
| -}
|
| -
|
| -// static flush key
|
| -HRESULT RegKey::FlushKey(const wchar_t* full_key_name) {
|
| - ASSERT(full_key_name != NULL);
|
| -
|
| - HRESULT hr = HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND);
|
| - // get the root HKEY
|
| - std::wstring key_name(full_key_name);
|
| - HKEY h_key = GetRootKeyInfo(&key_name);
|
| -
|
| - if (h_key != NULL) {
|
| - LONG res = ::RegFlushKey(h_key);
|
| - hr = HRESULT_FROM_WIN32(res);
|
| - }
|
| - return hr;
|
| -}
|
| -
|
| -// static SET helper
|
| -HRESULT RegKey::SetValueStaticHelper(const wchar_t* full_key_name,
|
| - const wchar_t* value_name,
|
| - DWORD type,
|
| - LPVOID value,
|
| - DWORD byte_count) {
|
| - ASSERT(full_key_name != NULL);
|
| -
|
| - HRESULT hr = HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND);
|
| - // get the root HKEY
|
| - std::wstring key_name(full_key_name);
|
| - HKEY h_key = GetRootKeyInfo(&key_name);
|
| -
|
| - if (h_key != NULL) {
|
| - RegKey key;
|
| - hr = key.Create(h_key, key_name.c_str());
|
| - if (hr == S_OK) {
|
| - switch (type) {
|
| - case REG_DWORD:
|
| - hr = key.SetValue(value_name, *(static_cast<DWORD*>(value)));
|
| - break;
|
| - case REG_QWORD:
|
| - hr = key.SetValue(value_name, *(static_cast<DWORD64*>(value)));
|
| - break;
|
| - case REG_SZ:
|
| - hr = key.SetValue(value_name, static_cast<const wchar_t*>(value));
|
| - break;
|
| - case REG_BINARY:
|
| - hr = key.SetValue(value_name, static_cast<const uint8_t*>(value),
|
| - byte_count);
|
| - break;
|
| - case REG_MULTI_SZ:
|
| - hr = key.SetValue(value_name, static_cast<const uint8_t*>(value),
|
| - byte_count, type);
|
| - break;
|
| - default:
|
| - ASSERT(false);
|
| - hr = HRESULT_FROM_WIN32(ERROR_DATATYPE_MISMATCH);
|
| - break;
|
| - }
|
| - // close the key after writing
|
| - HRESULT temp_hr = key.Close();
|
| - if (hr == S_OK) {
|
| - hr = temp_hr;
|
| - }
|
| - }
|
| - }
|
| - return hr;
|
| -}
|
| -
|
| -// static GET helper
|
| -HRESULT RegKey::GetValueStaticHelper(const wchar_t* full_key_name,
|
| - const wchar_t* value_name,
|
| - DWORD type,
|
| - LPVOID value,
|
| - DWORD* byte_count) {
|
| - ASSERT(full_key_name != NULL);
|
| -
|
| - HRESULT hr = HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND);
|
| - // get the root HKEY
|
| - std::wstring key_name(full_key_name);
|
| - HKEY h_key = GetRootKeyInfo(&key_name);
|
| -
|
| - if (h_key != NULL) {
|
| - RegKey key;
|
| - hr = key.Open(h_key, key_name.c_str(), KEY_READ);
|
| - if (hr == S_OK) {
|
| - switch (type) {
|
| - case REG_DWORD:
|
| - hr = key.GetValue(value_name, reinterpret_cast<DWORD*>(value));
|
| - break;
|
| - case REG_QWORD:
|
| - hr = key.GetValue(value_name, reinterpret_cast<DWORD64*>(value));
|
| - break;
|
| - case REG_SZ:
|
| - hr = key.GetValue(value_name, reinterpret_cast<wchar_t**>(value));
|
| - break;
|
| - case REG_MULTI_SZ:
|
| - hr = key.GetValue(value_name, reinterpret_cast<
|
| - std::vector<std::wstring>*>(value));
|
| - break;
|
| - case REG_BINARY:
|
| - hr = key.GetValue(value_name, reinterpret_cast<uint8_t**>(value),
|
| - byte_count);
|
| - break;
|
| - default:
|
| - ASSERT(false);
|
| - hr = HRESULT_FROM_WIN32(ERROR_DATATYPE_MISMATCH);
|
| - break;
|
| - }
|
| - // close the key after writing
|
| - HRESULT temp_hr = key.Close();
|
| - if (hr == S_OK) {
|
| - hr = temp_hr;
|
| - }
|
| - }
|
| - }
|
| - return hr;
|
| -}
|
| -
|
| -// GET helper
|
| -HRESULT RegKey::GetValueHelper(const wchar_t* value_name,
|
| - DWORD* type,
|
| - uint8_t** value,
|
| - DWORD* byte_count) const {
|
| - ASSERT(byte_count != NULL);
|
| - ASSERT(value != NULL);
|
| - ASSERT(type != NULL);
|
| -
|
| - // init return buffer
|
| - *value = NULL;
|
| -
|
| - // get the size of the return data buffer
|
| - LONG res = ::SHQueryValueEx(h_key_, value_name, NULL, type, NULL, byte_count);
|
| - HRESULT hr = HRESULT_FROM_WIN32(res);
|
| -
|
| - if (hr == S_OK) {
|
| - // if the value length is 0, nothing to do
|
| - if (*byte_count != 0) {
|
| - // allocate the buffer
|
| - *value = new byte[*byte_count];
|
| - ASSERT(*value != NULL);
|
| -
|
| - // make the call again to get the data
|
| - res = ::SHQueryValueEx(h_key_, value_name, NULL,
|
| - type, *value, byte_count);
|
| - hr = HRESULT_FROM_WIN32(res);
|
| - ASSERT(hr == S_OK);
|
| - }
|
| - }
|
| - return hr;
|
| -}
|
| -
|
| -// Int32 Get
|
| -HRESULT RegKey::GetValue(const wchar_t* value_name, DWORD* value) const {
|
| - ASSERT(value != NULL);
|
| -
|
| - DWORD type = 0;
|
| - DWORD byte_count = sizeof(DWORD);
|
| - LONG res = ::SHQueryValueEx(h_key_, value_name, NULL, &type,
|
| - value, &byte_count);
|
| - HRESULT hr = HRESULT_FROM_WIN32(res);
|
| - ASSERT((hr != S_OK) || (type == REG_DWORD));
|
| - ASSERT((hr != S_OK) || (byte_count == sizeof(DWORD)));
|
| - return hr;
|
| -}
|
| -
|
| -// Int64 Get
|
| -HRESULT RegKey::GetValue(const wchar_t* value_name, DWORD64* value) const {
|
| - ASSERT(value != NULL);
|
| -
|
| - DWORD type = 0;
|
| - DWORD byte_count = sizeof(DWORD64);
|
| - LONG res = ::SHQueryValueEx(h_key_, value_name, NULL, &type,
|
| - value, &byte_count);
|
| - HRESULT hr = HRESULT_FROM_WIN32(res);
|
| - ASSERT((hr != S_OK) || (type == REG_QWORD));
|
| - ASSERT((hr != S_OK) || (byte_count == sizeof(DWORD64)));
|
| - return hr;
|
| -}
|
| -
|
| -// String Get
|
| -HRESULT RegKey::GetValue(const wchar_t* value_name, wchar_t** value) const {
|
| - ASSERT(value != NULL);
|
| -
|
| - DWORD byte_count = 0;
|
| - DWORD type = 0;
|
| -
|
| - // first get the size of the string buffer
|
| - LONG res = ::SHQueryValueEx(h_key_, value_name, NULL,
|
| - &type, NULL, &byte_count);
|
| - HRESULT hr = HRESULT_FROM_WIN32(res);
|
| -
|
| - if (hr == S_OK) {
|
| - // allocate room for the string and a terminating \0
|
| - *value = new wchar_t[(byte_count / sizeof(wchar_t)) + 1];
|
| -
|
| - if ((*value) != NULL) {
|
| - if (byte_count != 0) {
|
| - // make the call again
|
| - res = ::SHQueryValueEx(h_key_, value_name, NULL, &type,
|
| - *value, &byte_count);
|
| - hr = HRESULT_FROM_WIN32(res);
|
| - } else {
|
| - (*value)[0] = L'\0';
|
| - }
|
| -
|
| - ASSERT((hr != S_OK) || (type == REG_SZ) ||
|
| - (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ));
|
| - } else {
|
| - hr = E_OUTOFMEMORY;
|
| - }
|
| - }
|
| -
|
| - return hr;
|
| -}
|
| -
|
| -// get a string value
|
| -HRESULT RegKey::GetValue(const wchar_t* value_name, std::wstring* value) const {
|
| - ASSERT(value != NULL);
|
| -
|
| - DWORD byte_count = 0;
|
| - DWORD type = 0;
|
| -
|
| - // first get the size of the string buffer
|
| - LONG res = ::SHQueryValueEx(h_key_, value_name, NULL,
|
| - &type, NULL, &byte_count);
|
| - HRESULT hr = HRESULT_FROM_WIN32(res);
|
| -
|
| - if (hr == S_OK) {
|
| - if (byte_count != 0) {
|
| - // Allocate some memory and make the call again
|
| - value->resize(byte_count / sizeof(wchar_t) + 1);
|
| - res = ::SHQueryValueEx(h_key_, value_name, NULL, &type,
|
| - &value->at(0), &byte_count);
|
| - hr = HRESULT_FROM_WIN32(res);
|
| - value->resize(wcslen(value->data()));
|
| - } else {
|
| - value->clear();
|
| - }
|
| -
|
| - ASSERT((hr != S_OK) || (type == REG_SZ) ||
|
| - (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ));
|
| - }
|
| -
|
| - return hr;
|
| -}
|
| -
|
| -// convert REG_MULTI_SZ bytes to string array
|
| -HRESULT RegKey::MultiSZBytesToStringArray(const uint8_t* buffer,
|
| - DWORD byte_count,
|
| - std::vector<std::wstring>* value) {
|
| - ASSERT(buffer != NULL);
|
| - ASSERT(value != NULL);
|
| -
|
| - const wchar_t* data = reinterpret_cast<const wchar_t*>(buffer);
|
| - DWORD data_len = byte_count / sizeof(wchar_t);
|
| - value->clear();
|
| - if (data_len > 1) {
|
| - // must be terminated by two null characters
|
| - if (data[data_len - 1] != 0 || data[data_len - 2] != 0) {
|
| - return E_INVALIDARG;
|
| - }
|
| -
|
| - // put null-terminated strings into arrays
|
| - while (*data) {
|
| - std::wstring str(data);
|
| - value->push_back(str);
|
| - data += str.length() + 1;
|
| - }
|
| - }
|
| - return S_OK;
|
| -}
|
| -
|
| -// get a std::vector<std::wstring> value from REG_MULTI_SZ type
|
| -HRESULT RegKey::GetValue(const wchar_t* value_name,
|
| - std::vector<std::wstring>* value) const {
|
| - ASSERT(value != NULL);
|
| -
|
| - DWORD byte_count = 0;
|
| - DWORD type = 0;
|
| - uint8_t* buffer = 0;
|
| -
|
| - // first get the size of the buffer
|
| - HRESULT hr = GetValueHelper(value_name, &type, &buffer, &byte_count);
|
| - ASSERT((hr != S_OK) || (type == REG_MULTI_SZ));
|
| -
|
| - if (SUCCEEDED(hr)) {
|
| - hr = MultiSZBytesToStringArray(buffer, byte_count, value);
|
| - }
|
| -
|
| - return hr;
|
| -}
|
| -
|
| -// Binary data Get
|
| -HRESULT RegKey::GetValue(const wchar_t* value_name,
|
| - uint8_t** value,
|
| - DWORD* byte_count) const {
|
| - ASSERT(byte_count != NULL);
|
| - ASSERT(value != NULL);
|
| -
|
| - DWORD type = 0;
|
| - HRESULT hr = GetValueHelper(value_name, &type, value, byte_count);
|
| - ASSERT((hr != S_OK) || (type == REG_MULTI_SZ) || (type == REG_BINARY));
|
| - return hr;
|
| -}
|
| -
|
| -// Raw data get
|
| -HRESULT RegKey::GetValue(const wchar_t* value_name,
|
| - uint8_t** value,
|
| - DWORD* byte_count,
|
| - DWORD* type) const {
|
| - ASSERT(type != NULL);
|
| - ASSERT(byte_count != NULL);
|
| - ASSERT(value != NULL);
|
| -
|
| - return GetValueHelper(value_name, type, value, byte_count);
|
| -}
|
| -
|
| -// Int32 set
|
| -HRESULT RegKey::SetValue(const wchar_t* value_name, DWORD value) const {
|
| - ASSERT(h_key_ != NULL);
|
| -
|
| - LONG res =
|
| - ::RegSetValueEx(h_key_, value_name, NULL, REG_DWORD,
|
| - reinterpret_cast<const uint8_t*>(&value), sizeof(DWORD));
|
| - return HRESULT_FROM_WIN32(res);
|
| -}
|
| -
|
| -// Int64 set
|
| -HRESULT RegKey::SetValue(const wchar_t* value_name, DWORD64 value) const {
|
| - ASSERT(h_key_ != NULL);
|
| -
|
| - LONG res = ::RegSetValueEx(h_key_, value_name, NULL, REG_QWORD,
|
| - reinterpret_cast<const uint8_t*>(&value),
|
| - sizeof(DWORD64));
|
| - return HRESULT_FROM_WIN32(res);
|
| -}
|
| -
|
| -// String set
|
| -HRESULT RegKey::SetValue(const wchar_t* value_name,
|
| - const wchar_t* value) const {
|
| - ASSERT(value != NULL);
|
| - ASSERT(h_key_ != NULL);
|
| -
|
| - LONG res = ::RegSetValueEx(h_key_, value_name, NULL, REG_SZ,
|
| - reinterpret_cast<const uint8_t*>(value),
|
| - (lstrlen(value) + 1) * sizeof(wchar_t));
|
| - return HRESULT_FROM_WIN32(res);
|
| -}
|
| -
|
| -// Binary data set
|
| -HRESULT RegKey::SetValue(const wchar_t* value_name,
|
| - const uint8_t* value,
|
| - DWORD byte_count) const {
|
| - ASSERT(h_key_ != NULL);
|
| -
|
| - // special case - if 'value' is NULL make sure byte_count is zero
|
| - if (value == NULL) {
|
| - byte_count = 0;
|
| - }
|
| -
|
| - LONG res = ::RegSetValueEx(h_key_, value_name, NULL,
|
| - REG_BINARY, value, byte_count);
|
| - return HRESULT_FROM_WIN32(res);
|
| -}
|
| -
|
| -// Raw data set
|
| -HRESULT RegKey::SetValue(const wchar_t* value_name,
|
| - const uint8_t* value,
|
| - DWORD byte_count,
|
| - DWORD type) const {
|
| - ASSERT(value != NULL);
|
| - ASSERT(h_key_ != NULL);
|
| -
|
| - LONG res = ::RegSetValueEx(h_key_, value_name, NULL, type, value, byte_count);
|
| - return HRESULT_FROM_WIN32(res);
|
| -}
|
| -
|
| -bool RegKey::HasKey(const wchar_t* full_key_name) {
|
| - ASSERT(full_key_name != NULL);
|
| -
|
| - // get the root HKEY
|
| - std::wstring key_name(full_key_name);
|
| - HKEY h_key = GetRootKeyInfo(&key_name);
|
| -
|
| - if (h_key != NULL) {
|
| - RegKey key;
|
| - HRESULT hr = key.Open(h_key, key_name.c_str(), KEY_READ);
|
| - key.Close();
|
| - return S_OK == hr;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -// static version of HasValue
|
| -bool RegKey::HasValue(const wchar_t* full_key_name, const wchar_t* value_name) {
|
| - ASSERT(full_key_name != NULL);
|
| -
|
| - bool has_value = false;
|
| - // get the root HKEY
|
| - std::wstring key_name(full_key_name);
|
| - HKEY h_key = GetRootKeyInfo(&key_name);
|
| -
|
| - if (h_key != NULL) {
|
| - RegKey key;
|
| - if (key.Open(h_key, key_name.c_str(), KEY_READ) == S_OK) {
|
| - has_value = key.HasValue(value_name);
|
| - key.Close();
|
| - }
|
| - }
|
| - return has_value;
|
| -}
|
| -
|
| -HRESULT RegKey::GetValueType(const wchar_t* full_key_name,
|
| - const wchar_t* value_name,
|
| - DWORD* value_type) {
|
| - ASSERT(full_key_name != NULL);
|
| - ASSERT(value_type != NULL);
|
| -
|
| - *value_type = REG_NONE;
|
| -
|
| - std::wstring key_name(full_key_name);
|
| - HKEY h_key = GetRootKeyInfo(&key_name);
|
| -
|
| - RegKey key;
|
| - HRESULT hr = key.Open(h_key, key_name.c_str(), KEY_READ);
|
| - if (SUCCEEDED(hr)) {
|
| - LONG res = ::SHQueryValueEx(key.h_key_, value_name, NULL, value_type,
|
| - NULL, NULL);
|
| - if (res != ERROR_SUCCESS) {
|
| - hr = HRESULT_FROM_WIN32(res);
|
| - }
|
| - }
|
| -
|
| - return hr;
|
| -}
|
| -
|
| -HRESULT RegKey::DeleteKey(const wchar_t* full_key_name) {
|
| - ASSERT(full_key_name != NULL);
|
| -
|
| - return DeleteKey(full_key_name, true);
|
| -}
|
| -
|
| -HRESULT RegKey::DeleteKey(const wchar_t* full_key_name, bool recursively) {
|
| - ASSERT(full_key_name != NULL);
|
| -
|
| - // need to open the parent key first
|
| - // get the root HKEY
|
| - std::wstring key_name(full_key_name);
|
| - HKEY h_key = GetRootKeyInfo(&key_name);
|
| -
|
| - // get the parent key
|
| - std::wstring parent_key(GetParentKeyInfo(&key_name));
|
| -
|
| - RegKey key;
|
| - HRESULT hr = key.Open(h_key, parent_key.c_str());
|
| -
|
| - if (hr == S_OK) {
|
| - hr = recursively ? key.RecurseDeleteSubKey(key_name.c_str())
|
| - : key.DeleteSubKey(key_name.c_str());
|
| - } else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) ||
|
| - hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)) {
|
| - hr = S_FALSE;
|
| - }
|
| -
|
| - key.Close();
|
| - return hr;
|
| -}
|
| -
|
| -HRESULT RegKey::DeleteValue(const wchar_t* full_key_name,
|
| - const wchar_t* value_name) {
|
| - ASSERT(full_key_name != NULL);
|
| -
|
| - HRESULT hr = HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND);
|
| - // get the root HKEY
|
| - std::wstring key_name(full_key_name);
|
| - HKEY h_key = GetRootKeyInfo(&key_name);
|
| -
|
| - if (h_key != NULL) {
|
| - RegKey key;
|
| - hr = key.Open(h_key, key_name.c_str());
|
| - if (hr == S_OK) {
|
| - hr = key.DeleteValue(value_name);
|
| - key.Close();
|
| - }
|
| - }
|
| - return hr;
|
| -}
|
| -
|
| -HRESULT RegKey::RecurseDeleteSubKey(const wchar_t* key_name) {
|
| - ASSERT(key_name != NULL);
|
| -
|
| - RegKey key;
|
| - HRESULT hr = key.Open(h_key_, key_name);
|
| -
|
| - if (hr == S_OK) {
|
| - // enumerate all subkeys of this key and recursivelly delete them
|
| - FILETIME time = {0};
|
| - wchar_t key_name_buf[kMaxKeyNameChars] = {0};
|
| - DWORD key_name_buf_size = kMaxKeyNameChars;
|
| - while (hr == S_OK &&
|
| - ::RegEnumKeyEx(key.h_key_, 0, key_name_buf, &key_name_buf_size,
|
| - NULL, NULL, NULL, &time) == ERROR_SUCCESS) {
|
| - hr = key.RecurseDeleteSubKey(key_name_buf);
|
| -
|
| - // restore the buffer size
|
| - key_name_buf_size = kMaxKeyNameChars;
|
| - }
|
| - // close the top key
|
| - key.Close();
|
| - }
|
| -
|
| - if (hr == S_OK) {
|
| - // the key has no more children keys
|
| - // delete the key and all of its values
|
| - hr = DeleteSubKey(key_name);
|
| - }
|
| -
|
| - return hr;
|
| -}
|
| -
|
| -HKEY RegKey::GetRootKeyInfo(std::wstring* full_key_name) {
|
| - ASSERT(full_key_name != NULL);
|
| -
|
| - HKEY h_key = NULL;
|
| - // get the root HKEY
|
| - size_t index = full_key_name->find(L'\\');
|
| - std::wstring root_key;
|
| -
|
| - if (index == -1) {
|
| - root_key = *full_key_name;
|
| - *full_key_name = L"";
|
| - } else {
|
| - root_key = full_key_name->substr(0, index);
|
| - *full_key_name = full_key_name->substr(index + 1,
|
| - full_key_name->length() - index - 1);
|
| - }
|
| -
|
| - for (std::wstring::iterator iter = root_key.begin();
|
| - iter != root_key.end(); ++iter) {
|
| - *iter = toupper(*iter);
|
| - }
|
| -
|
| - if (!root_key.compare(L"HKLM") ||
|
| - !root_key.compare(L"HKEY_LOCAL_MACHINE")) {
|
| - h_key = HKEY_LOCAL_MACHINE;
|
| - } else if (!root_key.compare(L"HKCU") ||
|
| - !root_key.compare(L"HKEY_CURRENT_USER")) {
|
| - h_key = HKEY_CURRENT_USER;
|
| - } else if (!root_key.compare(L"HKU") ||
|
| - !root_key.compare(L"HKEY_USERS")) {
|
| - h_key = HKEY_USERS;
|
| - } else if (!root_key.compare(L"HKCR") ||
|
| - !root_key.compare(L"HKEY_CLASSES_ROOT")) {
|
| - h_key = HKEY_CLASSES_ROOT;
|
| - }
|
| -
|
| - return h_key;
|
| -}
|
| -
|
| -
|
| -// Returns true if this key name is 'safe' for deletion
|
| -// (doesn't specify a key root)
|
| -bool RegKey::SafeKeyNameForDeletion(const wchar_t* key_name) {
|
| - ASSERT(key_name != NULL);
|
| - std::wstring key(key_name);
|
| -
|
| - HKEY root_key = GetRootKeyInfo(&key);
|
| -
|
| - if (!root_key) {
|
| - key = key_name;
|
| - }
|
| - if (key.empty()) {
|
| - return false;
|
| - }
|
| - bool found_subkey = false, backslash_found = false;
|
| - for (size_t i = 0 ; i < key.length() ; ++i) {
|
| - if (key[i] == L'\\') {
|
| - backslash_found = true;
|
| - } else if (backslash_found) {
|
| - found_subkey = true;
|
| - break;
|
| - }
|
| - }
|
| - return (root_key == HKEY_USERS) ? found_subkey : true;
|
| -}
|
| -
|
| -std::wstring RegKey::GetParentKeyInfo(std::wstring* key_name) {
|
| - ASSERT(key_name != NULL);
|
| -
|
| - // get the parent key
|
| - size_t index = key_name->rfind(L'\\');
|
| - std::wstring parent_key;
|
| - if (index == -1) {
|
| - parent_key = L"";
|
| - } else {
|
| - parent_key = key_name->substr(0, index);
|
| - *key_name = key_name->substr(index + 1, key_name->length() - index - 1);
|
| - }
|
| -
|
| - return parent_key;
|
| -}
|
| -
|
| -// get the number of values for this key
|
| -uint32_t RegKey::GetValueCount() {
|
| - DWORD num_values = 0;
|
| -
|
| - if (ERROR_SUCCESS != ::RegQueryInfoKey(
|
| - h_key_, // key handle
|
| - NULL, // buffer for class name
|
| - NULL, // size of class string
|
| - NULL, // reserved
|
| - NULL, // number of subkeys
|
| - NULL, // longest subkey size
|
| - NULL, // longest class string
|
| - &num_values, // number of values for this key
|
| - NULL, // longest value name
|
| - NULL, // longest value data
|
| - NULL, // security descriptor
|
| - NULL)) { // last write time
|
| - ASSERT(false);
|
| - }
|
| - return num_values;
|
| -}
|
| -
|
| -// Enumerators for the value_names for this key
|
| -
|
| -// Called to get the value name for the given value name index
|
| -// Use GetValueCount() to get the total value_name count for this key
|
| -// Returns failure if no key at the specified index
|
| -HRESULT RegKey::GetValueNameAt(int index, std::wstring* value_name,
|
| - DWORD* type) {
|
| - ASSERT(value_name != NULL);
|
| -
|
| - LONG res = ERROR_SUCCESS;
|
| - wchar_t value_name_buf[kMaxValueNameChars] = {0};
|
| - DWORD value_name_buf_size = kMaxValueNameChars;
|
| - res = ::RegEnumValue(h_key_, index, value_name_buf, &value_name_buf_size,
|
| - NULL, type, NULL, NULL);
|
| -
|
| - if (res == ERROR_SUCCESS) {
|
| - value_name->assign(value_name_buf);
|
| - }
|
| -
|
| - return HRESULT_FROM_WIN32(res);
|
| -}
|
| -
|
| -uint32_t RegKey::GetSubkeyCount() {
|
| - // number of values for key
|
| - DWORD num_subkeys = 0;
|
| -
|
| - if (ERROR_SUCCESS != ::RegQueryInfoKey(
|
| - h_key_, // key handle
|
| - NULL, // buffer for class name
|
| - NULL, // size of class string
|
| - NULL, // reserved
|
| - &num_subkeys, // number of subkeys
|
| - NULL, // longest subkey size
|
| - NULL, // longest class string
|
| - NULL, // number of values for this key
|
| - NULL, // longest value name
|
| - NULL, // longest value data
|
| - NULL, // security descriptor
|
| - NULL)) { // last write time
|
| - ASSERT(false);
|
| - }
|
| - return num_subkeys;
|
| -}
|
| -
|
| -HRESULT RegKey::GetSubkeyNameAt(int index, std::wstring* key_name) {
|
| - ASSERT(key_name != NULL);
|
| -
|
| - LONG res = ERROR_SUCCESS;
|
| - wchar_t key_name_buf[kMaxKeyNameChars] = {0};
|
| - DWORD key_name_buf_size = kMaxKeyNameChars;
|
| -
|
| - res = ::RegEnumKeyEx(h_key_, index, key_name_buf, &key_name_buf_size,
|
| - NULL, NULL, NULL, NULL);
|
| -
|
| - if (res == ERROR_SUCCESS) {
|
| - key_name->assign(key_name_buf);
|
| - }
|
| -
|
| - return HRESULT_FROM_WIN32(res);
|
| -}
|
| -
|
| -// Is the key empty: having no sub-keys and values
|
| -bool RegKey::IsKeyEmpty(const wchar_t* full_key_name) {
|
| - ASSERT(full_key_name != NULL);
|
| -
|
| - bool is_empty = true;
|
| -
|
| - // Get the root HKEY
|
| - std::wstring key_name(full_key_name);
|
| - HKEY h_key = GetRootKeyInfo(&key_name);
|
| -
|
| - // Open the key to check
|
| - if (h_key != NULL) {
|
| - RegKey key;
|
| - HRESULT hr = key.Open(h_key, key_name.c_str(), KEY_READ);
|
| - if (SUCCEEDED(hr)) {
|
| - is_empty = key.GetSubkeyCount() == 0 && key.GetValueCount() == 0;
|
| - key.Close();
|
| - }
|
| - }
|
| -
|
| - return is_empty;
|
| -}
|
| -
|
| -bool AdjustCurrentProcessPrivilege(const TCHAR* privilege, bool to_enable) {
|
| - ASSERT(privilege != NULL);
|
| -
|
| - bool ret = false;
|
| - HANDLE token;
|
| - if (::OpenProcessToken(::GetCurrentProcess(),
|
| - TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) {
|
| - LUID luid;
|
| - memset(&luid, 0, sizeof(luid));
|
| - if (::LookupPrivilegeValue(NULL, privilege, &luid)) {
|
| - TOKEN_PRIVILEGES privs;
|
| - privs.PrivilegeCount = 1;
|
| - privs.Privileges[0].Luid = luid;
|
| - privs.Privileges[0].Attributes = to_enable ? SE_PRIVILEGE_ENABLED : 0;
|
| - if (::AdjustTokenPrivileges(token, FALSE, &privs, 0, NULL, 0)) {
|
| - ret = true;
|
| - } else {
|
| - LOG_GLE(LS_ERROR) << "AdjustTokenPrivileges failed";
|
| - }
|
| - } else {
|
| - LOG_GLE(LS_ERROR) << "LookupPrivilegeValue failed";
|
| - }
|
| - CloseHandle(token);
|
| - } else {
|
| - LOG_GLE(LS_ERROR) << "OpenProcessToken(GetCurrentProcess) failed";
|
| - }
|
| -
|
| - return ret;
|
| -}
|
| -
|
| -} // namespace rtc
|
|
|