libicsneo/platform/windows/registry.cpp

123 lines
3.2 KiB
C++

#include "icsneo/platform/windows/registry.h"
#include "icsneo/platform/windows/strings.h"
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
#include <codecvt>
#include <vector>
#include <locale>
using namespace icsneo;
class Key {
public:
Key(std::wstring path, bool readwrite = false);
~Key();
HKEY GetKey() { return key; }
bool IsOpen() { return key != nullptr; }
private:
HKEY key;
};
Key::Key(std::wstring path, bool readwrite) {
DWORD dwDisposition;
if(readwrite)
RegCreateKeyExW(HKEY_LOCAL_MACHINE, path.c_str(), 0, nullptr, 0, KEY_QUERY_VALUE | KEY_WRITE, nullptr, &key, &dwDisposition);
else
RegOpenKeyExW(HKEY_LOCAL_MACHINE, path.c_str(), 0, KEY_READ, &key);
}
Key::~Key() {
if(IsOpen())
RegCloseKey(key);
}
bool Registry::EnumerateSubkeys(std::wstring path, std::vector<std::wstring>& subkeys) {
Key regKey(path);
if(!regKey.IsOpen())
return false;
wchar_t className[MAX_PATH];
memset(className, 0, sizeof(className));
DWORD classNameLen = MAX_PATH;
DWORD subKeyCount = 0;
DWORD maxSubKeyLen, maxClassStringLen, valueCount, maxValueNameLen, maxValueDataLen, securityDescriptorLen;
FILETIME lastWriteTime;
auto ret = RegQueryInfoKeyW(
regKey.GetKey(),
className,
&classNameLen,
nullptr,
&subKeyCount,
&maxSubKeyLen,
&maxClassStringLen,
&valueCount,
&maxValueNameLen,
&maxValueDataLen,
&securityDescriptorLen,
&lastWriteTime);
if(ret != ERROR_SUCCESS)
return false;
subkeys.clear();
for(DWORD i = 0; i < subKeyCount; i++) {
DWORD nameLen = MAX_PATH;
wchar_t name[MAX_PATH];
memset(name, 0, sizeof(name));
ret = RegEnumKeyExW(regKey.GetKey(), i, name, &nameLen, nullptr, nullptr, nullptr, &lastWriteTime);
if(ret == ERROR_SUCCESS)
subkeys.push_back(name);
}
return true;
}
bool Registry::Get(std::wstring path, std::wstring key, std::wstring& value) {
Key regKey(path);
if(!regKey.IsOpen())
return false;
// Query for the type and size of the data
DWORD type, size;
auto ret = RegQueryValueExW(regKey.GetKey(), key.c_str(), nullptr, &type, (LPBYTE)nullptr, &size);
if(ret != ERROR_SUCCESS)
return false;
// Query for the data itself
std::vector<wchar_t> data(size / 2 + 1);
DWORD bytesRead = size; // We want to read up to the size we got earlier
ret = RegQueryValueExW(regKey.GetKey(), key.c_str(), nullptr, &type, (LPBYTE)data.data(), &bytesRead);
if(ret != ERROR_SUCCESS)
return false;
value = data.data();
return true;
}
bool Registry::Get(std::string path, std::string key, std::string& value) {
std::wstring wvalue;
bool ret = Get(convertStringToWide(path), convertStringToWide(key), wvalue);
value = convertWideString(wvalue);
return ret;
}
bool Registry::Get(std::wstring path, std::wstring key, uint32_t& value) {
Key regKey(path);
if(!regKey.IsOpen())
return false;
// Query for the data
DWORD type, size = sizeof(DWORD), kvalue;
auto ret = RegQueryValueExW(regKey.GetKey(), key.c_str(), nullptr, &type, (LPBYTE)&kvalue, &size);
if(ret != ERROR_SUCCESS || type != REG_DWORD)
return false;
value = kvalue;
return true;
}
bool Registry::Get(std::string path, std::string key, uint32_t& value) {
return Get(convertStringToWide(path), convertStringToWide(key), value);
}