Update camhook to support new style camera detection #304

Merged
willxinc merged 2 commits from camhook-update into master 2024-05-22 08:29:11 +03:00
17 changed files with 800 additions and 398 deletions
+3
View File
@@ -22,6 +22,9 @@ io.tt_multiplier=1.0
# Disables the camera emulation
cam.disable_emu=true
# Camera port layout (0 = LDJ, 1 = CLDJ/TDJ-JA, 2 = TDJ-JB)
icex2 commented 2024-05-21 12:14:07 +03:00 (Migrated from github.com)
Review

Can you explain what the port layout implies here regarding which one to chose, e.g. in a home setup? Might be something for the readme.

Can you explain what the port layout implies here regarding which one to chose, e.g. in a home setup? Might be something for the readme.
willxinc commented 2024-05-21 12:48:18 +03:00 (Migrated from github.com)
Review

The port layout is used to control which set of ports it pretends the cameras are connected to, will update readme I guess

The port layout is used to control which set of ports it pretends the cameras are connected to, will update readme I guess
cam.port_layout=1
# Disable camera 1. Use, i.e., if you only have one camera and want it to be mapped to camera 2 ingame.
cam.disable_camera1=false
+3
View File
@@ -22,6 +22,9 @@ io.tt_multiplier=1.0
# Disables the camera emulation
cam.disable_emu=true
# Camera port layout (0 = LDJ, 1 = CLDJ/TDJ-JA, 2 = TDJ-JB)
cam.port_layout=1
# Disable camera 1. Use, i.e., if you only have one camera and want it to be mapped to camera 2 ingame.
cam.disable_camera1=false
+3
View File
@@ -22,6 +22,9 @@ io.tt_multiplier=1.0
# Disables the camera emulation
cam.disable_emu=true
# Camera port layout (0 = LDJ, 1 = CLDJ/TDJ-JA, 2 = TDJ-JB)
cam.port_layout=1
# Disable camera 1. Use, i.e., if you only have one camera and want it to be mapped to camera 2 ingame.
cam.disable_camera1=true
+3
View File
@@ -22,6 +22,9 @@ io.tt_multiplier=1.0
# Disables the camera emulation
cam.disable_emu=true
# Camera port layout (0 = LDJ, 1 = CLDJ/TDJ-JA, 2 = TDJ-JB)
cam.port_layout=1
# Disable camera 1. Use, i.e., if you only have one camera and want it to be mapped to camera 2 ingame.
cam.disable_camera1=true
+6
View File
@@ -93,6 +93,12 @@ The syntax for the "key=value" is the same as in the config file. Make sure to h
However, if a parameter is specifed in the configuration file and as a command line argument, the
command line argument overrides the config file's value.
# Note on camhook
The cammera hook (camhook) is used to allow other class compliant cameras to be used. Depending on the variant of the game, you will need to select the correct camera port layout.
For original LDJ, this is always 0, for conversion kit LDJ and original TDJ-JA, this is 1, and for TDJ-JB this will be 2 (this case is rare / you will know if this is needed on your setup).
# Eamuse network setup
If you want to run the games online, you need a valid PCBID and the service URL. Open
+1
View File
@@ -8,4 +8,5 @@ libs_camhook := \
src_camhook := \
cam.c \
cam-detect.c \
config-cam.c \
+402
View File
@@ -0,0 +1,402 @@
#define LOG_MODULE "cam-hook"
// clang-format off
// Don't format because the order is important here
#include <windows.h>
#include <initguid.h>
// clang-format on
#include <mfapi.h>
#include <mfidl.h>
#include <mfobjects.h>
#include <cfgmgr32.h>
#include <setupapi.h>
#include <stdio.h>
#include "camhook/cam-detect.h"
#include "util/defs.h"
#include "util/log.h"
#include "util/str.h"
EXTERN_GUID(
MY_MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
0xc60ac5fe,
0x252a,
0x478f,
0xa0,
0xef,
0xbc,
0x8f,
0xa5,
0xf7,
0xca,
0xd3);
EXTERN_GUID(
MY_MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID,
0x8ac3587a,
0x4ae7,
0x42d8,
0x99,
0xe0,
0x0a,
0x60,
0x13,
0xee,
0xf9,
0x0f);
EXTERN_GUID(
MY_MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK,
0x58f0aad8,
0x22bf,
0x4f8a,
0xbb,
0x3d,
0xd2,
0xc4,
0x97,
0x8c,
0x6e,
0x2f);
// define ourselves cause mingw has these wrong
bool check_four(const char inA[4], const char inB[4])
{
return (*(uint32_t *) inA == *(uint32_t *) inB);
}
char *grab_next_camera_id(char *buffer, size_t bsz)
{
static size_t gotten = 0;
IMFAttributes *pAttributes = NULL;
IMFActivate **ppDevices = NULL;
buffer[0] = '\0';
HRESULT hr = MFCreateAttributes(&pAttributes, 1);
if (FAILED(hr)) {
log_info("MFCreateAttributes failed: %ld", hr);
goto done;
}
hr = pAttributes->lpVtbl->SetGUID(
pAttributes,
&MY_MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
&MY_MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);
if (FAILED(hr)) {
log_info("SetGUID failed: %ld", hr);
goto done;
}
UINT32 count;
hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count);
if (FAILED(hr)) {
log_info("MFEnumDeviceSources failed: %ld", hr);
goto done;
}
if (count <= gotten) {
log_info("gotten failed: %d < %d", count, (int) gotten);
// not enough remaining
goto done;
}
wchar_t wSymLink[CAMERA_DATA_STRING_SIZE];
UINT32 sz;
hr = ppDevices[gotten]->lpVtbl->GetString(
ppDevices[gotten],
&MY_MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK,
wSymLink,
CAMERA_DATA_STRING_SIZE,
&sz);
if (FAILED(hr)) {
log_info("GetString failed: %ld", hr);
goto done;
}
wcstombs(buffer, wSymLink, bsz);
log_info("Detected webcam: %s\n", buffer);
++gotten;
done:
if (pAttributes) {
pAttributes->lpVtbl->Release(pAttributes);
}
for (DWORD i = 0; i < count; i++) {
if (ppDevices != NULL && ppDevices[i]) {
ppDevices[i]->lpVtbl->Release(ppDevices[i]);
}
}
CoTaskMemFree(ppDevices);
return buffer;
}
bool convert_sym_to_path(const char *sym, char *path)
{
HDEVINFO DeviceInfoSet = SetupDiCreateDeviceInfoList(NULL, NULL);
if (DeviceInfoSet == INVALID_HANDLE_VALUE) {
log_info("Could not open SetupDiCreateDeviceInfoList\n");
return 0;
}
SP_DEVICE_INTERFACE_DATA DeviceInterfaceData = {0};
DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
if (!SetupDiOpenDeviceInterfaceA(
DeviceInfoSet, sym, 0, &DeviceInterfaceData)) {
log_info("Could not SetupDiOpenDeviceInterfaceA\n");
return 0;
}
SP_DEVINFO_DATA DeviceInfoData = {0};
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
if (!SetupDiGetDeviceInterfaceDetailA(
DeviceInfoSet,
&DeviceInterfaceData,
NULL,
0,
NULL,
&DeviceInfoData)) {
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
log_info("Could not SetupDiGetDeviceInterfaceDetailA\n");
return 0;
}
}
DWORD sz;
if (!SetupDiGetDeviceInstanceIdA(
DeviceInfoSet,
&DeviceInfoData,
path,
CAMERA_DATA_STRING_SIZE,
&sz)) {
log_info("Could not SetupDiGetDeviceInstanceIdA\n");
return 0;
}
if (DeviceInfoSet != INVALID_HANDLE_VALUE) {
if (!SetupDiDeleteDeviceInterfaceData(
DeviceInfoSet, &DeviceInterfaceData)) {
log_info("Could not SetupDiDeleteDeviceInterfaceData\n");
return 0;
}
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
}
return 1;
}
void strtolower(char *str)
{
for (size_t i = 0; str[i]; i++) {
str[i] = tolower(str[i]);
}
}
bool convert_path_to_fakesym(const char *path, wchar_t *sym, char *extra_o)
{
char root[16] = {0};
char vidstr[16] = {0};
char pidstr[16] = {0};
char mistr[16] = {0};
char extra[64] = {0};
sscanf(
path,
"%[^\\]\\%[^&]&%[^&]&%[^\\]\\%s",
root,
vidstr,
pidstr,
mistr,
extra);
strcpy(extra_o, extra);
strtolower(root);
strtolower(vidstr);
strtolower(pidstr);
strtolower(mistr);
strtolower(extra);
char buffer[CAMERA_DATA_STRING_SIZE];
snprintf(
buffer,
CAMERA_DATA_STRING_SIZE,
"\\\\?\\%s#%s&%s&%s#%s",
root,
vidstr,
pidstr,
mistr,
extra);
mbstowcs(sym, buffer, CAMERA_DATA_STRING_SIZE);
return true;
}
void fill_cam_struct(struct camera_data *data, const char *devid)
{
char buffer[CAMERA_DATA_STRING_SIZE];
data->setup = false;
if (!devid || strlen(devid) == 0) {
devid = grab_next_camera_id(buffer, CAMERA_DATA_STRING_SIZE);
}
if (!devid || strlen(devid) == 0) {
// no more cameras remain?
return;
}
if (strlen(devid) >= CAMERA_DATA_STRING_SIZE) {
// error probably log something?
return;
}
// detect input type
if (check_four(devid, "\\\\?\\")) {
// SYMBOLIC_LINK
if (!convert_sym_to_path(devid, data->deviceInstancePath)) {
log_info("Could not convert %s to path", devid);
return;
}
} else if (check_four(devid, "USB\\")) {
// Device instance path
strcpy(data->deviceInstancePath, devid);
// continue
} else {
// UNKNOWN ENTRY
log_info("UNK: %s", devid);
log_info("Please enter the device instance path");
return;
}
if (!convert_path_to_fakesym(
data->deviceInstancePath,
data->deviceSymbolicLink,
data->extra_upper)) {
log_info("Could not convert %s to sym", data->deviceInstancePath);
return;
}
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;
CONFIGRET cmret;
cmret = CM_Locate_DevNodeA(
&dnDevInst, data->deviceInstancePath, CM_LOCATE_DEVNODE_NORMAL);
if (cmret != CR_SUCCESS) {
log_info("CM_Locate_DevNodeA fail: %s", data->deviceInstancePath);
return;
}
cmret = CM_Get_Parent(&parentDev, dnDevInst, 0);
if (cmret != CR_SUCCESS) {
log_info("CM_Get_Parent fail: %s", data->deviceInstancePath);
return;
}
cmret = CM_Get_Device_IDA(
parentDev, data->parent_deviceInstancePath, CAMERA_DATA_STRING_SIZE, 0);
if (cmret != CR_SUCCESS) {
log_info("CM_Get_Device_IDA parent fail: %s", data->deviceInstancePath);
return;
}
ULONG szAddr;
ULONG szDesc;
ULONG szDriverKey;
szAddr = 4;
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 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 CM_DRP_DEVICEDESC fail: %s",
data->deviceInstancePath);
return;
}
szAddr = 4;
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 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 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 %s", data->parent_name, data->parent_address, data->parent_driverKey);
data->setup = true;
}
+34
View File
@@ -0,0 +1,34 @@
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
#ifndef CAMHOOK_CAM_DETECT_H
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
#define CAMHOOK_CAM_DETECT_H
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
#include <stdbool.h>
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
#include <stdint.h>
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
#include <wchar.h>
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
#define CAMERA_DATA_STRING_SIZE 0x100
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
struct camera_data {
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
bool setup;
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
char name[CAMERA_DATA_STRING_SIZE];
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
char deviceInstancePath[CAMERA_DATA_STRING_SIZE];
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
wchar_t deviceSymbolicLink[CAMERA_DATA_STRING_SIZE];
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
char extra_upper[CAMERA_DATA_STRING_SIZE];
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
int address;
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
char parent_name[CAMERA_DATA_STRING_SIZE];
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
char parent_driverKey[CAMERA_DATA_STRING_SIZE];
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
char parent_deviceInstancePath[CAMERA_DATA_STRING_SIZE];
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
int parent_address;
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
int16_t vid;
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
int16_t pid;
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
bool fake_addressed;
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
int fake_address;
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
bool fake_located;
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
size_t fake_located_node;
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
};
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
void fill_cam_struct(struct camera_data *data, const char *devid);
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
#endif
icex2 commented 2024-05-21 12:11:52 +03:00 (Migrated from github.com)
Review

