6
0
mirror of https://github.com/JKornev/hidden synced 2024-06-16 12:08:05 +00:00
hidden/HiddenCLI/Helper.cpp
2017-01-07 23:28:40 +03:00

408 lines
8.5 KiB
C++

#include "helper.h"
#include <memory>
using namespace std;
// =================
std::wstringstream g_stdout;
std::wstringstream g_stderr;
// =================
WException::WException(unsigned int Code, wchar_t* Format, ...) :
m_errorCode(Code)
{
wchar_t buffer[256];
va_list args;
va_start(args, Format);
_vsnwprintf_s(buffer, _countof(buffer), _TRUNCATE, Format, args);
va_end(args);
m_errorMessage = buffer;
}
const wchar_t* WException::What()
{
return m_errorMessage.c_str();
}
unsigned int WException::Code()
{
return m_errorCode;
}
// =================
Arguments::Arguments(int argc, wchar_t* argv[], int start) :
m_argPointer(0)
{
for (int i = start; i < argc; i++)
m_arguments.push_back(argv[i]);
}
size_t Arguments::ArgsCount()
{
return m_arguments.size();
}
bool Arguments::Probe(std::wstring& arg)
{
if (m_argPointer >= m_arguments.size())
return false;
arg = m_arguments[m_argPointer];
return true;
}
bool Arguments::SwitchToNext()
{
if (m_argPointer >= m_arguments.size())
return false;
m_argPointer++;
return true;
}
bool Arguments::GetNext(wstring& arg)
{
if (m_argPointer >= m_arguments.size())
return false;
arg = m_arguments[m_argPointer++];
return true;
}
// =================
Handle::Handle(HANDLE handle) :
m_handle(handle),
m_error(::GetLastError())
{
}
Handle::~Handle()
{
if (m_handle != INVALID_HANDLE_VALUE)
::CloseHandle(m_handle);
}
HANDLE Handle::Get()
{
return m_handle;
}
DWORD Handle::Error()
{
return m_error;
}
// =================
RegistryKey::RegistryKey(std::wstring regKey, HKEY root, REGSAM access, bool newKey) : m_hkey(NULL)
{
if (newKey)
{
LONG status = RegCreateKeyExW(root, regKey.c_str(), 0, NULL, 0, access, NULL, &m_hkey, NULL);
if (status != ERROR_SUCCESS)
throw WException(status, L"Error, can't create registry key");
}
else
{
LONG status = RegOpenKeyExW(root, regKey.c_str(), 0, access, &m_hkey);
if (status != ERROR_SUCCESS)
throw WException(status, L"Error, can't open registry key");
}
}
RegistryKey::~RegistryKey()
{
RegCloseKey(m_hkey);
}
void RegistryKey::CopyTreeFrom(RegistryKey& src)
{
LONG status;
status = RegCopyTree(src.m_hkey, NULL, m_hkey);
if (status != ERROR_SUCCESS)
throw WException(status, L"Error, can't copy registry tree");
}
void RegistryKey::DeleteKey(std::wstring regKey, HKEY root)
{
LONG status;
status = RegDeleteTreeW(root, regKey.c_str());
if (status != ERROR_SUCCESS)
throw WException(status, L"Error, can't copy registry tree");
}
void RegistryKey::SetDwordValue(const wchar_t* name, DWORD value)
{
LONG status;
status = RegSetValueExW(m_hkey, name, NULL, REG_DWORD, (LPBYTE)&value, sizeof(value));
if (status != ERROR_SUCCESS)
throw WException(status, L"Error, can't set registry value");
}
DWORD RegistryKey::GetDwordValue(const wchar_t* name, DWORD defValue)
{
DWORD value, size = sizeof(value), type = REG_DWORD;
LONG status;
status = RegQueryValueEx(m_hkey, name, NULL, &type, (LPBYTE)&value, &size);
if (status != ERROR_SUCCESS)
{
if (status != ERROR_FILE_NOT_FOUND)
throw WException(status, L"Error, can't query registry value");
return defValue;
}
return value;
}
void RegistryKey::SetStrValue(const wchar_t* name, std::wstring& value, bool expanded)
{
LONG status;
status = RegSetValueExW(m_hkey, name, NULL, (expanded ? REG_EXPAND_SZ : REG_SZ), (LPBYTE)value.c_str(), (DWORD)(value.size() + 1) * sizeof(wchar_t));
if (status != ERROR_SUCCESS)
throw WException(status, L"Error, can't set registry value");
}
void RegistryKey::GetStrValue(const wchar_t* name, std::wstring& value, const wchar_t* defValue)
{
DWORD size = 0, type = REG_SZ;
LONG status;
status = RegQueryValueExW(m_hkey, name, NULL, &type, NULL, &size);
if (status != ERROR_SUCCESS)
{
if (status != ERROR_FILE_NOT_FOUND)
throw WException(status, L"Error, can't query registry value");
value = defValue;
return;
}
if (type != REG_SZ && type != REG_EXPAND_SZ)
throw WException(status, L"Error, invalid registry key type");
if (size == 0)
return;
value.clear();
value.insert(0, size / sizeof(wchar_t), L'\0');
status = RegQueryValueExW(m_hkey, name, NULL, &type, (LPBYTE)value.c_str(), &size);
if (status != ERROR_SUCCESS)
throw WException(status, L"Error, can't query registry value");
while (value.size() > 0 && value[value.size() - 1] == L'\0')
value.pop_back();
}
void RegistryKey::SetMultiStrValue(const wchar_t* name, const std::vector<std::wstring>& strs)
{
DWORD size = 0, offset = 0;
shared_ptr<BYTE> buffer;
LONG status;
for (auto it = strs.begin(); it != strs.end(); it++)
{
if (it->size() > 0)
size += (DWORD)(it->size() + 1) * sizeof(wchar_t);
}
if (size == 0)
{
WCHAR value = 0;
status = RegSetValueExW(m_hkey, name, NULL, REG_MULTI_SZ, (LPBYTE)&value, 2);
if (status != ERROR_SUCCESS)
throw WException(status, L"Error, can't set registry value");
return;
}
buffer.reset(new BYTE[size]);
memset(buffer.get(), 0, size);
for (auto it = strs.begin(); it != strs.end(); it++)
{
if (it->size() == 0)
continue;
DWORD strSize = (DWORD)(it->size() + 1) * sizeof(wchar_t);
memcpy(buffer.get() + offset, it->c_str(), strSize);
offset += strSize;
}
status = RegSetValueExW(m_hkey, name, NULL, REG_MULTI_SZ, buffer.get(), size);
if (status != ERROR_SUCCESS)
throw WException(status, L"Error, can't set registry value");
}
void RegistryKey::GetMultiStrValue(const wchar_t* name, std::vector<std::wstring>& strs)
{
DWORD size = 0, type = REG_MULTI_SZ;
shared_ptr<BYTE> buffer;
LPWSTR bufferPtr;
LONG status;
strs.clear();
status = RegQueryValueExW(m_hkey, name, NULL, &type, NULL, &size);
if (status != ERROR_SUCCESS)
{
if (status != ERROR_FILE_NOT_FOUND)
throw WException(status, L"Error, can't query registry value");
return;
}
if (type != REG_MULTI_SZ)
throw WException(status, L"Error, invalid registry key type");
if (size == 0)
return;
buffer.reset(new BYTE[size + sizeof(WCHAR)]);
memset(buffer.get(), 0, size + sizeof(WCHAR));
status = RegQueryValueExW(m_hkey, name, NULL, &type, buffer.get(), &size);
if (status != ERROR_SUCCESS)
throw WException(status, L"Error, can't query registry value");
bufferPtr = (LPWSTR)buffer.get();
while (size > 1)
{
ULONG inx, delta = 0;
ULONG len = size / sizeof(WCHAR);
for (inx = 0; inx < len; inx++)
{
if (bufferPtr[inx] == L'\0')
{
delta = 1;
break;
}
}
if (inx > 0)
strs.push_back(bufferPtr);
size -= (inx + delta) * sizeof(WCHAR);
bufferPtr += (inx + delta);
}
}
void RegistryKey::RemoveValue(const wchar_t* name)
{
LONG status = RegDeleteKeyValueW(m_hkey, NULL, name);
if (status != ERROR_SUCCESS)
throw WException(status, L"Error, can't delete registry value");
}
// =================
HidRegRootTypes GetRegType(wstring& path)
{
static wchar_t regHKLM[] = L"HKLM\\";
static wchar_t regHKCU[] = L"HKCU\\";
static wchar_t regHKU[] = L"HKU\\";
if (path.compare(0, _countof(regHKLM) - 1, regHKLM) == 0)
return HidRegRootTypes::RegHKLM;
else if (path.compare(0, _countof(regHKCU) - 1, regHKCU) == 0)
return HidRegRootTypes::RegHKCU;
else if (path.compare(0, _countof(regHKU) - 1, regHKU) == 0)
return HidRegRootTypes::RegHKU;
else
throw WException(ERROR_INVALID_DATA, L"Error, invalid registry prefix");
}
HidPsInheritTypes LoadInheritOption(Arguments& args, HidPsInheritTypes default)
{
wstring arg;
if (!args.Probe(arg))
return default;
if (arg == L"inherit:none")
{
args.SwitchToNext();
return HidPsInheritTypes::WithoutInherit;
}
else if (arg == L"inherit:always")
{
args.SwitchToNext();
return HidPsInheritTypes::InheritAlways;
}
else if (arg == L"inherit:once")
{
args.SwitchToNext();
return HidPsInheritTypes::InheritOnce;
}
return default;
}
bool LoadApplyOption(Arguments& args, bool applyByDefault)
{
wstring arg;
if (!args.Probe(arg))
return applyByDefault;
if (arg == L"apply:fornew")
{
args.SwitchToNext();
return false;
}
else if (arg == L"apply:forall")
{
args.SwitchToNext();
return true;
}
return applyByDefault;
}
const wchar_t* ConvertInheritTypeToUnicode(HidPsInheritTypes type)
{
switch (type)
{
case HidPsInheritTypes::WithoutInherit:
return L"none";
break;
case HidPsInheritTypes::InheritOnce:
return L"once";
break;
case HidPsInheritTypes::InheritAlways:
return L"always";
break;
}
return L"unknown";
}
const wchar_t* ConvertRegRootTypeToUnicode(HidRegRootTypes type)
{
switch (type)
{
case HidRegRootTypes::RegHKCU:
return L"HKCU";
break;
case HidRegRootTypes::RegHKLM:
return L"HKLM";
break;
case HidRegRootTypes::RegHKU:
return L"HKU";
break;
}
return L"unknown";
}