Bemanitools v5.26 release
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
#include <windows.h>
|
||||
#include <setupapi.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
Reference in New Issue
Block a user