HID: properly check return values and report IDs

This commit is contained in:
Megamouse 2022-06-05 15:20:38 +02:00
parent 4912202cfa
commit 09875a5180
3 changed files with 41 additions and 40 deletions

View File

@ -278,20 +278,21 @@ void ds3_pad_handler::check_add_device(hid_device* hidDevice, std::string_view p
std::array<u8, 0xFF> buf{}; std::array<u8, 0xFF> buf{};
buf[0] = 0xF2; buf[0] = 0xF2;
int res = hid_get_feature_report(hidDevice, buf.data(), 0xFF); int res = hid_get_feature_report(hidDevice, buf.data(), buf.size());
if (res < 0) if (res != static_cast<int>(buf.size()) || buf[0] != 0xF2)
{ {
ds3_log.warning("check_add_device: hid_get_feature_report 0xF2 failed! Trying again with 0x0. (result=%d, error=%s)", res, hid_error(hidDevice)); ds3_log.warning("check_add_device: hid_get_feature_report 0xF2 failed! Trying again with 0x0. (result=%d, buf[0]=0x%x, error=%s)", res, buf[0], hid_error(hidDevice));
buf = {}; buf = {};
buf[0] = 0; buf[0] = 0x0;
res = hid_get_feature_report(hidDevice, buf.data(), 0xFF); res = hid_get_feature_report(hidDevice, buf.data(), buf.size());
} if (res != static_cast<int>(buf.size()) || buf[0] != 0x0)
if (res < 0) {
{ ds3_log.error("check_add_device: hid_get_feature_report 0x0 failed! result=%d, buf[0]=0x%x, error=%s", res, buf[0], hid_error(hidDevice));
ds3_log.error("check_add_device: hid_get_feature_report 0x0 failed! result=%d, error=%s", res, hid_error(hidDevice)); hid_close(hidDevice);
hid_close(hidDevice); return;
return; }
} }
device->report_id = buf[0]; device->report_id = buf[0];
#elif defined (__APPLE__) #elif defined (__APPLE__)
int res = hid_init_sixaxis_usb(hidDevice); int res = hid_init_sixaxis_usb(hidDevice);
@ -332,12 +333,12 @@ ds3_pad_handler::DataStatus ds3_pad_handler::get_data(ds3_device* ds3dev)
#ifdef _WIN32 #ifdef _WIN32
ds3dev->padData[0] = ds3dev->report_id; ds3dev->padData[0] = ds3dev->report_id;
const int result = hid_get_feature_report(ds3dev->hidDevice, ds3dev->padData.data(), 64); const int result = hid_get_feature_report(ds3dev->hidDevice, ds3dev->padData.data(), ds3dev->padData.size());
#else #else
const int result = hid_read(ds3dev->hidDevice, ds3dev->padData.data(), 64); const int result = hid_read(ds3dev->hidDevice, ds3dev->padData.data(), ds3dev->padData.size());
#endif #endif
if (result > 0) if (result == static_cast<int>(ds3dev->padData.size()))
{ {
#ifdef _WIN32 #ifdef _WIN32
if (ds3dev->padData[0] == ds3dev->report_id) if (ds3dev->padData[0] == ds3dev->report_id)
@ -363,7 +364,7 @@ ds3_pad_handler::DataStatus ds3_pad_handler::get_data(ds3_device* ds3dev)
} }
else else
{ {
ds3_log.warning("Unknown packet received:0x%02x", ds3dev->padData[0]); ds3_log.warning("Unknown packet received: 0x%02x", ds3dev->padData[0]);
return DataStatus::NoNewData; return DataStatus::NoNewData;
} }
} }

View File

