2012-06-18 10:13:51 +00:00
|
|
|
#ifndef NALL_WINDOWS_REGISTRY_HPP
|
|
|
|
#define NALL_WINDOWS_REGISTRY_HPP
|
|
|
|
|
|
|
|
#include <nall/platform.hpp>
|
|
|
|
#include <nall/string.hpp>
|
|
|
|
|
|
|
|
#include <shlwapi.h>
|
2013-04-14 08:52:47 +00:00
|
|
|
#undef interface
|
2012-06-18 10:13:51 +00:00
|
|
|
#ifndef KEY_WOW64_64KEY
|
|
|
|
#define KEY_WOW64_64KEY 0x0100
|
|
|
|
#endif
|
|
|
|
#ifndef KEY_WOW64_32KEY
|
|
|
|
#define KEY_WOW64_32KEY 0x0200
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef NWR_FLAGS
|
|
|
|
#define NWR_FLAGS KEY_WOW64_64KEY
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef NWR_SIZE
|
|
|
|
#define NWR_SIZE 4096
|
|
|
|
#endif
|
|
|
|
|
|
|
|
namespace nall {
|
|
|
|
|
|
|
|
struct registry {
|
2013-05-02 11:25:45 +00:00
|
|
|
static bool exists(const string& name) {
|
2012-06-18 10:13:51 +00:00
|
|
|
lstring part = name.split("/");
|
|
|
|
HKEY handle, rootKey = root(part.take(0));
|
|
|
|
string node = part.take();
|
|
|
|
string path = part.concatenate("\\");
|
|
|
|
if(RegOpenKeyExW(rootKey, utf16_t(path), 0, NWR_FLAGS | KEY_READ, &handle) == ERROR_SUCCESS) {
|
|
|
|
wchar_t data[NWR_SIZE] = L"";
|
|
|
|
DWORD size = NWR_SIZE * sizeof(wchar_t);
|
2013-03-15 13:11:33 +00:00
|
|
|
LONG result = RegQueryValueExW(handle, utf16_t(node), nullptr, nullptr, (LPBYTE)&data, (LPDWORD)&size);
|
2012-06-18 10:13:51 +00:00
|
|
|
RegCloseKey(handle);
|
|
|
|
if(result == ERROR_SUCCESS) return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-05-02 11:25:45 +00:00
|
|
|
static string read(const string& name) {
|
2012-06-18 10:13:51 +00:00
|
|
|
lstring part = name.split("/");
|
|
|
|
HKEY handle, rootKey = root(part.take(0));
|
|
|
|
string node = part.take();
|
|
|
|
string path = part.concatenate("\\");
|
|
|
|
if(RegOpenKeyExW(rootKey, utf16_t(path), 0, NWR_FLAGS | KEY_READ, &handle) == ERROR_SUCCESS) {
|
|
|
|
wchar_t data[NWR_SIZE] = L"";
|
|
|
|
DWORD size = NWR_SIZE * sizeof(wchar_t);
|
2013-03-15 13:11:33 +00:00
|
|
|
LONG result = RegQueryValueExW(handle, utf16_t(node), nullptr, nullptr, (LPBYTE)&data, (LPDWORD)&size);
|
2012-06-18 10:13:51 +00:00
|
|
|
RegCloseKey(handle);
|
|
|
|
if(result == ERROR_SUCCESS) return (const char*)utf8_t(data);
|
|
|
|
}
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
2013-05-02 11:25:45 +00:00
|
|
|
static void write(const string& name, const string& data = "") {
|
2012-06-18 10:13:51 +00:00
|
|
|
lstring part = name.split("/");
|
|
|
|
HKEY handle, rootKey = root(part.take(0));
|
|
|
|
string node = part.take(), path;
|
|
|
|
DWORD disposition;
|
|
|
|
for(unsigned n = 0; n < part.size(); n++) {
|
|
|
|
path.append(part[n]);
|
2013-03-15 13:11:33 +00:00
|
|
|
if(RegCreateKeyExW(rootKey, utf16_t(path), 0, nullptr, 0, NWR_FLAGS | KEY_ALL_ACCESS, nullptr, &handle, &disposition) == ERROR_SUCCESS) {
|
2012-06-18 10:13:51 +00:00
|
|
|
if(n == part.size() - 1) {
|
|
|
|
RegSetValueExW(handle, utf16_t(node), 0, REG_SZ, (BYTE*)(wchar_t*)utf16_t(data), (data.length() + 1) * sizeof(wchar_t));
|
|
|
|
}
|
|
|
|
RegCloseKey(handle);
|
|
|
|
}
|
|
|
|
path.append("\\");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-02 11:25:45 +00:00
|
|
|
static bool remove(const string& name) {
|
2012-06-18 10:13:51 +00:00
|
|
|
lstring part = name.split("/");
|
|
|
|
HKEY rootKey = root(part.take(0));
|
|
|
|
string node = part.take();
|
|
|
|
string path = part.concatenate("\\");
|
|
|
|
if(node.empty()) return SHDeleteKeyW(rootKey, utf16_t(path)) == ERROR_SUCCESS;
|
|
|
|
return SHDeleteValueW(rootKey, utf16_t(path), utf16_t(node)) == ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2013-05-02 11:25:45 +00:00
|
|
|
static lstring contents(const string& name) {
|
2012-06-18 10:13:51 +00:00
|
|
|
lstring part = name.split("/"), result;
|
|
|
|
HKEY handle, rootKey = root(part.take(0));
|
|
|
|
part.remove();
|
|
|
|
string path = part.concatenate("\\");
|
|
|
|
if(RegOpenKeyExW(rootKey, utf16_t(path), 0, NWR_FLAGS | KEY_READ, &handle) == ERROR_SUCCESS) {
|
|
|
|
DWORD folders, nodes;
|
2013-03-15 13:11:33 +00:00
|
|
|
RegQueryInfoKey(handle, nullptr, nullptr, nullptr, &folders, nullptr, nullptr, &nodes, nullptr, nullptr, nullptr, nullptr);
|
2012-06-18 10:13:51 +00:00
|
|
|
for(unsigned n = 0; n < folders; n++) {
|
|
|
|
wchar_t name[NWR_SIZE] = L"";
|
|
|
|
DWORD size = NWR_SIZE * sizeof(wchar_t);
|
2013-03-15 13:11:33 +00:00
|
|
|
RegEnumKeyEx(handle, n, (wchar_t*)&name, &size, nullptr, nullptr, nullptr, nullptr);
|
2012-06-18 10:13:51 +00:00
|
|
|
result.append({(const char*)utf8_t(name), "/"});
|
|
|
|
}
|
|
|
|
for(unsigned n = 0; n < nodes; n++) {
|
|
|
|
wchar_t name[NWR_SIZE] = L"";
|
|
|
|
DWORD size = NWR_SIZE * sizeof(wchar_t);
|
2013-03-15 13:11:33 +00:00
|
|
|
RegEnumValueW(handle, n, (wchar_t*)&name, &size, nullptr, nullptr, nullptr, nullptr);
|
2012-06-18 10:13:51 +00:00
|
|
|
result.append((const char*)utf8_t(name));
|
|
|
|
}
|
|
|
|
RegCloseKey(handle);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2013-05-02 11:25:45 +00:00
|
|
|
static HKEY root(const string& name) {
|
2012-06-18 10:13:51 +00:00
|
|
|
if(name == "HKCR") return HKEY_CLASSES_ROOT;
|
|
|
|
if(name == "HKCC") return HKEY_CURRENT_CONFIG;
|
|
|
|
if(name == "HKCU") return HKEY_CURRENT_USER;
|
|
|
|
if(name == "HKLM") return HKEY_LOCAL_MACHINE;
|
|
|
|
if(name == "HKU" ) return HKEY_USERS;
|
2013-03-15 13:11:33 +00:00
|
|
|
return nullptr;
|
2012-06-18 10:13:51 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|