2019-05-14 22:03:25 +00:00
|
|
|
#include <windows.h>
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include "hook/table.h"
|
|
|
|
|
|
|
|
#include "hooklib/dll.h"
|
2019-05-15 15:10:27 +00:00
|
|
|
#include "hooklib/reg.h"
|
2019-05-14 22:03:25 +00:00
|
|
|
|
2019-05-18 03:10:09 +00:00
|
|
|
#include "platform/amvideo.h"
|
|
|
|
|
2019-05-14 22:03:25 +00:00
|
|
|
#include "util/dprintf.h"
|
|
|
|
|
|
|
|
/* Hook functions */
|
|
|
|
|
|
|
|
static int amDllVideoOpen(void *ctx);
|
|
|
|
static int amDllVideoClose(void *ctx);
|
|
|
|
static int amDllVideoSetResolution(void *ctx, void *param);
|
|
|
|
static int amDllVideoGetVBiosVersion(void *ctx, char *dest, size_t nchars);
|
|
|
|
|
2019-05-15 15:10:27 +00:00
|
|
|
static HRESULT amvideo_reg_read_name(void *bytes, uint32_t *nbytes);
|
|
|
|
static HRESULT amvideo_reg_read_port_X(void *bytes, uint32_t *nbytes);
|
|
|
|
static HRESULT amvideo_reg_read_resolution_1(void *bytes, uint32_t *nbytes);
|
2019-08-30 22:46:04 +00:00
|
|
|
static HRESULT amvideo_reg_read_setting(void *bytes, uint32_t *nbytes);
|
2019-05-15 15:10:27 +00:00
|
|
|
static HRESULT amvideo_reg_read_use_segatiming(void *bytes, uint32_t *nbytes);
|
|
|
|
|
|
|
|
static const wchar_t amvideo_dll_name[] = L"$amvideo";
|
|
|
|
|
|
|
|
static const struct reg_hook_val amvideo_reg_vals[] = {
|
|
|
|
{
|
|
|
|
.name = L"name",
|
|
|
|
.read = amvideo_reg_read_name,
|
|
|
|
.type = REG_SZ,
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct reg_hook_val amvideo_reg_mode_vals[] = {
|
|
|
|
{
|
2019-08-30 22:46:04 +00:00
|
|
|
.name = L"monitor_setting_1",
|
|
|
|
.read = amvideo_reg_read_setting,
|
|
|
|
.type = REG_SZ,
|
|
|
|
}, {
|
|
|
|
.name = L"monitor_setting_2",
|
|
|
|
.read = amvideo_reg_read_setting,
|
|
|
|
.type = REG_SZ,
|
|
|
|
}, {
|
2019-05-15 15:10:27 +00:00
|
|
|
.name = L"port_1",
|
|
|
|
.read = amvideo_reg_read_port_X,
|
|
|
|
.type = REG_DWORD
|
|
|
|
}, {
|
|
|
|
.name = L"port_2",
|
|
|
|
.read = amvideo_reg_read_port_X,
|
|
|
|
.type = REG_DWORD
|
|
|
|
}, {
|
|
|
|
.name = L"port_3",
|
|
|
|
.read = amvideo_reg_read_port_X,
|
|
|
|
.type = REG_DWORD
|
|
|
|
}, {
|
|
|
|
.name = L"port_4",
|
|
|
|
.read = amvideo_reg_read_port_X,
|
|
|
|
.type = REG_DWORD
|
|
|
|
}, {
|
|
|
|
.name = L"port_5",
|
|
|
|
.read = amvideo_reg_read_port_X,
|
|
|
|
.type = REG_DWORD
|
|
|
|
}, {
|
|
|
|
.name = L"port_6",
|
|
|
|
.read = amvideo_reg_read_port_X,
|
|
|
|
.type = REG_DWORD
|
|
|
|
}, {
|
|
|
|
.name = L"port_7",
|
|
|
|
.read = amvideo_reg_read_port_X,
|
|
|
|
.type = REG_DWORD
|
|
|
|
}, {
|
|
|
|
.name = L"port_8",
|
|
|
|
.read = amvideo_reg_read_port_X,
|
|
|
|
.type = REG_DWORD
|
|
|
|
}, {
|
|
|
|
.name = L"resolution_1",
|
|
|
|
.read = amvideo_reg_read_resolution_1,
|
|
|
|
.type = REG_SZ,
|
|
|
|
}, {
|
|
|
|
.name = L"use_segatiming",
|
|
|
|
.read = amvideo_reg_read_use_segatiming,
|
|
|
|
.type = REG_DWORD,
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-05-14 22:03:25 +00:00
|
|
|
static const struct hook_symbol amvideo_syms[] = {
|
|
|
|
{
|
|
|
|
.ordinal = 1,
|
|
|
|
.name = "amDllVideoOpen",
|
|
|
|
.patch = amDllVideoOpen,
|
|
|
|
}, {
|
|
|
|
.ordinal = 2,
|
|
|
|
.name = "amDllVideoClose",
|
|
|
|
.patch = amDllVideoClose,
|
|
|
|
}, {
|
|
|
|
.ordinal = 3,
|
|
|
|
.name = "amDllVideoSetResolution",
|
|
|
|
.patch = amDllVideoSetResolution,
|
|
|
|
}, {
|
|
|
|
.ordinal = 4,
|
|
|
|
.name = "amDllVideoGetVBiosVersion",
|
|
|
|
.patch = amDllVideoGetVBiosVersion,
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-05-18 03:10:09 +00:00
|
|
|
HRESULT amvideo_hook_init(const struct amvideo_config *cfg, HMODULE redir_mod)
|
2019-05-14 22:03:25 +00:00
|
|
|
{
|
2019-05-15 15:10:27 +00:00
|
|
|
HRESULT hr;
|
|
|
|
|
2019-05-18 03:10:09 +00:00
|
|
|
assert(cfg != NULL);
|
|
|
|
|
|
|
|
if (!cfg->enable) {
|
|
|
|
return S_FALSE;
|
|
|
|
}
|
|
|
|
|
2019-05-15 15:10:27 +00:00
|
|
|
hr = reg_hook_push_key(
|
|
|
|
HKEY_LOCAL_MACHINE,
|
|
|
|
L"SYSTEM\\SEGA\\SystemProperty\\amVideo",
|
|
|
|
amvideo_reg_vals,
|
|
|
|
_countof(amvideo_reg_vals));
|
|
|
|
|
|
|
|
if (FAILED(hr)) {
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
hr = reg_hook_push_key(
|
|
|
|
HKEY_LOCAL_MACHINE,
|
|
|
|
L"SYSTEM\\SEGA\\SystemProperty\\sgsetdisplaysetting\\CurrentSetting",
|
|
|
|
amvideo_reg_mode_vals,
|
|
|
|
_countof(amvideo_reg_mode_vals));
|
|
|
|
|
|
|
|
if (FAILED(hr)) {
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
hr = dll_hook_push(
|
2019-05-14 22:03:25 +00:00
|
|
|
redir_mod,
|
2019-05-15 15:10:27 +00:00
|
|
|
amvideo_dll_name,
|
2019-05-14 22:03:25 +00:00
|
|
|
amvideo_syms,
|
|
|
|
_countof(amvideo_syms));
|
2019-05-15 15:10:27 +00:00
|
|
|
|
|
|
|
if (FAILED(hr)) {
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return S_OK;
|
2019-05-14 22:03:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int amDllVideoOpen(void *ctx)
|
|
|
|
{
|
|
|
|
dprintf("AmVideo: %s(%p)\n", __func__, ctx);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int amDllVideoClose(void *ctx)
|
|
|
|
{
|
|
|
|
dprintf("AmVideo: %s(%p)\n", __func__, ctx);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int amDllVideoSetResolution(void *ctx, void *param)
|
|
|
|
{
|
|
|
|
dprintf("AmVideo: %s(%p, %p)\n", __func__, ctx, param);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int amDllVideoGetVBiosVersion(void *ctx, char *dest, size_t nchars)
|
|
|
|
{
|
|
|
|
dprintf("AmVideo: %s(%p, %p, %i)\n", __func__, ctx, dest, (int) nchars);
|
|
|
|
strcpy(dest, "01.02.03.04.05");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2019-05-15 15:10:27 +00:00
|
|
|
|
|
|
|
static HRESULT amvideo_reg_read_name(void *bytes, uint32_t *nbytes)
|
|
|
|
{
|
|
|
|
return reg_hook_read_wstr(bytes, nbytes, amvideo_dll_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT amvideo_reg_read_port_X(void *bytes, uint32_t *nbytes)
|
|
|
|
{
|
|
|
|
return reg_hook_read_u32(bytes, nbytes, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static HRESULT amvideo_reg_read_resolution_1(void *bytes, uint32_t *nbytes)
|
|
|
|
{
|
|
|
|
return reg_hook_read_wstr(bytes, nbytes, L"1920x1080");
|
|
|
|
}
|
|
|
|
|
2019-08-30 22:46:04 +00:00
|
|
|
static HRESULT amvideo_reg_read_setting(void *bytes, uint32_t *nbytes)
|
|
|
|
{
|
|
|
|
return reg_hook_read_wstr(bytes, nbytes, L"0");
|
|
|
|
}
|
|
|
|
|
2019-05-15 15:10:27 +00:00
|
|
|
static HRESULT amvideo_reg_read_use_segatiming(void *bytes, uint32_t *nbytes)
|
|
|
|
{
|
|
|
|
return reg_hook_read_u32(bytes, nbytes, 0);
|
|
|
|
}
|