From: Oleg Makarenko oleg@makarenk.ooo
--- dlls/hid/hid.spec | 2 +- dlls/hid/hidp.c | 60 +++++++++++++++++++++++++++++ dlls/hidparse.sys/hidparse.sys.spec | 2 +- include/ddk/hidpi.h | 1 + 4 files changed, 63 insertions(+), 2 deletions(-)
diff --git a/dlls/hid/hid.spec b/dlls/hid/hid.spec index 67c4473129d..e64dfc29843 100644 --- a/dlls/hid/hid.spec +++ b/dlls/hid/hid.spec @@ -34,7 +34,7 @@ @ stdcall HidP_InitializeReportForID(long long ptr ptr long) @ stdcall HidP_MaxDataListLength(long ptr) @ stdcall HidP_MaxUsageListLength(long long ptr) -@ stub HidP_SetData +@ stdcall HidP_SetData(long ptr ptr ptr ptr long) @ stdcall HidP_SetScaledUsageValue(long long long long long ptr ptr long) @ stdcall HidP_SetUsageValue(long long long long long ptr ptr long) @ stdcall HidP_SetUsageValueArray(long long long long ptr long ptr ptr long) diff --git a/dlls/hid/hidp.c b/dlls/hid/hidp.c index c24a98155b0..ffc3d70f68b 100644 --- a/dlls/hid/hidp.c +++ b/dlls/hid/hidp.c @@ -1029,3 +1029,63 @@ NTSTATUS WINAPI HidP_GetLinkCollectionNodes( HIDP_LINK_COLLECTION_NODE *nodes, U
return HIDP_STATUS_SUCCESS; } + +static NTSTATUS set_all_data( const struct hid_value_caps *caps, void *user ) +{ + struct find_all_data_params *params = user; + HIDP_DATA *data = params->data, *data_end = params->data_end; + unsigned char *report_buf; + USHORT bit; + + if (!caps->bit_size) return HIDP_STATUS_SUCCESS; + + report_buf = (unsigned char *)params->report_buf + caps->start_byte; + + if (HID_VALUE_CAPS_IS_ARRAY( caps )) + return HIDP_STATUS_IS_VALUE_ARRAY; + + for (; data < data_end; data++) + { + if (data->DataIndex < caps->data_index_min || data->DataIndex > caps->data_index_max) + continue; + + bit = caps->start_bit + (data->DataIndex - caps->data_index_min) * caps->bit_size; + + if (caps->flags & HID_VALUE_CAPS_IS_BUTTON) + { + if (data->On) + report_buf[bit / 8] |= (1 << (bit % 8)); + else + { + if (!(report_buf[bit / 8] & (1 << (bit % 8)))) + return HIDP_STATUS_BUTTON_NOT_PRESSED; + else + report_buf[bit / 8] &= ~(1 << (bit % 8)); + } + } + else if (caps->report_count == 1) + { + ULONG bit_count = caps->bit_size * caps->report_count; + copy_bits( report_buf, (void *)&data->RawValue, bit_count, -caps->start_bit ); + } + } + + return HIDP_STATUS_SUCCESS; +} + +NTSTATUS WINAPI HidP_SetData( HIDP_REPORT_TYPE report_type, HIDP_DATA *data, ULONG *data_len, + PHIDP_PREPARSED_DATA preparsed_data, char *report_buf, ULONG report_len ) +{ + struct find_all_data_params params = {.data = data, .data_end = data + *data_len, .report_buf = report_buf}; + struct hid_preparsed_data *preparsed = (struct hid_preparsed_data *)preparsed_data; + struct caps_filter filter = {.usage_page = USAGE_ANY, .usage = USAGE_ANY}; + USHORT limit = -1; + + TRACE( "report_type %d, data %p, data_len %p, preparsed_data %p, report_buf %p, report_len %lu.\n", + report_type, data, data_len, preparsed_data, report_buf, report_len ); + + if (!report_len) return HIDP_STATUS_INVALID_REPORT_LENGTH; + + filter.report_id = report_buf[0]; + return enum_value_caps( preparsed, report_type, report_len, &filter, set_all_data, ¶ms, &limit ); +} diff --git a/dlls/hidparse.sys/hidparse.sys.spec b/dlls/hidparse.sys/hidparse.sys.spec index c723b51bed5..39b05ec7b93 100644 --- a/dlls/hidparse.sys/hidparse.sys.spec +++ b/dlls/hidparse.sys/hidparse.sys.spec @@ -18,7 +18,7 @@ @ stdcall HidP_InitializeReportForID(long long ptr ptr long) @ stdcall HidP_MaxDataListLength(long ptr) @ stdcall HidP_MaxUsageListLength(long long ptr) -@ stub HidP_SetData +@ stdcall HidP_SetData(long ptr ptr ptr ptr long) @ stub HidP_SetScaledUsageValue @ stdcall HidP_SetUsages(long long long ptr ptr ptr ptr long) @ stdcall HidP_SetUsageValue(long long long long long ptr ptr long) diff --git a/include/ddk/hidpi.h b/include/ddk/hidpi.h index e2e2bd2229b..29c3c3221fc 100644 --- a/include/ddk/hidpi.h +++ b/include/ddk/hidpi.h @@ -217,6 +217,7 @@ NTSTATUS WINAPI HidP_GetSpecificValueCaps(HIDP_REPORT_TYPE ReportType, USAGE Usa NTSTATUS WINAPI HidP_GetUsagesEx(HIDP_REPORT_TYPE ReportType, USHORT LinkCollection, USAGE_AND_PAGE *ButtonList, ULONG *UsageLength, PHIDP_PREPARSED_DATA PreparsedData, CHAR *Report, ULONG ReportLength); ULONG WINAPI HidP_MaxDataListLength(HIDP_REPORT_TYPE ReportType, PHIDP_PREPARSED_DATA PreparsedData); NTSTATUS WINAPI HidP_GetData(HIDP_REPORT_TYPE ReportType, HIDP_DATA *DataList, ULONG *DataLength, PHIDP_PREPARSED_DATA PreparsedData, CHAR *Report, ULONG ReportLength); +NTSTATUS WINAPI HidP_SetData(HIDP_REPORT_TYPE ReportType, HIDP_DATA *DataList, ULONG *DataLength, PHIDP_PREPARSED_DATA PreparsedData, CHAR *Report, ULONG ReportLength); NTSTATUS WINAPI HidP_GetLinkCollectionNodes(HIDP_LINK_COLLECTION_NODE *LinkCollectionNode, ULONG *LinkCollectionNodeLength, PHIDP_PREPARSED_DATA PreparsedData);
#ifndef FACILITY_HID_ERROR_CODE