@ -386,7 +386,7 @@ bool ds4_pad_handler::GetCalibrationData(DS4Device* ds4Dev) const
buf = {}; buf = {};
buf[0] = 0x05; buf[0] = 0x05;
if (int res = hid_get_feature_report(ds4Dev->hidDevice, buf.data(), DS4_FEATURE_REPORT_0x05_SIZE); res <= 0) if (int res = hid_get_feature_report(ds4Dev->hidDevice, buf.data(), DS4_FEATURE_REPORT_0x05_SIZE); res != DS4_FEATURE_REPORT_0x05_SIZE || buf[0] != 0x05)
{ {
ds4_log.error("GetCalibrationData: hid_get_feature_report 0x05 for bluetooth controller failed! result=%d, error=%s", res, hid_error(ds4Dev->hidDevice)); ds4_log.error("GetCalibrationData: hid_get_feature_report 0x05 for bluetooth controller failed! result=%d, error=%s", res, hid_error(ds4Dev->hidDevice));
return false; return false;
@ -412,7 +412,7 @@ bool ds4_pad_handler::GetCalibrationData(DS4Device* ds4Dev) const
else else
{ {
buf[0] = 0x02; buf[0] = 0x02;
if (int res = hid_get_feature_report(ds4Dev->hidDevice, buf.data(), DS4_FEATURE_REPORT_0x02_SIZE); res <= 0) if (int res = hid_get_feature_report(ds4Dev->hidDevice, buf.data(), DS4_FEATURE_REPORT_0x02_SIZE); res != DS4_FEATURE_REPORT_0x02_SIZE || buf[0] != 0x02)
{ {
ds4_log.error("GetCalibrationData: hid_get_feature_report 0x02 for wired controller failed! result=%d, error=%s", res, hid_error(ds4Dev->hidDevice)); ds4_log.error("GetCalibrationData: hid_get_feature_report 0x02 for wired controller failed! result=%d, error=%s", res, hid_error(ds4Dev->hidDevice));
return false; return false;
@ -537,17 +537,17 @@ void ds4_pad_handler::check_add_device(hid_device* hidDevice, std::string_view p
int res = hid_get_feature_report(hidDevice, buf.data(), DS4_FEATURE_REPORT_0x81_SIZE); int res = hid_get_feature_report(hidDevice, buf.data(), DS4_FEATURE_REPORT_0x81_SIZE);
if (res > 0) if (res > 0)
{ {
if (res != DS4_FEATURE_REPORT_0x81_SIZE) if (res != DS4_FEATURE_REPORT_0x81_SIZE || buf[0] != 0x81)
{ {
// Controller may not be genuine. These controllers do not have feature 0x81 implemented and calibration data is in bluetooth format even in USB mode! // Controller may not be genuine. These controllers do not have feature 0x81 implemented and calibration data is in bluetooth format even in USB mode!
ds4_log.warning("check_add_device: DS4 controller may not be genuine. Workaround enabled."); ds4_log.warning("check_add_device: DS4 controller may not be genuine. Workaround enabled. (result=%d, buf[0]=0x%x)", res, buf[0]);
// Read feature report 0x12 instead which is what the console uses. // Read feature report 0x12 instead which is what the console uses.
buf = {}; buf = {};
buf[0] = 0x12; buf[0] = 0x12;
if (res = hid_get_feature_report(hidDevice, buf.data(), DS4_FEATURE_REPORT_0x12_SIZE); res < 0) if (res = hid_get_feature_report(hidDevice, buf.data(), DS4_FEATURE_REPORT_0x12_SIZE); res != DS4_FEATURE_REPORT_0x12_SIZE || buf[0] != 0x12)
{ {
ds4_log.error("check_add_device: hid_get_feature_report 0x12 failed! result=%d, error=%s", res, hid_error(hidDevice)); ds4_log.error("check_add_device: hid_get_feature_report 0x12 failed! result=%d, buf[0]=0x%x, error=%s", res, buf[0], hid_error(hidDevice));
} }
} }
@ -555,7 +555,7 @@ void ds4_pad_handler::check_add_device(hid_device* hidDevice, std::string_view p
} }
else else
{ {
ds4_log.warning("check_add_device: DS4 Bluetooth controller detected. (hid_get_feature_report 0x81 failed, result=%d, error=%s)", res, hid_error(hidDevice)); ds4_log.warning("check_add_device: DS4 Bluetooth controller detected. (hid_get_feature_report 0x81 failed, result=%d, buf[0]=0x%x, error=%s)", res, buf[0], hid_error(hidDevice));
device->bt_controller = true; device->bt_controller = true;
for (wchar_t ch : wide_serial) for (wchar_t ch : wide_serial)
serial += static_cast<uchar>(ch); serial += static_cast<uchar>(ch);
@ -578,9 +578,9 @@ void ds4_pad_handler::check_add_device(hid_device* hidDevice, std::string_view p
buf[0] = 0xA3; buf[0] = 0xA3;
res = hid_get_feature_report(hidDevice, buf.data(), DS4_FEATURE_REPORT_0xA3_SIZE); res = hid_get_feature_report(hidDevice, buf.data(), DS4_FEATURE_REPORT_0xA3_SIZE);
if (res <= 0) if (res != DS4_FEATURE_REPORT_0xA3_SIZE || buf[0] != 0xA3)
{ {
ds4_log.error("check_add_device: hid_get_feature_report 0xA3 failed! Could not retrieve firmware version! result=%d, error=%s", res, hid_error(hidDevice)); ds4_log.error("check_add_device: hid_get_feature_report 0xA3 failed! Could not retrieve firmware version! result=%d, buf[0]=0x%x, error=%s", res, buf[0], hid_error(hidDevice));
} }
else else
{ {
@ -682,7 +682,7 @@ ds4_pad_handler::DataStatus ds4_pad_handler::get_data(DS4Device* device)
std::array<u8, 78> buf{}; std::array<u8, 78> buf{};
const int res = hid_read(device->hidDevice, buf.data(), device->bt_controller ? 78 : 64); const int res = hid_read(device->hidDevice, buf.data(), device->bt_controller ? DS4_INPUT_REPORT_0x11_SIZE : 64);
if (res == -1) if (res == -1)
{ {
// looks like controller disconnected or read error // looks like controller disconnected or read error
@ -699,16 +699,16 @@ ds4_pad_handler::DataStatus ds4_pad_handler::get_data(DS4Device* device)
// tells controller to send 0x11 reports // tells controller to send 0x11 reports
std::array<u8, 64> buf_error{}; std::array<u8, 64> buf_error{};
buf_error[0] = 0x2; buf_error[0] = 0x2;
if (int res = hid_get_feature_report(device->hidDevice, buf_error.data(), buf_error.size()); res < 0) if (int res = hid_get_feature_report(device->hidDevice, buf_error.data(), buf_error.size()); res != static_cast<int>(buf_error.size()) || buf_error[0] != 0x2)
{ {
ds4_log.error("GetRawData: hid_get_feature_report 0x2 failed! result=%d, error=%s", res, hid_error(device->hidDevice)); ds4_log.error("GetRawData: hid_get_feature_report 0x2 failed! result=%d, buf[0]=0x%x, error=%s", res, buf[0], hid_error(device->hidDevice));
} }
return DataStatus::NoNewData; return DataStatus::NoNewData;
} }
int offset; int offset;
// check report and set offset // check report and set offset
if (device->bt_controller && buf[0] == 0x11 && res == 78) if (device->bt_controller && buf[0] == 0x11 && res == DS4_INPUT_REPORT_0x11_SIZE)
{ {
offset = 2; offset = 2;

View File

@ -176,16 +176,16 @@ void dualsense_pad_handler::check_add_device(hid_device* hidDevice, std::string_
std::string serial; std::string serial;
std::array<u8, 65> buf{}; std::array<u8, 64> buf{};
buf[0] = 0x09; buf[0] = 0x09;
// This will give us the bluetooth mac address of the device, regardless if we are on wired or bluetooth. // This will give us the bluetooth mac address of the device, regardless if we are on wired or bluetooth.
// So we can't use this to determine if it is a bluetooth device or not. // So we can't use this to determine if it is a bluetooth device or not.
// Will also enable enhanced feature reports for bluetooth. // Will also enable enhanced feature reports for bluetooth.
int res = hid_get_feature_report(hidDevice, buf.data(), 64); int res = hid_get_feature_report(hidDevice, buf.data(), buf.size());
if (res < 0) if (res < 0 || buf[0] != 0x09)
{ {
dualsense_log.error("check_add_device: hid_get_feature_report 0x09 failed! result=%d, error=%s", res, hid_error(hidDevice)); dualsense_log.error("check_add_device: hid_get_feature_report 0x09 failed! result=%d, buf[0]=0x%x, error=%s", res, buf[0], hid_error(hidDevice));
return; return;
} }
@ -222,14 +222,14 @@ void dualsense_pad_handler::check_add_device(hid_device* hidDevice, std::string_
buf[0] = 0x20; buf[0] = 0x20;
res = hid_get_feature_report(hidDevice, buf.data(), DUALSENSE_VERSION_REPORT_SIZE); res = hid_get_feature_report(hidDevice, buf.data(), DUALSENSE_VERSION_REPORT_SIZE);
if (res > 0) // Old versions return 65, newer versions return 64 if (res != DUALSENSE_VERSION_REPORT_SIZE || buf[0] != 0x20) // Old versions return 65, newer versions return 64
{ {
hw_version = read_u32(&buf[24]); dualsense_log.error("check_add_device: hid_get_feature_report 0x20 failed! Could not retrieve firmware version! result=%d, buf[0]=0x%x, error=%s", res, buf[0], hid_error(hidDevice));
fw_version = read_u32(&buf[28]);
} }
else else
{ {
dualsense_log.error("check_add_device: hid_get_feature_report 0x20 failed! Could not retrieve firmware version! result=%d, error=%s", res, hid_error(hidDevice)); hw_version = read_u32(&buf[24]);
fw_version = read_u32(&buf[28]);
} }
if (hid_set_nonblocking(hidDevice, 1) == -1) if (hid_set_nonblocking(hidDevice, 1) == -1)
@ -427,9 +427,9 @@ bool dualsense_pad_handler::get_calibration_data(DualSenseDevice* dualsense_devi
buf = {}; buf = {};
buf[0] = 0x05; buf[0] = 0x05;
if (int res = hid_get_feature_report(dualsense_device->hidDevice, buf.data(), DUALSENSE_CALIBRATION_REPORT_SIZE); res <= 0) if (int res = hid_get_feature_report(dualsense_device->hidDevice, buf.data(), DUALSENSE_CALIBRATION_REPORT_SIZE); res != DUALSENSE_CALIBRATION_REPORT_SIZE || buf[0] != 0x05)
{ {
dualsense_log.error("get_calibration_data: hid_get_feature_report 0x05 for bluetooth controller failed! result=%d, error=%s", res, hid_error(dualsense_device->hidDevice)); dualsense_log.error("get_calibration_data: hid_get_feature_report 0x05 for bluetooth controller failed! result=%d, buf[0]=0x%x, error=%s", res, buf[0], hid_error(dualsense_device->hidDevice));
return false; return false;
} }
@ -454,9 +454,9 @@ bool dualsense_pad_handler::get_calibration_data(DualSenseDevice* dualsense_devi
{ {
buf[0] = 0x05; buf[0] = 0x05;
if (int res = hid_get_feature_report(dualsense_device->hidDevice, buf.data(), DUALSENSE_CALIBRATION_REPORT_SIZE); res <= 0) if (int res = hid_get_feature_report(dualsense_device->hidDevice, buf.data(), DUALSENSE_CALIBRATION_REPORT_SIZE); res != DUALSENSE_CALIBRATION_REPORT_SIZE || buf[0] != 0x05)
{ {
dualsense_log.error("get_calibration_data: hid_get_feature_report 0x05 for wired controller failed! result=%d, error=%s", res, hid_error(dualsense_device->hidDevice)); dualsense_log.error("get_calibration_data: hid_get_feature_report 0x05 for wired controller failed! result=%d, buf[0]=0x%x, error=%s", res, buf[0], hid_error(dualsense_device->hidDevice));
return false; return false;
} }
} }