camhook: fix camhook for new style camera detection
This commit was merged in pull request #304.
This commit is contained in:
@@ -247,7 +247,7 @@ bool convert_path_to_fakesym(const char *path, wchar_t *sym, char *extra_o)
|
||||
return true;
|
||||
}
|
||||
|
||||
void fill_cam_struct(struct CameraData *data, const char *devid)
|
||||
void fill_cam_struct(struct camera_data *data, const char *devid)
|
||||
{
|
||||
char buffer[CAMERA_DATA_STRING_SIZE];
|
||||
|
||||
@@ -295,6 +295,21 @@ void fill_cam_struct(struct CameraData *data, const char *devid)
|
||||
|
||||
log_info("dev path: %s", data->deviceInstancePath);
|
||||
|
||||
char* vid_str = strstr(data->deviceInstancePath, "VID_");
|
||||
char* pid_str = strstr(data->deviceInstancePath, "PID_");
|
||||
|
||||
if (!vid_str || !pid_str) {
|
||||
log_info("Could not parse VID/PID in %s", data->deviceInstancePath);
|
||||
return;
|
||||
}
|
||||
|
||||
data->vid = strtol(vid_str + 4, NULL, 16);
|
||||
data->pid = strtol(pid_str + 4, NULL, 16);
|
||||
|
||||
log_info("vid: %04x", data->vid);
|
||||
log_info("pid: %04x", data->pid);
|
||||
|
||||
|
||||
// locate device nodes
|
||||
DEVINST dnDevInst;
|
||||
DEVINST parentDev;
|
||||
@@ -324,52 +339,64 @@ void fill_cam_struct(struct CameraData *data, const char *devid)
|
||||
|
||||
ULONG szAddr;
|
||||
ULONG szDesc;
|
||||
ULONG szDriverKey;
|
||||
|
||||
szAddr = 4;
|
||||
szDesc = CAMERA_DATA_STRING_SIZE;
|
||||
cmret = CM_Get_DevNode_Registry_PropertyA(
|
||||
dnDevInst, CM_DRP_ADDRESS, NULL, &data->address, &szAddr, 0);
|
||||
|
||||
if (cmret != CR_SUCCESS) {
|
||||
log_info(
|
||||
"CM_Get_DevNode_Registry_PropertyA fail: %s",
|
||||
"CM_Get_DevNode_Registry_PropertyA CM_DRP_ADDRESS fail: %s",
|
||||
data->deviceInstancePath);
|
||||
return;
|
||||
}
|
||||
|
||||
szDesc = CAMERA_DATA_STRING_SIZE;
|
||||
cmret = CM_Get_DevNode_Registry_PropertyA(
|
||||
dnDevInst, CM_DRP_DEVICEDESC, NULL, &data->name, &szDesc, 0);
|
||||
|
||||
if (cmret != CR_SUCCESS) {
|
||||
log_info(
|
||||
"CM_Get_DevNode_Registry_PropertyA fail: %s",
|
||||
"CM_Get_DevNode_Registry_PropertyA CM_DRP_DEVICEDESC fail: %s",
|
||||
data->deviceInstancePath);
|
||||
return;
|
||||
}
|
||||
|
||||
szAddr = 4;
|
||||
szDesc = CAMERA_DATA_STRING_SIZE;
|
||||
cmret = CM_Get_DevNode_Registry_PropertyA(
|
||||
parentDev, CM_DRP_ADDRESS, NULL, &data->parent_address, &szAddr, 0);
|
||||
|
||||
if (cmret != CR_SUCCESS) {
|
||||
log_info(
|
||||
"CM_Get_DevNode_Registry_PropertyA parent fail: %s",
|
||||
"CM_Get_DevNode_Registry_PropertyA CM_DRP_ADDRESS parent fail: %s",
|
||||
data->deviceInstancePath);
|
||||
return;
|
||||
}
|
||||
|
||||
szDesc = CAMERA_DATA_STRING_SIZE;
|
||||
cmret = CM_Get_DevNode_Registry_PropertyA(
|
||||
parentDev, CM_DRP_DEVICEDESC, NULL, &data->parent_name, &szDesc, 0);
|
||||
|
||||
if (cmret != CR_SUCCESS) {
|
||||
log_info(
|
||||
"CM_Get_DevNode_Registry_PropertyA parent fail: %s",
|
||||
"CM_Get_DevNode_Registry_PropertyA CM_DRP_DEVICEDESC parent fail: %s",
|
||||
data->deviceInstancePath);
|
||||
return;
|
||||
}
|
||||
|
||||
szDriverKey = CAMERA_DATA_STRING_SIZE;
|
||||
cmret = CM_Get_DevNode_Registry_PropertyA(
|
||||
parentDev, CM_DRP_DRIVER, NULL, &data->parent_driverKey, &szDriverKey, 0);
|
||||
|
||||
if (cmret != CR_SUCCESS) {
|
||||
log_info(
|
||||
"CM_Get_DevNode_Registry_PropertyA CM_DRP_DRIVER parent fail: %s",
|
||||
data->deviceInstancePath);
|
||||
return;
|
||||
}
|
||||
|
||||
log_info("Found %s @ %d", data->name, data->address);
|
||||
log_info("Parent %s @ %d", data->parent_name, data->parent_address);
|
||||
log_info("Parent %s @ %d %s", data->parent_name, data->parent_address, data->parent_driverKey);
|
||||
data->setup = true;
|
||||
}
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
#define CAMHOOK_CAM_DETECT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#define CAMERA_DATA_STRING_SIZE 0x100
|
||||
|
||||
struct CameraData {
|
||||
struct camera_data {
|
||||
bool setup;
|
||||
char name[CAMERA_DATA_STRING_SIZE];
|
||||
char deviceInstancePath[CAMERA_DATA_STRING_SIZE];
|
||||
@@ -14,9 +15,13 @@ struct CameraData {
|
||||
char extra_upper[CAMERA_DATA_STRING_SIZE];
|
||||
int address;
|
||||
char parent_name[CAMERA_DATA_STRING_SIZE];
|
||||
char parent_driverKey[CAMERA_DATA_STRING_SIZE];
|
||||
char parent_deviceInstancePath[CAMERA_DATA_STRING_SIZE];
|
||||
int parent_address;
|
||||
|
||||
int16_t vid;
|
||||
int16_t pid;
|
||||
|
||||
bool fake_addressed;
|
||||
int fake_address;
|
||||
|
||||
@@ -24,6 +29,6 @@ struct CameraData {
|
||||
size_t fake_located_node;
|
||||
};
|
||||
|
||||
void fill_cam_struct(struct CameraData *data, const char *devid);
|
||||
void fill_cam_struct(struct camera_data *data, const char *devid);
|
||||
|
||||
#endif
|
||||
|
||||
+311
-40
@@ -4,6 +4,8 @@
|
||||
// Don't format because the order is important here
|
||||
#include <windows.h>
|
||||
#include <initguid.h>
|
||||
#include <winioctl.h>
|
||||
#include <usbioctl.h>
|
||||
// clang-format on
|
||||
|
||||
#include <mfapi.h>
|
||||
@@ -25,15 +27,19 @@
|
||||
#include "util/log.h"
|
||||
#include "util/str.h"
|
||||
|
||||
static struct CameraData camData[CAMHOOK_CONFIG_CAM_MAX];
|
||||
int camAddresses[CAMHOOK_CONFIG_CAM_MAX] = {
|
||||
1,
|
||||
7,
|
||||
#define CAMHOOK_NUM_LAYOUTS 3
|
||||
|
||||
static struct camera_data camData[CAMHOOK_CONFIG_CAM_MAX];
|
||||
int camAddresses[CAMHOOK_NUM_LAYOUTS][CAMHOOK_CONFIG_CAM_MAX] = {
|
||||
{1, 7},
|
||||
{4, 9},
|
||||
{4, 3},
|
||||
};
|
||||
static size_t num_addressed_cams = 0;
|
||||
static size_t num_located_cams = 0;
|
||||
static int camhook_port_layout = 0;
|
||||
|
||||
static enum camhook_version camhook_version = CAMHOOK_OLD;
|
||||
static enum camhook_version camhook_version = CAMHOOK_VERSION_OLD;
|
||||
|
||||
static CONFIGRET my_CM_Locate_DevNodeA(
|
||||
PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags);
|
||||
@@ -97,6 +103,26 @@ static HDEVINFO my_SetupDiGetClassDevsA(
|
||||
static HDEVINFO (*real_SetupDiGetClassDevsA)(
|
||||
CONST GUID *ClassGuid, PCSTR Enumerator, HWND hwndParent, DWORD Flags);
|
||||
|
||||
static BOOL STDCALL my_DeviceIoControl(
|
||||
HANDLE hFile,
|
||||
uint32_t dwIoControlCode,
|
||||
void *lpInBuffer,
|
||||
uint32_t nInBufferSize,
|
||||
void *lpOutBuffer,
|
||||
uint32_t nOutBufferSize,
|
||||
uint32_t *lpBytesReturned,
|
||||
OVERLAPPED *lpOverlapped);
|
||||
|
||||
static BOOL(STDCALL *real_DeviceIoControl)(
|
||||
HANDLE fd,
|
||||
uint32_t code,
|
||||
void *in_bytes,
|
||||
uint32_t in_nbytes,
|
||||
void *out_bytes,
|
||||
uint32_t out_nbytes,
|
||||
uint32_t *out_returned,
|
||||
OVERLAPPED *ovl);
|
||||
|
||||
static const struct hook_symbol camhook_cfgmgr32_syms[] = {
|
||||
{.name = "CM_Locate_DevNodeA",
|
||||
.patch = my_CM_Locate_DevNodeA,
|
||||
@@ -121,12 +147,24 @@ static const struct hook_symbol camhook_cfgmgr32_syms[] = {
|
||||
.link = (void **) &real_SetupDiGetClassDevsA},
|
||||
};
|
||||
|
||||
static const struct hook_symbol camhook_cfgmgr32_syms_new[] = {
|
||||
{.name = "CM_Locate_DevNodeA",
|
||||
.patch = my_CM_Locate_DevNodeA,
|
||||
.link = (void **) &real_CM_Locate_DevNodeA},
|
||||
};
|
||||
|
||||
static const struct hook_symbol camhook_mf_syms[] = {
|
||||
{.name = "MFEnumDeviceSources",
|
||||
.patch = my_MFEnumDeviceSources,
|
||||
.link = (void **) &real_MFEnumDeviceSources},
|
||||
};
|
||||
|
||||
static struct hook_symbol camhook_ioctl_syms[] = {
|
||||
{.name = "DeviceIoControl",
|
||||
.patch = my_DeviceIoControl,
|
||||
.link = (void *) &real_DeviceIoControl},
|
||||
};
|
||||
|
||||
DEVINST camhook_custom_nodes[CAMHOOK_CONFIG_CAM_MAX] = {
|
||||
0x04040004,
|
||||
0x04040008,
|
||||
@@ -150,25 +188,42 @@ my_CM_Locate_DevNodeA(PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags)
|
||||
log_info("seeking: %s", pDeviceID);
|
||||
for (size_t i = 0; i < CAMHOOK_CONFIG_CAM_MAX; ++i) {
|
||||
if (camData[i].setup) {
|
||||
snprintf(
|
||||
builtString,
|
||||
CAMERA_DATA_STRING_SIZE,
|
||||
"USB\\VID_288C&PID_0002&MI_00\\%s",
|
||||
camData[i].extra_upper);
|
||||
if (camhook_version == CAMHOOK_VERSION_OLD) {
|
||||
snprintf(
|
||||
builtString,
|
||||
CAMERA_DATA_STRING_SIZE,
|
||||
"USB\\VID_288C&PID_0002&MI_00\\%s",
|
||||
camData[i].extra_upper);
|
||||
} else if (camhook_version == CAMHOOK_VERSION_NEW) {
|
||||
snprintf(
|
||||
builtString,
|
||||
CAMERA_DATA_STRING_SIZE,
|
||||
"USB\\VID_05A3&PID_9230&MI_00\\%s",
|
||||
camData[i].extra_upper);
|
||||
}
|
||||
|
||||
log_info("built: %s", builtString);
|
||||
if (strcmp(pDeviceID, builtString) == 0) {
|
||||
if (!camData[i].fake_located) {
|
||||
camData[i].fake_located_node = num_located_cams;
|
||||
camData[i].fake_located = true;
|
||||
++num_located_cams;
|
||||
if (camhook_version == CAMHOOK_VERSION_OLD) {
|
||||
if (!camData[i].fake_located) {
|
||||
camData[i].fake_located_node = num_located_cams;
|
||||
camData[i].fake_located = true;
|
||||
++num_located_cams;
|
||||
}
|
||||
log_info(
|
||||
"Injecting custom device %d to node %x",
|
||||
(int) i,
|
||||
(int) camData[i].fake_located_node);
|
||||
*pdnDevInst =
|
||||
camhook_custom_nodes[camData[i].fake_located_node];
|
||||
return CR_SUCCESS;
|
||||
} else if (camhook_version == CAMHOOK_VERSION_NEW) {
|
||||
// inject original device
|
||||
log_info(
|
||||
"Injecting original device %d %s -> %s",
|
||||
(int) i, pDeviceID, camData[i].deviceInstancePath);
|
||||
pDeviceID = camData[i].deviceInstancePath;
|
||||
}
|
||||
log_info(
|
||||
"Injecting custom device %d to node %x",
|
||||
(int) i,
|
||||
(int) camData[i].fake_located_node);
|
||||
*pdnDevInst =
|
||||
camhook_custom_nodes[camData[i].fake_located_node];
|
||||
return CR_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -219,7 +274,7 @@ HRESULT my_GetAllocatedString(
|
||||
IMFActivate *self, REFGUID guidKey, LPWSTR *ppwszValue, UINT32 *pcchLength)
|
||||
{
|
||||
HRESULT ret;
|
||||
log_info("Inside: %s", __FUNCTION__);
|
||||
// log_info("Inside: %s", __FUNCTION__);
|
||||
|
||||
// should probably check GUID == MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, oh well
|
||||
ret = real_GetAllocatedString(self, guidKey, ppwszValue, pcchLength);
|
||||
@@ -240,19 +295,35 @@ HRESULT my_GetAllocatedString(
|
||||
|
||||
// if matches, replace with target device ID
|
||||
if (pwc) {
|
||||
// \\?\usb#vid_288c&pid_0002&mi_00
|
||||
pwc[12] = L'2';
|
||||
pwc[13] = L'8';
|
||||
pwc[14] = L'8';
|
||||
pwc[15] = L'c';
|
||||
if (camhook_version == CAMHOOK_VERSION_OLD) {
|
||||
// \\?\usb#vid_288c&pid_0002&mi_00
|
||||
pwc[12] = L'2';
|
||||
pwc[13] = L'8';
|
||||
pwc[14] = L'8';
|
||||
pwc[15] = L'c';
|
||||
|
||||
pwc[21] = L'0';
|
||||
pwc[22] = L'0';
|
||||
pwc[23] = L'0';
|
||||
pwc[24] = L'2';
|
||||
pwc[21] = L'0';
|
||||
pwc[22] = L'0';
|
||||
pwc[23] = L'0';
|
||||
pwc[24] = L'2';
|
||||
|
||||
pwc[29] = L'0';
|
||||
pwc[30] = L'0';
|
||||
pwc[29] = L'0';
|
||||
pwc[30] = L'0';
|
||||
} else if (camhook_version == CAMHOOK_VERSION_NEW) {
|
||||
// \\?\usb#vid_05a3&pid_9230&mi_00
|
||||
pwc[12] = L'0';
|
||||
pwc[13] = L'5';
|
||||
pwc[14] = L'a';
|
||||
pwc[15] = L'3';
|
||||
|
||||
pwc[21] = L'9';
|
||||
pwc[22] = L'2';
|
||||
pwc[23] = L'3';
|
||||
pwc[24] = L'0';
|
||||
|
||||
pwc[29] = L'0';
|
||||
pwc[30] = L'0';
|
||||
}
|
||||
|
||||
wcstombs(pMBBuffer, *ppwszValue, 0x100);
|
||||
log_info("Replaced: %s", pMBBuffer);
|
||||
@@ -275,7 +346,7 @@ static HRESULT my_MFEnumDeviceSources(
|
||||
|
||||
HRESULT ret;
|
||||
|
||||
log_info("Inside: %s", __FUNCTION__);
|
||||
// log_info("Inside: %s", __FUNCTION__);
|
||||
ret = real_MFEnumDeviceSources(
|
||||
pAttributes, pppSourceActivate, pcSourceActivate);
|
||||
nsrcs = *pcSourceActivate;
|
||||
@@ -378,8 +449,9 @@ static BOOL my_SetupDiGetDeviceRegistryPropertyA(
|
||||
if (camData[i].setup) {
|
||||
if (addr == camData[i].parent_address) {
|
||||
if (!camData[i].fake_addressed) {
|
||||
// old style always uses set 0
|
||||
camData[i].fake_address =
|
||||
camAddresses[num_addressed_cams];
|
||||
camAddresses[0][num_addressed_cams];
|
||||
camData[i].fake_addressed = true;
|
||||
++num_addressed_cams;
|
||||
}
|
||||
@@ -432,6 +504,178 @@ static HDEVINFO my_SetupDiGetClassDevsA(
|
||||
return real_SetupDiGetClassDevsA(ClassGuid, Enumerator, hwndParent, Flags);
|
||||
}
|
||||
|
||||
ULONG get_matching_device_replacement_id(
|
||||
HANDLE hFile,
|
||||
ULONG ConnectionIndex,
|
||||
USB_DEVICE_DESCRIPTOR* desc)
|
||||
{
|
||||
ULONG replacement_id = 0;
|
||||
for (size_t i = 0; i < CAMHOOK_CONFIG_CAM_MAX; ++i) {
|
||||
if (camData[i].setup) {
|
||||
// log_info("Checking %lu %04x %04x vs %lu %04x %04x",
|
||||
// ConnectionIndex, desc->idVendor, desc->idProduct,
|
||||
// camData[i].address, camData[i].vid, camData[i].pid);
|
||||
if (
|
||||
ConnectionIndex == camData[i].parent_address &&
|
||||
desc->idVendor == camData[i].vid &&
|
||||
desc->idProduct == camData[i].pid
|
||||
) {
|
||||
// do secondary check for driver key using
|
||||
// IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME
|
||||
USB_NODE_CONNECTION_DRIVERKEY_NAME req;
|
||||
req.ActualLength = 0;
|
||||
req.ConnectionIndex = ConnectionIndex;
|
||||
req.DriverKeyName[0] = '\0';
|
||||
|
||||
DWORD nBytes;
|
||||
|
||||
if (!DeviceIoControl(
|
||||
hFile,
|
||||
IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME,
|
||||
&req,
|
||||
sizeof(req),
|
||||
&req,
|
||||
sizeof(req),
|
||||
&nBytes,
|
||||
0LL
|
||||
)) {
|
||||
log_warning(
|
||||
"Failed to get driver key name size for device %04x %04x",
|
||||
desc->idVendor,
|
||||
desc->idProduct);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (req.ActualLength <= sizeof(req)) {
|
||||
log_warning(
|
||||
"Driver key name size too small for device %04x %04x",
|
||||
desc->idVendor,
|
||||
desc->idProduct);
|
||||
continue;
|
||||
}
|
||||
|
||||
nBytes = req.ActualLength;
|
||||
|
||||
USB_NODE_CONNECTION_DRIVERKEY_NAME *driverKeyNameW = malloc(nBytes);
|
||||
if (!driverKeyNameW) {
|
||||
log_warning("Failed to allocate driver key name buffer for device %04x %04x",
|
||||
desc->idVendor,
|
||||
desc->idProduct);
|
||||
continue;
|
||||
}
|
||||
driverKeyNameW->ActualLength = 0;
|
||||
driverKeyNameW->ConnectionIndex = ConnectionIndex;
|
||||
driverKeyNameW->DriverKeyName[0] = '\0';
|
||||
|
||||
if (!DeviceIoControl(
|
||||
hFile,
|
||||
IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME,
|
||||
driverKeyNameW,
|
||||
nBytes,
|
||||
driverKeyNameW,
|
||||
nBytes,
|
||||
&nBytes,
|
||||
0LL
|
||||
)) {
|
||||
log_warning(
|
||||
"Failed to get driver key name for device %04x %04x",
|
||||
desc->idVendor,
|
||||
desc->idProduct);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
char *driverKeyNameA = NULL;
|
||||
wstr_narrow(driverKeyNameW->DriverKeyName, &driverKeyNameA);
|
||||
|
||||
free(driverKeyNameW);
|
||||
|
||||
|
||||
if (strcmp(driverKeyNameA, camData[i].parent_driverKey) != 0) {
|
||||
// log just in case?
|
||||
log_info(
|
||||
"Driver key name mismatch for device %04x %04x %s != %s",
|
||||
desc->idVendor,
|
||||
desc->idProduct,
|
||||
driverKeyNameA,
|
||||
camData[i].parent_driverKey);
|
||||
if (driverKeyNameA) {
|
||||
free(driverKeyNameA);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
log_info(
|
||||
"Replacing device @ %lu with %d for %04x %04x %s",
|
||||
ConnectionIndex,
|
||||
camAddresses[camhook_port_layout][i],
|
||||
desc->idVendor,
|
||||
desc->idProduct,
|
||||
driverKeyNameA);
|
||||
|
||||
if (driverKeyNameA) {
|
||||
free(driverKeyNameA);
|
||||
}
|
||||
|
||||
replacement_id = camAddresses[camhook_port_layout][i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return replacement_id;
|
||||
}
|
||||
|
||||
static BOOL STDCALL my_DeviceIoControl(
|
||||
HANDLE hFile,
|
||||
uint32_t dwIoControlCode,
|
||||
void *lpInBuffer,
|
||||
uint32_t nInBufferSize,
|
||||
void *lpOutBuffer,
|
||||
uint32_t nOutBufferSize,
|
||||
uint32_t *lpBytesReturned,
|
||||
OVERLAPPED *lpOverlapped)
|
||||
{
|
||||
BOOL res;
|
||||
|
||||
res = real_DeviceIoControl(
|
||||
hFile,
|
||||
dwIoControlCode,
|
||||
lpInBuffer,
|
||||
nInBufferSize,
|
||||
lpOutBuffer,
|
||||
nOutBufferSize,
|
||||
lpBytesReturned,
|
||||
lpOverlapped);
|
||||
|
||||
// if error just return
|
||||
if (!res) {
|
||||
return res;
|
||||
}
|
||||
|
||||
// detect IOCTL_USB_GET_NODE_CONNECTION_INFORMATION (_EX)
|
||||
// we don't bother faking the rest as it's never read
|
||||
if (dwIoControlCode == IOCTL_USB_GET_NODE_CONNECTION_INFORMATION) {
|
||||
USB_NODE_CONNECTION_INFORMATION *connectionInfo = lpOutBuffer;
|
||||
|
||||
ULONG replacement_id = get_matching_device_replacement_id(
|
||||
hFile, connectionInfo->ConnectionIndex, &connectionInfo->DeviceDescriptor);
|
||||
if (replacement_id > 0) {
|
||||
connectionInfo->ConnectionIndex = replacement_id;
|
||||
}
|
||||
} else if (dwIoControlCode == IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX) {
|
||||
USB_NODE_CONNECTION_INFORMATION_EX *connectionInfoEx = lpOutBuffer;
|
||||
|
||||
ULONG replacement_id = get_matching_device_replacement_id(
|
||||
hFile, connectionInfoEx->ConnectionIndex, &connectionInfoEx->DeviceDescriptor);
|
||||
if (replacement_id > 0) {
|
||||
connectionInfoEx->ConnectionIndex = replacement_id;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void camhook_set_version(enum camhook_version version) {
|
||||
camhook_version = version;
|
||||
}
|
||||
@@ -461,15 +705,42 @@ void camhook_init(struct camhook_config_cam *config_cam)
|
||||
}
|
||||
}
|
||||
|
||||
camhook_port_layout = config_cam->port_layout;
|
||||
if (camhook_port_layout < 0 || camhook_port_layout >= CAMHOOK_NUM_LAYOUTS) {
|
||||
camhook_port_layout = 0;
|
||||
}
|
||||
|
||||
if (num_setup > 0) {
|
||||
hook_table_apply(
|
||||
NULL,
|
||||
"setupapi.dll",
|
||||
camhook_cfgmgr32_syms,
|
||||
lengthof(camhook_cfgmgr32_syms));
|
||||
// always
|
||||
hook_table_apply(
|
||||
NULL, "Mf.dll", camhook_mf_syms, lengthof(camhook_mf_syms));
|
||||
|
||||
if (camhook_version == CAMHOOK_VERSION_OLD) {
|
||||
hook_table_apply(
|
||||
NULL,
|
||||
"cfgmgr32.dll",
|
||||
camhook_cfgmgr32_syms,
|
||||
lengthof(camhook_cfgmgr32_syms));
|
||||
} else if (camhook_version == CAMHOOK_VERSION_NEW) {
|
||||
// for CAMHOOK_VERSION_NEW we restore original VID/PID
|
||||
// so the parent lookup succeeds later
|
||||
// yes the DLL moved???
|
||||
hook_table_apply(
|
||||
NULL,
|
||||
"setupapi.dll",
|
||||
camhook_cfgmgr32_syms_new,
|
||||
lengthof(camhook_cfgmgr32_syms_new));
|
||||
|
||||
// they copied / forked usb/usbview/enum.c
|
||||
// however they don't use most of it
|
||||
// so we only need DeviceIoControl to inject port #
|
||||
hook_table_apply(
|
||||
NULL,
|
||||
"kernel32.dll",
|
||||
camhook_ioctl_syms,
|
||||
lengthof(camhook_ioctl_syms));
|
||||
}
|
||||
|
||||
log_info("Inserted cam hooks for %d cams", (int) num_setup);
|
||||
// If the user has manually disabled all cams, don't print this in the
|
||||
// log
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
|
||||
#include "camhook/config-cam.h"
|
||||
|
||||
// unused to control which camhook version is being used
|
||||
// defaults to CAMHOOK_VERSION_OLD
|
||||
enum camhook_version {
|
||||
CAMHOOK_OLD,
|
||||
CAMHOOK_NEW,
|
||||
CAMHOOK_VERSION_OLD,
|
||||
CAMHOOK_VERSION_NEW,
|
||||
};
|
||||
|
||||
void camhook_set_version(enum camhook_version version);
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
#define CAMHOOK_CONFIG_CAM_DISABLE_EMU_KEY "cam.disable_emu"
|
||||
#define CAMHOOK_CONFIG_CAM_DEFAULT_DISABLE_EMU_VALUE false
|
||||
|
||||
#define CAMHOOK_CONFIG_CAM_PORT_LAYOUT_KEY "cam.port_layout"
|
||||
#define CAMHOOK_CONFIG_CAM_DEFAULT_PORT_LAYOUT_VALUE 0
|
||||
|
||||
// the following four arrays are based on CAMHOOK_CONFIG_CAM_MAX
|
||||
// please insert more elements if more cams are added
|
||||
const char *camhook_config_disable_camera[CAMHOOK_CONFIG_CAM_MAX] = {
|
||||
@@ -30,7 +33,7 @@ const char *camhook_config_device_default_values[CAMHOOK_CONFIG_CAM_MAX] = {
|
||||
"",
|
||||
};
|
||||
|
||||
void camhook_config_cam_init(struct cconfig *config, size_t num_cams)
|
||||
void camhook_config_cam_init(struct cconfig *config, size_t num_cams, bool use_port_layout)
|
||||
{
|
||||
cconfig_util_set_bool(
|
||||
config,
|
||||
@@ -38,6 +41,14 @@ void camhook_config_cam_init(struct cconfig *config, size_t num_cams)
|
||||
CAMHOOK_CONFIG_CAM_DEFAULT_DISABLE_EMU_VALUE,
|
||||
"Disables the camera emulation");
|
||||
|
||||
if (use_port_layout) {
|
||||
cconfig_util_set_int(
|
||||
config,
|
||||
CAMHOOK_CONFIG_CAM_PORT_LAYOUT_KEY,
|
||||
CAMHOOK_CONFIG_CAM_DEFAULT_PORT_LAYOUT_VALUE,
|
||||
"Camera port layout (0 = LDJ, 1 = CLDJ/TDJ-JA, 2 = TDJ-JB)");
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < num_cams; ++i) {
|
||||
cconfig_util_set_bool(
|
||||
config,
|
||||
@@ -56,7 +67,8 @@ void camhook_config_cam_init(struct cconfig *config, size_t num_cams)
|
||||
void camhook_config_cam_get(
|
||||
struct camhook_config_cam *config_cam,
|
||||
struct cconfig *config,
|
||||
size_t num_cams)
|
||||
size_t num_cams,
|
||||
bool use_port_layout)
|
||||
{
|
||||
config_cam->num_devices = num_cams;
|
||||
|
||||
@@ -71,6 +83,21 @@ void camhook_config_cam_get(
|
||||
CAMHOOK_CONFIG_CAM_DISABLE_EMU_KEY,
|
||||
CAMHOOK_CONFIG_CAM_DEFAULT_DISABLE_EMU_VALUE);
|
||||
}
|
||||
|
||||
if (use_port_layout) {
|
||||
if (!cconfig_util_get_int(
|
||||
config,
|
||||
CAMHOOK_CONFIG_CAM_PORT_LAYOUT_KEY,
|
||||
&config_cam->port_layout,
|
||||
CAMHOOK_CONFIG_CAM_DEFAULT_PORT_LAYOUT_VALUE)) {
|
||||
log_warning(
|
||||
"Invalid value for key '%s' specified, fallback "
|
||||
"to default '%d'",
|
||||
CAMHOOK_CONFIG_CAM_PORT_LAYOUT_KEY,
|
||||
CAMHOOK_CONFIG_CAM_DEFAULT_PORT_LAYOUT_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < num_cams; ++i) {
|
||||
if (!cconfig_util_get_bool(
|
||||
config,
|
||||
|
||||
@@ -10,15 +10,20 @@
|
||||
struct camhook_config_cam {
|
||||
bool disable_emu;
|
||||
size_t num_devices;
|
||||
int port_layout;
|
||||
char device_id[CAMHOOK_CONFIG_CAM_MAX][MAX_PATH];
|
||||
bool disable_camera[CAMHOOK_CONFIG_CAM_MAX];
|
||||
};
|
||||
|
||||
void camhook_config_cam_init(struct cconfig *config, size_t num_cams);
|
||||
void camhook_config_cam_init(
|
||||
struct cconfig *config,
|
||||
size_t num_cams,
|
||||
bool use_port_layout);
|
||||
|
||||
void camhook_config_cam_get(
|
||||
struct camhook_config_cam *config_cam,
|
||||
struct cconfig *config,
|
||||
size_t num_cams);
|
||||
size_t num_cams,
|
||||
bool use_port_layout);
|
||||
|
||||
#endif
|
||||
@@ -106,7 +106,7 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
||||
|
||||
iidxhook_config_gfx_init(config);
|
||||
iidxhook8_config_io_init(config);
|
||||
camhook_config_cam_init(config, 2);
|
||||
camhook_config_cam_init(config, 2, false);
|
||||
|
||||
if (!cconfig_hook_config_init(
|
||||
config,
|
||||
@@ -119,7 +119,7 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
||||
|
||||
iidxhook_config_gfx_get(&config_gfx, config);
|
||||
iidxhook8_config_io_get(&iidxhook8_config_io, config);
|
||||
camhook_config_cam_get(&config_cam, config, 2);
|
||||
camhook_config_cam_get(&config_cam, config, 2, false);
|
||||
|
||||
cconfig_finit(config);
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ static bool load_configs()
|
||||
config = cconfig_init();
|
||||
|
||||
iidxhook9_config_io_init(config);
|
||||
camhook_config_cam_init(config, 2);
|
||||
camhook_config_cam_init(config, 2, true);
|
||||
|
||||
d3d9exhook_config_gfx_init(config);
|
||||
|
||||
@@ -84,7 +84,7 @@ static bool load_configs()
|
||||
}
|
||||
|
||||
iidxhook9_config_io_get(&iidxhook9_config_io, config);
|
||||
camhook_config_cam_get(&config_cam, config, 2);
|
||||
camhook_config_cam_get(&config_cam, config, 2, true);
|
||||
|
||||
d3d9exhook_config_gfx_get(&config_gfx, config);
|
||||
|
||||
@@ -188,6 +188,7 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
||||
|
||||
// camera hooks
|
||||
if (!config_cam.disable_emu) {
|
||||
camhook_set_version(CAMHOOK_VERSION_NEW);
|
||||
camhook_init(&config_cam);
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
||||
|
||||
sdvxhook2_cn_config_init(config);
|
||||
d3d9exhook_config_gfx_init(config);
|
||||
camhook_config_cam_init(config, 1);
|
||||
camhook_config_cam_init(config, 1, false);
|
||||
|
||||
if (!cconfig_hook_config_init(
|
||||
config,
|
||||
@@ -62,7 +62,7 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
||||
}
|
||||
|
||||
sdvxhook2_cn_config_get(&config_cn, config);
|
||||
camhook_config_cam_get(&config_cam, config, 1);
|
||||
camhook_config_cam_get(&config_cam, config, 1, false);
|
||||
d3d9exhook_config_gfx_get(&config_gfx, config);
|
||||
|
||||
cconfig_finit(config);
|
||||
|
||||
@@ -79,7 +79,7 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
||||
|
||||
sdvxhook2_config_io_init(config);
|
||||
d3d9exhook_config_gfx_init(config);
|
||||
camhook_config_cam_init(config, 1);
|
||||
camhook_config_cam_init(config, 1, false);
|
||||
hooklib_config_adapter_init(config);
|
||||
|
||||
if (!cconfig_hook_config_init(
|
||||
@@ -91,7 +91,7 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
||||
}
|
||||
|
||||
sdvxhook2_config_io_get(&config_io, config);
|
||||
camhook_config_cam_get(&config_cam, config, 1);
|
||||
camhook_config_cam_get(&config_cam, config, 1, false);
|
||||
d3d9exhook_config_gfx_get(&config_gfx, config);
|
||||
hooklib_config_adapter_get(&config_adapter, config);
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ static void test_config_cam_defaults()
|
||||
|
||||
config = cconfig_init();
|
||||
|
||||
camhook_config_cam_init(config, 2);
|
||||
camhook_config_cam_get(&config_cam, config, 2);
|
||||
camhook_config_cam_init(config, 2, false);
|
||||
camhook_config_cam_get(&config_cam, config, 2, false);
|
||||
|
||||
cconfig_finit(config);
|
||||
|
||||
@@ -30,13 +30,13 @@ static void test_config_cam()
|
||||
|
||||
config = cconfig_init();
|
||||
|
||||
camhook_config_cam_init(config, 2);
|
||||
camhook_config_cam_init(config, 2, false);
|
||||
|
||||
cconfig_set2(config, "cam.disable_emu", "true");
|
||||
cconfig_set2(config, "cam.device_id1", "asdjkasd");
|
||||
cconfig_set2(config, "cam.device_id2", "1234");
|
||||
|
||||
camhook_config_cam_get(&config_cam, config, 2);
|
||||
camhook_config_cam_get(&config_cam, config, 2, false);
|
||||
|
||||
cconfig_finit(config);
|
||||
|
||||
@@ -52,13 +52,13 @@ static void test_config_cam_invalid_values()
|
||||
|
||||
config = cconfig_init();
|
||||
|
||||
camhook_config_cam_init(config, 2);
|
||||
camhook_config_cam_init(config, 2, false);
|
||||
|
||||
cconfig_set2(config, "cam.disable_emu", "123");
|
||||
cconfig_set2(config, "cam.device_id1", "asdjkasd");
|
||||
cconfig_set2(config, "cam.device_id2", "1234");
|
||||
|
||||
camhook_config_cam_get(&config_cam, config, 2);
|
||||
camhook_config_cam_get(&config_cam, config, 2, false);
|
||||
|
||||
cconfig_finit(config);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user