controllers/npad: Validate device handles before use
Some games such as NEKOPARA Vol. 3 send invalid device handles when calling InitializeVibrationDevice. Introduce a check to validate the device handle before use.
This commit is contained in:
parent
69b46dd607
commit
1c773c0869
2 changed files with 45 additions and 0 deletions
|
@ -116,6 +116,31 @@ u32 Controller_NPad::IndexToNPad(std::size_t index) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Controller_NPad::IsNpadIdValid(u32 npad_id) {
|
||||||
|
switch (npad_id) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
case 5:
|
||||||
|
case 6:
|
||||||
|
case 7:
|
||||||
|
case NPAD_UNKNOWN:
|
||||||
|
case NPAD_HANDHELD:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
LOG_ERROR(Service_HID, "Invalid npad id {}", npad_id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Controller_NPad::IsDeviceHandleValid(const DeviceHandle& device_handle) {
|
||||||
|
return IsNpadIdValid(device_handle.npad_id) &&
|
||||||
|
device_handle.npad_type < NpadType::MaxNpadType &&
|
||||||
|
device_handle.device_index < DeviceIndex::MaxDeviceIndex;
|
||||||
|
}
|
||||||
|
|
||||||
Controller_NPad::Controller_NPad(Core::System& system) : ControllerBase(system), system(system) {}
|
Controller_NPad::Controller_NPad(Core::System& system) : ControllerBase(system), system(system) {}
|
||||||
|
|
||||||
Controller_NPad::~Controller_NPad() {
|
Controller_NPad::~Controller_NPad() {
|
||||||
|
@ -742,6 +767,10 @@ bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index, std::size
|
||||||
|
|
||||||
void Controller_NPad::VibrateController(const DeviceHandle& vibration_device_handle,
|
void Controller_NPad::VibrateController(const DeviceHandle& vibration_device_handle,
|
||||||
const VibrationValue& vibration_value) {
|
const VibrationValue& vibration_value) {
|
||||||
|
if (!IsDeviceHandleValid(vibration_device_handle)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) {
|
if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -798,12 +827,20 @@ void Controller_NPad::VibrateControllers(const std::vector<DeviceHandle>& vibrat
|
||||||
|
|
||||||
Controller_NPad::VibrationValue Controller_NPad::GetLastVibration(
|
Controller_NPad::VibrationValue Controller_NPad::GetLastVibration(
|
||||||
const DeviceHandle& vibration_device_handle) const {
|
const DeviceHandle& vibration_device_handle) const {
|
||||||
|
if (!IsDeviceHandleValid(vibration_device_handle)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id);
|
const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id);
|
||||||
const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
|
const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
|
||||||
return latest_vibration_values[npad_index][device_index];
|
return latest_vibration_values[npad_index][device_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller_NPad::InitializeVibrationDevice(const DeviceHandle& vibration_device_handle) {
|
void Controller_NPad::InitializeVibrationDevice(const DeviceHandle& vibration_device_handle) {
|
||||||
|
if (!IsDeviceHandleValid(vibration_device_handle)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id);
|
const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id);
|
||||||
const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
|
const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
|
||||||
InitializeVibrationDeviceAtIndex(npad_index, device_index);
|
InitializeVibrationDeviceAtIndex(npad_index, device_index);
|
||||||
|
@ -824,6 +861,10 @@ void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Controller_NPad::IsVibrationDeviceMounted(const DeviceHandle& vibration_device_handle) const {
|
bool Controller_NPad::IsVibrationDeviceMounted(const DeviceHandle& vibration_device_handle) const {
|
||||||
|
if (!IsDeviceHandleValid(vibration_device_handle)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id);
|
const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id);
|
||||||
const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
|
const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
|
||||||
return vibration_devices_mounted[npad_index][device_index];
|
return vibration_devices_mounted[npad_index][device_index];
|
||||||
|
|
|
@ -56,12 +56,14 @@ public:
|
||||||
JoyconLeft = 6,
|
JoyconLeft = 6,
|
||||||
JoyconRight = 7,
|
JoyconRight = 7,
|
||||||
Pokeball = 9,
|
Pokeball = 9,
|
||||||
|
MaxNpadType = 10,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class DeviceIndex : u8 {
|
enum class DeviceIndex : u8 {
|
||||||
Left = 0,
|
Left = 0,
|
||||||
Right = 1,
|
Right = 1,
|
||||||
None = 2,
|
None = 2,
|
||||||
|
MaxDeviceIndex = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class GyroscopeZeroDriftMode : u32 {
|
enum class GyroscopeZeroDriftMode : u32 {
|
||||||
|
@ -213,6 +215,8 @@ public:
|
||||||
static Settings::ControllerType MapNPadToSettingsType(Controller_NPad::NPadControllerType type);
|
static Settings::ControllerType MapNPadToSettingsType(Controller_NPad::NPadControllerType type);
|
||||||
static std::size_t NPadIdToIndex(u32 npad_id);
|
static std::size_t NPadIdToIndex(u32 npad_id);
|
||||||
static u32 IndexToNPad(std::size_t index);
|
static u32 IndexToNPad(std::size_t index);
|
||||||
|
static bool IsNpadIdValid(u32 npad_id);
|
||||||
|
static bool IsDeviceHandleValid(const DeviceHandle& device_handle);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct CommonHeader {
|
struct CommonHeader {
|
||||||
|
|
Loading…
Reference in a new issue