From 762a30d0dbb2505c6f2b1691ec7d712a8b58adc7 Mon Sep 17 00:00:00 2001
From: german77 <juangerman-13@hotmail.com>
Date: Sat, 21 May 2022 16:56:06 -0500
Subject: [PATCH] service: hid: Add error handling to sixaxis functions

---
 src/core/hle/service/hid/controllers/npad.cpp | 82 ++++++++++++-------
 src/core/hle/service/hid/controllers/npad.h   |  3 +-
 src/core/hle/service/hid/errors.h             |  1 +
 3 files changed, 55 insertions(+), 31 deletions(-)

diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 8badefdec..ef6befbd9 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -56,11 +56,22 @@ bool Controller_NPad::IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle
     return npad_id && npad_type && device_index;
 }
 
-bool Controller_NPad::IsDeviceHandleValid(const Core::HID::SixAxisSensorHandle& device_handle) {
+ResultCode Controller_NPad::VerifyValidSixAxisSensorHandle(
+    const Core::HID::SixAxisSensorHandle& device_handle) {
     const auto npad_id = IsNpadIdValid(static_cast<Core::HID::NpadIdType>(device_handle.npad_id));
-    const bool npad_type = device_handle.npad_type < Core::HID::NpadStyleIndex::MaxNpadType;
+    if (!npad_id) {
+        return InvalidNpadId;
+    }
     const bool device_index = device_handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex;
-    return npad_id && npad_type && device_index;
+    if (!device_index) {
+        return NpadDeviceIndexOutOfRange;
+    }
+    // This doesn't get validaded on nnsdk
+    const bool npad_type = device_handle.npad_type < Core::HID::NpadStyleIndex::MaxNpadType;
+    if (!npad_type) {
+        return NpadInvalidHandle;
+    }
+    return ResultSuccess;
 }
 
 Controller_NPad::Controller_NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
@@ -1010,9 +1021,10 @@ ResultCode Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
 }
 ResultCode Controller_NPad::SetGyroscopeZeroDriftMode(
     const Core::HID::SixAxisSensorHandle& sixaxis_handle, GyroscopeZeroDriftMode drift_mode) {
-    if (!IsDeviceHandleValid(sixaxis_handle)) {
-        LOG_ERROR(Service_HID, "Invalid handle");
-        return NpadInvalidHandle;
+    const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
+    if (is_valid.IsError()) {
+        LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
+        return is_valid;
     }
 
     auto& sixaxis = GetSixaxisState(sixaxis_handle);
@@ -1024,9 +1036,10 @@ ResultCode Controller_NPad::SetGyroscopeZeroDriftMode(
 ResultCode Controller_NPad::GetGyroscopeZeroDriftMode(
     const Core::HID::SixAxisSensorHandle& sixaxis_handle,
     GyroscopeZeroDriftMode& drift_mode) const {
-    if (!IsDeviceHandleValid(sixaxis_handle)) {
-        LOG_ERROR(Service_HID, "Invalid handle");
-        return NpadInvalidHandle;
+    const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
+    if (is_valid.IsError()) {
+        LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
+        return is_valid;
     }
 
     const auto& sixaxis = GetSixaxisState(sixaxis_handle);
@@ -1037,9 +1050,10 @@ ResultCode Controller_NPad::GetGyroscopeZeroDriftMode(
 
 ResultCode Controller_NPad::IsSixAxisSensorAtRest(
     const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_at_rest) const {
-    if (!IsDeviceHandleValid(sixaxis_handle)) {
-        LOG_ERROR(Service_HID, "Invalid handle");
-        return NpadInvalidHandle;
+    const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
+    if (is_valid.IsError()) {
+        LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
+        return is_valid;
     }
 
     const auto& controller = GetControllerFromHandle(sixaxis_handle);
@@ -1049,9 +1063,10 @@ ResultCode Controller_NPad::IsSixAxisSensorAtRest(
 
 ResultCode Controller_NPad::IsFirmwareUpdateAvailableForSixAxisSensor(
     const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_firmware_available) const {
-    if (!IsDeviceHandleValid(sixaxis_handle)) {
-        LOG_ERROR(Service_HID, "Invalid handle");
-        return NpadInvalidHandle;
+    const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
+    if (is_valid.IsError()) {
+        LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
+        return is_valid;
     }
 
     // We don't support joycon firmware updates
@@ -1061,10 +1076,12 @@ ResultCode Controller_NPad::IsFirmwareUpdateAvailableForSixAxisSensor(
 
 ResultCode Controller_NPad::SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle,
                                               bool sixaxis_status) {
-    if (!IsDeviceHandleValid(sixaxis_handle)) {
-        LOG_ERROR(Service_HID, "Invalid handle");
-        return NpadInvalidHandle;
+    const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
+    if (is_valid.IsError()) {
+        LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
+        return is_valid;
     }
+
     auto& controller = GetControllerFromHandle(sixaxis_handle);
     controller.sixaxis_sensor_enabled = sixaxis_status;
     return ResultSuccess;
@@ -1072,9 +1089,10 @@ ResultCode Controller_NPad::SetSixAxisEnabled(const Core::HID::SixAxisSensorHand
 
 ResultCode Controller_NPad::IsSixAxisSensorFusionEnabled(
     const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_fusion_enabled) const {
-    if (!IsDeviceHandleValid(sixaxis_handle)) {
-        LOG_ERROR(Service_HID, "Invalid handle");
-        return NpadInvalidHandle;
+    const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
+    if (is_valid.IsError()) {
+        LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
+        return is_valid;
     }
 
     const auto& sixaxis = GetSixaxisState(sixaxis_handle);
@@ -1084,9 +1102,10 @@ ResultCode Controller_NPad::IsSixAxisSensorFusionEnabled(
 }
 ResultCode Controller_NPad::SetSixAxisFusionEnabled(
     const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_fusion_enabled) {
-    if (!IsDeviceHandleValid(sixaxis_handle)) {
-        LOG_ERROR(Service_HID, "Invalid handle");
-        return NpadInvalidHandle;
+    const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
+    if (is_valid.IsError()) {
+        LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
+        return is_valid;
     }
 
     auto& sixaxis = GetSixaxisState(sixaxis_handle);
@@ -1098,10 +1117,12 @@ ResultCode Controller_NPad::SetSixAxisFusionEnabled(
 ResultCode Controller_NPad::SetSixAxisFusionParameters(
     const Core::HID::SixAxisSensorHandle& sixaxis_handle,
     Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters) {
-    if (!IsDeviceHandleValid(sixaxis_handle)) {
-        LOG_ERROR(Service_HID, "Invalid handle");
-        return NpadInvalidHandle;
+    const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
+    if (is_valid.IsError()) {
+        LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
+        return is_valid;
     }
+
     const auto param1 = sixaxis_fusion_parameters.parameter1;
     if (param1 < 0.0f || param1 > 1.0f) {
         return InvalidSixAxisFusionRange;
@@ -1116,9 +1137,10 @@ ResultCode Controller_NPad::SetSixAxisFusionParameters(
 ResultCode Controller_NPad::GetSixAxisFusionParameters(
     const Core::HID::SixAxisSensorHandle& sixaxis_handle,
     Core::HID::SixAxisSensorFusionParameters& parameters) const {
-    if (!IsDeviceHandleValid(sixaxis_handle)) {
-        LOG_ERROR(Service_HID, "Invalid handle");
-        return NpadInvalidHandle;
+    const auto is_valid = VerifyValidSixAxisSensorHandle(sixaxis_handle);
+    if (is_valid.IsError()) {
+        LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw);
+        return is_valid;
     }
 
     const auto& sixaxis = GetSixaxisState(sixaxis_handle);
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index dfb4de740..e6125ffcc 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -185,8 +185,9 @@ public:
     Core::HID::NpadButton GetAndResetPressState();
 
     static bool IsNpadIdValid(Core::HID::NpadIdType npad_id);
-    static bool IsDeviceHandleValid(const Core::HID::SixAxisSensorHandle& device_handle);
     static bool IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle);
+    static ResultCode VerifyValidSixAxisSensorHandle(
+        const Core::HID::SixAxisSensorHandle& device_handle);
 
 private:
     static constexpr std::size_t NPAD_COUNT = 10;
diff --git a/src/core/hle/service/hid/errors.h b/src/core/hle/service/hid/errors.h
index d518fd069..6c8ad04af 100644
--- a/src/core/hle/service/hid/errors.h
+++ b/src/core/hle/service/hid/errors.h
@@ -8,6 +8,7 @@
 namespace Service::HID {
 
 constexpr ResultCode NpadInvalidHandle{ErrorModule::HID, 100};
+constexpr ResultCode NpadDeviceIndexOutOfRange{ErrorModule::HID, 107};
 constexpr ResultCode InvalidSixAxisFusionRange{ErrorModule::HID, 423};
 constexpr ResultCode NpadIsDualJoycon{ErrorModule::HID, 601};
 constexpr ResultCode NpadIsSameType{ErrorModule::HID, 602};