nit: code style camera_data

nit: code style `camera_data`
+285 -380
View File
@@ -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>
@@ -19,80 +21,25 @@
#include "hook/table.h"
#include "camhook/cam.h"
#include "camhook/cam-detect.h"
#include "util/defs.h"
#include "util/log.h"
#include "util/str.h"
#include "util/time.h"
#define CAMERA_DATA_STRING_SIZE 0x100
#define CAMHOOK_NUM_LAYOUTS 3
EXTERN_GUID(
MY_MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
0xc60ac5fe,
0x252a,
0x478f,
0xa0,
0xef,
0xbc,
0x8f,
0xa5,
0xf7,
0xca,
0xd3);
EXTERN_GUID(
MY_MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID,
0x8ac3587a,
0x4ae7,
0x42d8,
0x99,
0xe0,
0x0a,
0x60,
0x13,
0xee,
0xf9,
0x0f);
EXTERN_GUID(
MY_MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK,
0x58f0aad8,
0x22bf,
0x4f8a,
0xbb,
0x3d,
0xd2,
0xc4,
0x97,
0x8c,
0x6e,
0x2f);
// define ourselves cause mingw has these wrong
struct CameraData {
bool setup;
char name[CAMERA_DATA_STRING_SIZE];
char deviceInstancePath[CAMERA_DATA_STRING_SIZE];
wchar_t deviceSymbolicLink[CAMERA_DATA_STRING_SIZE];
char extra_upper[CAMERA_DATA_STRING_SIZE];
int address;
char parent_name[CAMERA_DATA_STRING_SIZE];
char parent_deviceInstancePath[CAMERA_DATA_STRING_SIZE];
int parent_address;
bool fake_addressed;
int fake_address;
bool fake_located;
size_t fake_located_node;
};
static struct CameraData camData[CAMHOOK_CONFIG_CAM_MAX];
int camAddresses[CAMHOOK_CONFIG_CAM_MAX] = {
1,
7,
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_VERSION_OLD;
static CONFIGRET my_CM_Locate_DevNodeA(
PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags);
@@ -156,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,
@@ -180,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,
@@ -209,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;
}
}
}
@@ -278,9 +274,9 @@ 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, oh well
// should probably check GUID == MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, oh well
ret = real_GetAllocatedString(self, guidKey, ppwszValue, pcchLength);
char *pMBBuffer = (char *) malloc(0x100);
wcstombs(pMBBuffer, *ppwszValue, 0x100);
@@ -299,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);
@@ -334,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;
@@ -437,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;
}
2
@@ -491,315 +504,180 @@ static HDEVINFO my_SetupDiGetClassDevsA(
return real_SetupDiGetClassDevsA(ClassGuid, Enumerator, hwndParent, Flags);
}
bool check_four(const char inA[4], const char inB[4])
ULONG get_matching_device_replacement_id(
HANDLE hFile,
ULONG ConnectionIndex,
USB_DEVICE_DESCRIPTOR* desc)
{
return (*(uint32_t *) inA == *(uint32_t *) inB);
}
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';
char *grab_next_camera_id(char *buffer, size_t bsz)
{
static size_t gotten = 0;
DWORD nBytes;
IMFAttributes *pAttributes = NULL;
IMFActivate **ppDevices = NULL;
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;
}
buffer[0] = '\0';
if (req.ActualLength <= sizeof(req)) {
log_warning(
"Driver key name size too small for device %04x %04x",
desc->idVendor,
desc->idProduct);
continue;
}
HRESULT hr = MFCreateAttributes(&pAttributes, 1);
nBytes = req.ActualLength;
if (FAILED(hr)) {
log_info("MFCreateAttributes failed: %ld", hr);
goto done;
}
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';
hr = pAttributes->lpVtbl->SetGUID(
pAttributes,
&MY_MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
&MY_MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);
if (FAILED(hr)) {
log_info("SetGUID failed: %ld", hr);
goto done;
}
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;
}
UINT32 count;
hr = MFEnumDeviceSources(pAttributes, &ppDevices, &count);
char *driverKeyNameA = NULL;
wstr_narrow(driverKeyNameW->DriverKeyName, &driverKeyNameA);
if (FAILED(hr)) {
log_info("MFEnumDeviceSources failed: %ld", hr);
goto done;
}
free(driverKeyNameW);
if (count <= gotten) {
log_info("gotten failed: %d < %d", count, (int) gotten);
// not enough remaining
goto done;
}
wchar_t wSymLink[CAMERA_DATA_STRING_SIZE];
UINT32 sz;
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;
}
hr = ppDevices[gotten]->lpVtbl->GetString(
ppDevices[gotten],
&MY_MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK,
wSymLink,
CAMERA_DATA_STRING_SIZE,
&sz);
log_info(
"Replacing device @ %lu with %d for %04x %04x %s",
ConnectionIndex,
camAddresses[camhook_port_layout][i],
desc->idVendor,
desc->idProduct,
driverKeyNameA);
if (FAILED(hr)) {
log_info("GetString failed: %ld", hr);
goto done;
}
if (driverKeyNameA) {
free(driverKeyNameA);
}
wcstombs(buffer, wSymLink, bsz);
log_info("Detected webcam: %s\n", buffer);
++gotten;
done:
if (pAttributes) {
pAttributes->lpVtbl->Release(pAttributes);
}
for (DWORD i = 0; i < count; i++) {
if (ppDevices != NULL && ppDevices[i]) {
ppDevices[i]->lpVtbl->Release(ppDevices[i]);
replacement_id = camAddresses[camhook_port_layout][i];
break;
}
}
}
CoTaskMemFree(ppDevices);
return buffer;
return replacement_id;
}
bool convert_sym_to_path(const char *sym, char *path)
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)
{
HDEVINFO DeviceInfoSet = SetupDiCreateDeviceInfoList(NULL, NULL);
BOOL res;
if (DeviceInfoSet == INVALID_HANDLE_VALUE) {
log_info("Could not open SetupDiCreateDeviceInfoList\n");
return 0;
res = real_DeviceIoControl(
hFile,
dwIoControlCode,
lpInBuffer,
nInBufferSize,
lpOutBuffer,
nOutBufferSize,
lpBytesReturned,
lpOverlapped);
// if error just return
if (!res) {
return res;
}
SP_DEVICE_INTERFACE_DATA DeviceInterfaceData = {0};
DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
// 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;
if (!SetupDiOpenDeviceInterfaceA(
DeviceInfoSet, sym, 0, &DeviceInterfaceData)) {
log_info("Could not SetupDiOpenDeviceInterfaceA\n");
return 0;
}
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;
SP_DEVINFO_DATA DeviceInfoData = {0};
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
if (!SetupDiGetDeviceInterfaceDetailA(
DeviceInfoSet,
&DeviceInterfaceData,
NULL,
0,
NULL,
&DeviceInfoData)) {
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
log_info("Could not SetupDiGetDeviceInterfaceDetailA\n");
return 0;
ULONG replacement_id = get_matching_device_replacement_id(
hFile, connectionInfoEx->ConnectionIndex, &connectionInfoEx->DeviceDescriptor);
if (replacement_id > 0) {
connectionInfoEx->ConnectionIndex = replacement_id;
}
}
DWORD sz;
if (!SetupDiGetDeviceInstanceIdA(
DeviceInfoSet,
&DeviceInfoData,
path,
CAMERA_DATA_STRING_SIZE,
&sz)) {
log_info("Could not SetupDiGetDeviceInstanceIdA\n");
return 0;
}
if (DeviceInfoSet != INVALID_HANDLE_VALUE) {
if (!SetupDiDeleteDeviceInterfaceData(
DeviceInfoSet, &DeviceInterfaceData)) {
log_info("Could not SetupDiDeleteDeviceInterfaceData\n");
return 0;
}
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
}
return 1;
return res;
}
void strtolower(char *str)
{
for (size_t i = 0; str[i]; i++) {
str[i] = tolower(str[i]);
}
}
bool convert_path_to_fakesym(const char *path, wchar_t *sym, char *extra_o)
{
char root[16] = {0};
char vidstr[16] = {0};
char pidstr[16] = {0};
char mistr[16] = {0};
char extra[64] = {0};
sscanf(
path,
"%[^\\]\\%[^&]&%[^&]&%[^\\]\\%s",
root,
vidstr,
pidstr,
mistr,
extra);
strcpy(extra_o, extra);
strtolower(root);
strtolower(vidstr);
strtolower(pidstr);
strtolower(mistr);
strtolower(extra);
char buffer[CAMERA_DATA_STRING_SIZE];
snprintf(
buffer,
CAMERA_DATA_STRING_SIZE,
"\\\\?\\%s#%s&%s&%s#%s",
root,
vidstr,
pidstr,
mistr,
extra);
mbstowcs(sym, buffer, CAMERA_DATA_STRING_SIZE);
return true;
}
void fill_cam_struct(struct CameraData *data, const char *devid)
{
char buffer[CAMERA_DATA_STRING_SIZE];
data->setup = false;
if (!devid || strlen(devid) == 0) {
devid = grab_next_camera_id(buffer, CAMERA_DATA_STRING_SIZE);
}
if (!devid || strlen(devid) == 0) {
// no more cameras remain?
return;
}
if (strlen(devid) >= CAMERA_DATA_STRING_SIZE) {
// error probably log something?
return;
}
// detect input type
if (check_four(devid, "\\\\?\\")) {
// SYMBOLIC_LINK
if (!convert_sym_to_path(devid, data->deviceInstancePath)) {
log_info("Could not convert %s to path", devid);
return;
}
} else if (check_four(devid, "USB\\")) {
// Device instance path
strcpy(data->deviceInstancePath, devid);
// continue
} else {
// UNKNOWN ENTRY
log_info("UNK: %s", devid);
log_info("Please enter the device instance path");
return;
}
if (!convert_path_to_fakesym(
data->deviceInstancePath,
data->deviceSymbolicLink,
data->extra_upper)) {
log_info("Could not convert %s to sym", data->deviceInstancePath);
return;
}
log_info("dev path: %s", data->deviceInstancePath);
// locate device nodes
DEVINST dnDevInst;
DEVINST parentDev;
CONFIGRET cmret;
cmret = CM_Locate_DevNodeA(
&dnDevInst, data->deviceInstancePath, CM_LOCATE_DEVNODE_NORMAL);
if (cmret != CR_SUCCESS) {
log_info("CM_Locate_DevNodeA fail: %s", data->deviceInstancePath);
return;
}
cmret = CM_Get_Parent(&parentDev, dnDevInst, 0);
if (cmret != CR_SUCCESS) {
log_info("CM_Get_Parent fail: %s", data->deviceInstancePath);
return;
}
cmret = CM_Get_Device_IDA(
parentDev, data->parent_deviceInstancePath, CAMERA_DATA_STRING_SIZE, 0);
if (cmret != CR_SUCCESS) {
log_info("CM_Get_Device_IDA parent fail: %s", data->deviceInstancePath);
return;
}
ULONG szAddr;
ULONG szDesc;
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",
data->deviceInstancePath);
return;
}
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",
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",
data->deviceInstancePath);
return;
}
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",
data->deviceInstancePath);
return;
}
log_info("Found %s @ %d", data->name, data->address);
log_info("Parent %s @ %d", data->parent_name, data->parent_address);
data->setup = true;
void camhook_set_version(enum camhook_version version) {
camhook_version = version;
}
void camhook_init(struct camhook_config_cam *config_cam)
@@ -827,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
+9
View File
2
@@ -3,6 +3,15 @@
#include "camhook/config-cam.h"
// unused to control which camhook version is being used
// defaults to CAMHOOK_VERSION_OLD
enum camhook_version {
CAMHOOK_VERSION_OLD,
CAMHOOK_VERSION_NEW,
};
void camhook_set_version(enum camhook_version version);
void camhook_init(struct camhook_config_cam *config_cam);
void camhook_fini(void);
+29 -2
View File
@@ -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,
+7 -2
View File
@@ -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
+2 -2
View File
@@ -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);
+3 -2
View File
@@ -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);
}
+2 -2
View File
@@ -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);
+2 -2
View File
@@ -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);