bemanitools/src/main/bio2drv/detect.c

164 lines
4.1 KiB
C

#define LOG_MODULE "bio2drv-detect"
#include <initguid.h>
#include <windows.h>
#include <cfgmgr32.h>
#include <setupapi.h>
#include "bio2drv/detect.h"
#include <stdio.h>
#include <string.h>
#include "util/log.h"
DEFINE_GUID(
GUID_COM_BUS_ENUMERATOR,
0x4D36E978,
0xE325,
0x11CE,
0xBF,
0xC1,
0x08,
0x00,
0x2B,
0xE1,
0x03,
0x18);
static char work_buffer[0x400];
static bool check_property(
HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA PDeviceInfoData, DWORD property)
{
if (SetupDiGetDeviceRegistryPropertyA(
DeviceInfoSet,
PDeviceInfoData,
property,
NULL,
(BYTE *) work_buffer,
sizeof(work_buffer),
NULL)) {
if (strstr(work_buffer, "BIO2(VIDEO)")) {
log_info("Found matching device: %s", work_buffer);
return true;
}
}
log_info("Device with property: %s does not match", work_buffer);
return false;
}
static bool check_id(
HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA PDeviceInfoData)
{
if (CM_Get_Device_IDA(PDeviceInfoData->DevInst, work_buffer, sizeof(work_buffer), 0)) {
return false;
}
if (strstr(work_buffer, "VID_1CCF&PID_804C")) {
log_info("Found matching device: %s", work_buffer);
return true;
}
if (strstr(work_buffer, "VID_1CCF&PID_8040")) {
log_info("Found matching device: %s", work_buffer);
return true;
}
log_info("Device with ID: %s does not match", work_buffer);
return false;
}
static bool get_device_by_filter(
bool id_filter, DWORD property, size_t devnum, char *path, size_t length)
{
HDEVINFO DeviceInfoSet = SetupDiGetClassDevsA(
&GUID_COM_BUS_ENUMERATOR, NULL, NULL, DIGCF_PRESENT);
if (DeviceInfoSet == INVALID_HANDLE_VALUE) {
return false;
}
SP_DEVINFO_DATA DeviceInfoData;
ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
DWORD idx = 0;
size_t num_found = 0;
while (SetupDiEnumDeviceInfo(DeviceInfoSet, idx, &DeviceInfoData)) {
HKEY DeviceRegKey = SetupDiOpenDevRegKey(
DeviceInfoSet,
&DeviceInfoData,
DICS_FLAG_GLOBAL,
0,
DIREG_DEV,
KEY_QUERY_VALUE);
if (DeviceRegKey) {
bool found = false;
log_info("Found a serial device at index: %d", idx);
if (!id_filter) {
if (check_property(DeviceInfoSet, &DeviceInfoData, property)) {
found = true;
}
} else {
if (check_id(DeviceInfoSet, &DeviceInfoData)) {
found = true;
}
}
if (found) {
if (num_found == devnum) {
DWORD path_length = length;
RegQueryValueExA(
DeviceRegKey,
"PortName",
0,
NULL,
(BYTE *) path,
&path_length);
log_info("Using port: %s", path);
return true;
}
num_found++;
}
}
++idx;
}
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
log_warning("No matching device found");
return false;
}
void bio2drv_set_loggers(
log_formatter_t misc,
log_formatter_t info,
log_formatter_t warning,
log_formatter_t fatal)
{
log_to_external(misc, info, warning, fatal);
}
bool bio2drv_detect(
enum bio2drv_detect_mode mode, size_t index, char *path, size_t length)
{
if (mode == DETECT_DEVICEDESC) {
return get_device_by_filter(
false, SPDRP_DEVICEDESC, index, path, length);
} else if (mode == DETECT_FRIENDLYNAME) {
return get_device_by_filter(
false, SPDRP_FRIENDLYNAME, index, path, length);
} else if (mode == DETECT_DEVICEID) {
return get_device_by_filter(true, -1, index, path, length);
}
log_warning("Unknown autodetect mode: %d", mode);
return false;
}