[PATCH] hidclass.sys: Calculate correct bitCount for vendor-specific 1 bit repeated elements.

Aric Stewart aric at codeweavers.com
Thu Jan 21 12:54:47 CST 2021


Signed-off-by: Aric Stewart <aric at codeweavers.com>


On 1/21/21 10:11 AM, Arkadiusz Hiler wrote:
> DualSense controller's report descriptor comes with a 1 bit vendor specific
> (Usage Page & Usage) element repeated through 'report count'.
> 
> Those were correctly interpreted as non-ranged buttons (exposed as button caps
> with appropriate usage values) but their size was incorrectly assumed to be 1
> ignoring the 'report count'.
> 
> Because of that the InputReportByteLength is miscalculated as 63 instead of
> 64. If the buffer passed to HidD_GetInputReport() is allocated using that
> value the call will fail with ERROR_INSUFFICIENT_BUFFER.
> 
> This change fixes the above and cleans up the code a bit so the size for each
> case is calculated directly from the count and size instead of using the
> values that were derived from them.
> 
> Signed-off-by: Arkadiusz Hiler <ahiler at codeweavers.com>
> ---
>   dlls/hidclass.sys/descriptor.c | 10 ++++------
>   1 file changed, 4 insertions(+), 6 deletions(-)
> 
> diff --git a/dlls/hidclass.sys/descriptor.c b/dlls/hidclass.sys/descriptor.c
> index 56e4da4ad10..c02988494fd 100644
> --- a/dlls/hidclass.sys/descriptor.c
> +++ b/dlls/hidclass.sys/descriptor.c
> @@ -698,6 +698,10 @@ static void build_elements(WINE_HID_REPORT *wine_report, WINE_HID_ELEMENT *elems
>       }
>   
>       wine_element->valueStartBit = wine_report->bitSize;
> +
> +    wine_element->bitCount = (feature->caps.BitSize * feature->caps.ReportCount);
> +    wine_report->bitSize += wine_element->bitCount;
> +
>       if (feature->caps.BitSize == 1)
>       {
>           wine_element->ElementType = ButtonElement;
> @@ -713,8 +717,6 @@ static void build_elements(WINE_HID_REPORT *wine_report, WINE_HID_ELEMENT *elems
>           wine_element->caps.button.IsAbsolute = feature->IsAbsolute;
>           if (wine_element->caps.button.IsRange)
>           {
> -            wine_element->bitCount = (feature->caps.u.Range.UsageMax - feature->caps.u.Range.UsageMin) + 1;
> -            wine_report->bitSize += wine_element->bitCount;
>               wine_element->caps.button.u.Range.UsageMin = feature->caps.u.Range.UsageMin;
>               wine_element->caps.button.u.Range.UsageMax = feature->caps.u.Range.UsageMax;
>               wine_element->caps.button.u.Range.StringMin = feature->caps.u.Range.StringMin;
> @@ -727,8 +729,6 @@ static void build_elements(WINE_HID_REPORT *wine_report, WINE_HID_ELEMENT *elems
>           }
>           else
>           {
> -            wine_report->bitSize++;
> -            wine_element->bitCount = 1;
>               wine_element->caps.button.u.NotRange.Usage = feature->caps.u.NotRange.Usage;
>               wine_element->caps.button.u.NotRange.Reserved1 = feature->caps.u.NotRange.Usage;
>               wine_element->caps.button.u.NotRange.StringIndex = feature->caps.u.NotRange.StringIndex;
> @@ -756,8 +756,6 @@ static void build_elements(WINE_HID_REPORT *wine_report, WINE_HID_ELEMENT *elems
>           wine_element->caps.value.HasNull = feature->HasNull;
>           wine_element->caps.value.BitSize = feature->caps.BitSize;
>           wine_element->caps.value.ReportCount = feature->caps.ReportCount;
> -        wine_element->bitCount = (feature->caps.BitSize * wine_element->caps.value.ReportCount);
> -        wine_report->bitSize += wine_element->bitCount;
>           wine_element->caps.value.UnitsExp = feature->caps.UnitsExp;
>           wine_element->caps.value.Units = feature->caps.Units;
>           wine_element->caps.value.LogicalMin = feature->caps.LogicalMin;
> 



More information about the wine-devel mailing list