mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
cppkore uses string/wstring as StringBase while we use std::string/std::wstring as string/wstring. Changed all types in cppkore to String/WString instead.
218 lines
6.5 KiB
C++
218 lines
6.5 KiB
C++
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include "StringBase.h"
|
|
#include <Windows.h>
|
|
#include "Win32Error.h"
|
|
#include "ListBase.h"
|
|
#include "StringBase.h"
|
|
#include "RegistryHive.h"
|
|
#include "RegistryView.h"
|
|
#include "RegistryValueType.h"
|
|
|
|
namespace Win32
|
|
{
|
|
class RegistryKey
|
|
{
|
|
private:
|
|
RegistryKey(HKEY hKey, bool Writable, RegistryView View);
|
|
RegistryKey(HKEY hKey, bool Writable, bool SystemKey, RegistryView View);
|
|
|
|
public:
|
|
~RegistryKey();
|
|
|
|
// Closes all resources tied to this key
|
|
void Close();
|
|
// Flush all pending changes to the disk
|
|
void Flush();
|
|
// Creates a new subkey
|
|
RegistryKey CreateSubKey(const String& SubKey);
|
|
// Deletes a subkey
|
|
void DeleteSubKey(const String& SubKey, bool ThrowOnMissingSubKey = false);
|
|
// Deletes a subkey and all nested values
|
|
void DeleteSubKeyTree(const String& SubKey, bool ThrowOnMissingSubKey = false);
|
|
// Deletes a value
|
|
void DeleteValue(const String& Name, bool ThrowOnMissingSubKey = false);
|
|
// Opens a subkey of this instance
|
|
RegistryKey OpenSubKey(const String& Name, bool Writable = true);
|
|
// Returns a value
|
|
template<RegistryValueType T>
|
|
auto GetValue(const String& Name);
|
|
// Returns a list of value names
|
|
List<String> GetValueNames();
|
|
// Returns the type of value this key is
|
|
RegistryValueType GetValueKind(const String& Name);
|
|
// Sets a value
|
|
template<RegistryValueType T, typename Tval>
|
|
void SetValue(const String& Name, const Tval& Value);
|
|
// Returns the count of subkeys
|
|
uint32_t GetSubKeyCount();
|
|
// Returns the count of values
|
|
uint32_t GetValueCount();
|
|
// Returns the subkey names
|
|
List<String> GetSubKeyNames();
|
|
|
|
// Opens one of the base registry hives on the system
|
|
static RegistryKey OpenBaseKey(RegistryHive Hive, RegistryView View);
|
|
// Returns a key from the specified handle
|
|
static RegistryKey FromHandle(HKEY hKey, RegistryView View);
|
|
|
|
private:
|
|
// Cached key flags
|
|
HKEY _Handle;
|
|
uint32_t _State;
|
|
RegistryView _View;
|
|
String _KeyName;
|
|
|
|
// Helper routines
|
|
bool IsDirty();
|
|
bool IsSystemKey();
|
|
bool IsWritable();
|
|
|
|
// Internal routine to create a subkeu
|
|
RegistryKey CreateSubKeyInternal(const String& SubKey);
|
|
// Internal routine to delete a subkey tree
|
|
void DeleteSubKeyTreeInternal(const String& SubKey);
|
|
// Internal routine to open a subkey
|
|
RegistryKey InternalOpenSubKey(const String& SubKey, bool Writable);
|
|
// Internal routine to get a value
|
|
std::unique_ptr<uint8_t[]> InternalGetValue(const String& Name, uint64_t& ValueSize);
|
|
// Internal routine to set a value
|
|
void InternalSetValue(const String& Name, uint32_t ValueType, uint8_t* Buffer, uint64_t BufferSize);
|
|
// Internal routine to get subkey count
|
|
uint32_t InternalSubKeyCount();
|
|
// Internal routine to get value count
|
|
uint32_t InternalValueCount();
|
|
// Internal routine to get subkey names
|
|
List<String> InternalGetSubKeyNames();
|
|
|
|
// Cleans up a key name
|
|
static String FixupName(String Name);
|
|
// Cleans up a key path
|
|
static void FixupPath(String& Path);
|
|
|
|
// Internal key states
|
|
constexpr static uint32_t STATE_DIRTY = 0x1;
|
|
constexpr static uint32_t STATE_SYSTEMKEY = 0x2;
|
|
constexpr static uint32_t STATE_WRITEACCESS = 0x4;
|
|
|
|
// Maximum key lengths
|
|
constexpr static uint32_t MaxKeyLength = 255;
|
|
constexpr static uint32_t MaxValueLength = 16383;
|
|
|
|
// Internal hive names
|
|
constexpr static const char* const HiveNames[] =
|
|
{
|
|
"HKEY_CLASSES_ROOT",
|
|
"HKEY_CURRENT_USER",
|
|
"HKEY_LOCAL_MACHINE",
|
|
"HKEY_USERS",
|
|
"HKEY_PERFORMANCE_DATA",
|
|
"HKEY_CURRENT_CONFIG",
|
|
"HKEY_DYN_DATA"
|
|
};
|
|
};
|
|
|
|
template<RegistryValueType T>
|
|
inline auto RegistryKey::GetValue(const String& Name)
|
|
{
|
|
uint64_t BufferSize = 0;
|
|
auto Buffer = this->InternalGetValue(Name, BufferSize);
|
|
|
|
if constexpr (T == RegistryValueType::Dword)
|
|
{
|
|
return *(uint32_t*)Buffer.get();
|
|
}
|
|
else if constexpr (T == RegistryValueType::DwordBigEndian)
|
|
{
|
|
return _byteswap_ulong(*(uint32_t*)Buffer.get());
|
|
}
|
|
else if constexpr (T == RegistryValueType::Qword)
|
|
{
|
|
return *(uint64_t*)Buffer.get();
|
|
}
|
|
else if constexpr (T == RegistryValueType::String)
|
|
{
|
|
return String((const char*)Buffer.get());
|
|
}
|
|
else if constexpr (T == RegistryValueType::MultiString)
|
|
{
|
|
auto Result = List<String>();
|
|
uint64_t Position = 0;
|
|
|
|
// We must parse each String as we go, and ensure we haven't reached the buffer size
|
|
while (Position < BufferSize)
|
|
{
|
|
// Read the str with strlen() because it doesn't store the size of each one
|
|
auto cStr = String((const char*)(Buffer.get() + Position));
|
|
|
|
// Shift based on the size + null char...
|
|
Position += cStr.Length() + sizeof(char);
|
|
|
|
// Move the str into it's list
|
|
Result.EmplaceBack(std::move(cStr));
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
else if constexpr (T == RegistryValueType::Binary)
|
|
{
|
|
RegistryBinaryBlob Blob;
|
|
|
|
Blob.Buffer = std::move(Buffer);
|
|
Blob.Size = BufferSize;
|
|
|
|
return Blob;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
template<RegistryValueType T, typename Tval>
|
|
inline void RegistryKey::SetValue(const String& Name, const Tval& Value)
|
|
{
|
|
if constexpr (T == RegistryValueType::Dword)
|
|
{
|
|
uint32_t LittleEndian = (uint32_t)Value;
|
|
this->InternalSetValue(Name, REG_DWORD, (uint8_t*)&LittleEndian, sizeof(uint32_t));
|
|
}
|
|
else if constexpr (T == RegistryValueType::DwordBigEndian)
|
|
{
|
|
uint32_t BigEndian = _byteswap_ulong((uint32_t)Value);
|
|
this->InternalSetValue(Name, REG_DWORD_BIG_ENDIAN, (uint8_t*)&BigEndian, sizeof(uint32_t));
|
|
}
|
|
else if constexpr (T == RegistryValueType::Qword)
|
|
{
|
|
uint64_t LittleEndian = (uint64_t)Value;
|
|
this->InternalSetValue(Name, REG_QWORD, (uint8_t*)&LittleEndian, sizeof(uint64_t));
|
|
}
|
|
else if constexpr (T == RegistryValueType::String)
|
|
{
|
|
this->InternalSetValue(Name, REG_SZ, (uint8_t*)&Value[0], Value.Length() + sizeof(char));
|
|
}
|
|
else if constexpr (T == RegistryValueType::MultiString)
|
|
{
|
|
// Calculate the resulting buffer size
|
|
uint32_t BufferSize = 0;
|
|
for (auto& Str : Value)
|
|
BufferSize += Str.Length() + sizeof(char);
|
|
auto Buffer = std::make_unique<uint8_t[]>(BufferSize);
|
|
|
|
BufferSize = 0;
|
|
|
|
// Iterate and copy the entire string including the null-char which is in StringBase<>
|
|
for (auto& Str : Value)
|
|
{
|
|
std::memcpy(Buffer.get() + BufferSize, &Str[0], Str.Length() + sizeof(char));
|
|
BufferSize += Str.Length() + sizeof(char);
|
|
}
|
|
|
|
// Pass our temporary buffer of all strings to the value
|
|
this->InternalSetValue(Name, REG_MULTI_SZ, (uint8_t*)Buffer.get(), BufferSize);
|
|
}
|
|
else if constexpr (T == RegistryValueType::Binary)
|
|
{
|
|
this->InternalSetValue(Name, REG_BINARY, (uint8_t*)Value.Buffer, Value.Size);
|
|
}
|
|
}
|
|
} |