Files

277 lines
7.0 KiB
C

#include <windows.h>
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include "hook/table.h"
#include "hooklib/reg.h"
#include "platform/misc.h"
#include <shlwapi.h>
#include "util/dprintf.h"
static BOOL WINAPI misc_ExitWindowsEx(unsigned int flags, uint32_t reason);
static HRESULT misc_read_os_version(void *bytes, uint32_t *nbytes);
static HRESULT misc_read_app_loader_count(void *bytes, uint32_t *nbytes);
static HRESULT misc_read_cpu_temp_error(void *bytes, uint32_t *nbytes);
static HRESULT misc_read_cpu_temp_warning(void *bytes, uint32_t *nbytes);
static HRESULT misc_read_platform_id(void *bytes, uint32_t *nbytes);
static HRESULT misc_read_platform_name(void *bytes, uint32_t *nbytes);
static HRESULT misc_read_main_nic(void *bytes, uint32_t *nbytes);
static HRESULT misc_read_extend_nic(void *bytes, uint32_t *nbytes);
static HRESULT misc_read_downloadui_done(void *bytes, uint32_t *nbytes);
static HRESULT misc_read_next_process(void *bytes, uint32_t *nbytes);
static HRESULT misc_write_next_process(const void *bytes, uint32_t nbytes);
static const struct hook_symbol misc_syms[] = {
{
.name = "ExitWindowsEx",
.patch = misc_ExitWindowsEx,
}
};
static const struct reg_hook_val misc_root_keys[] = {
{
.name = L"OSVersion",
.read = misc_read_os_version,
.type = REG_SZ,
}
};
static const struct reg_hook_val misc_master_keys[] = {
{
.name = L"AppLoaderCount",
.read = misc_read_app_loader_count,
.type = REG_DWORD,
}, {
.name = L"NextProcess",
.read = misc_read_next_process,
.write = misc_write_next_process,
.type = REG_SZ,
}, {
/* Black-hole val for reading, list it here so we don't get a warning msg */
.name = L"SystemError",
.type = REG_SZ,
}
};
static const struct reg_hook_val misc_static_keys[] = {
{
.name = L"CpuTempError",
.read = misc_read_cpu_temp_error,
.type = REG_DWORD,
}, {
.name = L"CpuTempWarning",
.read = misc_read_cpu_temp_warning,
.type = REG_DWORD,
}, {
.name = L"PlatformId",
.read = misc_read_platform_id,
.type = REG_SZ,
}, {
.name = L"PlatformName",
.read = misc_read_platform_name,
.type = REG_SZ,
}
};
static const struct reg_hook_val misc_wireless_keys[] = {
{
.name = L"main_nic",
.read = misc_read_main_nic,
.type = REG_DWORD,
}, {
.name = L"extend_nic",
.read = misc_read_extend_nic,
.type = REG_DWORD,
}
};
static const struct reg_hook_val misc_downloadui_keys[] = {
{
.name = L"IsDone",
.read = misc_read_downloadui_done,
.type = REG_DWORD,
},
};
static wchar_t misc_platform_id[5];
static const struct misc_config *config;
HRESULT misc_hook_init(const struct misc_config *cfg, const char *platform_id)
{
HRESULT hr;
assert(cfg != NULL);
assert(platform_id != NULL && strlen(platform_id) == 4);
config = cfg;
if (!cfg->enable) {
return S_FALSE;
}
/* Set platform ID registry value */
mbstowcs_s(
NULL,
misc_platform_id,
_countof(misc_platform_id),
platform_id,
_countof(misc_platform_id) - 1);
/* Add hardcoded dummy keys */
hr = reg_hook_push_key(
HKEY_LOCAL_MACHINE,
L"SYSTEM\\SEGA\\SystemProperty",
misc_root_keys,
_countof(misc_root_keys));
if (FAILED(hr)) {
return hr;
}
hr = reg_hook_push_key(
HKEY_LOCAL_MACHINE,
L"SYSTEM\\SEGA\\SystemProperty\\static",
misc_static_keys,
_countof(misc_static_keys));
if (FAILED(hr)) {
return hr;
}
if (!cfg->allowMasterKeyWrite) {
hr = reg_hook_push_key(
HKEY_LOCAL_MACHINE,
L"SYSTEM\\SEGA\\SystemProperty\\Master",
misc_master_keys,
_countof(misc_master_keys));
if (FAILED(hr)) {
return hr;
}
}
hr = reg_hook_push_key(
HKEY_LOCAL_MACHINE,
L"SYSTEM\\SEGA\\SystemProperty\\wirelessNetwork",
misc_wireless_keys,
_countof(misc_wireless_keys));
if (FAILED(hr)) {
return hr;
}
hr = reg_hook_push_key(
HKEY_LOCAL_MACHINE,
L"SYSTEM\\SEGA\\SystemProperty\\downloadui",
misc_downloadui_keys,
_countof(misc_downloadui_keys));
if (FAILED(hr)) {
return hr;
}
/* Apply function hooks */
if (!cfg->allowReboot) {
hook_table_apply(NULL, "user32.dll", misc_syms, _countof(misc_syms));
}
if (PathFileExistsW(cfg->nextProcessFile)) {
DeleteFileW(cfg->nextProcessFile);
}
return S_OK;
}
static BOOL WINAPI misc_ExitWindowsEx(unsigned int flags, uint32_t reason)
{
dprintf("Misc: Blocked system reboot\n");
return TRUE;
}
static HRESULT misc_read_os_version(void *bytes, uint32_t *nbytes)
{
return reg_hook_read_wstr(bytes, nbytes, L"0_0_0");
}
static HRESULT misc_read_app_loader_count(void *bytes, uint32_t *nbytes)
{
return reg_hook_read_u32(bytes, nbytes, 1);
}
static HRESULT misc_read_cpu_temp_error(void *bytes, uint32_t *nbytes)
{
return reg_hook_read_u32(bytes, nbytes, 100);
}
static HRESULT misc_read_cpu_temp_warning(void *bytes, uint32_t *nbytes)
{
return reg_hook_read_u32(bytes, nbytes, 95);
}
static HRESULT misc_read_platform_id(void *bytes, uint32_t *nbytes)
{
return reg_hook_read_wstr(bytes, nbytes, misc_platform_id);
}
static HRESULT misc_read_platform_name(void *bytes, uint32_t *nbytes)
{
return reg_hook_read_wstr(bytes, nbytes, L"ALLS MX2.1"); // TODO: Dynamic
}
static HRESULT misc_read_main_nic(void *bytes, uint32_t *nbytes)
{
return reg_hook_read_wstr(bytes, nbytes, L"");
}
static HRESULT misc_read_extend_nic(void *bytes, uint32_t *nbytes)
{
return reg_hook_read_wstr(bytes, nbytes, L"");
}
static HRESULT misc_read_downloadui_done(void *bytes, uint32_t *nbytes)
{
return reg_hook_read_u32(bytes, nbytes, 1);
}
static HRESULT misc_read_next_process(void *bytes, uint32_t *nbytes)
{
return reg_hook_read_wstr(bytes, nbytes, L"");
}
static HRESULT misc_write_next_process(const void *bytes, uint32_t nbytes)
{
HRESULT hr;
DWORD dwBytesWritten;
wchar_t* nextProcess = malloc(nbytes);
memcpy(nextProcess, bytes, nbytes);
dprintf("Misc: Next Process: %ls\n", nextProcess);
HANDLE hFile = CreateFileW(config->nextProcessFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
hr = HRESULT_FROM_WIN32(GetLastError());
dprintf("Misc: Error opening %ls for writing: %x\n", config->nextProcessFile, (int) hr);
return hr;
}
WriteFile(hFile, nextProcess, nbytes, &dwBytesWritten, NULL);
CloseHandle(hFile);
return S_OK;
}