Merge commit '852f2a6343518919e5ca8d3c1bbcab9f493e3cd8'

This commit is contained in:
2024-01-17 17:02:59 +01:00
1244 changed files with 50102 additions and 28146 deletions

View File

@ -214,7 +214,7 @@ This is done to let the host project's developer decide what is important (what
In a _subdirectory build_, even if not set, those variables remain unchanged, so a host project's developer has a full control over the HIDAPI build configuration.
Available CMake targets after `add_subdirectory(hidapi)` _are the same as in case of [standalone build](#standalone-package-build)_, and a few additional ones:
- `hidapi_include` - the interface library; `hidapi::hidapi` is an alias of it;
- `hidapi_include` - the interface library; `hidapi::include` is an alias of it;
- `hidapi_winapi` - library target on Windows; `hidapi::winapi` is an alias of it;
- `hidapi_darwin` - library target on macOS; `hidapi::darwin` is an alias of it;
- `hidapi_libusb` - library target for libusb backend; `hidapi::libusb` is an alias of it;

View File

@ -42,6 +42,9 @@ elseif(NOT WIN32)
option(HIDAPI_WITH_HIDRAW "Build HIDRAW-based implementation of HIDAPI" ON)
option(HIDAPI_WITH_LIBUSB "Build LIBUSB-based implementation of HIDAPI" ON)
endif()
if(CMAKE_SYSTEM_NAME MATCHES "NetBSD")
option(HIDAPI_WITH_NETBSD "Build NetBSD/UHID implementation of HIDAPI" ON)
endif()
endif()
option(BUILD_SHARED_LIBS "Build shared version of the libraries, otherwise build statically" ON)

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -573,6 +573,8 @@ typedef struct PLATFORM_hid_device_ PLATFORM_hid_device;
#ifdef __LINUX__
#include "SDL_hidapi_linux.h"
#elif defined(__NETBSD__)
#include "SDL_hidapi_netbsd.h"
#elif defined(__MACOS__)
#include "SDL_hidapi_mac.h"
#elif defined(__WINDOWS__) || defined(__WINGDK__)

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -0,0 +1,25 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#undef HIDAPI_H__
#include "netbsd/hid.c"
#define HAVE_PLATFORM_BACKEND 1
#define udev_ctx 1

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -214,7 +214,7 @@ JAVADOC_BANNER = NO
# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
# line (until the first dot) of a Qt-style comment as the brief description. If
# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
# requiring an explicit \brief command for a brief description.)
# requiring an explicit command for a brief description.)
# The default value is: NO.
QT_AUTOBRIEF = NO

View File

@ -77,7 +77,7 @@ void print_device(struct hid_device_info *cur_dev) {
printf(" Release: %hx\n", cur_dev->release_number);
printf(" Interface: %d\n", cur_dev->interface_number);
printf(" Usage (page): 0x%hx (0x%hx)\n", cur_dev->usage, cur_dev->usage_page);
printf(" Bus type: %d (%s)\n", cur_dev->bus_type, hid_bus_name(cur_dev->bus_type));
printf(" Bus type: %u (%s)\n", (unsigned)cur_dev->bus_type, hid_bus_name(cur_dev->bus_type));
printf("\n");
}

View File

@ -123,6 +123,7 @@ struct hid_device_ {
/* Quirks */
int skip_output_report_id;
int no_skip_output_report_id;
int no_output_reports_on_intr_ep;
/* List of received input reports. */
@ -867,6 +868,7 @@ static int is_xboxone(unsigned short vendor_id, const struct libusb_interface_de
static const int xb1_iface_subclass = 71;
static const int xb1_iface_protocol = 208;
static const int supported_vendors[] = {
0x03f0, /* HP */
0x044f, /* Thrustmaster */
0x045e, /* Microsoft */
0x0738, /* Mad Catz */
@ -1346,6 +1348,7 @@ static int hidapi_initialize_device(hid_device *dev, const struct libusb_interfa
/* Initialize XBox 360 controllers */
if (is_xbox360(desc.idVendor, intf_desc)) {
dev->no_skip_output_report_id = 1;
init_xbox360(dev->device_handle, desc.idVendor, desc.idProduct, conf_desc);
}
@ -1571,7 +1574,7 @@ int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t
report_number = data[0];
if (report_number == 0x0 || dev->skip_output_report_id) {
if ((!dev->no_skip_output_report_id && report_number == 0x0) || dev->skip_output_report_id) {
data++;
length--;
skipped_report_id = 1;
@ -2085,7 +2088,7 @@ uint16_t get_usb_code_for_current_locale(void)
return 0x0;
/* Make a copy of the current locale string. */
strncpy(search_string, locale, sizeof(search_string));
strncpy(search_string, locale, sizeof(search_string)-1);
search_string[sizeof(search_string)-1] = '\0';
/* Chop off the encoding part, and make it lower case. */

View File

@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages

View File

@ -54,15 +54,15 @@ static int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrie
{
(void) attr;
if(count == 0) {
if (count == 0) {
errno = EINVAL;
return -1;
}
if(pthread_mutex_init(&barrier->mutex, 0) < 0) {
if (pthread_mutex_init(&barrier->mutex, 0) < 0) {
return -1;
}
if(pthread_cond_init(&barrier->cond, 0) < 0) {
if (pthread_cond_init(&barrier->cond, 0) < 0) {
pthread_mutex_destroy(&barrier->mutex);
return -1;
}
@ -83,16 +83,18 @@ static int pthread_barrier_wait(pthread_barrier_t *barrier)
{
pthread_mutex_lock(&barrier->mutex);
++(barrier->count);
if(barrier->count >= barrier->trip_count)
{
if (barrier->count >= barrier->trip_count) {
barrier->count = 0;
pthread_cond_broadcast(&barrier->cond);
pthread_mutex_unlock(&barrier->mutex);
pthread_cond_broadcast(&barrier->cond);
return 1;
}
else
{
pthread_cond_wait(&barrier->cond, &(barrier->mutex));
else {
do {
pthread_cond_wait(&barrier->cond, &(barrier->mutex));
}
while (barrier->count != 0);
pthread_mutex_unlock(&barrier->mutex);
return 0;
}
@ -1230,7 +1232,9 @@ static int return_data(hid_device *dev, unsigned char *data, size_t length)
return buffer (data), and delete the liked list item. */
struct input_report *rpt = dev->input_reports;
size_t len = (length < rpt->len)? length: rpt->len;
memcpy(data, rpt->data, len);
if (data != NULL) {
memcpy(data, rpt->data, len);
}
dev->input_reports = rpt->next;
free(rpt->data);
free(rpt);

View File

@ -0,0 +1,35 @@
cmake_minimum_required(VERSION 3.6.3 FATAL_ERROR)
add_library(hidapi_netbsd
${HIDAPI_PUBLIC_HEADERS}
hid.c
)
target_link_libraries(hidapi_netbsd PUBLIC hidapi_include)
find_package(Threads REQUIRED)
target_link_libraries(hidapi_netbsd PRIVATE Threads::Threads)
set_target_properties(hidapi_netbsd
PROPERTIES
EXPORT_NAME "netbsd"
OUTPUT_NAME "hidapi-netbsd"
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
PUBLIC_HEADER "${HIDAPI_PUBLIC_HEADERS}"
)
# compatibility with find_package()
add_library(hidapi::netbsd ALIAS hidapi_netbsd)
# compatibility with raw library link
add_library(hidapi-netbsd ALIAS hidapi_netbsd)
if(HIDAPI_INSTALL_TARGETS)
install(TARGETS hidapi_netbsd EXPORT hidapi
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/hidapi"
)
endif()
hidapi_configure_pc("${PROJECT_ROOT}/pc/hidapi-netbsd.pc.in")

View File

@ -0,0 +1,29 @@
Implementation Notes
--------------------
NetBSD maps every `uhidev` device to one or more `uhid`
devices. Each `uhid` device only supports one report ID.
The parent device `uhidev` creates one `uhid` device per
report ID found in the hardware's report descriptor.
In the event there are no report ID(s) found within the
report descriptor, only one `uhid` device with a report ID
of `0` is created.
In order to remain compatible with existing `hidapi` APIs,
all the `uhid` devices created by the parent `uhidev` device
must be opened under the same `hid_device` instance to ensure
that we can route reports to their appropriate `uhid` device.
Internally the `uhid` driver will insert the report ID as
needed so we must also omit the report ID in any situation
where the `hidapi` API expects it to be included in the
report data stream.
Given the design of `uhid`, it must be augmented with extra
platform specific APIs to ensure that the exact relationship
between `uhidev` devices and `uhid` devices can be determined.
The NetBSD implementation does this via the `drvctl` kernel
driver. At present there is no known way to do this on OpenBSD
for a `uhid` implementation to be at the same level as the
NetBSD one.

1173
external/sdl/SDL/src/hidapi/netbsd/hid.c vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: hidapi-netbsd
Description: C Library for USB/Bluetooth HID device access from Linux, Mac OS X, FreeBSD, and Windows. This is the netbsd implementation.
URL: https://github.com/libusb/hidapi
Version: @VERSION@
Libs: -L${libdir} -lhidapi-netbsd
Cflags: -I${includedir}/hidapi

View File

@ -68,8 +68,9 @@ function(hidapi_configure_pc PC_IN_FILE)
get_filename_component(PC_IN_FILENAME "${PC_IN_FILE}" NAME_WE)
set(PC_FILE "${CMAKE_CURRENT_BINARY_DIR}/pc/${PC_IN_FILENAME}.pc")
configure_file("${PC_IN_FILE}" "${PC_FILE}" @ONLY)
install(FILES "${PC_FILE}" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig/")
if(HIDAPI_INSTALL_TARGETS)
install(FILES "${PC_FILE}" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig/")
endif()
endfunction()
# The library
@ -140,6 +141,18 @@ else()
set(HIDAPI_NEED_EXPORT_LIBUDEV TRUE)
endif()
endif()
elseif(CMAKE_SYSTEM_NAME MATCHES "NetBSD")
if(NOT DEFINED HIDAPI_WITH_NETBSD)
set(HIDAPI_WITH_NETBSD ON)
endif()
if(HIDAPI_WITH_NETBSD)
add_subdirectory("${PROJECT_ROOT}/netbsd" netbsd)
list(APPEND EXPORT_COMPONENTS netbsd)
set(EXPORT_ALIAS netbsd)
if(NOT BUILD_SHARED_LIBS)
set(HIDAPI_NEED_EXPORT_THREADS TRUE)
endif()
endif()
else()
set(HIDAPI_WITH_LIBUSB ON)
endif()

View File

@ -120,7 +120,7 @@ static void free_library_handles()
cfgmgr32_lib_handle = NULL;
}
#if defined(__GNUC__)
#ifdef HAVE_GCC_DIAGNOSTIC_PRAGMA
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wcast-function-type"
#endif
@ -170,7 +170,7 @@ err:
return -1;
}
#if defined(__GNUC__)
#ifdef HAVE_GCC_DIAGNOSTIC_PRAGMA
# pragma GCC diagnostic pop
#endif
@ -325,7 +325,7 @@ static void register_winapi_error_to_buffer(wchar_t **error_buffer, const WCHAR
#endif
}
#if defined(__GNUC__)
#ifdef HAVE_GCC_DIAGNOSTIC_PRAGMA
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Warray-bounds"
#endif
@ -355,7 +355,7 @@ static void register_string_error_to_buffer(wchar_t **error_buffer, const WCHAR
#endif /* HIDAPI_USING_SDL_RUNTIME */
}
#if defined(__GNUC__)
#ifdef HAVE_GCC_DIAGNOSTIC_PRAGMA
# pragma GCC diagnostic pop
#endif
@ -1462,7 +1462,7 @@ int HID_API_EXPORT HID_API_CALL hid_get_input_report(hid_device *dev, unsigned c
return hid_get_report(dev, IOCTL_HID_GET_INPUT_REPORT, data, length);
}
#if defined(__GNUC__)
#ifdef HAVE_GCC_DIAGNOSTIC_PRAGMA
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wcast-function-type"
#endif
@ -1486,7 +1486,7 @@ void HID_API_EXPORT HID_API_CALL hid_close(hid_device *dev)
}
free_hid_device(dev);
}
#if defined(__GNUC__)
#ifdef HAVE_GCC_DIAGNOSTIC_PRAGMA
# pragma GCC diagnostic pop
#endif

View File

@ -37,6 +37,7 @@
#include <windows.h>
#include "hidapi_hidsdi.h"
/*#include <assert.h>*/
#define NUM_OF_HIDP_REPORT_TYPES 3
@ -125,6 +126,14 @@ typedef struct hid_pp_link_collection_node_ {
// Same as the public API structure HIDP_LINK_COLLECTION_NODE, but without PVOID UserContext at the end
} hid_pp_link_collection_node, *phid_pp_link_collection_node;
// Note: This is risk-reduction-measure for this specific struct, as it has ULONG bit-field.
// Although very unlikely, it might still be possible that the compiler creates a memory layout that is
// not binary compatile.
// Other structs are not checked at the time of writing.
//static_assert(sizeof(struct hid_pp_link_collection_node_) == 16,
// "Size of struct hid_pp_link_collection_node_ not as expected. This might break binary compatibility");
SDL_COMPILE_TIME_ASSERT(hid_pp_link_collection_node_, sizeof(struct hid_pp_link_collection_node_) == 16);
typedef struct hidp_unknown_token_ {
UCHAR Token; /* Specifies the one-byte prefix of a global item. */
UCHAR Reserved[3];
@ -213,15 +222,19 @@ typedef struct hidp_preparsed_data_ {
USHORT FirstByteOfLinkCollectionArray;
USHORT NumberLinkCollectionNodes;
#if defined(__MINGW32__) || defined(__CYGWIN__)
#ifndef _MSC_VER
// MINGW fails with: Flexible array member in union not supported
// Solution: https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
union {
#ifdef HAVE_GCC_DIAGNOSTIC_PRAGMA
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
hid_pp_cap caps[0];
hid_pp_link_collection_node LinkCollectionArray[0];
#ifdef HAVE_GCC_DIAGNOSTIC_PRAGMA
#pragma GCC diagnostic pop
#endif
};
#else
union {

View File

@ -1,95 +1,95 @@
#if defined(__MINGW32__)
// Needed for %hh
#define __USE_MINGW_ANSI_STDIO 1
#endif
#include <hid.c>
#include <../windows/hidapi_descriptor_reconstruct.h>
#include <hidapi.h>
#if defined(__MINGW32__)
#pragma GCC diagnostic ignored "-Wformat"
#pragma GCC diagnostic ignored "-Wformat-extra-args"
#endif
void dump_hid_pp_cap(FILE* file, phid_pp_cap pp_cap, unsigned int cap_idx) {
fprintf(file, "pp_data->cap[%d]->UsagePage = 0x%04hX\n", cap_idx, pp_cap->UsagePage);
fprintf(file, "pp_data->cap[%d]->ReportID = 0x%02hhX\n", cap_idx, pp_cap->ReportID);
fprintf(file, "pp_data->cap[%d]->BitPosition = %hhu\n", cap_idx, pp_cap->BitPosition);
fprintf(file, "pp_data->cap[%d]->BitSize = %hu\n", cap_idx, pp_cap->ReportSize);
fprintf(file, "pp_data->cap[%d]->ReportCount = %hu\n", cap_idx, pp_cap->ReportCount);
fprintf(file, "pp_data->cap[%d]->BytePosition = 0x%04hX\n", cap_idx, pp_cap->BytePosition);
fprintf(file, "pp_data->cap[%d]->BitCount = %hu\n", cap_idx, pp_cap->BitCount);
fprintf(file, "pp_data->cap[%d]->BitField = 0x%02lX\n", cap_idx, pp_cap->BitField);
fprintf(file, "pp_data->cap[%d]->NextBytePosition = 0x%04hX\n", cap_idx, pp_cap->NextBytePosition);
fprintf(file, "pp_data->cap[%d]->LinkCollection = 0x%04hX\n", cap_idx, pp_cap->LinkCollection);
fprintf(file, "pp_data->cap[%d]->LinkUsagePage = 0x%04hX\n", cap_idx, pp_cap->LinkUsagePage);
fprintf(file, "pp_data->cap[%d]->LinkUsage = 0x%04hX\n", cap_idx, pp_cap->LinkUsage);
fprintf(file, "pp_data->cap[%u]->UsagePage = 0x%04hX\n", cap_idx, pp_cap->UsagePage);
fprintf(file, "pp_data->cap[%u]->ReportID = 0x%02hhX\n", cap_idx, pp_cap->ReportID);
fprintf(file, "pp_data->cap[%u]->BitPosition = %hhu\n", cap_idx, pp_cap->BitPosition);
fprintf(file, "pp_data->cap[%u]->BitSize = %hu\n", cap_idx, pp_cap->ReportSize);
fprintf(file, "pp_data->cap[%u]->ReportCount = %hu\n", cap_idx, pp_cap->ReportCount);
fprintf(file, "pp_data->cap[%u]->BytePosition = 0x%04hX\n", cap_idx, pp_cap->BytePosition);
fprintf(file, "pp_data->cap[%u]->BitCount = %hu\n", cap_idx, pp_cap->BitCount);
fprintf(file, "pp_data->cap[%u]->BitField = 0x%02lX\n", cap_idx, pp_cap->BitField);
fprintf(file, "pp_data->cap[%u]->NextBytePosition = 0x%04hX\n", cap_idx, pp_cap->NextBytePosition);
fprintf(file, "pp_data->cap[%u]->LinkCollection = 0x%04hX\n", cap_idx, pp_cap->LinkCollection);
fprintf(file, "pp_data->cap[%u]->LinkUsagePage = 0x%04hX\n", cap_idx, pp_cap->LinkUsagePage);
fprintf(file, "pp_data->cap[%u]->LinkUsage = 0x%04hX\n", cap_idx, pp_cap->LinkUsage);
// 8 Flags in one byte
fprintf(file, "pp_data->cap[%d]->IsMultipleItemsForArray = %hhu\n", cap_idx, pp_cap->IsMultipleItemsForArray);
fprintf(file, "pp_data->cap[%d]->IsButtonCap = %hhu\n", cap_idx, pp_cap->IsButtonCap);
fprintf(file, "pp_data->cap[%d]->IsPadding = %hhu\n", cap_idx, pp_cap->IsPadding);
fprintf(file, "pp_data->cap[%d]->IsAbsolute = %hhu\n", cap_idx, pp_cap->IsAbsolute);
fprintf(file, "pp_data->cap[%d]->IsRange = %hhu\n", cap_idx, pp_cap->IsRange);
fprintf(file, "pp_data->cap[%d]->IsAlias = %hhu\n", cap_idx, pp_cap->IsAlias);
fprintf(file, "pp_data->cap[%d]->IsStringRange = %hhu\n", cap_idx, pp_cap->IsStringRange);
fprintf(file, "pp_data->cap[%d]->IsDesignatorRange = %hhu\n", cap_idx, pp_cap->IsDesignatorRange);
fprintf(file, "pp_data->cap[%u]->IsMultipleItemsForArray = %hhu\n", cap_idx, pp_cap->IsMultipleItemsForArray);
fprintf(file, "pp_data->cap[%u]->IsButtonCap = %hhu\n", cap_idx, pp_cap->IsButtonCap);
fprintf(file, "pp_data->cap[%u]->IsPadding = %hhu\n", cap_idx, pp_cap->IsPadding);
fprintf(file, "pp_data->cap[%u]->IsAbsolute = %hhu\n", cap_idx, pp_cap->IsAbsolute);
fprintf(file, "pp_data->cap[%u]->IsRange = %hhu\n", cap_idx, pp_cap->IsRange);
fprintf(file, "pp_data->cap[%u]->IsAlias = %hhu\n", cap_idx, pp_cap->IsAlias);
fprintf(file, "pp_data->cap[%u]->IsStringRange = %hhu\n", cap_idx, pp_cap->IsStringRange);
fprintf(file, "pp_data->cap[%u]->IsDesignatorRange = %hhu\n", cap_idx, pp_cap->IsDesignatorRange);
fprintf(file, "pp_data->cap[%d]->Reserved1 = 0x%02hhX%02hhX%02hhX\n", cap_idx, pp_cap->Reserved1[0], pp_cap->Reserved1[1], pp_cap->Reserved1[2]);
fprintf(file, "pp_data->cap[%u]->Reserved1 = 0x%02hhX%02hhX%02hhX\n", cap_idx, pp_cap->Reserved1[0], pp_cap->Reserved1[1], pp_cap->Reserved1[2]);
for (int token_idx = 0; token_idx < 4; token_idx++) {
fprintf(file, "pp_data->cap[%d]->pp_cap->UnknownTokens[%d].Token = 0x%02hhX\n", cap_idx, token_idx, pp_cap->UnknownTokens[token_idx].Token);
fprintf(file, "pp_data->cap[%d]->pp_cap->UnknownTokens[%d].Reserved = 0x%02hhX%02hhX%02hhX\n", cap_idx, token_idx, pp_cap->UnknownTokens[token_idx].Reserved[0], pp_cap->UnknownTokens[token_idx].Reserved[1], pp_cap->UnknownTokens[token_idx].Reserved[2]);
fprintf(file, "pp_data->cap[%d]->pp_cap->UnknownTokens[%d].BitField = 0x%08lX\n", cap_idx, token_idx, pp_cap->UnknownTokens[token_idx].BitField);
fprintf(file, "pp_data->cap[%u]->pp_cap->UnknownTokens[%d].Token = 0x%02hhX\n", cap_idx, token_idx, pp_cap->UnknownTokens[token_idx].Token);
fprintf(file, "pp_data->cap[%u]->pp_cap->UnknownTokens[%d].Reserved = 0x%02hhX%02hhX%02hhX\n", cap_idx, token_idx, pp_cap->UnknownTokens[token_idx].Reserved[0], pp_cap->UnknownTokens[token_idx].Reserved[1], pp_cap->UnknownTokens[token_idx].Reserved[2]);
fprintf(file, "pp_data->cap[%u]->pp_cap->UnknownTokens[%d].BitField = 0x%08lX\n", cap_idx, token_idx, pp_cap->UnknownTokens[token_idx].BitField);
}
if (pp_cap->IsRange) {
fprintf(file, "pp_data->cap[%d]->Range.UsageMin = 0x%04hX\n", cap_idx, pp_cap->Range.UsageMin);
fprintf(file, "pp_data->cap[%d]->Range.UsageMax = 0x%04hX\n", cap_idx, pp_cap->Range.UsageMax);
fprintf(file, "pp_data->cap[%d]->Range.StringMin = %hu\n", cap_idx, pp_cap->Range.StringMin);
fprintf(file, "pp_data->cap[%d]->Range.StringMax = %hu\n", cap_idx, pp_cap->Range.StringMax);
fprintf(file, "pp_data->cap[%d]->Range.DesignatorMin = %hu\n", cap_idx, pp_cap->Range.DesignatorMin);
fprintf(file, "pp_data->cap[%d]->Range.DesignatorMax = %hu\n", cap_idx, pp_cap->Range.DesignatorMax);
fprintf(file, "pp_data->cap[%d]->Range.DataIndexMin = %hu\n", cap_idx, pp_cap->Range.DataIndexMin);
fprintf(file, "pp_data->cap[%d]->Range.DataIndexMax = %hu\n", cap_idx, pp_cap->Range.DataIndexMax);
fprintf(file, "pp_data->cap[%u]->Range.UsageMin = 0x%04hX\n", cap_idx, pp_cap->Range.UsageMin);
fprintf(file, "pp_data->cap[%u]->Range.UsageMax = 0x%04hX\n", cap_idx, pp_cap->Range.UsageMax);
fprintf(file, "pp_data->cap[%u]->Range.StringMin = %hu\n", cap_idx, pp_cap->Range.StringMin);
fprintf(file, "pp_data->cap[%u]->Range.StringMax = %hu\n", cap_idx, pp_cap->Range.StringMax);
fprintf(file, "pp_data->cap[%u]->Range.DesignatorMin = %hu\n", cap_idx, pp_cap->Range.DesignatorMin);
fprintf(file, "pp_data->cap[%u]->Range.DesignatorMax = %hu\n", cap_idx, pp_cap->Range.DesignatorMax);
fprintf(file, "pp_data->cap[%u]->Range.DataIndexMin = %hu\n", cap_idx, pp_cap->Range.DataIndexMin);
fprintf(file, "pp_data->cap[%u]->Range.DataIndexMax = %hu\n", cap_idx, pp_cap->Range.DataIndexMax);
}
else {
fprintf(file, "pp_data->cap[%d]->NotRange.Usage = 0x%04hX\n", cap_idx, pp_cap->NotRange.Usage);
fprintf(file, "pp_data->cap[%d]->NotRange.Reserved1 = 0x%04hX\n", cap_idx, pp_cap->NotRange.Reserved1);
fprintf(file, "pp_data->cap[%d]->NotRange.StringIndex = %hu\n", cap_idx, pp_cap->NotRange.StringIndex);
fprintf(file, "pp_data->cap[%d]->NotRange.Reserved2 = %hu\n", cap_idx, pp_cap->NotRange.Reserved2);
fprintf(file, "pp_data->cap[%d]->NotRange.DesignatorIndex = %hu\n", cap_idx, pp_cap->NotRange.DesignatorIndex);
fprintf(file, "pp_data->cap[%d]->NotRange.Reserved3 = %hu\n", cap_idx, pp_cap->NotRange.Reserved3);
fprintf(file, "pp_data->cap[%d]->NotRange.DataIndex = %hu\n", cap_idx, pp_cap->NotRange.DataIndex);
fprintf(file, "pp_data->cap[%d]->NotRange.Reserved4 = %hu\n", cap_idx, pp_cap->NotRange.Reserved4);
fprintf(file, "pp_data->cap[%u]->NotRange.Usage = 0x%04hX\n", cap_idx, pp_cap->NotRange.Usage);
fprintf(file, "pp_data->cap[%u]->NotRange.Reserved1 = 0x%04hX\n", cap_idx, pp_cap->NotRange.Reserved1);
fprintf(file, "pp_data->cap[%u]->NotRange.StringIndex = %hu\n", cap_idx, pp_cap->NotRange.StringIndex);
fprintf(file, "pp_data->cap[%u]->NotRange.Reserved2 = %hu\n", cap_idx, pp_cap->NotRange.Reserved2);
fprintf(file, "pp_data->cap[%u]->NotRange.DesignatorIndex = %hu\n", cap_idx, pp_cap->NotRange.DesignatorIndex);
fprintf(file, "pp_data->cap[%u]->NotRange.Reserved3 = %hu\n", cap_idx, pp_cap->NotRange.Reserved3);
fprintf(file, "pp_data->cap[%u]->NotRange.DataIndex = %hu\n", cap_idx, pp_cap->NotRange.DataIndex);
fprintf(file, "pp_data->cap[%u]->NotRange.Reserved4 = %hu\n", cap_idx, pp_cap->NotRange.Reserved4);
}
if (pp_cap->IsButtonCap) {
fprintf(file, "pp_data->cap[%d]->Button.LogicalMin = %ld\n", cap_idx, pp_cap->Button.LogicalMin);
fprintf(file, "pp_data->cap[%d]->Button.LogicalMax = %ld\n", cap_idx, pp_cap->Button.LogicalMax);
fprintf(file, "pp_data->cap[%u]->Button.LogicalMin = %ld\n", cap_idx, pp_cap->Button.LogicalMin);
fprintf(file, "pp_data->cap[%u]->Button.LogicalMax = %ld\n", cap_idx, pp_cap->Button.LogicalMax);
}
else
{
fprintf(file, "pp_data->cap[%d]->NotButton.HasNull = %hhu\n", cap_idx, pp_cap->NotButton.HasNull);
fprintf(file, "pp_data->cap[%d]->NotButton.Reserved4 = 0x%02hhX%02hhX%02hhX\n", cap_idx, pp_cap->NotButton.Reserved4[0], pp_cap->NotButton.Reserved4[1], pp_cap->NotButton.Reserved4[2]);
fprintf(file, "pp_data->cap[%d]->NotButton.LogicalMin = %ld\n", cap_idx, pp_cap->NotButton.LogicalMin);
fprintf(file, "pp_data->cap[%d]->NotButton.LogicalMax = %ld\n", cap_idx, pp_cap->NotButton.LogicalMax);
fprintf(file, "pp_data->cap[%d]->NotButton.PhysicalMin = %ld\n", cap_idx, pp_cap->NotButton.PhysicalMin);
fprintf(file, "pp_data->cap[%d]->NotButton.PhysicalMax = %ld\n", cap_idx, pp_cap->NotButton.PhysicalMax);
fprintf(file, "pp_data->cap[%u]->NotButton.HasNull = %hhu\n", cap_idx, pp_cap->NotButton.HasNull);
fprintf(file, "pp_data->cap[%u]->NotButton.Reserved4 = 0x%02hhX%02hhX%02hhX\n", cap_idx, pp_cap->NotButton.Reserved4[0], pp_cap->NotButton.Reserved4[1], pp_cap->NotButton.Reserved4[2]);
fprintf(file, "pp_data->cap[%u]->NotButton.LogicalMin = %ld\n", cap_idx, pp_cap->NotButton.LogicalMin);
fprintf(file, "pp_data->cap[%u]->NotButton.LogicalMax = %ld\n", cap_idx, pp_cap->NotButton.LogicalMax);
fprintf(file, "pp_data->cap[%u]->NotButton.PhysicalMin = %ld\n", cap_idx, pp_cap->NotButton.PhysicalMin);
fprintf(file, "pp_data->cap[%u]->NotButton.PhysicalMax = %ld\n", cap_idx, pp_cap->NotButton.PhysicalMax);
};
fprintf(file, "pp_data->cap[%d]->Units = %lu\n", cap_idx, pp_cap->Units);
fprintf(file, "pp_data->cap[%d]->UnitsExp = %lu\n", cap_idx, pp_cap->UnitsExp);
fprintf(file, "pp_data->cap[%u]->Units = %lu\n", cap_idx, pp_cap->Units);
fprintf(file, "pp_data->cap[%u]->UnitsExp = %lu\n", cap_idx, pp_cap->UnitsExp);
}
void dump_hidp_link_collection_node(FILE* file, phid_pp_link_collection_node pcoll, unsigned int coll_idx) {
fprintf(file, "pp_data->LinkCollectionArray[%d]->LinkUsage = 0x%04hX\n", coll_idx, pcoll->LinkUsage);
fprintf(file, "pp_data->LinkCollectionArray[%d]->LinkUsagePage = 0x%04hX\n", coll_idx, pcoll->LinkUsagePage);
fprintf(file, "pp_data->LinkCollectionArray[%d]->Parent = %hu\n", coll_idx, pcoll->Parent);
fprintf(file, "pp_data->LinkCollectionArray[%d]->NumberOfChildren = %hu\n", coll_idx, pcoll->NumberOfChildren);
fprintf(file, "pp_data->LinkCollectionArray[%d]->NextSibling = %hu\n", coll_idx, pcoll->NextSibling);
fprintf(file, "pp_data->LinkCollectionArray[%d]->FirstChild = %hu\n", coll_idx, pcoll->FirstChild);
fprintf(file, "pp_data->LinkCollectionArray[%d]->CollectionType = %d\n", coll_idx, pcoll->CollectionType);
fprintf(file, "pp_data->LinkCollectionArray[%d]->IsAlias = %d\n", coll_idx, pcoll->IsAlias);
fprintf(file, "pp_data->LinkCollectionArray[%d]->Reserved = 0x%08X\n", coll_idx, pcoll->Reserved);
fprintf(file, "pp_data->LinkCollectionArray[%u]->LinkUsage = 0x%04hX\n", coll_idx, pcoll->LinkUsage);
fprintf(file, "pp_data->LinkCollectionArray[%u]->LinkUsagePage = 0x%04hX\n", coll_idx, pcoll->LinkUsagePage);
fprintf(file, "pp_data->LinkCollectionArray[%u]->Parent = %hu\n", coll_idx, pcoll->Parent);
fprintf(file, "pp_data->LinkCollectionArray[%u]->NumberOfChildren = %hu\n", coll_idx, pcoll->NumberOfChildren);
fprintf(file, "pp_data->LinkCollectionArray[%u]->NextSibling = %hu\n", coll_idx, pcoll->NextSibling);
fprintf(file, "pp_data->LinkCollectionArray[%u]->FirstChild = %hu\n", coll_idx, pcoll->FirstChild);
// The compilers are not consistent on ULONG-bit-fields: They lose the unsinged or define them as int.
// Thus just always cast them to unsinged int, which should be fine, as the biggest bit-field is 28 bit
fprintf(file, "pp_data->LinkCollectionArray[%u]->CollectionType = %u\n", coll_idx, (unsigned int)(pcoll->CollectionType));
fprintf(file, "pp_data->LinkCollectionArray[%u]->IsAlias = %u\n", coll_idx, (unsigned int)(pcoll->IsAlias));
fprintf(file, "pp_data->LinkCollectionArray[%u]->Reserved = 0x%08X\n", coll_idx, (unsigned int)(pcoll->Reserved));
}
int dump_pp_data(FILE* file, hid_device* dev)

View File

@ -1,12 +1,14 @@
#if defined(__MINGW32__)
// Needed for %zu
#define __USE_MINGW_ANSI_STDIO 1
#endif
#include "../hidapi_descriptor_reconstruct.h"
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#if defined(__MINGW32__)
#pragma GCC diagnostic ignored "-Wformat"
#endif
static hidp_preparsed_data * alloc_preparsed_data_from_file(char* filename)
{
FILE* file;
@ -107,25 +109,25 @@ static hidp_preparsed_data * alloc_preparsed_data_from_file(char* filename)
if (sscanf(line, "pp_data->UsagePage = 0x%04hX\n", &pp_data->UsagePage)) continue;
if (sscanf(line, "pp_data->Reserved = 0x%04hX%04hX\n", &pp_data->Reserved[0], &pp_data->Reserved[1])) continue;
if (sscanf(line, "pp_data->caps_info[%d]", &rt_idx) == 1) {
if (sscanf(line, "pp_data->caps_info[%u]", &rt_idx) == 1) {
const size_t caps_info_count = sizeof(pp_data->caps_info) / sizeof(pp_data->caps_info[0]);
if (rt_idx >= caps_info_count) {
fprintf(stderr, "Broken pp_data file, pp_data->caps_info[<idx>] can have at most %zu elements, accessing %ud, (%s)", caps_info_count, rt_idx, line);
continue;
}
if (sscanf(line, "pp_data->caps_info[%d]->FirstCap = %hu\n", &rt_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->caps_info[%u]->FirstCap = %hu\n", &rt_idx, &temp_ushort) == 2) {
pp_data->caps_info[rt_idx].FirstCap = temp_ushort;
continue;
}
if (sscanf(line, "pp_data->caps_info[%d]->LastCap = %hu\n", &rt_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->caps_info[%u]->LastCap = %hu\n", &rt_idx, &temp_ushort) == 2) {
pp_data->caps_info[rt_idx].LastCap = temp_ushort;
continue;
}
if (sscanf(line, "pp_data->caps_info[%d]->NumberOfCaps = %hu\n", &rt_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->caps_info[%u]->NumberOfCaps = %hu\n", &rt_idx, &temp_ushort) == 2) {
pp_data->caps_info[rt_idx].NumberOfCaps = temp_ushort;
continue;
}
if (sscanf(line, "pp_data->caps_info[%d]->ReportByteLength = %hu\n", &rt_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->caps_info[%u]->ReportByteLength = %hu\n", &rt_idx, &temp_ushort) == 2) {
pp_data->caps_info[rt_idx].ReportByteLength = temp_ushort;
continue;
}
@ -140,7 +142,7 @@ static hidp_preparsed_data * alloc_preparsed_data_from_file(char* filename)
continue;
}
if (sscanf(line, "pp_data->cap[%d]", &caps_idx) == 1) {
if (sscanf(line, "pp_data->cap[%u]", &caps_idx) == 1) {
if (pp_data->FirstByteOfLinkCollectionArray == 0) {
fprintf(stderr, "Error reading pp_data file (%s): FirstByteOfLinkCollectionArray is 0 or not reported yet\n", line);
continue;
@ -149,113 +151,113 @@ static hidp_preparsed_data * alloc_preparsed_data_from_file(char* filename)
fprintf(stderr, "Error reading pp_data file (%s): the caps index (%u) is out of pp_data bytes boundary (%hu vs %hu)\n", line, caps_idx, (unsigned short) ((caps_idx + 1) * sizeof(hid_pp_cap)), pp_data->FirstByteOfLinkCollectionArray);
continue;
}
if (sscanf(line, "pp_data->cap[%d]->UsagePage = 0x%04hX\n", &caps_idx, &temp_usage) == 2) {
if (sscanf(line, "pp_data->cap[%u]->UsagePage = 0x%04hX\n", &caps_idx, &temp_usage) == 2) {
pp_data->caps[caps_idx].UsagePage = temp_usage;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->ReportID = 0x%02hhX\n", &caps_idx, &temp_uchar[0]) == 2) {
if (sscanf(line, "pp_data->cap[%u]->ReportID = 0x%02hhX\n", &caps_idx, &temp_uchar[0]) == 2) {
pp_data->caps[caps_idx].ReportID = temp_uchar[0];
continue;
}
if (sscanf(line, "pp_data->cap[%d]->BitPosition = %hhu\n", &caps_idx, &temp_uchar[0]) == 2) {
if (sscanf(line, "pp_data->cap[%u]->BitPosition = %hhu\n", &caps_idx, &temp_uchar[0]) == 2) {
pp_data->caps[caps_idx].BitPosition = temp_uchar[0];
continue;
}
if (sscanf(line, "pp_data->cap[%d]->BitSize = %hu\n", &caps_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->cap[%u]->BitSize = %hu\n", &caps_idx, &temp_ushort) == 2) {
pp_data->caps[caps_idx].ReportSize = temp_ushort;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->ReportCount = %hu\n", &caps_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->cap[%u]->ReportCount = %hu\n", &caps_idx, &temp_ushort) == 2) {
pp_data->caps[caps_idx].ReportCount = temp_ushort;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->BytePosition = 0x%04hX\n", &caps_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->cap[%u]->BytePosition = 0x%04hX\n", &caps_idx, &temp_ushort) == 2) {
pp_data->caps[caps_idx].BytePosition = temp_ushort;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->BitCount = %hu\n", &caps_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->cap[%u]->BitCount = %hu\n", &caps_idx, &temp_ushort) == 2) {
pp_data->caps[caps_idx].BitCount = temp_ushort;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->BitField = 0x%02lX\n", &caps_idx, &temp_ulong) == 2) {
if (sscanf(line, "pp_data->cap[%u]->BitField = 0x%02lX\n", &caps_idx, &temp_ulong) == 2) {
pp_data->caps[caps_idx].BitField = temp_ulong;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->NextBytePosition = 0x%04hX\n", &caps_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->cap[%u]->NextBytePosition = 0x%04hX\n", &caps_idx, &temp_ushort) == 2) {
pp_data->caps[caps_idx].NextBytePosition = temp_ushort;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->LinkCollection = 0x%04hX\n", &caps_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->cap[%u]->LinkCollection = 0x%04hX\n", &caps_idx, &temp_ushort) == 2) {
pp_data->caps[caps_idx].LinkCollection = temp_ushort;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->LinkUsagePage = 0x%04hX\n", &caps_idx, &temp_usage) == 2) {
if (sscanf(line, "pp_data->cap[%u]->LinkUsagePage = 0x%04hX\n", &caps_idx, &temp_usage) == 2) {
pp_data->caps[caps_idx].LinkUsagePage = temp_usage;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->LinkUsage = 0x%04hX\n", &caps_idx, &temp_usage) == 2) {
if (sscanf(line, "pp_data->cap[%u]->LinkUsage = 0x%04hX\n", &caps_idx, &temp_usage) == 2) {
pp_data->caps[caps_idx].LinkUsage = temp_usage;
continue;
}
// 8 Flags in one byte
if (sscanf(line, "pp_data->cap[%d]->IsMultipleItemsForArray = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
if (sscanf(line, "pp_data->cap[%u]->IsMultipleItemsForArray = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
pp_data->caps[caps_idx].IsMultipleItemsForArray = temp_boolean[0];
continue;
}
if (sscanf(line, "pp_data->cap[%d]->IsButtonCap = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
if (sscanf(line, "pp_data->cap[%u]->IsButtonCap = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
pp_data->caps[caps_idx].IsButtonCap = temp_boolean[0];
continue;
}
if (sscanf(line, "pp_data->cap[%d]->IsPadding = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
if (sscanf(line, "pp_data->cap[%u]->IsPadding = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
pp_data->caps[caps_idx].IsPadding = temp_boolean[0];
continue;
}
if (sscanf(line, "pp_data->cap[%d]->IsAbsolute = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
if (sscanf(line, "pp_data->cap[%u]->IsAbsolute = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
pp_data->caps[caps_idx].IsAbsolute = temp_boolean[0];
continue;
}
if (sscanf(line, "pp_data->cap[%d]->IsRange = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
if (sscanf(line, "pp_data->cap[%u]->IsRange = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
pp_data->caps[caps_idx].IsRange = temp_boolean[0];
continue;
}
if (sscanf(line, "pp_data->cap[%d]->IsAlias = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
if (sscanf(line, "pp_data->cap[%u]->IsAlias = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
pp_data->caps[caps_idx].IsAlias = temp_boolean[0];
continue;
}
if (sscanf(line, "pp_data->cap[%d]->IsStringRange = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
if (sscanf(line, "pp_data->cap[%u]->IsStringRange = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
pp_data->caps[caps_idx].IsStringRange = temp_boolean[0];
continue;
}
if (sscanf(line, "pp_data->cap[%d]->IsDesignatorRange = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
if (sscanf(line, "pp_data->cap[%u]->IsDesignatorRange = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
pp_data->caps[caps_idx].IsDesignatorRange = temp_boolean[0];
continue;
}
if (sscanf(line, "pp_data->cap[%d]->Reserved1 = 0x%hhu%hhu%hhu\n", &caps_idx, &temp_uchar[0], &temp_uchar[1], &temp_uchar[2]) == 4) {
if (sscanf(line, "pp_data->cap[%u]->Reserved1 = 0x%hhu%hhu%hhu\n", &caps_idx, &temp_uchar[0], &temp_uchar[1], &temp_uchar[2]) == 4) {
pp_data->caps[caps_idx].Reserved1[0] = temp_uchar[0];
pp_data->caps[caps_idx].Reserved1[1] = temp_uchar[1];
pp_data->caps[caps_idx].Reserved1[2] = temp_uchar[2];
continue;
}
if (sscanf(line, "pp_data->cap[%d]->pp_cap->UnknownTokens[%d]", &caps_idx, &token_idx) == 2) {
if (sscanf(line, "pp_data->cap[%u]->pp_cap->UnknownTokens[%u]", &caps_idx, &token_idx) == 2) {
const size_t unknown_tokens_count = sizeof(pp_data->caps[0].UnknownTokens) / sizeof(pp_data->caps[0].UnknownTokens[0]);
if (token_idx >= unknown_tokens_count) {
fprintf(stderr, "Broken pp_data file, pp_data->caps[<idx>].UnknownTokens[<idx>] can have at most %zu elements, accessing %ud, (%s)", unknown_tokens_count, token_idx, line);
continue;
}
if (sscanf(line, "pp_data->cap[%d]->pp_cap->UnknownTokens[%d].Token = 0x%02hhX\n", &caps_idx, &token_idx, &temp_uchar[0]) == 3) {
if (sscanf(line, "pp_data->cap[%u]->pp_cap->UnknownTokens[%u].Token = 0x%02hhX\n", &caps_idx, &token_idx, &temp_uchar[0]) == 3) {
pp_data->caps[caps_idx].UnknownTokens[token_idx].Token = temp_uchar[0];
continue;
}
if (sscanf(line, "pp_data->cap[%d]->pp_cap->UnknownTokens[%d].Reserved = 0x%02hhX%02hhX%02hhX\n", &caps_idx, &token_idx, &temp_uchar[0], &temp_uchar[1], &temp_uchar[2]) == 5) {
if (sscanf(line, "pp_data->cap[%u]->pp_cap->UnknownTokens[%u].Reserved = 0x%02hhX%02hhX%02hhX\n", &caps_idx, &token_idx, &temp_uchar[0], &temp_uchar[1], &temp_uchar[2]) == 5) {
pp_data->caps[caps_idx].UnknownTokens[token_idx].Reserved[0] = temp_uchar[0];
pp_data->caps[caps_idx].UnknownTokens[token_idx].Reserved[1] = temp_uchar[1];
pp_data->caps[caps_idx].UnknownTokens[token_idx].Reserved[2] = temp_uchar[2];
continue;
}
if (sscanf(line, "pp_data->cap[%d]->pp_cap->UnknownTokens[%d].BitField = 0x%08lX\n", &caps_idx, &token_idx, &temp_ulong) == 3) {
if (sscanf(line, "pp_data->cap[%u]->pp_cap->UnknownTokens[%u].BitField = 0x%08lX\n", &caps_idx, &token_idx, &temp_ulong) == 3) {
pp_data->caps[caps_idx].UnknownTokens[token_idx].BitField = temp_ulong;
continue;
}
@ -264,120 +266,120 @@ static hidp_preparsed_data * alloc_preparsed_data_from_file(char* filename)
}
// Range
if (sscanf(line, "pp_data->cap[%d]->Range.UsageMin = 0x%04hX\n", &caps_idx, &temp_usage) == 2) {
if (sscanf(line, "pp_data->cap[%u]->Range.UsageMin = 0x%04hX\n", &caps_idx, &temp_usage) == 2) {
pp_data->caps[caps_idx].Range.UsageMin = temp_usage;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->Range.UsageMax = 0x%04hX\n", &caps_idx, &temp_usage) == 2) {
if (sscanf(line, "pp_data->cap[%u]->Range.UsageMax = 0x%04hX\n", &caps_idx, &temp_usage) == 2) {
pp_data->caps[caps_idx].Range.UsageMax = temp_usage;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->Range.StringMin = %hu\n", &caps_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->cap[%u]->Range.StringMin = %hu\n", &caps_idx, &temp_ushort) == 2) {
pp_data->caps[caps_idx].Range.StringMin = temp_ushort;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->Range.StringMax = %hu\n", &caps_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->cap[%u]->Range.StringMax = %hu\n", &caps_idx, &temp_ushort) == 2) {
pp_data->caps[caps_idx].Range.StringMax = temp_ushort;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->Range.DesignatorMin = %hu\n", &caps_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->cap[%u]->Range.DesignatorMin = %hu\n", &caps_idx, &temp_ushort) == 2) {
pp_data->caps[caps_idx].Range.DesignatorMin = temp_ushort;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->Range.DesignatorMax = %hu\n", &caps_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->cap[%u]->Range.DesignatorMax = %hu\n", &caps_idx, &temp_ushort) == 2) {
pp_data->caps[caps_idx].Range.DesignatorMax = temp_ushort;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->Range.DataIndexMin = %hu\n", &caps_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->cap[%u]->Range.DataIndexMin = %hu\n", &caps_idx, &temp_ushort) == 2) {
pp_data->caps[caps_idx].Range.DataIndexMin = temp_ushort;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->Range.DataIndexMax = %hu\n", &caps_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->cap[%u]->Range.DataIndexMax = %hu\n", &caps_idx, &temp_ushort) == 2) {
pp_data->caps[caps_idx].Range.DataIndexMax = temp_ushort;
continue;
}
// NotRange
if (sscanf(line, "pp_data->cap[%d]->NotRange.Usage = 0x%04hX\n", &caps_idx, &temp_usage) == 2) {
if (sscanf(line, "pp_data->cap[%u]->NotRange.Usage = 0x%04hX\n", &caps_idx, &temp_usage) == 2) {
pp_data->caps[caps_idx].NotRange.Usage = temp_usage;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->NotRange.Reserved1 = 0x%04hX\n", &caps_idx, &temp_usage) == 2) {
if (sscanf(line, "pp_data->cap[%u]->NotRange.Reserved1 = 0x%04hX\n", &caps_idx, &temp_usage) == 2) {
pp_data->caps[caps_idx].NotRange.Reserved1 = temp_usage;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->NotRange.StringIndex = %hu\n", &caps_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->cap[%u]->NotRange.StringIndex = %hu\n", &caps_idx, &temp_ushort) == 2) {
pp_data->caps[caps_idx].NotRange.StringIndex = temp_ushort;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->NotRange.Reserved2 = %hu\n", &caps_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->cap[%u]->NotRange.Reserved2 = %hu\n", &caps_idx, &temp_ushort) == 2) {
pp_data->caps[caps_idx].NotRange.Reserved2 = temp_ushort;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->NotRange.DesignatorIndex = %hu\n", &caps_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->cap[%u]->NotRange.DesignatorIndex = %hu\n", &caps_idx, &temp_ushort) == 2) {
pp_data->caps[caps_idx].NotRange.DesignatorIndex = temp_ushort;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->NotRange.Reserved3 = %hu\n", &caps_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->cap[%u]->NotRange.Reserved3 = %hu\n", &caps_idx, &temp_ushort) == 2) {
pp_data->caps[caps_idx].NotRange.Reserved3 = temp_ushort;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->NotRange.DataIndex = %hu\n", &caps_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->cap[%u]->NotRange.DataIndex = %hu\n", &caps_idx, &temp_ushort) == 2) {
pp_data->caps[caps_idx].NotRange.DataIndex = temp_ushort;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->NotRange.Reserved4 = %hu\n", &caps_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->cap[%u]->NotRange.Reserved4 = %hu\n", &caps_idx, &temp_ushort) == 2) {
pp_data->caps[caps_idx].NotRange.Reserved4 = temp_ushort;
continue;
}
// Button
if (sscanf(line, "pp_data->cap[%d]->Button.LogicalMin = %ld\n", &caps_idx, &temp_long) == 2) {
if (sscanf(line, "pp_data->cap[%u]->Button.LogicalMin = %ld\n", &caps_idx, &temp_long) == 2) {
pp_data->caps[caps_idx].Button.LogicalMin = temp_long;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->Button.LogicalMax = %ld\n", &caps_idx, &temp_long) == 2) {
if (sscanf(line, "pp_data->cap[%u]->Button.LogicalMax = %ld\n", &caps_idx, &temp_long) == 2) {
pp_data->caps[caps_idx].Button.LogicalMax = temp_long;
continue;
}
// NotButton
if (sscanf(line, "pp_data->cap[%d]->NotButton.HasNull = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
if (sscanf(line, "pp_data->cap[%u]->NotButton.HasNull = %hhu\n", &caps_idx, &temp_boolean[0]) == 2) {
pp_data->caps[caps_idx].NotButton.HasNull = temp_boolean[0];
continue;
}
if (sscanf(line, "pp_data->cap[%d]->NotButton.Reserved4 = 0x%02hhX%02hhX%02hhX\n", &caps_idx, &temp_uchar[0], &temp_uchar[1], &temp_uchar[2]) == 4) {
if (sscanf(line, "pp_data->cap[%u]->NotButton.Reserved4 = 0x%02hhX%02hhX%02hhX\n", &caps_idx, &temp_uchar[0], &temp_uchar[1], &temp_uchar[2]) == 4) {
pp_data->caps[caps_idx].NotButton.Reserved4[0] = temp_uchar[0];
pp_data->caps[caps_idx].NotButton.Reserved4[1] = temp_uchar[1];
pp_data->caps[caps_idx].NotButton.Reserved4[2] = temp_uchar[2];
continue;
}
if (sscanf(line, "pp_data->cap[%d]->NotButton.LogicalMin = %ld\n", &caps_idx, &temp_long) == 2) {
if (sscanf(line, "pp_data->cap[%u]->NotButton.LogicalMin = %ld\n", &caps_idx, &temp_long) == 2) {
pp_data->caps[caps_idx].NotButton.LogicalMin = temp_long;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->NotButton.LogicalMax = %ld\n", &caps_idx, &temp_long) == 2) {
if (sscanf(line, "pp_data->cap[%u]->NotButton.LogicalMax = %ld\n", &caps_idx, &temp_long) == 2) {
pp_data->caps[caps_idx].NotButton.LogicalMax = temp_long;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->NotButton.PhysicalMin = %ld\n", &caps_idx, &temp_long) == 2) {
if (sscanf(line, "pp_data->cap[%u]->NotButton.PhysicalMin = %ld\n", &caps_idx, &temp_long) == 2) {
pp_data->caps[caps_idx].NotButton.PhysicalMin = temp_long;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->NotButton.PhysicalMax = %ld\n", &caps_idx, &temp_long) == 2) {
if (sscanf(line, "pp_data->cap[%u]->NotButton.PhysicalMax = %ld\n", &caps_idx, &temp_long) == 2) {
pp_data->caps[caps_idx].NotButton.PhysicalMax = temp_long;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->Units = %lu\n", &caps_idx, &temp_ulong) == 2) {
if (sscanf(line, "pp_data->cap[%u]->Units = %lu\n", &caps_idx, &temp_ulong) == 2) {
pp_data->caps[caps_idx].Units = temp_ulong;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->UnitsExp = %lu\n", &caps_idx, &temp_ulong) == 2) {
if (sscanf(line, "pp_data->cap[%u]->UnitsExp = %lu\n", &caps_idx, &temp_ulong) == 2) {
pp_data->caps[caps_idx].UnitsExp = temp_ulong;
continue;
}
if (sscanf(line, "pp_data->cap[%d]->Reserved1 = 0x%02hhu%02hhu%02hhu\n", &coll_idx, &temp_uchar[0], &temp_uchar[1], &temp_uchar[2]) == 4) {
if (sscanf(line, "pp_data->cap[%u]->Reserved1 = 0x%02hhu%02hhu%02hhu\n", &coll_idx, &temp_uchar[0], &temp_uchar[1], &temp_uchar[2]) == 4) {
pp_data->caps[caps_idx].Reserved1[0] = temp_uchar[0];
pp_data->caps[caps_idx].Reserved1[1] = temp_uchar[1];
pp_data->caps[caps_idx].Reserved1[2] = temp_uchar[2];
@ -387,7 +389,7 @@ static hidp_preparsed_data * alloc_preparsed_data_from_file(char* filename)
continue;
}
if (sscanf(line, "pp_data->LinkCollectionArray[%d]", &coll_idx) == 1) {
if (sscanf(line, "pp_data->LinkCollectionArray[%u]", &coll_idx) == 1) {
if (pp_data->FirstByteOfLinkCollectionArray == 0 || pp_data->NumberLinkCollectionNodes == 0) {
fprintf(stderr, "Error reading pp_data file (%s): FirstByteOfLinkCollectionArray or NumberLinkCollectionNodes is 0 or not reported yet\n", line);
continue;
@ -397,39 +399,39 @@ static hidp_preparsed_data * alloc_preparsed_data_from_file(char* filename)
continue;
}
phid_pp_link_collection_node pcoll = (phid_pp_link_collection_node)(((unsigned char*)&pp_data->caps[0]) + pp_data->FirstByteOfLinkCollectionArray);
if (sscanf(line, "pp_data->LinkCollectionArray[%d]->LinkUsage = 0x%04hX\n", &coll_idx, &temp_usage) == 2) {
if (sscanf(line, "pp_data->LinkCollectionArray[%u]->LinkUsage = 0x%04hX\n", &coll_idx, &temp_usage) == 2) {
pcoll[coll_idx].LinkUsage = temp_usage;
continue;
}
if (sscanf(line, "pp_data->LinkCollectionArray[%d]->LinkUsagePage = 0x%04hX\n", &coll_idx, &temp_usage) == 2) {
if (sscanf(line, "pp_data->LinkCollectionArray[%u]->LinkUsagePage = 0x%04hX\n", &coll_idx, &temp_usage) == 2) {
pcoll[coll_idx].LinkUsagePage = temp_usage;
continue;
}
if (sscanf(line, "pp_data->LinkCollectionArray[%d]->Parent = %hu\n", &coll_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->LinkCollectionArray[%u]->Parent = %hu\n", &coll_idx, &temp_ushort) == 2) {
pcoll[coll_idx].Parent = temp_ushort;
continue;
}
if (sscanf(line, "pp_data->LinkCollectionArray[%d]->NumberOfChildren = %hu\n", &coll_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->LinkCollectionArray[%u]->NumberOfChildren = %hu\n", &coll_idx, &temp_ushort) == 2) {
pcoll[coll_idx].NumberOfChildren = temp_ushort;
continue;
}
if (sscanf(line, "pp_data->LinkCollectionArray[%d]->NextSibling = %hu\n", &coll_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->LinkCollectionArray[%u]->NextSibling = %hu\n", &coll_idx, &temp_ushort) == 2) {
pcoll[coll_idx].NextSibling = temp_ushort;
continue;
}
if (sscanf(line, "pp_data->LinkCollectionArray[%d]->FirstChild = %hu\n", &coll_idx, &temp_ushort) == 2) {
if (sscanf(line, "pp_data->LinkCollectionArray[%u]->FirstChild = %hu\n", &coll_idx, &temp_ushort) == 2) {
pcoll[coll_idx].FirstChild = temp_ushort;
continue;
}
if (sscanf(line, "pp_data->LinkCollectionArray[%d]->CollectionType = %ld\n", &coll_idx, &temp_ulong) == 2) {
if (sscanf(line, "pp_data->LinkCollectionArray[%u]->CollectionType = %lu\n", &coll_idx, &temp_ulong) == 2) {
pcoll[coll_idx].CollectionType = temp_ulong;
continue;
}
if (sscanf(line, "pp_data->LinkCollectionArray[%d]->IsAlias = %ld\n", &coll_idx, &temp_ulong) == 2) {
if (sscanf(line, "pp_data->LinkCollectionArray[%u]->IsAlias = %lu\n", &coll_idx, &temp_ulong) == 2) {
pcoll[coll_idx].IsAlias = temp_ulong;
continue;
}
if (sscanf(line, "pp_data->LinkCollectionArray[%d]->Reserved = %ld\n", &coll_idx, &temp_ulong) == 2) {
if (sscanf(line, "pp_data->LinkCollectionArray[%u]->Reserved = %lu\n", &coll_idx, &temp_ulong) == 2) {
pcoll[coll_idx].Reserved = temp_ulong;
continue;
}