mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-06-28 01:49:33 -06:00
Host: Implement a Windows-only implementation of GetDeviceNameFromVIDPID
This commit is contained in:
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <SetupAPI.h>
|
||||||
|
|
||||||
#define strerror_r(err, buf, len) strerror_s(buf, len, err)
|
#define strerror_r(err, buf, len) strerror_s(buf, len, err)
|
||||||
|
|
||||||
@ -91,5 +92,28 @@ std::optional<std::wstring> GetModuleName(void* hInstance)
|
|||||||
name.resize(size);
|
name.resize(size);
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::wstring GetDeviceProperty(const HDEVINFO& device_info, const PSP_DEVINFO_DATA device_data,
|
||||||
|
const DEVPROPKEY* requested_property)
|
||||||
|
{
|
||||||
|
DWORD required_size = 0;
|
||||||
|
DEVPROPTYPE device_property_type;
|
||||||
|
BOOL result;
|
||||||
|
|
||||||
|
result = SetupDiGetDeviceProperty(device_info, device_data, requested_property,
|
||||||
|
&device_property_type, nullptr, 0, &required_size, 0);
|
||||||
|
if (!result && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
||||||
|
return std::wstring();
|
||||||
|
|
||||||
|
std::vector<TCHAR> unicode_buffer(required_size / sizeof(TCHAR));
|
||||||
|
|
||||||
|
result = SetupDiGetDeviceProperty(
|
||||||
|
device_info, device_data, requested_property, &device_property_type,
|
||||||
|
reinterpret_cast<PBYTE>(unicode_buffer.data()), required_size, nullptr, 0);
|
||||||
|
if (!result)
|
||||||
|
return std::wstring();
|
||||||
|
|
||||||
|
return std::wstring(unicode_buffer.data());
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
} // namespace Common
|
} // namespace Common
|
||||||
|
@ -5,6 +5,12 @@
|
|||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <SetupAPI.h>
|
||||||
|
#include <cfgmgr32.h>
|
||||||
|
#include <devpropdef.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
@ -58,5 +64,9 @@ std::string GetWin32ErrorString(unsigned long error_code);
|
|||||||
|
|
||||||
// Obtains a full path to the specified module.
|
// Obtains a full path to the specified module.
|
||||||
std::optional<std::wstring> GetModuleName(void* hInstance);
|
std::optional<std::wstring> GetModuleName(void* hInstance);
|
||||||
|
|
||||||
|
// Obtains a device property and returns it as a wide string.
|
||||||
|
std::wstring GetDeviceProperty(const HANDLE& device_info, const PSP_DEVINFO_DATA device_data,
|
||||||
|
const DEVPROPKEY* requested_property);
|
||||||
#endif
|
#endif
|
||||||
} // namespace Common
|
} // namespace Common
|
||||||
|
@ -210,28 +210,6 @@ bool ForgetWiimote(BLUETOOTH_DEVICE_INFO_STRUCT&);
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
std::wstring GetDeviceProperty(const HDEVINFO& device_info, const PSP_DEVINFO_DATA device_data,
|
|
||||||
const DEVPROPKEY* requested_property)
|
|
||||||
{
|
|
||||||
DWORD required_size = 0;
|
|
||||||
DEVPROPTYPE device_property_type;
|
|
||||||
|
|
||||||
SetupDiGetDeviceProperty(device_info, device_data, requested_property, &device_property_type,
|
|
||||||
nullptr, 0, &required_size, 0);
|
|
||||||
|
|
||||||
std::vector<BYTE> unicode_buffer(required_size, 0);
|
|
||||||
|
|
||||||
BOOL result =
|
|
||||||
SetupDiGetDeviceProperty(device_info, device_data, requested_property, &device_property_type,
|
|
||||||
unicode_buffer.data(), required_size, nullptr, 0);
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
return std::wstring();
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::wstring((PWCHAR)unicode_buffer.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
int IOWritePerSetOutputReport(HANDLE& dev_handle, const u8* buf, size_t len, DWORD* written)
|
int IOWritePerSetOutputReport(HANDLE& dev_handle, const u8* buf, size_t len, DWORD* written)
|
||||||
{
|
{
|
||||||
const BOOLEAN result =
|
const BOOLEAN result =
|
||||||
@ -403,8 +381,8 @@ bool CheckForToshibaStack(const DEVINST& hid_interface_device_instance)
|
|||||||
|
|
||||||
if (GetParentDevice(hid_interface_device_instance, &parent_device_info, &parent_device_data))
|
if (GetParentDevice(hid_interface_device_instance, &parent_device_info, &parent_device_data))
|
||||||
{
|
{
|
||||||
std::wstring class_driver_provider =
|
std::wstring class_driver_provider = Common::GetDeviceProperty(
|
||||||
GetDeviceProperty(parent_device_info, &parent_device_data, &DEVPKEY_Device_DriverProvider);
|
parent_device_info, &parent_device_data, &DEVPKEY_Device_DriverProvider);
|
||||||
|
|
||||||
SetupDiDestroyDeviceInfoList(parent_device_info);
|
SetupDiDestroyDeviceInfoList(parent_device_info);
|
||||||
|
|
||||||
|
@ -11,12 +11,20 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
#include <fmt/xchar.h>
|
||||||
|
#ifdef HAVE_LIBUDEV
|
||||||
|
#include <libudev.h>
|
||||||
|
#endif
|
||||||
#ifdef __LIBUSB__
|
#ifdef __LIBUSB__
|
||||||
#include <libusb.h>
|
#include <libusb.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <SetupAPI.h>
|
||||||
|
#include <cfgmgr32.h>
|
||||||
|
#include <devpkey.h>
|
||||||
|
|
||||||
#ifdef HAVE_LIBUDEV
|
#include "Common/CommonFuncs.h"
|
||||||
#include <libudev.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Common/ChunkFile.h"
|
#include "Common/ChunkFile.h"
|
||||||
@ -56,7 +64,50 @@ std::optional<IPCReply> USBHost::Open(const OpenRequest& request)
|
|||||||
std::string USBHost::GetDeviceNameFromVIDPID(u16 vid, u16 pid)
|
std::string USBHost::GetDeviceNameFromVIDPID(u16 vid, u16 pid)
|
||||||
{
|
{
|
||||||
std::string device_name;
|
std::string device_name;
|
||||||
#ifdef __LIBUSB__
|
#ifdef _WIN32
|
||||||
|
const std::wstring filter = fmt::format(L"VID_{:04X}&PID_{:04X}", vid, pid);
|
||||||
|
|
||||||
|
HDEVINFO dev_info =
|
||||||
|
SetupDiGetClassDevs(nullptr, nullptr, nullptr, DIGCF_PRESENT | DIGCF_ALLCLASSES);
|
||||||
|
if (dev_info == INVALID_HANDLE_VALUE)
|
||||||
|
return device_name;
|
||||||
|
|
||||||
|
SP_DEVINFO_DATA dev_info_data;
|
||||||
|
dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA);
|
||||||
|
|
||||||
|
for (DWORD i = 0; SetupDiEnumDeviceInfo(dev_info, i, &dev_info_data); ++i)
|
||||||
|
{
|
||||||
|
TCHAR instance_id[MAX_DEVICE_ID_LEN];
|
||||||
|
if (CM_Get_Device_ID(dev_info_data.DevInst, instance_id, MAX_DEVICE_ID_LEN, 0) != CR_SUCCESS)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const std::wstring_view id_wstr(instance_id);
|
||||||
|
if (id_wstr.find(filter) == std::wstring::npos)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
std::wstring property_value =
|
||||||
|
Common::GetDeviceProperty(dev_info, &dev_info_data, &DEVPKEY_Device_FriendlyName);
|
||||||
|
if (property_value.empty())
|
||||||
|
{
|
||||||
|
property_value =
|
||||||
|
Common::GetDeviceProperty(dev_info, &dev_info_data, &DEVPKEY_Device_DeviceDesc);
|
||||||
|
}
|
||||||
|
|
||||||
|
device_name = WStringToUTF8(property_value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetupDiDestroyDeviceInfoList(dev_info);
|
||||||
|
if (!device_name.empty())
|
||||||
|
return device_name;
|
||||||
|
#endif
|
||||||
|
// libusb can cause BSODs with certain bad OEM drivers on Windows when opening a device.
|
||||||
|
// All offending drivers are known to depend on the BthUsb.sys driver, which is a Miniport Driver
|
||||||
|
// for Bluetooth.
|
||||||
|
// Known offenders:
|
||||||
|
// - btfilter.sys from Qualcomm Atheros Communications
|
||||||
|
// - ibtusb.sys from Intel Corporation
|
||||||
|
#if defined(__LIBUSB__) && !defined(_WIN32)
|
||||||
LibusbUtils::Context context;
|
LibusbUtils::Context context;
|
||||||
|
|
||||||
if (!context.IsValid())
|
if (!context.IsValid())
|
||||||
|
Reference in New Issue
Block a user