Files
djhackersdev_bemanitools/src/main/ddrhook/monitor.c
T
icex2 b6e588116d Various import fixes caused by clang-format
Added format protection block to avoid re-ordering of header files
according to formatting rules.
2019-10-22 21:04:45 +02:00

194 lines
4.6 KiB
C

// clang-format off
// Don't format because the order is important here
#include <windows.h>
#include <setupapi.h>
// clang-format on
#include <stdbool.h>
#include <wchar.h>
#include "ddrhook/monitor.h"
#include "hook/table.h"
#include "util/defs.h"
#include "util/log.h"
#include "util/str.h"
/* Link pointers */
static HDEVINFO(WINAPI *next_SetupDiGetClassDevsW)(
const GUID *class_guid, const wchar_t *enumerator, HWND hwnd, DWORD flags);
static BOOL(WINAPI *next_SetupDiEnumDeviceInfo)(
HDEVINFO dev_info, DWORD index, SP_DEVINFO_DATA *info_data);
static BOOL(WINAPI *next_SetupDiGetDeviceRegistryPropertyA)(
HDEVINFO dev_info,
SP_DEVINFO_DATA *info_data,
DWORD prop,
DWORD *reg_type,
BYTE *bytes,
DWORD nbytes,
DWORD *need_nbytes);
static BOOL(WINAPI *next_SetupDiDestroyDeviceInfoList)(HDEVINFO dev_info);
/* API hooks */
static HDEVINFO WINAPI my_SetupDiGetClassDevsW(
const GUID *class_guid, const wchar_t *enumerator, HWND hwnd, DWORD flags);
static BOOL WINAPI my_SetupDiEnumDeviceInfo(
HDEVINFO dev_info, DWORD index, SP_DEVINFO_DATA *info_data);
static BOOL WINAPI my_SetupDiGetDeviceRegistryPropertyA(
HDEVINFO dev_info,
SP_DEVINFO_DATA *info_data,
DWORD prop,
DWORD *reg_type,
BYTE *bytes,
DWORD nbytes,
DWORD *need_nbytes);
static BOOL WINAPI my_SetupDiDestroyDeviceInfoList(HDEVINFO dev_info);
static const struct hook_symbol monitor_setupapi_syms[] = {
{
.name = "SetupDiGetClassDevsW",
.patch = my_SetupDiGetClassDevsW,
.link = (void **) &next_SetupDiGetClassDevsW,
},
{
.name = "SetupDiEnumDeviceInfo",
.patch = my_SetupDiEnumDeviceInfo,
.link = (void **) &next_SetupDiEnumDeviceInfo,
},
{
.name = "SetupDiGetDeviceRegistryPropertyA",
.patch = my_SetupDiGetDeviceRegistryPropertyA,
.link = (void **) &next_SetupDiGetDeviceRegistryPropertyA,
},
{
.name = "SetupDiDestroyDeviceInfoList",
.patch = my_SetupDiDestroyDeviceInfoList,
.link = (void **) &next_SetupDiDestroyDeviceInfoList,
},
};
extern bool standard_def;
static HDEVINFO monitor_hdevinfo;
static HDEVINFO WINAPI my_SetupDiGetClassDevsW(
const GUID *class_guid, const wchar_t *enumerator, HWND hwnd, DWORD flags)
{
HDEVINFO result;
result = next_SetupDiGetClassDevsW(class_guid, enumerator, hwnd, flags);
if (result != INVALID_HANDLE_VALUE &&
IsEqualGUID(class_guid, &monitor_guid)) {
monitor_hdevinfo = result;
}
return result;
}
static BOOL WINAPI my_SetupDiEnumDeviceInfo(
HDEVINFO dev_info, DWORD index, SP_DEVINFO_DATA *info_data)
{
if (dev_info != monitor_hdevinfo) {
return next_SetupDiEnumDeviceInfo(dev_info, index, info_data);
}
if (info_data == NULL || info_data->cbSize != sizeof(*info_data)) {
SetLastError(ERROR_INVALID_USER_BUFFER);
return FALSE;
}
if (index > 0) {
SetLastError(ERROR_NO_MORE_ITEMS);
return FALSE;
}
SetLastError(ERROR_SUCCESS);
return TRUE;
}
static BOOL WINAPI my_SetupDiGetDeviceRegistryPropertyA(
HDEVINFO dev_info,
SP_DEVINFO_DATA *info_data,
DWORD prop,
DWORD *reg_type,
BYTE *bytes,
DWORD nbytes,
DWORD *nbytes_out)
{
const char *txt;
size_t txt_nbytes;
if (dev_info != monitor_hdevinfo) {
return next_SetupDiGetDeviceRegistryPropertyA(
dev_info, info_data, prop, reg_type, bytes, nbytes, nbytes_out);
}
/* The only implemented property */
log_assert(prop == SPDRP_DEVICEDESC);
if (standard_def) {
txt = "Generic Television";
} else {
txt = "Generic Monitor";
}
txt_nbytes = strlen(txt) + 1;
if (reg_type != NULL) {
*reg_type = REG_SZ;
}
if (nbytes_out != NULL) {
*nbytes_out = txt_nbytes;
}
if (nbytes < txt_nbytes) {
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
if (bytes == NULL) {
SetLastError(ERROR_INVALID_USER_BUFFER);
return FALSE;
}
str_cpy((char *) bytes, nbytes, txt);
SetLastError(ERROR_SUCCESS);
return TRUE;
}
static BOOL WINAPI my_SetupDiDestroyDeviceInfoList(HDEVINFO dev_info)
{
if (dev_info == monitor_hdevinfo) {
monitor_hdevinfo = NULL;
}
return next_SetupDiDestroyDeviceInfoList(dev_info);
}
void monitor_setupapi_insert_hooks(HMODULE target)
{
hook_table_apply(
target,
"setupapi.dll",
monitor_setupapi_syms,
lengthof(monitor_setupapi_syms));
log_info("Inserted monitor setupapi hooks into %p", target);
}