diff --git a/sdk/include/ViGEm/Client.h b/sdk/include/ViGEm/Client.h index f4839e4..591d742 100644 --- a/sdk/include/ViGEm/Client.h +++ b/sdk/include/ViGEm/Client.h @@ -380,13 +380,15 @@ extern "C" { * @author Benjamin "Nefarius" Höglinger-Stelzer * @date 07.09.2020 * - * @param vigem The driver connection object. - * @param target The target device object. - * @param report The report buffer. + * @param vigem The driver connection object. + * @param target The target device object. + * @param report The report buffer. + * @param reportLength Length of the report buffer. * * @returns A VIGEM_ERROR. */ - VIGEM_API VIGEM_ERROR vigem_target_ds4_update_ex(PVIGEM_CLIENT vigem, PVIGEM_TARGET target, PUCHAR report); + VIGEM_API VIGEM_ERROR vigem_target_ds4_update_ex(PVIGEM_CLIENT vigem, PVIGEM_TARGET target, PUCHAR report, + ULONG reportLength); /** * Returns the internal index (serial number) the bus driver assigned to the provided diff --git a/sdk/src/ViGEmClient.cpp b/sdk/src/ViGEmClient.cpp index 51ff099..5377adf 100644 --- a/sdk/src/ViGEmClient.cpp +++ b/sdk/src/ViGEmClient.cpp @@ -975,9 +975,52 @@ VIGEM_ERROR vigem_target_ds4_update( return VIGEM_ERROR_NONE; } -VIGEM_ERROR vigem_target_ds4_update_ex(PVIGEM_CLIENT vigem, PVIGEM_TARGET target, PUCHAR report) +VIGEM_ERROR vigem_target_ds4_update_ex(PVIGEM_CLIENT vigem, PVIGEM_TARGET target, PUCHAR report, ULONG reportLength) { - return VIGEM_API VIGEM_ERROR(); + if (!vigem) + return VIGEM_ERROR_BUS_INVALID_HANDLE; + + if (!target) + return VIGEM_ERROR_INVALID_TARGET; + + if (vigem->hBusDevice == INVALID_HANDLE_VALUE) + return VIGEM_ERROR_BUS_NOT_FOUND; + + if (target->SerialNo == 0) + return VIGEM_ERROR_INVALID_TARGET; + + DWORD transferred = 0; + OVERLAPPED lOverlapped = { 0 }; + lOverlapped.hEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); + + DS4_SUBMIT_REPORT_EX dsr; + DS4_SUBMIT_REPORT_EX_INIT(&dsr, target->SerialNo); + + memcpy_s(dsr.Report, sizeof(dsr.Report), report, reportLength); + + DeviceIoControl( + vigem->hBusDevice, + IOCTL_DS4_SUBMIT_REPORT, // Same IOCTL, just different size + &dsr, + dsr.Size, + nullptr, + 0, + &transferred, + &lOverlapped + ); + + if (GetOverlappedResult(vigem->hBusDevice, &lOverlapped, &transferred, TRUE) == 0) + { + if (GetLastError() == ERROR_ACCESS_DENIED) + { + CloseHandle(lOverlapped.hEvent); + return VIGEM_ERROR_INVALID_TARGET; + } + } + + CloseHandle(lOverlapped.hEvent); + + return VIGEM_ERROR_NONE; } ULONG vigem_target_get_index(PVIGEM_TARGET target)