mirror of
https://github.com/RPCS3/hidapi.git
synced 2026-07-18 10:34:30 -04:00
RFC: add hid_get_report_descriptor API function (#451)
- native implementations for hidraw/libusb/macOS; - HID Report Descriptor reconstruction from HIDP_PREPARSED_DATA on Windows; - unit-tests for some known devices for `hid_winapi_descriptor_reconstruct_pp_data`; - support for ASAN builds (mainly to check the `hid_winapi_descriptor_reconstruct_pp_data`/its unit-tests;
This commit is contained in:
@@ -42,9 +42,9 @@ jobs:
|
||||
- name: Configure CMake
|
||||
run: |
|
||||
rm -rf build install
|
||||
cmake -B build/shared -S hidapisrc -DCMAKE_INSTALL_PREFIX=install/shared -DHIDAPI_BUILD_HIDTEST=ON "-DCMAKE_C_FLAGS=${NIX_COMPILE_FLAGS}"
|
||||
cmake -B build/static -S hidapisrc -DCMAKE_INSTALL_PREFIX=install/static -DBUILD_SHARED_LIBS=FALSE -DHIDAPI_BUILD_HIDTEST=ON "-DCMAKE_C_FLAGS=${NIX_COMPILE_FLAGS}"
|
||||
cmake -B build/framework -S hidapisrc -DCMAKE_INSTALL_PREFIX=install/framework -DCMAKE_FRAMEWORK=ON -DHIDAPI_BUILD_HIDTEST=ON "-DCMAKE_C_FLAGS=${NIX_COMPILE_FLAGS}"
|
||||
cmake -B build/shared -S hidapisrc -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHIDAPI_ENABLE_ASAN=ON -DCMAKE_INSTALL_PREFIX=install/shared -DHIDAPI_BUILD_HIDTEST=ON "-DCMAKE_C_FLAGS=${NIX_COMPILE_FLAGS}"
|
||||
cmake -B build/static -S hidapisrc -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHIDAPI_ENABLE_ASAN=ON -DCMAKE_INSTALL_PREFIX=install/static -DBUILD_SHARED_LIBS=FALSE -DHIDAPI_BUILD_HIDTEST=ON "-DCMAKE_C_FLAGS=${NIX_COMPILE_FLAGS}"
|
||||
cmake -B build/framework -S hidapisrc -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHIDAPI_ENABLE_ASAN=ON -DCMAKE_INSTALL_PREFIX=install/framework -DCMAKE_FRAMEWORK=ON -DHIDAPI_BUILD_HIDTEST=ON "-DCMAKE_C_FLAGS=${NIX_COMPILE_FLAGS}"
|
||||
- name: Build CMake Shared
|
||||
working-directory: build/shared
|
||||
run: make install
|
||||
@@ -110,8 +110,8 @@ jobs:
|
||||
- name: Configure CMake
|
||||
run: |
|
||||
rm -rf build install
|
||||
cmake -B build/shared -S hidapisrc -DCMAKE_INSTALL_PREFIX=install/shared -DHIDAPI_BUILD_HIDTEST=ON "-DCMAKE_C_FLAGS=${NIX_COMPILE_FLAGS}"
|
||||
cmake -B build/static -S hidapisrc -DCMAKE_INSTALL_PREFIX=install/static -DBUILD_SHARED_LIBS=FALSE -DHIDAPI_BUILD_HIDTEST=ON "-DCMAKE_C_FLAGS=${NIX_COMPILE_FLAGS}"
|
||||
cmake -B build/shared -S hidapisrc -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHIDAPI_ENABLE_ASAN=ON -DCMAKE_INSTALL_PREFIX=install/shared -DHIDAPI_BUILD_HIDTEST=ON "-DCMAKE_C_FLAGS=${NIX_COMPILE_FLAGS}"
|
||||
cmake -B build/static -S hidapisrc -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHIDAPI_ENABLE_ASAN=ON -DCMAKE_INSTALL_PREFIX=install/static -DBUILD_SHARED_LIBS=FALSE -DHIDAPI_BUILD_HIDTEST=ON "-DCMAKE_C_FLAGS=${NIX_COMPILE_FLAGS}"
|
||||
- name: Build CMake Shared
|
||||
working-directory: build/shared
|
||||
run: make install
|
||||
@@ -173,10 +173,10 @@ jobs:
|
||||
- name: Configure CMake MSVC
|
||||
shell: cmd
|
||||
run: |
|
||||
cmake -B build\msvc -S hidapisrc -DCMAKE_INSTALL_PREFIX=install\msvc -DHIDAPI_BUILD_HIDTEST=ON "-DCMAKE_C_FLAGS=%MSVC_COMPILE_FLAGS%"
|
||||
cmake -B build\msvc -S hidapisrc -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHIDAPI_WITH_TESTS=ON -DHIDAPI_BUILD_PP_DATA_DUMP=ON -DHIDAPI_ENABLE_ASAN=ON -DCMAKE_INSTALL_PREFIX=install\msvc -DHIDAPI_BUILD_HIDTEST=ON "-DCMAKE_C_FLAGS=%MSVC_COMPILE_FLAGS%"
|
||||
- name: Build CMake MSVC
|
||||
working-directory: build/msvc
|
||||
run: cmake --build . --target install
|
||||
run: cmake --build . --config RelWithDebInfo --target install
|
||||
- name: Check artifacts MSVC
|
||||
uses: andstor/file-existence-action@v2
|
||||
with:
|
||||
@@ -196,12 +196,16 @@ jobs:
|
||||
"-DCMAKE_C_FLAGS=%MSVC_COMPILE_FLAGS%"
|
||||
cd build\msvc_test
|
||||
cmake --build . --target install
|
||||
- name: Run CTest MSVC
|
||||
shell: cmd
|
||||
working-directory: build/msvc
|
||||
run: ctest -C RelWithDebInfo --rerun-failed --output-on-failure
|
||||
|
||||
- name: Configure CMake NMake
|
||||
shell: cmd
|
||||
run: |
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
||||
cmake -G"NMake Makefiles" -B build\nmake -S hidapisrc -DCMAKE_INSTALL_PREFIX=install\nmake -DHIDAPI_BUILD_HIDTEST=ON "-DCMAKE_C_FLAGS=%MSVC_COMPILE_FLAGS%"
|
||||
cmake -G"NMake Makefiles" -B build\nmake -S hidapisrc -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHIDAPI_WITH_TESTS=ON -DHIDAPI_BUILD_PP_DATA_DUMP=ON -DHIDAPI_ENABLE_ASAN=ON -DCMAKE_INSTALL_PREFIX=install\nmake -DHIDAPI_BUILD_HIDTEST=ON "-DCMAKE_C_FLAGS=%MSVC_COMPILE_FLAGS%"
|
||||
- name: Build CMake NMake
|
||||
working-directory: build\nmake
|
||||
shell: cmd
|
||||
@@ -229,11 +233,14 @@ jobs:
|
||||
"-DCMAKE_C_FLAGS=%MSVC_COMPILE_FLAGS%"
|
||||
cd build\nmake_test
|
||||
nmake install
|
||||
- name: Run CTest NMake
|
||||
working-directory: build\nmake
|
||||
run: ctest --rerun-failed --output-on-failure
|
||||
|
||||
- name: Configure CMake MinGW
|
||||
shell: cmd
|
||||
run: |
|
||||
cmake -G"MinGW Makefiles" -B build\mingw -S hidapisrc -DCMAKE_INSTALL_PREFIX=install\mingw -DHIDAPI_BUILD_HIDTEST=ON "-DCMAKE_C_FLAGS=%NIX_COMPILE_FLAGS%"
|
||||
cmake -G"MinGW Makefiles" -B build\mingw -S hidapisrc -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHIDAPI_WITH_TESTS=ON -DHIDAPI_BUILD_PP_DATA_DUMP=ON -DCMAKE_INSTALL_PREFIX=install\mingw -DHIDAPI_BUILD_HIDTEST=ON "-DCMAKE_C_FLAGS=%NIX_COMPILE_FLAGS%"
|
||||
- name: Build CMake MinGW
|
||||
working-directory: build\mingw
|
||||
run: cmake --build . --target install
|
||||
@@ -257,6 +264,9 @@ jobs:
|
||||
"-DCMAKE_C_FLAGS=%NIX_COMPILE_FLAGS%"
|
||||
cd build\mingw_test
|
||||
cmake --build . --target install
|
||||
- name: Run CTest MinGW
|
||||
working-directory: build\mingw
|
||||
run: ctest --rerun-failed --output-on-failure
|
||||
|
||||
- name: Check Meson build
|
||||
shell: cmd
|
||||
|
||||
@@ -88,6 +88,8 @@ Some of the [standard](https://cmake.org/cmake/help/latest/manual/cmake-variable
|
||||
HIDAPI-specific CMake variables:
|
||||
|
||||
- `HIDAPI_BUILD_HIDTEST` - when set to TRUE, build a small test application `hidtest`;
|
||||
- `HIDAPI_WITH_TESTS` - when set to TRUE, build all (unit-)tests;
|
||||
currently this option is only available on Windows, since only Windows backend has tests;
|
||||
|
||||
<details>
|
||||
<summary>Linux-specific variables</summary>
|
||||
|
||||
+49
-5
@@ -49,13 +49,57 @@ option(BUILD_SHARED_LIBS "Build shared version of the libraries, otherwise build
|
||||
set(HIDAPI_INSTALL_TARGETS ON)
|
||||
set(HIDAPI_PRINT_VERSION ON)
|
||||
|
||||
set(IS_DEBUG_BUILD OFF)
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(IS_DEBUG_BUILD ON)
|
||||
endif()
|
||||
|
||||
option(HIDAPI_ENABLE_ASAN "Build HIDAPI with ASAN address sanitizer instrumentation" OFF)
|
||||
|
||||
if(HIDAPI_ENABLE_ASAN)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
|
||||
if(MSVC)
|
||||
# the default is to have "/INCREMENTAL" which causes a warning when "-fsanitize=address" is present
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /INCREMENTAL:NO")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /INCREMENTAL:NO")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /INCREMENTAL:NO")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} /INCREMENTAL:NO")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
# so far only Windows has tests
|
||||
option(HIDAPI_WITH_TESTS "Build HIDAPI (unit-)tests" ${IS_DEBUG_BUILD})
|
||||
else()
|
||||
set(HIDAPI_WITH_TESTS OFF)
|
||||
endif()
|
||||
|
||||
if(HIDAPI_WITH_TESTS)
|
||||
enable_testing()
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
option(HIDAPI_BUILD_PP_DATA_DUMP "Build small Windows console application pp_data_dump.exe" ${IS_DEBUG_BUILD})
|
||||
endif()
|
||||
|
||||
add_subdirectory(src)
|
||||
|
||||
set(BUILD_HIDTEST_DEFAULT OFF)
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(BUILD_HIDTEST_DEFAULT ON)
|
||||
endif()
|
||||
option(HIDAPI_BUILD_HIDTEST "Build small console test application hidtest" ${BUILD_HIDTEST_DEFAULT})
|
||||
option(HIDAPI_BUILD_HIDTEST "Build small console test application hidtest" ${IS_DEBUG_BUILD})
|
||||
if(HIDAPI_BUILD_HIDTEST)
|
||||
add_subdirectory(hidtest)
|
||||
endif()
|
||||
|
||||
if(HIDAPI_ENABLE_ASAN)
|
||||
if(NOT MSVC)
|
||||
# MSVC doesn't recognize those options, other compilers - requiring it
|
||||
foreach(HIDAPI_TARGET hidapi_winapi hidapi_darwin hidapi_hidraw hidapi_libusb hidtest_hidraw hidtest_libusb hidtest)
|
||||
if(TARGET ${HIDAPI_TARGET})
|
||||
if(BUILD_SHARED_LIBS)
|
||||
target_link_options(${HIDAPI_TARGET} PRIVATE -fsanitize=address)
|
||||
else()
|
||||
target_link_options(${HIDAPI_TARGET} PUBLIC -fsanitize=address)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -550,6 +550,21 @@ extern "C" {
|
||||
*/
|
||||
int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen);
|
||||
|
||||
/** @brief Get a report descriptor from a HID device.
|
||||
|
||||
User has to provide a preallocated buffer where descriptor will be copied to.
|
||||
The recommended size for preallocated buffer is @ref HID_API_MAX_REPORT_DESCRIPTOR_SIZE bytes.
|
||||
|
||||
@ingroup API
|
||||
@param dev A device handle returned from hid_open().
|
||||
@param buf The buffer to copy descriptor into.
|
||||
@param buf_size The size of the buffer in bytes.
|
||||
|
||||
@returns
|
||||
This function returns non-negative number of bytes actually copied, or -1 on error.
|
||||
*/
|
||||
int HID_API_EXPORT_CALL hid_get_report_descriptor(hid_device *dev, unsigned char *buf, size_t buf_size);
|
||||
|
||||
/** @brief Get a string describing the last error which occurred.
|
||||
|
||||
This function is intended for logging/debugging purposes.
|
||||
|
||||
+44
-5
@@ -64,10 +64,48 @@ void print_device(struct hid_device_info *cur_dev) {
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void print_hid_report_descriptor_from_device(hid_device *device) {
|
||||
unsigned char descriptor[HID_API_MAX_REPORT_DESCRIPTOR_SIZE];
|
||||
int res = 0;
|
||||
|
||||
printf(" Report Descriptor: ");
|
||||
res = hid_get_report_descriptor(device, descriptor, sizeof(descriptor));
|
||||
if (res < 0) {
|
||||
printf("error getting: %ls", hid_error(device));
|
||||
}
|
||||
else {
|
||||
printf("(%d bytes)", res);
|
||||
}
|
||||
for (int i = 0; i < res; i++) {
|
||||
if (i % 10 == 0) {
|
||||
printf("\n");
|
||||
}
|
||||
printf("0x%02x, ", descriptor[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void print_hid_report_descriptor_from_path(const char *path) {
|
||||
hid_device *device = hid_open_path(path);
|
||||
if (device) {
|
||||
print_hid_report_descriptor_from_device(device);
|
||||
hid_close(device);
|
||||
}
|
||||
else {
|
||||
printf(" Report Descriptor: Unable to open device by path\n");
|
||||
}
|
||||
}
|
||||
|
||||
void print_devices(struct hid_device_info *cur_dev) {
|
||||
while (cur_dev) {
|
||||
for (; cur_dev; cur_dev = cur_dev->next) {
|
||||
print_device(cur_dev);
|
||||
cur_dev = cur_dev->next;
|
||||
}
|
||||
}
|
||||
|
||||
void print_devices_with_descriptor(struct hid_device_info *cur_dev) {
|
||||
for (; cur_dev; cur_dev = cur_dev->next) {
|
||||
print_device(cur_dev);
|
||||
print_hid_report_descriptor_from_path(cur_dev->path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +141,7 @@ int main(int argc, char* argv[])
|
||||
#endif
|
||||
|
||||
devs = hid_enumerate(0x0, 0x0);
|
||||
print_devices(devs);
|
||||
print_devices_with_descriptor(devs);
|
||||
hid_free_enumeration(devs);
|
||||
|
||||
// Set up the command buffer.
|
||||
@@ -141,8 +179,9 @@ int main(int argc, char* argv[])
|
||||
res = hid_get_serial_number_string(handle, wstr, MAX_STR);
|
||||
if (res < 0)
|
||||
printf("Unable to read serial number string\n");
|
||||
printf("Serial Number String: (%d) %ls", wstr[0], wstr);
|
||||
printf("\n");
|
||||
printf("Serial Number String: (%d) %ls\n", wstr[0], wstr);
|
||||
|
||||
print_hid_report_descriptor_from_device(handle);
|
||||
|
||||
struct hid_device_info* info = hid_get_device_info(handle);
|
||||
if (info == NULL) {
|
||||
|
||||
@@ -1631,6 +1631,12 @@ int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index
|
||||
}
|
||||
|
||||
|
||||
int HID_API_EXPORT_CALL hid_get_report_descriptor(hid_device *dev, unsigned char *buf, size_t buf_size)
|
||||
{
|
||||
return hid_get_report_descriptor_libusb(dev->device_handle, dev->interface, dev->report_descriptor_size, buf, buf_size);
|
||||
}
|
||||
|
||||
|
||||
HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
|
||||
{
|
||||
(void)dev;
|
||||
|
||||
+41
@@ -481,6 +481,28 @@ static int parse_hid_vid_pid_from_sysfs(const char *sysfs_path, unsigned *bus_ty
|
||||
return res;
|
||||
}
|
||||
|
||||
static int get_hid_report_descriptor_from_hidraw(hid_device *dev, struct hidraw_report_descriptor *rpt_desc)
|
||||
{
|
||||
int desc_size = 0;
|
||||
|
||||
/* Get Report Descriptor Size */
|
||||
int res = ioctl(dev->device_handle, HIDIOCGRDESCSIZE, &desc_size);
|
||||
if (res < 0) {
|
||||
register_device_error_format(dev, "ioctl(GRDESCSIZE): %s", strerror(errno));
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Get Report Descriptor */
|
||||
memset(rpt_desc, 0x0, sizeof(*rpt_desc));
|
||||
rpt_desc->size = desc_size;
|
||||
res = ioctl(dev->device_handle, HIDIOCGRDESC, rpt_desc);
|
||||
if (res < 0) {
|
||||
register_device_error_format(dev, "ioctl(GRDESC): %s", strerror(errno));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* The caller is responsible for free()ing the (newly-allocated) character
|
||||
* strings pointed to by serial_number_utf8 and product_name_utf8 after use.
|
||||
@@ -1236,6 +1258,25 @@ int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index
|
||||
}
|
||||
|
||||
|
||||
int HID_API_EXPORT_CALL hid_get_report_descriptor(hid_device *dev, unsigned char *buf, size_t buf_size)
|
||||
{
|
||||
struct hidraw_report_descriptor rpt_desc;
|
||||
int res = get_hid_report_descriptor_from_hidraw(dev, &rpt_desc);
|
||||
if (res < 0) {
|
||||
/* error already registered */
|
||||
return res;
|
||||
}
|
||||
|
||||
if (rpt_desc.size < buf_size) {
|
||||
buf_size = (size_t) rpt_desc.size;
|
||||
}
|
||||
|
||||
memcpy(buf, rpt_desc.value, buf_size);
|
||||
|
||||
return (int) buf_size;
|
||||
}
|
||||
|
||||
|
||||
/* Passing in NULL means asking for the last global error message. */
|
||||
HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
|
||||
{
|
||||
|
||||
@@ -1431,6 +1431,33 @@ int HID_API_EXPORT_CALL hid_darwin_is_device_open_exclusive(hid_device *dev)
|
||||
return (dev->open_options == kIOHIDOptionsTypeSeizeDevice) ? 1 : 0;
|
||||
}
|
||||
|
||||
int HID_API_EXPORT_CALL hid_get_report_descriptor(hid_device *dev, unsigned char *buf, size_t buf_size)
|
||||
{
|
||||
CFTypeRef ref = IOHIDDeviceGetProperty(dev->device_handle, CFSTR(kIOHIDReportDescriptorKey));
|
||||
if (ref != NULL && CFGetTypeID(ref) == CFDataGetTypeID()) {
|
||||
CFDataRef report_descriptor = (CFDataRef) ref;
|
||||
const UInt8 *descriptor_buf = CFDataGetBytePtr(report_descriptor);
|
||||
CFIndex descriptor_buf_len = CFDataGetLength(report_descriptor);
|
||||
size_t copy_len = (size_t) descriptor_buf_len;
|
||||
|
||||
if (descriptor_buf == NULL || descriptor_buf_len < 0) {
|
||||
register_device_error(dev, "Zero buffer/length");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buf_size < copy_len) {
|
||||
copy_len = buf_size;
|
||||
}
|
||||
|
||||
memcpy(buf, descriptor_buf, copy_len);
|
||||
return copy_len;
|
||||
}
|
||||
else {
|
||||
register_device_error(dev, "Failed to get kIOHIDReportDescriptorKey property");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
|
||||
{
|
||||
if (dev) {
|
||||
|
||||
@@ -26,6 +26,9 @@ project(hidapi VERSION "${VERSION}" LANGUAGES C)
|
||||
|
||||
# Defaults and required options
|
||||
|
||||
if(NOT DEFINED HIDAPI_WITH_TESTS)
|
||||
set(HIDAPI_WITH_TESTS OFF)
|
||||
endif()
|
||||
if(NOT DEFINED BUILD_SHARED_LIBS)
|
||||
set(BUILD_SHARED_LIBS ON)
|
||||
endif()
|
||||
|
||||
@@ -3,6 +3,8 @@ list(APPEND HIDAPI_PUBLIC_HEADERS "hidapi_winapi.h")
|
||||
set(SOURCES
|
||||
hid.c
|
||||
hidapi_cfgmgr32.h
|
||||
hidapi_descriptor_reconstruct.c
|
||||
hidapi_descriptor_reconstruct.h
|
||||
hidapi_hidclass.h
|
||||
hidapi_hidpi.h
|
||||
hidapi_hidsdi.h
|
||||
@@ -51,3 +53,11 @@ if(HIDAPI_INSTALL_TARGETS)
|
||||
endif()
|
||||
|
||||
hidapi_configure_pc("${PROJECT_ROOT}/pc/hidapi.pc.in")
|
||||
|
||||
if(HIDAPI_WITH_TESTS)
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
|
||||
if(DEFINED HIDAPI_BUILD_PP_DATA_DUMP AND HIDAPI_BUILD_PP_DATA_DUMP)
|
||||
add_subdirectory(pp_data_dump)
|
||||
endif()
|
||||
|
||||
+21
-1
@@ -30,7 +30,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "hidapi.h"
|
||||
#include "hidapi_winapi.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
@@ -1307,6 +1307,22 @@ end:
|
||||
}
|
||||
|
||||
|
||||
int HID_API_EXPORT_CALL hid_get_report_descriptor(hid_device *dev, unsigned char *buf, size_t buf_size)
|
||||
{
|
||||
PHIDP_PREPARSED_DATA pp_data = NULL;
|
||||
|
||||
if (!HidD_GetPreparsedData(dev->device_handle, &pp_data) || pp_data == NULL) {
|
||||
register_string_error(dev, L"HidD_GetPreparsedData");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int res = hid_winapi_descriptor_reconstruct_pp_data(pp_data, buf, buf_size);
|
||||
|
||||
HidD_FreePreparsedData(pp_data);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
|
||||
{
|
||||
if (dev) {
|
||||
@@ -1320,6 +1336,10 @@ HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
|
||||
return last_global_error_str;
|
||||
}
|
||||
|
||||
#ifndef hidapi_winapi_EXPORTS
|
||||
#include "hidapi_descriptor_reconstruct.c"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,988 @@
|
||||
/*******************************************************
|
||||
HIDAPI - Multi-Platform library for
|
||||
communication with HID devices.
|
||||
|
||||
libusb/hidapi Team
|
||||
|
||||
Copyright 2022, All Rights Reserved.
|
||||
|
||||
At the discretion of the user of this library,
|
||||
this software may be licensed under the terms of the
|
||||
GNU General Public License v3, a BSD-Style license, or the
|
||||
original HIDAPI license as outlined in the LICENSE.txt,
|
||||
LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
|
||||
files located at the root of the source distribution.
|
||||
These files may also be found in the public source
|
||||
code repository located at:
|
||||
https://github.com/libusb/hidapi .
|
||||
********************************************************/
|
||||
#include "hidapi_descriptor_reconstruct.h"
|
||||
|
||||
/**
|
||||
* @brief References to report descriptor buffer.
|
||||
*
|
||||
*/
|
||||
struct rd_buffer {
|
||||
unsigned char* buf; /* Pointer to the array which stores the reconstructed descriptor */
|
||||
size_t buf_size; /* Size of the buffer in bytes */
|
||||
size_t byte_idx; /* Index of the next report byte to write to buf array */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Function that appends a byte to encoded report descriptor buffer.
|
||||
*
|
||||
* @param[in] byte Single byte to append.
|
||||
* @param rpt_desc Pointer to report descriptor buffer struct.
|
||||
*/
|
||||
static void rd_append_byte(unsigned char byte, struct rd_buffer* rpt_desc) {
|
||||
if (rpt_desc->byte_idx < rpt_desc->buf_size) {
|
||||
rpt_desc->buf[rpt_desc->byte_idx] = byte;
|
||||
rpt_desc->byte_idx++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes a short report descriptor item according USB HID spec 1.11 chapter 6.2.2.2.
|
||||
*
|
||||
* @param[in] rd_item Enumeration identifying type (Main, Global, Local) and function (e.g Usage or Report Count) of the item.
|
||||
* @param[in] data Data (Size depends on rd_item 0,1,2 or 4bytes).
|
||||
* @param list Chained list of report descriptor bytes.
|
||||
*
|
||||
* @return Returns 0 if successful, -1 for error.
|
||||
*/
|
||||
static int rd_write_short_item(rd_items rd_item, LONG64 data, struct rd_buffer* rpt_desc) {
|
||||
if (rd_item & 0x03) {
|
||||
// Invalid input data, last to bits are reserved for data size
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rd_item == rd_main_collection_end) {
|
||||
// Item without data (1Byte prefix only)
|
||||
unsigned char oneBytePrefix = (unsigned char) rd_item + 0x00;
|
||||
rd_append_byte(oneBytePrefix, rpt_desc);
|
||||
}
|
||||
else if ((rd_item == rd_global_logical_minimum) ||
|
||||
(rd_item == rd_global_logical_maximum) ||
|
||||
(rd_item == rd_global_physical_minimum) ||
|
||||
(rd_item == rd_global_physical_maximum)) {
|
||||
// Item with signed integer data
|
||||
if ((data >= -128) && (data <= 127)) {
|
||||
// 1Byte prefix + 1Byte data
|
||||
unsigned char oneBytePrefix = (unsigned char) rd_item + 0x01;
|
||||
char localData = (char)data;
|
||||
rd_append_byte(oneBytePrefix, rpt_desc);
|
||||
rd_append_byte(localData & 0xFF, rpt_desc);
|
||||
}
|
||||
else if ((data >= -32768) && (data <= 32767)) {
|
||||
// 1Byte prefix + 2Byte data
|
||||
unsigned char oneBytePrefix = (unsigned char) rd_item + 0x02;
|
||||
INT16 localData = (INT16)data;
|
||||
rd_append_byte(oneBytePrefix, rpt_desc);
|
||||
rd_append_byte(localData & 0xFF, rpt_desc);
|
||||
rd_append_byte(localData >> 8 & 0xFF, rpt_desc);
|
||||
}
|
||||
else if ((data >= -2147483648LL) && (data <= 2147483647)) {
|
||||
// 1Byte prefix + 4Byte data
|
||||
unsigned char oneBytePrefix = (unsigned char) rd_item + 0x03;
|
||||
INT32 localData = (INT32)data;
|
||||
rd_append_byte(oneBytePrefix, rpt_desc);
|
||||
rd_append_byte(localData & 0xFF, rpt_desc);
|
||||
rd_append_byte(localData >> 8 & 0xFF, rpt_desc);
|
||||
rd_append_byte(localData >> 16 & 0xFF, rpt_desc);
|
||||
rd_append_byte(localData >> 24 & 0xFF, rpt_desc);
|
||||
}
|
||||
else {
|
||||
// Data out of 32 bit signed integer range
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Item with unsigned integer data
|
||||
if ((data >= 0) && (data <= 0xFF)) {
|
||||
// 1Byte prefix + 1Byte data
|
||||
unsigned char oneBytePrefix = (unsigned char) rd_item + 0x01;
|
||||
unsigned char localData = (unsigned char)data;
|
||||
rd_append_byte(oneBytePrefix, rpt_desc);
|
||||
rd_append_byte(localData & 0xFF, rpt_desc);
|
||||
}
|
||||
else if ((data >= 0) && (data <= 0xFFFF)) {
|
||||
// 1Byte prefix + 2Byte data
|
||||
unsigned char oneBytePrefix = (unsigned char) rd_item + 0x02;
|
||||
UINT16 localData = (UINT16)data;
|
||||
rd_append_byte(oneBytePrefix, rpt_desc);
|
||||
rd_append_byte(localData & 0xFF, rpt_desc);
|
||||
rd_append_byte(localData >> 8 & 0xFF, rpt_desc);
|
||||
}
|
||||
else if ((data >= 0) && (data <= 0xFFFFFFFF)) {
|
||||
// 1Byte prefix + 4Byte data
|
||||
unsigned char oneBytePrefix = (unsigned char) rd_item + 0x03;
|
||||
UINT32 localData = (UINT32)data;
|
||||
rd_append_byte(oneBytePrefix, rpt_desc);
|
||||
rd_append_byte(localData & 0xFF, rpt_desc);
|
||||
rd_append_byte(localData >> 8 & 0xFF, rpt_desc);
|
||||
rd_append_byte(localData >> 16 & 0xFF, rpt_desc);
|
||||
rd_append_byte(localData >> 24 & 0xFF, rpt_desc);
|
||||
}
|
||||
else {
|
||||
// Data out of 32 bit unsigned integer range
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct rd_main_item_node * rd_append_main_item_node(int first_bit, int last_bit, rd_node_type type_of_node, int caps_index, int collection_index, rd_main_items main_item_type, unsigned char report_id, struct rd_main_item_node **list) {
|
||||
struct rd_main_item_node *new_list_node;
|
||||
|
||||
// Determine last node in the list
|
||||
while (*list != NULL)
|
||||
{
|
||||
list = &(*list)->next;
|
||||
}
|
||||
|
||||
new_list_node = malloc(sizeof(*new_list_node)); // Create new list entry
|
||||
new_list_node->FirstBit = first_bit;
|
||||
new_list_node->LastBit = last_bit;
|
||||
new_list_node->TypeOfNode = type_of_node;
|
||||
new_list_node->CapsIndex = caps_index;
|
||||
new_list_node->CollectionIndex = collection_index;
|
||||
new_list_node->MainItemType = main_item_type;
|
||||
new_list_node->ReportID = report_id;
|
||||
new_list_node->next = NULL; // NULL marks last node in the list
|
||||
|
||||
*list = new_list_node;
|
||||
return new_list_node;
|
||||
}
|
||||
|
||||
static struct rd_main_item_node * rd_insert_main_item_node(int first_bit, int last_bit, rd_node_type type_of_node, int caps_index, int collection_index, rd_main_items main_item_type, unsigned char report_id, struct rd_main_item_node **list) {
|
||||
// Insert item after the main item node referenced by list
|
||||
struct rd_main_item_node *next_item = (*list)->next;
|
||||
(*list)->next = NULL;
|
||||
rd_append_main_item_node(first_bit, last_bit, type_of_node, caps_index, collection_index, main_item_type, report_id, list);
|
||||
(*list)->next->next = next_item;
|
||||
return (*list)->next;
|
||||
}
|
||||
|
||||
static struct rd_main_item_node * rd_search_main_item_list_for_bit_position(int search_bit, rd_main_items main_item_type, unsigned char report_id, struct rd_main_item_node **list) {
|
||||
// Determine first INPUT/OUTPUT/FEATURE main item, where the last bit position is equal or greater than the search bit position
|
||||
|
||||
while (((*list)->next->MainItemType != rd_collection) &&
|
||||
((*list)->next->MainItemType != rd_collection_end) &&
|
||||
!(((*list)->next->LastBit >= search_bit) &&
|
||||
((*list)->next->ReportID == report_id) &&
|
||||
((*list)->next->MainItemType == main_item_type))
|
||||
)
|
||||
{
|
||||
list = &(*list)->next;
|
||||
}
|
||||
return *list;
|
||||
}
|
||||
|
||||
int hid_winapi_descriptor_reconstruct_pp_data(void *preparsed_data, unsigned char *buf, size_t buf_size)
|
||||
{
|
||||
hidp_preparsed_data *pp_data = (hidp_preparsed_data *) preparsed_data;
|
||||
|
||||
// Check if MagicKey is correct, to ensure that pp_data points to an valid preparse data structure
|
||||
if (memcmp(pp_data->MagicKey, "HidP KDR", 8) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct rd_buffer rpt_desc = {
|
||||
.buf = buf,
|
||||
.buf_size = buf_size,
|
||||
.byte_idx = 0
|
||||
};
|
||||
|
||||
// Set pointer to the first node of link_collection_nodes
|
||||
phid_pp_link_collection_node link_collection_nodes = (phid_pp_link_collection_node)(((unsigned char*)&pp_data->caps[0]) + pp_data->FirstByteOfLinkCollectionArray);
|
||||
|
||||
// ****************************************************************************************************************************
|
||||
// Create lookup tables for the bit range of each report per collection (position of first bit and last bit in each collection)
|
||||
// coll_bit_range[COLLECTION_INDEX][REPORT_ID][INPUT/OUTPUT/FEATURE]
|
||||
// ****************************************************************************************************************************
|
||||
|
||||
// Allocate memory and initialize lookup table
|
||||
rd_bit_range ****coll_bit_range;
|
||||
coll_bit_range = malloc(pp_data->NumberLinkCollectionNodes * sizeof(*coll_bit_range));
|
||||
for (USHORT collection_node_idx = 0; collection_node_idx < pp_data->NumberLinkCollectionNodes; collection_node_idx++) {
|
||||
coll_bit_range[collection_node_idx] = malloc(256 * sizeof(coll_bit_range[0])); // 256 possible report IDs (incl. 0x00)
|
||||
for (int reportid_idx = 0; reportid_idx < 256; reportid_idx++) {
|
||||
coll_bit_range[collection_node_idx][reportid_idx] = malloc(NUM_OF_HIDP_REPORT_TYPES * sizeof(coll_bit_range[0][0]));
|
||||
for (HIDP_REPORT_TYPE rt_idx = 0; rt_idx < NUM_OF_HIDP_REPORT_TYPES; rt_idx++) {
|
||||
coll_bit_range[collection_node_idx][reportid_idx][rt_idx] = malloc(sizeof(rd_bit_range));
|
||||
coll_bit_range[collection_node_idx][reportid_idx][rt_idx]->FirstBit = -1;
|
||||
coll_bit_range[collection_node_idx][reportid_idx][rt_idx]->LastBit = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fill the lookup table where caps exist
|
||||
for (HIDP_REPORT_TYPE rt_idx = 0; rt_idx < NUM_OF_HIDP_REPORT_TYPES; rt_idx++) {
|
||||
for (USHORT caps_idx = pp_data->caps_info[rt_idx].FirstCap; caps_idx < pp_data->caps_info[rt_idx].LastCap; caps_idx++) {
|
||||
int first_bit, last_bit;
|
||||
first_bit = (pp_data->caps[caps_idx].BytePosition - 1) * 8
|
||||
+ pp_data->caps[caps_idx].BitPosition;
|
||||
last_bit = first_bit + pp_data->caps[caps_idx].ReportSize
|
||||
* pp_data->caps[caps_idx].ReportCount - 1;
|
||||
if (coll_bit_range[pp_data->caps[caps_idx].LinkCollection][pp_data->caps[caps_idx].ReportID][rt_idx]->FirstBit == -1 ||
|
||||
coll_bit_range[pp_data->caps[caps_idx].LinkCollection][pp_data->caps[caps_idx].ReportID][rt_idx]->FirstBit > first_bit) {
|
||||
coll_bit_range[pp_data->caps[caps_idx].LinkCollection][pp_data->caps[caps_idx].ReportID][rt_idx]->FirstBit = first_bit;
|
||||
}
|
||||
if (coll_bit_range[pp_data->caps[caps_idx].LinkCollection][pp_data->caps[caps_idx].ReportID][rt_idx]->LastBit < last_bit) {
|
||||
coll_bit_range[pp_data->caps[caps_idx].LinkCollection][pp_data->caps[caps_idx].ReportID][rt_idx]->LastBit = last_bit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *************************************************************************
|
||||
// -Determine hierachy levels of each collections and store it in:
|
||||
// coll_levels[COLLECTION_INDEX]
|
||||
// -Determine number of direct childs of each collections and store it in:
|
||||
// coll_number_of_direct_childs[COLLECTION_INDEX]
|
||||
// *************************************************************************
|
||||
int max_coll_level = 0;
|
||||
int *coll_levels = malloc(pp_data->NumberLinkCollectionNodes * sizeof(coll_levels[0]));
|
||||
int *coll_number_of_direct_childs = malloc(pp_data->NumberLinkCollectionNodes * sizeof(coll_number_of_direct_childs[0]));
|
||||
for (USHORT collection_node_idx = 0; collection_node_idx < pp_data->NumberLinkCollectionNodes; collection_node_idx++) {
|
||||
coll_levels[collection_node_idx] = -1;
|
||||
coll_number_of_direct_childs[collection_node_idx] = 0;
|
||||
}
|
||||
|
||||
{
|
||||
int actual_coll_level = 0;
|
||||
USHORT collection_node_idx = 0;
|
||||
while (actual_coll_level >= 0) {
|
||||
coll_levels[collection_node_idx] = actual_coll_level;
|
||||
if ((link_collection_nodes[collection_node_idx].NumberOfChildren > 0) &&
|
||||
(coll_levels[link_collection_nodes[collection_node_idx].FirstChild] == -1)) {
|
||||
actual_coll_level++;
|
||||
coll_levels[collection_node_idx] = actual_coll_level;
|
||||
if (max_coll_level < actual_coll_level) {
|
||||
max_coll_level = actual_coll_level;
|
||||
}
|
||||
coll_number_of_direct_childs[collection_node_idx]++;
|
||||
collection_node_idx = link_collection_nodes[collection_node_idx].FirstChild;
|
||||
}
|
||||
else if (link_collection_nodes[collection_node_idx].NextSibling != 0) {
|
||||
coll_number_of_direct_childs[link_collection_nodes[collection_node_idx].Parent]++;
|
||||
collection_node_idx = link_collection_nodes[collection_node_idx].NextSibling;
|
||||
}
|
||||
else {
|
||||
actual_coll_level--;
|
||||
if (actual_coll_level >= 0) {
|
||||
collection_node_idx = link_collection_nodes[collection_node_idx].Parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************************************
|
||||
// Propagate the bit range of each report from the child collections to their parent
|
||||
// and store the merged result for the parent
|
||||
// *********************************************************************************
|
||||
for (int actual_coll_level = max_coll_level - 1; actual_coll_level >= 0; actual_coll_level--) {
|
||||
for (USHORT collection_node_idx = 0; collection_node_idx < pp_data->NumberLinkCollectionNodes; collection_node_idx++) {
|
||||
if (coll_levels[collection_node_idx] == actual_coll_level) {
|
||||
USHORT child_idx = link_collection_nodes[collection_node_idx].FirstChild;
|
||||
while (child_idx) {
|
||||
for (int reportid_idx = 0; reportid_idx < 256; reportid_idx++) {
|
||||
for (HIDP_REPORT_TYPE rt_idx = 0; rt_idx < NUM_OF_HIDP_REPORT_TYPES; rt_idx++) {
|
||||
// Merge bit range from childs
|
||||
if ((coll_bit_range[child_idx][reportid_idx][rt_idx]->FirstBit != -1) &&
|
||||
(coll_bit_range[collection_node_idx][reportid_idx][rt_idx]->FirstBit > coll_bit_range[child_idx][reportid_idx][rt_idx]->FirstBit)) {
|
||||
coll_bit_range[collection_node_idx][reportid_idx][rt_idx]->FirstBit = coll_bit_range[child_idx][reportid_idx][rt_idx]->FirstBit;
|
||||
}
|
||||
if (coll_bit_range[collection_node_idx][reportid_idx][rt_idx]->LastBit < coll_bit_range[child_idx][reportid_idx][rt_idx]->LastBit) {
|
||||
coll_bit_range[collection_node_idx][reportid_idx][rt_idx]->LastBit = coll_bit_range[child_idx][reportid_idx][rt_idx]->LastBit;
|
||||
}
|
||||
child_idx = link_collection_nodes[child_idx].NextSibling;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *************************************************************************************************
|
||||
// Determine child collection order of the whole hierachy, based on previously determined bit ranges
|
||||
// and store it this index coll_child_order[COLLECTION_INDEX][DIRECT_CHILD_INDEX]
|
||||
// *************************************************************************************************
|
||||
USHORT **coll_child_order;
|
||||
coll_child_order = malloc(pp_data->NumberLinkCollectionNodes * sizeof(*coll_child_order));
|
||||
{
|
||||
BOOLEAN *coll_parsed_flag;
|
||||
coll_parsed_flag = malloc(pp_data->NumberLinkCollectionNodes * sizeof(coll_parsed_flag[0]));
|
||||
for (USHORT collection_node_idx = 0; collection_node_idx < pp_data->NumberLinkCollectionNodes; collection_node_idx++) {
|
||||
coll_parsed_flag[collection_node_idx] = FALSE;
|
||||
}
|
||||
int actual_coll_level = 0;
|
||||
USHORT collection_node_idx = 0;
|
||||
while (actual_coll_level >= 0) {
|
||||
if ((coll_number_of_direct_childs[collection_node_idx] != 0) &&
|
||||
(coll_parsed_flag[link_collection_nodes[collection_node_idx].FirstChild] == FALSE)) {
|
||||
coll_parsed_flag[link_collection_nodes[collection_node_idx].FirstChild] = TRUE;
|
||||
coll_child_order[collection_node_idx] = malloc((coll_number_of_direct_childs[collection_node_idx]) * sizeof(coll_child_order[0]));
|
||||
|
||||
{
|
||||
// Create list of child collection indices
|
||||
// sorted reverse to the order returned to HidP_GetLinkCollectionNodeschild
|
||||
// which seems to match teh original order, as long as no bit position needs to be considered
|
||||
USHORT child_idx = link_collection_nodes[collection_node_idx].FirstChild;
|
||||
int child_count = coll_number_of_direct_childs[collection_node_idx] - 1;
|
||||
coll_child_order[collection_node_idx][child_count] = child_idx;
|
||||
while (link_collection_nodes[child_idx].NextSibling) {
|
||||
child_count--;
|
||||
child_idx = link_collection_nodes[child_idx].NextSibling;
|
||||
coll_child_order[collection_node_idx][child_count] = child_idx;
|
||||
}
|
||||
}
|
||||
|
||||
if (coll_number_of_direct_childs[collection_node_idx] > 1) {
|
||||
// Sort child collections indices by bit positions
|
||||
for (HIDP_REPORT_TYPE rt_idx = 0; rt_idx < NUM_OF_HIDP_REPORT_TYPES; rt_idx++) {
|
||||
for (int reportid_idx = 0; reportid_idx < 256; reportid_idx++) {
|
||||
for (int child_idx = 1; child_idx < coll_number_of_direct_childs[collection_node_idx]; child_idx++) {
|
||||
// since the coll_bit_range array is not sorted, we need to reference the collection index in
|
||||
// our sorted coll_child_order array, and look up the corresponding bit ranges for comparing values to sort
|
||||
int prev_coll_idx = coll_child_order[collection_node_idx][child_idx - 1];
|
||||
int cur_coll_idx = coll_child_order[collection_node_idx][child_idx];
|
||||
if ((coll_bit_range[prev_coll_idx][reportid_idx][rt_idx]->FirstBit != -1) &&
|
||||
(coll_bit_range[cur_coll_idx][reportid_idx][rt_idx]->FirstBit != -1) &&
|
||||
(coll_bit_range[prev_coll_idx][reportid_idx][rt_idx]->FirstBit > coll_bit_range[cur_coll_idx][reportid_idx][rt_idx]->FirstBit)) {
|
||||
// Swap position indices of the two compared child collections
|
||||
USHORT idx_latch = coll_child_order[collection_node_idx][child_idx - 1];
|
||||
coll_child_order[collection_node_idx][child_idx - 1] = coll_child_order[collection_node_idx][child_idx];
|
||||
coll_child_order[collection_node_idx][child_idx] = idx_latch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
actual_coll_level++;
|
||||
collection_node_idx = link_collection_nodes[collection_node_idx].FirstChild;
|
||||
}
|
||||
else if (link_collection_nodes[collection_node_idx].NextSibling != 0) {
|
||||
collection_node_idx = link_collection_nodes[collection_node_idx].NextSibling;
|
||||
}
|
||||
else {
|
||||
actual_coll_level--;
|
||||
if (actual_coll_level >= 0) {
|
||||
collection_node_idx = link_collection_nodes[collection_node_idx].Parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(coll_parsed_flag);
|
||||
}
|
||||
|
||||
|
||||
// ***************************************************************************************
|
||||
// Create sorted main_item_list containing all the Collection and CollectionEnd main items
|
||||
// ***************************************************************************************
|
||||
struct rd_main_item_node *main_item_list = (struct rd_main_item_node*)malloc(sizeof(main_item_list));
|
||||
main_item_list = NULL; // List root
|
||||
// Lookup table to find the Collection items in the list by index
|
||||
struct rd_main_item_node **coll_begin_lookup = malloc(pp_data->NumberLinkCollectionNodes * sizeof(*coll_begin_lookup));
|
||||
struct rd_main_item_node **coll_end_lookup = malloc(pp_data->NumberLinkCollectionNodes * sizeof(*coll_end_lookup));
|
||||
{
|
||||
int *coll_last_written_child = malloc(pp_data->NumberLinkCollectionNodes * sizeof(coll_last_written_child[0]));
|
||||
for (USHORT collection_node_idx = 0; collection_node_idx < pp_data->NumberLinkCollectionNodes; collection_node_idx++) {
|
||||
coll_last_written_child[collection_node_idx] = -1;
|
||||
}
|
||||
|
||||
int actual_coll_level = 0;
|
||||
USHORT collection_node_idx = 0;
|
||||
struct rd_main_item_node *firstDelimiterNode = NULL;
|
||||
struct rd_main_item_node *delimiterCloseNode = NULL;
|
||||
coll_begin_lookup[0] = rd_append_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_collection, 0, &main_item_list);
|
||||
while (actual_coll_level >= 0) {
|
||||
if ((coll_number_of_direct_childs[collection_node_idx] != 0) &&
|
||||
(coll_last_written_child[collection_node_idx] == -1)) {
|
||||
// Collection has child collections, but none is written to the list yet
|
||||
|
||||
coll_last_written_child[collection_node_idx] = coll_child_order[collection_node_idx][0];
|
||||
collection_node_idx = coll_child_order[collection_node_idx][0];
|
||||
|
||||
// In a HID Report Descriptor, the first usage declared is the most preferred usage for the control.
|
||||
// While the order in the WIN32 capabiliy strutures is the opposite:
|
||||
// Here the preferred usage is the last aliased usage in the sequence.
|
||||
|
||||
if (link_collection_nodes[collection_node_idx].IsAlias && (firstDelimiterNode == NULL)) {
|
||||
// Alliased Collection (First node in link_collection_nodes -> Last entry in report descriptor output)
|
||||
firstDelimiterNode = main_item_list;
|
||||
coll_begin_lookup[collection_node_idx] = rd_append_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_delimiter_usage, 0, &main_item_list);
|
||||
coll_begin_lookup[collection_node_idx] = rd_append_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_delimiter_close, 0, &main_item_list);
|
||||
delimiterCloseNode = main_item_list;
|
||||
}
|
||||
else {
|
||||
// Normal not aliased collection
|
||||
coll_begin_lookup[collection_node_idx] = rd_append_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_collection, 0, &main_item_list);
|
||||
actual_coll_level++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else if ((coll_number_of_direct_childs[collection_node_idx] > 1) &&
|
||||
(coll_last_written_child[collection_node_idx] != coll_child_order[collection_node_idx][coll_number_of_direct_childs[collection_node_idx] - 1])) {
|
||||
// Collection has child collections, and this is not the first child
|
||||
|
||||
int nextChild = 1;
|
||||
while (coll_last_written_child[collection_node_idx] != coll_child_order[collection_node_idx][nextChild - 1]) {
|
||||
nextChild++;
|
||||
}
|
||||
coll_last_written_child[collection_node_idx] = coll_child_order[collection_node_idx][nextChild];
|
||||
collection_node_idx = coll_child_order[collection_node_idx][nextChild];
|
||||
|
||||
if (link_collection_nodes[collection_node_idx].IsAlias && (firstDelimiterNode == NULL)) {
|
||||
// Alliased Collection (First node in link_collection_nodes -> Last entry in report descriptor output)
|
||||
firstDelimiterNode = main_item_list;
|
||||
coll_begin_lookup[collection_node_idx] = rd_append_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_delimiter_usage, 0, &main_item_list);
|
||||
coll_begin_lookup[collection_node_idx] = rd_append_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_delimiter_close, 0, &main_item_list);
|
||||
delimiterCloseNode = main_item_list;
|
||||
}
|
||||
else if (link_collection_nodes[collection_node_idx].IsAlias && (firstDelimiterNode != NULL)) {
|
||||
coll_begin_lookup[collection_node_idx] = rd_insert_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_delimiter_usage, 0, &firstDelimiterNode);
|
||||
}
|
||||
else if (!link_collection_nodes[collection_node_idx].IsAlias && (firstDelimiterNode != NULL)) {
|
||||
coll_begin_lookup[collection_node_idx] = rd_insert_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_delimiter_usage, 0, &firstDelimiterNode);
|
||||
coll_begin_lookup[collection_node_idx] = rd_insert_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_delimiter_open, 0, &firstDelimiterNode);
|
||||
firstDelimiterNode = NULL;
|
||||
main_item_list = delimiterCloseNode;
|
||||
delimiterCloseNode = NULL; // Last entry of alias has .IsAlias == FALSE
|
||||
}
|
||||
if (!link_collection_nodes[collection_node_idx].IsAlias) {
|
||||
coll_begin_lookup[collection_node_idx] = rd_append_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_collection, 0, &main_item_list);
|
||||
actual_coll_level++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
actual_coll_level--;
|
||||
coll_end_lookup[collection_node_idx] = rd_append_main_item_node(0, 0, rd_item_node_collection, 0, collection_node_idx, rd_collection_end, 0, &main_item_list);
|
||||
collection_node_idx = link_collection_nodes[collection_node_idx].Parent;
|
||||
}
|
||||
}
|
||||
free(coll_last_written_child);
|
||||
}
|
||||
|
||||
|
||||
// ****************************************************************
|
||||
// Inserted Input/Output/Feature main items into the main_item_list
|
||||
// in order of reconstructed bit positions
|
||||
// ****************************************************************
|
||||
for (HIDP_REPORT_TYPE rt_idx = 0; rt_idx < NUM_OF_HIDP_REPORT_TYPES; rt_idx++) {
|
||||
// Add all value caps to node list
|
||||
struct rd_main_item_node *firstDelimiterNode = NULL;
|
||||
struct rd_main_item_node *delimiterCloseNode = NULL;
|
||||
for (USHORT caps_idx = pp_data->caps_info[rt_idx].FirstCap; caps_idx < pp_data->caps_info[rt_idx].LastCap; caps_idx++) {
|
||||
struct rd_main_item_node *coll_begin = coll_begin_lookup[pp_data->caps[caps_idx].LinkCollection];
|
||||
int first_bit, last_bit;
|
||||
first_bit = (pp_data->caps[caps_idx].BytePosition - 1) * 8 +
|
||||
pp_data->caps[caps_idx].BitPosition;
|
||||
last_bit = first_bit + pp_data->caps[caps_idx].ReportSize *
|
||||
pp_data->caps[caps_idx].ReportCount - 1;
|
||||
|
||||
for (int child_idx = 0; child_idx < coll_number_of_direct_childs[pp_data->caps[caps_idx].LinkCollection]; child_idx++) {
|
||||
// Determine in which section before/between/after child collection the item should be inserted
|
||||
if (first_bit < coll_bit_range[coll_child_order[pp_data->caps[caps_idx].LinkCollection][child_idx]][pp_data->caps[caps_idx].ReportID][rt_idx]->FirstBit)
|
||||
{
|
||||
// Note, that the default value for undefined coll_bit_range is -1, which can't be greater than the bit position
|
||||
break;
|
||||
}
|
||||
coll_begin = coll_end_lookup[coll_child_order[pp_data->caps[caps_idx].LinkCollection][child_idx]];
|
||||
}
|
||||
struct rd_main_item_node *list_node;
|
||||
list_node = rd_search_main_item_list_for_bit_position(first_bit, (rd_main_items) rt_idx, pp_data->caps[caps_idx].ReportID, &coll_begin);
|
||||
|
||||
// In a HID Report Descriptor, the first usage declared is the most preferred usage for the control.
|
||||
// While the order in the WIN32 capabiliy strutures is the opposite:
|
||||
// Here the preferred usage is the last aliased usage in the sequence.
|
||||
|
||||
if (pp_data->caps[caps_idx].IsAlias && (firstDelimiterNode == NULL)) {
|
||||
// Alliased Usage (First node in pp_data->caps -> Last entry in report descriptor output)
|
||||
firstDelimiterNode = list_node;
|
||||
rd_insert_main_item_node(first_bit, last_bit, rd_item_node_cap, caps_idx, pp_data->caps[caps_idx].LinkCollection, rd_delimiter_usage, pp_data->caps[caps_idx].ReportID, &list_node);
|
||||
rd_insert_main_item_node(first_bit, last_bit, rd_item_node_cap, caps_idx, pp_data->caps[caps_idx].LinkCollection, rd_delimiter_close, pp_data->caps[caps_idx].ReportID, &list_node);
|
||||
delimiterCloseNode = list_node;
|
||||
} else if (pp_data->caps[caps_idx].IsAlias && (firstDelimiterNode != NULL)) {
|
||||
rd_insert_main_item_node(first_bit, last_bit, rd_item_node_cap, caps_idx, pp_data->caps[caps_idx].LinkCollection, rd_delimiter_usage, pp_data->caps[caps_idx].ReportID, &list_node);
|
||||
}
|
||||
else if (!pp_data->caps[caps_idx].IsAlias && (firstDelimiterNode != NULL)) {
|
||||
// Alliased Collection (Last node in pp_data->caps -> First entry in report descriptor output)
|
||||
rd_insert_main_item_node(first_bit, last_bit, rd_item_node_cap, caps_idx, pp_data->caps[caps_idx].LinkCollection, rd_delimiter_usage, pp_data->caps[caps_idx].ReportID, &list_node);
|
||||
rd_insert_main_item_node(first_bit, last_bit, rd_item_node_cap, caps_idx, pp_data->caps[caps_idx].LinkCollection, rd_delimiter_open, pp_data->caps[caps_idx].ReportID, &list_node);
|
||||
firstDelimiterNode = NULL;
|
||||
list_node = delimiterCloseNode;
|
||||
delimiterCloseNode = NULL; // Last entry of alias has .IsAlias == FALSE
|
||||
}
|
||||
if (!pp_data->caps[caps_idx].IsAlias) {
|
||||
rd_insert_main_item_node(first_bit, last_bit, rd_item_node_cap, caps_idx, pp_data->caps[caps_idx].LinkCollection, (rd_main_items) rt_idx, pp_data->caps[caps_idx].ReportID, &list_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ***********************************************************
|
||||
// Add const main items for padding to main_item_list
|
||||
// -To fill all bit gaps
|
||||
// -At each report end for 8bit padding
|
||||
// Note that information about the padding at the report end,
|
||||
// is not stored in the preparsed data, but in practice all
|
||||
// report descriptors seem to have it, as assumed here.
|
||||
// ***********************************************************
|
||||
{
|
||||
int last_bit_position[NUM_OF_HIDP_REPORT_TYPES][256];
|
||||
struct rd_main_item_node *last_report_item_lookup[NUM_OF_HIDP_REPORT_TYPES][256];
|
||||
for (HIDP_REPORT_TYPE rt_idx = 0; rt_idx < NUM_OF_HIDP_REPORT_TYPES; rt_idx++) {
|
||||
for (int reportid_idx = 0; reportid_idx < 256; reportid_idx++) {
|
||||
last_bit_position[rt_idx][reportid_idx] = -1;
|
||||
last_report_item_lookup[rt_idx][reportid_idx] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct rd_main_item_node *list = main_item_list; // List root;
|
||||
|
||||
while (list->next != NULL)
|
||||
{
|
||||
if ((list->MainItemType >= rd_input) &&
|
||||
(list->MainItemType <= rd_feature)) {
|
||||
// INPUT, OUTPUT or FEATURE
|
||||
if (list->FirstBit != -1) {
|
||||
if ((last_bit_position[list->MainItemType][list->ReportID] + 1 != list->FirstBit) &&
|
||||
(last_report_item_lookup[list->MainItemType][list->ReportID] != NULL) &&
|
||||
(last_report_item_lookup[list->MainItemType][list->ReportID]->FirstBit != list->FirstBit) // Happens in case of IsMultipleItemsForArray for multiple dedicated usages for a multi-button array
|
||||
) {
|
||||
struct rd_main_item_node *list_node = rd_search_main_item_list_for_bit_position(last_bit_position[list->MainItemType][list->ReportID], list->MainItemType, list->ReportID, &last_report_item_lookup[list->MainItemType][list->ReportID]);
|
||||
rd_insert_main_item_node(last_bit_position[list->MainItemType][list->ReportID] + 1, list->FirstBit - 1, rd_item_node_padding, -1, 0, list->MainItemType, list->ReportID, &list_node);
|
||||
}
|
||||
last_bit_position[list->MainItemType][list->ReportID] = list->LastBit;
|
||||
last_report_item_lookup[list->MainItemType][list->ReportID] = list;
|
||||
}
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
// Add 8 bit padding at each report end
|
||||
for (HIDP_REPORT_TYPE rt_idx = 0; rt_idx < NUM_OF_HIDP_REPORT_TYPES; rt_idx++) {
|
||||
for (int reportid_idx = 0; reportid_idx < 256; reportid_idx++) {
|
||||
if (last_bit_position[rt_idx][reportid_idx] != -1) {
|
||||
int padding = 8 - ((last_bit_position[rt_idx][reportid_idx] + 1) % 8);
|
||||
if (padding < 8) {
|
||||
// Insert padding item after item referenced in last_report_item_lookup
|
||||
rd_insert_main_item_node(last_bit_position[rt_idx][reportid_idx] + 1, last_bit_position[rt_idx][reportid_idx] + padding, rd_item_node_padding, -1, 0, (rd_main_items) rt_idx, (unsigned char) reportid_idx, &last_report_item_lookup[rt_idx][reportid_idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ***********************************
|
||||
// Encode the report descriptor output
|
||||
// ***********************************
|
||||
UCHAR last_report_id = 0;
|
||||
USAGE last_usage_page = 0;
|
||||
LONG last_physical_min = 0;// If both, Physical Minimum and Physical Maximum are 0, the logical limits should be taken as physical limits according USB HID spec 1.11 chapter 6.2.2.7
|
||||
LONG last_physical_max = 0;
|
||||
ULONG last_unit_exponent = 0; // If Unit Exponent is Undefined it should be considered as 0 according USB HID spec 1.11 chapter 6.2.2.7
|
||||
ULONG last_unit = 0; // If the first nibble is 7, or second nibble of Unit is 0, the unit is None according USB HID spec 1.11 chapter 6.2.2.7
|
||||
BOOLEAN inhibit_write_of_usage = FALSE; // Needed in case of delimited usage print, before the normal collection or cap
|
||||
int report_count = 0;
|
||||
while (main_item_list != NULL)
|
||||
{
|
||||
int rt_idx = main_item_list->MainItemType;
|
||||
int caps_idx = main_item_list->CapsIndex;
|
||||
if (main_item_list->MainItemType == rd_collection) {
|
||||
if (last_usage_page != link_collection_nodes[main_item_list->CollectionIndex].LinkUsagePage) {
|
||||
// Write "Usage Page" at the begin of a collection - except it refers the same table as wrote last
|
||||
rd_write_short_item(rd_global_usage_page, link_collection_nodes[main_item_list->CollectionIndex].LinkUsagePage, &rpt_desc);
|
||||
last_usage_page = link_collection_nodes[main_item_list->CollectionIndex].LinkUsagePage;
|
||||
}
|
||||
if (inhibit_write_of_usage) {
|
||||
// Inhibit only once after DELIMITER statement
|
||||
inhibit_write_of_usage = FALSE;
|
||||
}
|
||||
else {
|
||||
// Write "Usage" of collection
|
||||
rd_write_short_item(rd_local_usage, link_collection_nodes[main_item_list->CollectionIndex].LinkUsage, &rpt_desc);
|
||||
}
|
||||
// Write begin of "Collection"
|
||||
rd_write_short_item(rd_main_collection, link_collection_nodes[main_item_list->CollectionIndex].CollectionType, &rpt_desc);
|
||||
}
|
||||
else if (main_item_list->MainItemType == rd_collection_end) {
|
||||
// Write "End Collection"
|
||||
rd_write_short_item(rd_main_collection_end, 0, &rpt_desc);
|
||||
}
|
||||
else if (main_item_list->MainItemType == rd_delimiter_open) {
|
||||
if (main_item_list->CollectionIndex != -1) {
|
||||
// Write "Usage Page" inside of a collection delmiter section
|
||||
if (last_usage_page != link_collection_nodes[main_item_list->CollectionIndex].LinkUsagePage) {
|
||||
rd_write_short_item(rd_global_usage_page, link_collection_nodes[main_item_list->CollectionIndex].LinkUsagePage, &rpt_desc);
|
||||
last_usage_page = link_collection_nodes[main_item_list->CollectionIndex].LinkUsagePage;
|
||||
}
|
||||
}
|
||||
else if (main_item_list->CapsIndex != 0) {
|
||||
// Write "Usage Page" inside of a main item delmiter section
|
||||
if (pp_data->caps[caps_idx].UsagePage != last_usage_page) {
|
||||
rd_write_short_item(rd_global_usage_page, pp_data->caps[caps_idx].UsagePage, &rpt_desc);
|
||||
last_usage_page = pp_data->caps[caps_idx].UsagePage;
|
||||
}
|
||||
}
|
||||
// Write "Delimiter Open"
|
||||
rd_write_short_item(rd_local_delimiter, 1, &rpt_desc); // 1 = open set of aliased usages
|
||||
}
|
||||
else if (main_item_list->MainItemType == rd_delimiter_usage) {
|
||||
if (main_item_list->CollectionIndex != -1) {
|
||||
// Write aliased collection "Usage"
|
||||
rd_write_short_item(rd_local_usage, link_collection_nodes[main_item_list->CollectionIndex].LinkUsage, &rpt_desc);
|
||||
} if (main_item_list->CapsIndex != 0) {
|
||||
// Write aliased main item range from "Usage Minimum" to "Usage Maximum"
|
||||
if (pp_data->caps[caps_idx].IsRange) {
|
||||
rd_write_short_item(rd_local_usage_minimum, pp_data->caps[caps_idx].Range.UsageMin, &rpt_desc);
|
||||
rd_write_short_item(rd_local_usage_maximum, pp_data->caps[caps_idx].Range.UsageMax, &rpt_desc);
|
||||
}
|
||||
else {
|
||||
// Write single aliased main item "Usage"
|
||||
rd_write_short_item(rd_local_usage, pp_data->caps[caps_idx].NotRange.Usage, &rpt_desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (main_item_list->MainItemType == rd_delimiter_close) {
|
||||
// Write "Delimiter Close"
|
||||
rd_write_short_item(rd_local_delimiter, 0, &rpt_desc); // 0 = close set of aliased usages
|
||||
// Inhibit next usage write
|
||||
inhibit_write_of_usage = TRUE;
|
||||
}
|
||||
else if (main_item_list->TypeOfNode == rd_item_node_padding) {
|
||||
// Padding
|
||||
// The preparsed data doesn't contain any information about padding. Therefore all undefined gaps
|
||||
// in the reports are filled with the same style of constant padding.
|
||||
|
||||
// Write "Report Size" with number of padding bits
|
||||
rd_write_short_item(rd_global_report_size, (main_item_list->LastBit - main_item_list->FirstBit + 1), &rpt_desc);
|
||||
|
||||
// Write "Report Count" for padding always as 1
|
||||
rd_write_short_item(rd_global_report_count, 1, &rpt_desc);
|
||||
|
||||
if (rt_idx == HidP_Input) {
|
||||
// Write "Input" main item - We know it's Constant - We can only guess the other bits, but they don't matter in case of const
|
||||
rd_write_short_item(rd_main_input, 0x03, &rpt_desc); // Const / Abs
|
||||
}
|
||||
else if (rt_idx == HidP_Output) {
|
||||
// Write "Output" main item - We know it's Constant - We can only guess the other bits, but they don't matter in case of const
|
||||
rd_write_short_item(rd_main_output, 0x03, &rpt_desc); // Const / Abs
|
||||
}
|
||||
else if (rt_idx == HidP_Feature) {
|
||||
// Write "Feature" main item - We know it's Constant - We can only guess the other bits, but they don't matter in case of const
|
||||
rd_write_short_item(rd_main_feature, 0x03, &rpt_desc); // Const / Abs
|
||||
}
|
||||
report_count = 0;
|
||||
}
|
||||
else if (pp_data->caps[caps_idx].IsButtonCap) {
|
||||
// Button
|
||||
// (The preparsed data contain different data for 1 bit Button caps, than for parametric Value caps)
|
||||
|
||||
if (last_report_id != pp_data->caps[caps_idx].ReportID) {
|
||||
// Write "Report ID" if changed
|
||||
rd_write_short_item(rd_global_report_id, pp_data->caps[caps_idx].ReportID, &rpt_desc);
|
||||
last_report_id = pp_data->caps[caps_idx].ReportID;
|
||||
}
|
||||
|
||||
// Write "Usage Page" when changed
|
||||
if (pp_data->caps[caps_idx].UsagePage != last_usage_page) {
|
||||
rd_write_short_item(rd_global_usage_page, pp_data->caps[caps_idx].UsagePage, &rpt_desc);
|
||||
last_usage_page = pp_data->caps[caps_idx].UsagePage;
|
||||
}
|
||||
|
||||
// Write only local report items for each cap, if ReportCount > 1
|
||||
if (pp_data->caps[caps_idx].IsRange) {
|
||||
report_count += (pp_data->caps[caps_idx].Range.DataIndexMax - pp_data->caps[caps_idx].Range.DataIndexMin);
|
||||
}
|
||||
|
||||
if (inhibit_write_of_usage) {
|
||||
// Inhibit only once after Delimiter - Reset flag
|
||||
inhibit_write_of_usage = FALSE;
|
||||
}
|
||||
else {
|
||||
if (pp_data->caps[caps_idx].IsRange) {
|
||||
// Write range from "Usage Minimum" to "Usage Maximum"
|
||||
rd_write_short_item(rd_local_usage_minimum, pp_data->caps[caps_idx].Range.UsageMin, &rpt_desc);
|
||||
rd_write_short_item(rd_local_usage_maximum, pp_data->caps[caps_idx].Range.UsageMax, &rpt_desc);
|
||||
}
|
||||
else {
|
||||
// Write single "Usage"
|
||||
rd_write_short_item(rd_local_usage, pp_data->caps[caps_idx].NotRange.Usage, &rpt_desc);
|
||||
}
|
||||
}
|
||||
|
||||
if (pp_data->caps[caps_idx].IsDesignatorRange) {
|
||||
// Write physical descriptor indices range from "Designator Minimum" to "Designator Maximum"
|
||||
rd_write_short_item(rd_local_designator_minimum, pp_data->caps[caps_idx].Range.DesignatorMin, &rpt_desc);
|
||||
rd_write_short_item(rd_local_designator_maximum, pp_data->caps[caps_idx].Range.DesignatorMax, &rpt_desc);
|
||||
}
|
||||
else if (pp_data->caps[caps_idx].NotRange.DesignatorIndex != 0) {
|
||||
// Designator set 0 is a special descriptor set (of the HID Physical Descriptor),
|
||||
// that specifies the number of additional descriptor sets.
|
||||
// Therefore Designator Index 0 can never be a useful reference for a control and we can inhibit it.
|
||||
// Write single "Designator Index"
|
||||
rd_write_short_item(rd_local_designator_index, pp_data->caps[caps_idx].NotRange.DesignatorIndex, &rpt_desc);
|
||||
}
|
||||
|
||||
if (pp_data->caps[caps_idx].IsStringRange) {
|
||||
// Write range of indices of the USB string descriptor, from "String Minimum" to "String Maximum"
|
||||
rd_write_short_item(rd_local_string_minimum, pp_data->caps[caps_idx].Range.StringMin, &rpt_desc);
|
||||
rd_write_short_item(rd_local_string_maximum, pp_data->caps[caps_idx].Range.StringMax, &rpt_desc);
|
||||
}
|
||||
else if (pp_data->caps[caps_idx].NotRange.StringIndex != 0) {
|
||||
// String Index 0 is a special entry of the USB string descriptor, that contains a list of supported languages,
|
||||
// therefore Designator Index 0 can never be a useful reference for a control and we can inhibit it.
|
||||
// Write single "String Index"
|
||||
rd_write_short_item(rd_local_string, pp_data->caps[caps_idx].NotRange.StringIndex, &rpt_desc);
|
||||
}
|
||||
|
||||
if ((main_item_list->next != NULL) &&
|
||||
((int)main_item_list->next->MainItemType == rt_idx) &&
|
||||
(main_item_list->next->TypeOfNode == rd_item_node_cap) &&
|
||||
(pp_data->caps[main_item_list->next->CapsIndex].IsButtonCap) &&
|
||||
(!pp_data->caps[caps_idx].IsRange) && // This node in list is no array
|
||||
(!pp_data->caps[main_item_list->next->CapsIndex].IsRange) && // Next node in list is no array
|
||||
(pp_data->caps[main_item_list->next->CapsIndex].UsagePage == pp_data->caps[caps_idx].UsagePage) &&
|
||||
(pp_data->caps[main_item_list->next->CapsIndex].ReportID == pp_data->caps[caps_idx].ReportID) &&
|
||||
(pp_data->caps[main_item_list->next->CapsIndex].BitField == pp_data->caps[caps_idx].BitField)
|
||||
) {
|
||||
if (main_item_list->next->FirstBit != main_item_list->FirstBit) {
|
||||
// In case of IsMultipleItemsForArray for multiple dedicated usages for a multi-button array, the report count should be incremented
|
||||
|
||||
// Skip global items until any of them changes, than use ReportCount item to write the count of identical report fields
|
||||
report_count++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
if ((pp_data->caps[caps_idx].Button.LogicalMin == 0) &&
|
||||
(pp_data->caps[caps_idx].Button.LogicalMax == 0)) {
|
||||
// While a HID report descriptor must always contain LogicalMinimum and LogicalMaximum,
|
||||
// the preparsed data contain both fields set to zero, for the case of simple buttons
|
||||
// Write "Logical Minimum" set to 0 and "Logical Maximum" set to 1
|
||||
rd_write_short_item(rd_global_logical_minimum, 0, &rpt_desc);
|
||||
rd_write_short_item(rd_global_logical_maximum, 1, &rpt_desc);
|
||||
}
|
||||
else {
|
||||
// Write logical range from "Logical Minimum" to "Logical Maximum"
|
||||
rd_write_short_item(rd_global_logical_minimum, pp_data->caps[caps_idx].Button.LogicalMin, &rpt_desc);
|
||||
rd_write_short_item(rd_global_logical_maximum, pp_data->caps[caps_idx].Button.LogicalMax, &rpt_desc);
|
||||
}
|
||||
|
||||
// Write "Report Size"
|
||||
rd_write_short_item(rd_global_report_size, pp_data->caps[caps_idx].ReportSize, &rpt_desc);
|
||||
|
||||
// Write "Report Count"
|
||||
if (!pp_data->caps[caps_idx].IsRange) {
|
||||
// Variable bit field with one bit per button
|
||||
// In case of multiple usages with the same items, only "Usage" is written per cap, and "Report Count" is incremented
|
||||
rd_write_short_item(rd_global_report_count, pp_data->caps[caps_idx].ReportCount + report_count, &rpt_desc);
|
||||
}
|
||||
else {
|
||||
// Button array of "Report Size" x "Report Count
|
||||
rd_write_short_item(rd_global_report_count, pp_data->caps[caps_idx].ReportCount, &rpt_desc);
|
||||
}
|
||||
|
||||
|
||||
// Buttons have only 1 bit and therefore no physical limits/units -> Set to undefined state
|
||||
if (last_physical_min != 0) {
|
||||
// Write "Physical Minimum", but only if changed
|
||||
last_physical_min = 0;
|
||||
rd_write_short_item(rd_global_physical_minimum, last_physical_min, &rpt_desc);
|
||||
}
|
||||
if (last_physical_max != 0) {
|
||||
// Write "Physical Maximum", but only if changed
|
||||
last_physical_max = 0;
|
||||
rd_write_short_item(rd_global_physical_maximum, last_physical_max, &rpt_desc);
|
||||
}
|
||||
if (last_unit_exponent != 0) {
|
||||
// Write "Unit Exponent", but only if changed
|
||||
last_unit_exponent = 0;
|
||||
rd_write_short_item(rd_global_unit_exponent, last_unit_exponent, &rpt_desc);
|
||||
}
|
||||
if (last_unit != 0) {
|
||||
// Write "Unit",but only if changed
|
||||
last_unit = 0;
|
||||
rd_write_short_item(rd_global_unit, last_unit, &rpt_desc);
|
||||
}
|
||||
|
||||
// Write "Input" main item
|
||||
if (rt_idx == HidP_Input) {
|
||||
rd_write_short_item(rd_main_input, pp_data->caps[caps_idx].BitField, &rpt_desc);
|
||||
}
|
||||
// Write "Output" main item
|
||||
else if (rt_idx == HidP_Output) {
|
||||
rd_write_short_item(rd_main_output, pp_data->caps[caps_idx].BitField, &rpt_desc);
|
||||
}
|
||||
// Write "Feature" main item
|
||||
else if (rt_idx == HidP_Feature) {
|
||||
rd_write_short_item(rd_main_feature, pp_data->caps[caps_idx].BitField, &rpt_desc);
|
||||
}
|
||||
report_count = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
if (last_report_id != pp_data->caps[caps_idx].ReportID) {
|
||||
// Write "Report ID" if changed
|
||||
rd_write_short_item(rd_global_report_id, pp_data->caps[caps_idx].ReportID, &rpt_desc);
|
||||
last_report_id = pp_data->caps[caps_idx].ReportID;
|
||||
}
|
||||
|
||||
// Write "Usage Page" if changed
|
||||
if (pp_data->caps[caps_idx].UsagePage != last_usage_page) {
|
||||
rd_write_short_item(rd_global_usage_page, pp_data->caps[caps_idx].UsagePage, &rpt_desc);
|
||||
last_usage_page = pp_data->caps[caps_idx].UsagePage;
|
||||
}
|
||||
|
||||
if (inhibit_write_of_usage) {
|
||||
// Inhibit only once after Delimiter - Reset flag
|
||||
inhibit_write_of_usage = FALSE;
|
||||
}
|
||||
else {
|
||||
if (pp_data->caps[caps_idx].IsRange) {
|
||||
// Write usage range from "Usage Minimum" to "Usage Maximum"
|
||||
rd_write_short_item(rd_local_usage_minimum, pp_data->caps[caps_idx].Range.UsageMin, &rpt_desc);
|
||||
rd_write_short_item(rd_local_usage_maximum, pp_data->caps[caps_idx].Range.UsageMax, &rpt_desc);
|
||||
}
|
||||
else {
|
||||
// Write single "Usage"
|
||||
rd_write_short_item(rd_local_usage, pp_data->caps[caps_idx].NotRange.Usage, &rpt_desc);
|
||||
}
|
||||
}
|
||||
|
||||
if (pp_data->caps[caps_idx].IsDesignatorRange) {
|
||||
// Write physical descriptor indices range from "Designator Minimum" to "Designator Maximum"
|
||||
rd_write_short_item(rd_local_designator_minimum, pp_data->caps[caps_idx].Range.DesignatorMin, &rpt_desc);
|
||||
rd_write_short_item(rd_local_designator_maximum, pp_data->caps[caps_idx].Range.DesignatorMax, &rpt_desc);
|
||||
}
|
||||
else if (pp_data->caps[caps_idx].NotRange.DesignatorIndex != 0) {
|
||||
// Designator set 0 is a special descriptor set (of the HID Physical Descriptor),
|
||||
// that specifies the number of additional descriptor sets.
|
||||
// Therefore Designator Index 0 can never be a useful reference for a control and we can inhibit it.
|
||||
// Write single "Designator Index"
|
||||
rd_write_short_item(rd_local_designator_index, pp_data->caps[caps_idx].NotRange.DesignatorIndex, &rpt_desc);
|
||||
}
|
||||
|
||||
if (pp_data->caps[caps_idx].IsStringRange) {
|
||||
// Write range of indices of the USB string descriptor, from "String Minimum" to "String Maximum"
|
||||
rd_write_short_item(rd_local_string_minimum, pp_data->caps[caps_idx].Range.StringMin, &rpt_desc);
|
||||
rd_write_short_item(rd_local_string_maximum, pp_data->caps[caps_idx].Range.StringMax, &rpt_desc);
|
||||
}
|
||||
else if (pp_data->caps[caps_idx].NotRange.StringIndex != 0) {
|
||||
// String Index 0 is a special entry of the USB string descriptor, that contains a list of supported languages,
|
||||
// therefore Designator Index 0 can never be a useful reference for a control and we can inhibit it.
|
||||
// Write single "String Index"
|
||||
rd_write_short_item(rd_local_string, pp_data->caps[caps_idx].NotRange.StringIndex, &rpt_desc);
|
||||
}
|
||||
|
||||
if ((pp_data->caps[caps_idx].BitField & 0x02) != 0x02) {
|
||||
// In case of an value array overwrite "Report Count"
|
||||
pp_data->caps[caps_idx].ReportCount = pp_data->caps[caps_idx].Range.DataIndexMax - pp_data->caps[caps_idx].Range.DataIndexMin + 1;
|
||||
}
|
||||
|
||||
|
||||
// Print only local report items for each cap, if ReportCount > 1
|
||||
if ((main_item_list->next != NULL) &&
|
||||
((int) main_item_list->next->MainItemType == rt_idx) &&
|
||||
(main_item_list->next->TypeOfNode == rd_item_node_cap) &&
|
||||
(!pp_data->caps[main_item_list->next->CapsIndex].IsButtonCap) &&
|
||||
(!pp_data->caps[caps_idx].IsRange) && // This node in list is no array
|
||||
(!pp_data->caps[main_item_list->next->CapsIndex].IsRange) && // Next node in list is no array
|
||||
(pp_data->caps[main_item_list->next->CapsIndex].UsagePage == pp_data->caps[caps_idx].UsagePage) &&
|
||||
(pp_data->caps[main_item_list->next->CapsIndex].NotButton.LogicalMin == pp_data->caps[caps_idx].NotButton.LogicalMin) &&
|
||||
(pp_data->caps[main_item_list->next->CapsIndex].NotButton.LogicalMax == pp_data->caps[caps_idx].NotButton.LogicalMax) &&
|
||||
(pp_data->caps[main_item_list->next->CapsIndex].NotButton.PhysicalMin == pp_data->caps[caps_idx].NotButton.PhysicalMin) &&
|
||||
(pp_data->caps[main_item_list->next->CapsIndex].NotButton.PhysicalMax == pp_data->caps[caps_idx].NotButton.PhysicalMax) &&
|
||||
(pp_data->caps[main_item_list->next->CapsIndex].UnitsExp == pp_data->caps[caps_idx].UnitsExp) &&
|
||||
(pp_data->caps[main_item_list->next->CapsIndex].Units == pp_data->caps[caps_idx].Units) &&
|
||||
(pp_data->caps[main_item_list->next->CapsIndex].ReportSize == pp_data->caps[caps_idx].ReportSize) &&
|
||||
(pp_data->caps[main_item_list->next->CapsIndex].ReportID == pp_data->caps[caps_idx].ReportID) &&
|
||||
(pp_data->caps[main_item_list->next->CapsIndex].BitField == pp_data->caps[caps_idx].BitField) &&
|
||||
(pp_data->caps[main_item_list->next->CapsIndex].ReportCount == 1) &&
|
||||
(pp_data->caps[caps_idx].ReportCount == 1)
|
||||
) {
|
||||
// Skip global items until any of them changes, than use ReportCount item to write the count of identical report fields
|
||||
report_count++;
|
||||
}
|
||||
else {
|
||||
// Value
|
||||
|
||||
// Write logical range from "Logical Minimum" to "Logical Maximum"
|
||||
rd_write_short_item(rd_global_logical_minimum, pp_data->caps[caps_idx].NotButton.LogicalMin, &rpt_desc);
|
||||
rd_write_short_item(rd_global_logical_maximum, pp_data->caps[caps_idx].NotButton.LogicalMax, &rpt_desc);
|
||||
|
||||
if ((last_physical_min != pp_data->caps[caps_idx].NotButton.PhysicalMin) ||
|
||||
(last_physical_max != pp_data->caps[caps_idx].NotButton.PhysicalMax)) {
|
||||
// Write range from "Physical Minimum" to " Physical Maximum", but only if one of them changed
|
||||
rd_write_short_item(rd_global_physical_minimum, pp_data->caps[caps_idx].NotButton.PhysicalMin, &rpt_desc);
|
||||
last_physical_min = pp_data->caps[caps_idx].NotButton.PhysicalMin;
|
||||
rd_write_short_item(rd_global_physical_maximum, pp_data->caps[caps_idx].NotButton.PhysicalMax, &rpt_desc);
|
||||
last_physical_max = pp_data->caps[caps_idx].NotButton.PhysicalMax;
|
||||
}
|
||||
|
||||
|
||||
if (last_unit_exponent != pp_data->caps[caps_idx].UnitsExp) {
|
||||
// Write "Unit Exponent", but only if changed
|
||||
rd_write_short_item(rd_global_unit_exponent, pp_data->caps[caps_idx].UnitsExp, &rpt_desc);
|
||||
last_unit_exponent = pp_data->caps[caps_idx].UnitsExp;
|
||||
}
|
||||
|
||||
if (last_unit != pp_data->caps[caps_idx].Units) {
|
||||
// Write physical "Unit", but only if changed
|
||||
rd_write_short_item(rd_global_unit, pp_data->caps[caps_idx].Units, &rpt_desc);
|
||||
last_unit = pp_data->caps[caps_idx].Units;
|
||||
}
|
||||
|
||||
// Write "Report Size"
|
||||
rd_write_short_item(rd_global_report_size, pp_data->caps[caps_idx].ReportSize, &rpt_desc);
|
||||
|
||||
// Write "Report Count"
|
||||
rd_write_short_item(rd_global_report_count, pp_data->caps[caps_idx].ReportCount + report_count, &rpt_desc);
|
||||
|
||||
if (rt_idx == HidP_Input) {
|
||||
// Write "Input" main item
|
||||
rd_write_short_item(rd_main_input, pp_data->caps[caps_idx].BitField, &rpt_desc);
|
||||
}
|
||||
else if (rt_idx == HidP_Output) {
|
||||
// Write "Output" main item
|
||||
rd_write_short_item(rd_main_output, pp_data->caps[caps_idx].BitField, &rpt_desc);
|
||||
}
|
||||
else if (rt_idx == HidP_Feature) {
|
||||
// Write "Feature" main item
|
||||
rd_write_short_item(rd_main_feature, pp_data->caps[caps_idx].BitField, &rpt_desc);
|
||||
}
|
||||
report_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Go to next item in main_item_list and free the memory of the actual item
|
||||
struct rd_main_item_node *main_item_list_prev = main_item_list;
|
||||
main_item_list = main_item_list->next;
|
||||
free(main_item_list_prev);
|
||||
}
|
||||
|
||||
// Free multidimensionable array: coll_bit_range[COLLECTION_INDEX][REPORT_ID][INPUT/OUTPUT/FEATURE]
|
||||
// Free multidimensionable array: coll_child_order[COLLECTION_INDEX][DIRECT_CHILD_INDEX]
|
||||
for (USHORT collection_node_idx = 0; collection_node_idx < pp_data->NumberLinkCollectionNodes; collection_node_idx++) {
|
||||
for (int reportid_idx = 0; reportid_idx < 256; reportid_idx++) {
|
||||
for (HIDP_REPORT_TYPE rt_idx = 0; rt_idx < NUM_OF_HIDP_REPORT_TYPES; rt_idx++) {
|
||||
free(coll_bit_range[collection_node_idx][reportid_idx][rt_idx]);
|
||||
}
|
||||
free(coll_bit_range[collection_node_idx][reportid_idx]);
|
||||
}
|
||||
free(coll_bit_range[collection_node_idx]);
|
||||
if (coll_number_of_direct_childs[collection_node_idx] != 0) free(coll_child_order[collection_node_idx]);
|
||||
}
|
||||
free(coll_bit_range);
|
||||
free(coll_child_order);
|
||||
|
||||
// Free one dimensional arrays
|
||||
free(coll_begin_lookup);
|
||||
free(coll_end_lookup);
|
||||
free(coll_levels);
|
||||
free(coll_number_of_direct_childs);
|
||||
|
||||
return (int) rpt_desc.byte_idx;
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
/*******************************************************
|
||||
HIDAPI - Multi-Platform library for
|
||||
communication with HID devices.
|
||||
|
||||
libusb/hidapi Team
|
||||
|
||||
Copyright 2022, All Rights Reserved.
|
||||
|
||||
At the discretion of the user of this library,
|
||||
this software may be licensed under the terms of the
|
||||
GNU General Public License v3, a BSD-Style license, or the
|
||||
original HIDAPI license as outlined in the LICENSE.txt,
|
||||
LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
|
||||
files located at the root of the source distribution.
|
||||
These files may also be found in the public source
|
||||
code repository located at:
|
||||
https://github.com/libusb/hidapi .
|
||||
********************************************************/
|
||||
#ifndef HIDAPI_DESCRIPTOR_RECONSTRUCT_H__
|
||||
#define HIDAPI_DESCRIPTOR_RECONSTRUCT_H__
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
/* Do not warn about wcsncpy usage.
|
||||
https://docs.microsoft.com/cpp/c-runtime-library/security-features-in-the-crt */
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include "hidapi_winapi.h"
|
||||
|
||||
#if _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4200)
|
||||
#pragma warning(disable: 4201)
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "hidapi_hidsdi.h"
|
||||
|
||||
#define NUM_OF_HIDP_REPORT_TYPES 3
|
||||
|
||||
typedef enum rd_items_ {
|
||||
rd_main_input = 0x80, /* 1000 00 nn */
|
||||
rd_main_output = 0x90, /* 1001 00 nn */
|
||||
rd_main_feature = 0xB0, /* 1011 00 nn */
|
||||
rd_main_collection = 0xA0, /* 1010 00 nn */
|
||||
rd_main_collection_end = 0xC0, /* 1100 00 nn */
|
||||
rd_global_usage_page = 0x04, /* 0000 01 nn */
|
||||
rd_global_logical_minimum = 0x14, /* 0001 01 nn */
|
||||
rd_global_logical_maximum = 0x24, /* 0010 01 nn */
|
||||
rd_global_physical_minimum = 0x34, /* 0011 01 nn */
|
||||
rd_global_physical_maximum = 0x44, /* 0100 01 nn */
|
||||
rd_global_unit_exponent = 0x54, /* 0101 01 nn */
|
||||
rd_global_unit = 0x64, /* 0110 01 nn */
|
||||
rd_global_report_size = 0x74, /* 0111 01 nn */
|
||||
rd_global_report_id = 0x84, /* 1000 01 nn */
|
||||
rd_global_report_count = 0x94, /* 1001 01 nn */
|
||||
rd_global_push = 0xA4, /* 1010 01 nn */
|
||||
rd_global_pop = 0xB4, /* 1011 01 nn */
|
||||
rd_local_usage = 0x08, /* 0000 10 nn */
|
||||
rd_local_usage_minimum = 0x18, /* 0001 10 nn */
|
||||
rd_local_usage_maximum = 0x28, /* 0010 10 nn */
|
||||
rd_local_designator_index = 0x38, /* 0011 10 nn */
|
||||
rd_local_designator_minimum = 0x48, /* 0100 10 nn */
|
||||
rd_local_designator_maximum = 0x58, /* 0101 10 nn */
|
||||
rd_local_string = 0x78, /* 0111 10 nn */
|
||||
rd_local_string_minimum = 0x88, /* 1000 10 nn */
|
||||
rd_local_string_maximum = 0x98, /* 1001 10 nn */
|
||||
rd_local_delimiter = 0xA8 /* 1010 10 nn */
|
||||
} rd_items;
|
||||
|
||||
typedef enum rd_main_items_ {
|
||||
rd_input = HidP_Input,
|
||||
rd_output = HidP_Output,
|
||||
rd_feature = HidP_Feature,
|
||||
rd_collection,
|
||||
rd_collection_end,
|
||||
rd_delimiter_open,
|
||||
rd_delimiter_usage,
|
||||
rd_delimiter_close,
|
||||
} rd_main_items;
|
||||
|
||||
typedef struct rd_bit_range_ {
|
||||
int FirstBit;
|
||||
int LastBit;
|
||||
} rd_bit_range;
|
||||
|
||||
typedef enum rd_item_node_type_ {
|
||||
rd_item_node_cap,
|
||||
rd_item_node_padding,
|
||||
rd_item_node_collection,
|
||||
} rd_node_type;
|
||||
|
||||
struct rd_main_item_node {
|
||||
int FirstBit; /* Position of first bit in report (counting from 0) */
|
||||
int LastBit; /* Position of last bit in report (counting from 0) */
|
||||
rd_node_type TypeOfNode; /* Information if caps index refers to the array of button caps, value caps,
|
||||
or if the node is just a padding element to fill unused bit positions.
|
||||
The node can also be a collection node without any bits in the report. */
|
||||
int CapsIndex; /* Index in the array of caps */
|
||||
int CollectionIndex; /* Index in the array of link collections */
|
||||
rd_main_items MainItemType; /* Input, Output, Feature, Collection or Collection End */
|
||||
unsigned char ReportID;
|
||||
struct rd_main_item_node* next;
|
||||
};
|
||||
|
||||
typedef struct hid_pp_caps_info_ {
|
||||
USHORT FirstCap;
|
||||
USHORT NumberOfCaps; // Includes empty caps after LastCap
|
||||
USHORT LastCap;
|
||||
USHORT ReportByteLength;
|
||||
} hid_pp_caps_info, *phid_pp_caps_info;
|
||||
|
||||
typedef struct hid_pp_link_collection_node_ {
|
||||
USAGE LinkUsage;
|
||||
USAGE LinkUsagePage;
|
||||
USHORT Parent;
|
||||
USHORT NumberOfChildren;
|
||||
USHORT NextSibling;
|
||||
USHORT FirstChild;
|
||||
ULONG CollectionType : 8;
|
||||
ULONG IsAlias : 1;
|
||||
ULONG Reserved : 23;
|
||||
// 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;
|
||||
|
||||
typedef struct hidp_unknown_token_ {
|
||||
UCHAR Token; /* Specifies the one-byte prefix of a global item. */
|
||||
UCHAR Reserved[3];
|
||||
ULONG BitField; /* Specifies the data part of the global item. */
|
||||
} hidp_unknown_token, * phidp_unknown_token;
|
||||
|
||||
typedef struct hid_pp_cap_ {
|
||||
USAGE UsagePage;
|
||||
UCHAR ReportID;
|
||||
UCHAR BitPosition;
|
||||
USHORT ReportSize; // WIN32 term for this is BitSize
|
||||
USHORT ReportCount;
|
||||
USHORT BytePosition;
|
||||
USHORT BitCount;
|
||||
ULONG BitField;
|
||||
USHORT NextBytePosition;
|
||||
USHORT LinkCollection;
|
||||
USAGE LinkUsagePage;
|
||||
USAGE LinkUsage;
|
||||
|
||||
// Start of 8 Flags in one byte
|
||||
BOOLEAN IsMultipleItemsForArray:1;
|
||||
|
||||
BOOLEAN IsPadding:1;
|
||||
BOOLEAN IsButtonCap:1;
|
||||
BOOLEAN IsAbsolute:1;
|
||||
BOOLEAN IsRange:1;
|
||||
BOOLEAN IsAlias:1; // IsAlias is set to TRUE in the first n-1 capability structures added to the capability array. IsAlias set to FALSE in the nth capability structure.
|
||||
BOOLEAN IsStringRange:1;
|
||||
BOOLEAN IsDesignatorRange:1;
|
||||
// End of 8 Flags in one byte
|
||||
BOOLEAN Reserved1[3];
|
||||
|
||||
hidp_unknown_token UnknownTokens[4]; // 4 x 8 Byte
|
||||
|
||||
union {
|
||||
struct {
|
||||
USAGE UsageMin;
|
||||
USAGE UsageMax;
|
||||
USHORT StringMin;
|
||||
USHORT StringMax;
|
||||
USHORT DesignatorMin;
|
||||
USHORT DesignatorMax;
|
||||
USHORT DataIndexMin;
|
||||
USHORT DataIndexMax;
|
||||
} Range;
|
||||
struct {
|
||||
USAGE Usage;
|
||||
USAGE Reserved1;
|
||||
USHORT StringIndex;
|
||||
USHORT Reserved2;
|
||||
USHORT DesignatorIndex;
|
||||
USHORT Reserved3;
|
||||
USHORT DataIndex;
|
||||
USHORT Reserved4;
|
||||
} NotRange;
|
||||
};
|
||||
union {
|
||||
struct {
|
||||
LONG LogicalMin;
|
||||
LONG LogicalMax;
|
||||
} Button;
|
||||
struct {
|
||||
BOOLEAN HasNull;
|
||||
UCHAR Reserved4[3];
|
||||
LONG LogicalMin;
|
||||
LONG LogicalMax;
|
||||
LONG PhysicalMin;
|
||||
LONG PhysicalMax;
|
||||
} NotButton;
|
||||
};
|
||||
ULONG Units;
|
||||
ULONG UnitsExp;
|
||||
|
||||
} hid_pp_cap, *phid_pp_cap;
|
||||
|
||||
typedef struct hidp_preparsed_data_ {
|
||||
UCHAR MagicKey[8];
|
||||
USAGE Usage;
|
||||
USAGE UsagePage;
|
||||
USHORT Reserved[2];
|
||||
|
||||
// CAPS structure for Input, Output and Feature
|
||||
hid_pp_caps_info caps_info[3];
|
||||
|
||||
USHORT FirstByteOfLinkCollectionArray;
|
||||
USHORT NumberLinkCollectionNodes;
|
||||
|
||||
#if defined(__MINGW32__) || defined(__CYGWIN__)
|
||||
// MINGW fails with: Flexible array member in union not supported
|
||||
// Solution: https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
|
||||
union {
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpedantic"
|
||||
hid_pp_cap caps[0];
|
||||
hid_pp_link_collection_node LinkCollectionArray[0];
|
||||
#pragma GCC diagnostic pop
|
||||
};
|
||||
#else
|
||||
union {
|
||||
hid_pp_cap caps[];
|
||||
hid_pp_link_collection_node LinkCollectionArray[];
|
||||
};
|
||||
#endif
|
||||
|
||||
} hidp_preparsed_data;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -29,6 +29,13 @@
|
||||
/* This part of the header mimics hidpi.h,
|
||||
but only what is used by HIDAPI */
|
||||
|
||||
typedef enum _HIDP_REPORT_TYPE
|
||||
{
|
||||
HidP_Input,
|
||||
HidP_Output,
|
||||
HidP_Feature
|
||||
} HIDP_REPORT_TYPE;
|
||||
|
||||
typedef struct _HIDP_PREPARSED_DATA * PHIDP_PREPARSED_DATA;
|
||||
|
||||
typedef struct _HIDP_CAPS
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#ifndef HIDAPI_WINAPI_H__
|
||||
#define HIDAPI_WINAPI_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <guiddef.h>
|
||||
|
||||
#include "hidapi.h"
|
||||
@@ -51,6 +53,20 @@ extern "C" {
|
||||
*/
|
||||
int HID_API_EXPORT_CALL hid_winapi_get_container_id(hid_device *dev, GUID *container_id);
|
||||
|
||||
/**
|
||||
* @brief Reconstructs a HID Report Descriptor from a Win32 HIDP_PREPARSED_DATA structure.
|
||||
* This reconstructed report descriptor is logical identical to the real report descriptor,
|
||||
* but not byte wise identical.
|
||||
*
|
||||
* @param[in] hidp_preparsed_data Pointer to the HIDP_PREPARSED_DATA to read, i.e.: the value of PHIDP_PREPARSED_DATA,
|
||||
* as returned by HidD_GetPreparsedData WinAPI function.
|
||||
* @param buf Pointer to the buffer where the report descriptor should be stored.
|
||||
* @param[in] buf_size Size of the buffer. The recommended size for the buffer is @ref HID_API_MAX_REPORT_DESCRIPTOR_SIZE bytes.
|
||||
*
|
||||
* @return Returns size of reconstructed report descriptor if successful, -1 for error.
|
||||
*/
|
||||
int HID_API_EXPORT_CALL hid_winapi_descriptor_reconstruct_pp_data(void *hidp_preparsed_data, unsigned char *buf, size_t buf_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
project(pp_data_dump C)
|
||||
|
||||
add_executable(pp_data_dump pp_data_dump.c)
|
||||
set_target_properties(pp_data_dump
|
||||
PROPERTIES
|
||||
C_STANDARD 11
|
||||
C_STANDARD_REQUIRED TRUE
|
||||
)
|
||||
target_link_libraries(pp_data_dump
|
||||
PRIVATE hidapi_winapi
|
||||
)
|
||||
|
||||
install(TARGETS pp_data_dump
|
||||
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||
)
|
||||
@@ -0,0 +1,122 @@
|
||||
## pp_data_dump.exe for Windows
|
||||
|
||||
|
||||
pp_data_dump.exe is a small command line tool for Windows, which dumps the content of the [Preparsed Data](https://learn.microsoft.com/en-us/windows-hardware/drivers/hid/preparsed-data) structure, provided by the Windows HID subsystem, into a file.
|
||||
|
||||
The generated file is in a text format, which is readable for human, as by the hid_report_reconstructor_test.exe unit test executable of the HIDAPI project. This unit test allows it to test the HIDAPIs report descriptor reconstructor - offline, without the hardware device connected.
|
||||
|
||||
pp_data_dump.exe has no arguments, just connect you HID device and execute pp_data_dump.exe. It will generate one file with the name
|
||||
```
|
||||
<vendor_id>_<product_id>_<usage>_<usage_table>.pp_data
|
||||
```
|
||||
for each top-level collection, of each connected HID device.
|
||||
|
||||
|
||||
## File content
|
||||
|
||||
The content of such a .pp_data file looks like the struct, which HIDAPI uses internally to represent the Preparsed Data.
|
||||
|
||||
*NOTE:
|
||||
Windows parses HID report descriptors into opaque `_HIDP_PREPARSED_DATA` objects.
|
||||
The internal structure of `_HIDP_PREPARSED_DATA` is reserved for internal system use.\
|
||||
Microsoft doesn't document this structure. [hid_preparsed_data.cc](https://chromium.googlesource.com/chromium/src/+/73fdaaf605bb60caf34d5f30bb84a417688aa528/services/device/hid/hid_preparsed_data.cc) is taken as a reference for its parsing.*
|
||||
|
||||
```
|
||||
# HIDAPI device info struct:
|
||||
dev->vendor_id = 0x046D
|
||||
dev->product_id = 0xB010
|
||||
dev->manufacturer_string = "Logitech"
|
||||
dev->product_string = "Logitech Bluetooth Wireless Mouse"
|
||||
dev->release_number = 0x0000
|
||||
dev->interface_number = -1
|
||||
dev->usage = 0x0001
|
||||
dev->usage_page = 0x000C
|
||||
dev->path = "\\?\hid#{00001124-0000-1000-8000-00805f9b34fb}_vid&0002046d_pid&b010&col02#8&1cf1c1b9&3&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}"
|
||||
|
||||
# Preparsed Data struct:
|
||||
pp_data->MagicKey = 0x48696450204B4452
|
||||
pp_data->Usage = 0x0001
|
||||
pp_data->UsagePage = 0x000C
|
||||
pp_data->Reserved = 0x00000000
|
||||
# Input caps_info struct:
|
||||
pp_data->caps_info[0]->FirstCap = 0
|
||||
pp_data->caps_info[0]->LastCap = 1
|
||||
pp_data->caps_info[0]->NumberOfCaps = 1
|
||||
pp_data->caps_info[0]->ReportByteLength = 2
|
||||
# Output caps_info struct:
|
||||
pp_data->caps_info[1]->FirstCap = 1
|
||||
pp_data->caps_info[1]->LastCap = 1
|
||||
pp_data->caps_info[1]->NumberOfCaps = 0
|
||||
pp_data->caps_info[1]->ReportByteLength = 0
|
||||
# Feature caps_info struct:
|
||||
pp_data->caps_info[2]->FirstCap = 1
|
||||
pp_data->caps_info[2]->LastCap = 1
|
||||
pp_data->caps_info[2]->NumberOfCaps = 0
|
||||
pp_data->caps_info[2]->ReportByteLength = 0
|
||||
# LinkCollectionArray Offset & Size:
|
||||
pp_data->FirstByteOfLinkCollectionArray = 0x0068
|
||||
pp_data->NumberLinkCollectionNodes = 1
|
||||
# Input hid_pp_cap struct:
|
||||
pp_data->cap[0]->UsagePage = 0x0006
|
||||
pp_data->cap[0]->ReportID = 0x03
|
||||
pp_data->cap[0]->BitPosition = 0
|
||||
pp_data->cap[0]->BitSize = 8
|
||||
pp_data->cap[0]->ReportCount = 1
|
||||
pp_data->cap[0]->BytePosition = 0x0001
|
||||
pp_data->cap[0]->BitCount = 8
|
||||
pp_data->cap[0]->BitField = 0x02
|
||||
pp_data->cap[0]->NextBytePosition = 0x0002
|
||||
pp_data->cap[0]->LinkCollection = 0x0000
|
||||
pp_data->cap[0]->LinkUsagePage = 0x000C
|
||||
pp_data->cap[0]->LinkUsage = 0x0001
|
||||
pp_data->cap[0]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[0]->IsButtonCap = 0
|
||||
pp_data->cap[0]->IsPadding = 0
|
||||
pp_data->cap[0]->IsAbsolute = 1
|
||||
pp_data->cap[0]->IsRange = 0
|
||||
pp_data->cap[0]->IsAlias = 0
|
||||
pp_data->cap[0]->IsStringRange = 0
|
||||
pp_data->cap[0]->IsDesignatorRange = 0
|
||||
pp_data->cap[0]->Reserved1 = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[0]->NotRange.Usage = 0x0020
|
||||
pp_data->cap[0]->NotRange.Reserved1 = 0x0020
|
||||
pp_data->cap[0]->NotRange.StringIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[0]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[0]->NotRange.DataIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved4 = 0
|
||||
pp_data->cap[0]->NotButton.HasNull = 0
|
||||
pp_data->cap[0]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[0]->NotButton.LogicalMin = 0
|
||||
pp_data->cap[0]->NotButton.LogicalMax = 100
|
||||
pp_data->cap[0]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[0]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[0]->Units = 0
|
||||
pp_data->cap[0]->UnitsExp = 0
|
||||
|
||||
# Output hid_pp_cap struct:
|
||||
# Feature hid_pp_cap struct:
|
||||
# Link Collections:
|
||||
pp_data->LinkCollectionArray[0]->LinkUsage = 0x0001
|
||||
pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x000C
|
||||
pp_data->LinkCollectionArray[0]->Parent = 0
|
||||
pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[0]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[0]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[0]->CollectionType = 1
|
||||
pp_data->LinkCollectionArray[0]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
|
||||
```
|
||||
@@ -0,0 +1,238 @@
|
||||
|
||||
|
||||
#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);
|
||||
|
||||
// 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[%d]->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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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[%d]->Units = %lu\n", cap_idx, pp_cap->Units);
|
||||
fprintf(file, "pp_data->cap[%d]->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);
|
||||
}
|
||||
|
||||
int dump_pp_data(FILE* file, hid_device* dev)
|
||||
{
|
||||
BOOL res;
|
||||
hidp_preparsed_data* pp_data = NULL;
|
||||
|
||||
res = HidD_GetPreparsedData(dev->device_handle, (PHIDP_PREPARSED_DATA*) &pp_data);
|
||||
if (!res) {
|
||||
printf("ERROR: HidD_GetPreparsedData failed!");
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
fprintf(file, "pp_data->MagicKey = 0x%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX\n", pp_data->MagicKey[0], pp_data->MagicKey[1], pp_data->MagicKey[2], pp_data->MagicKey[3], pp_data->MagicKey[4], pp_data->MagicKey[5], pp_data->MagicKey[6], pp_data->MagicKey[7]);
|
||||
fprintf(file, "pp_data->Usage = 0x%04hX\n", pp_data->Usage);
|
||||
fprintf(file, "pp_data->UsagePage = 0x%04hX\n", pp_data->UsagePage);
|
||||
fprintf(file, "pp_data->Reserved = 0x%04hX%04hX\n", pp_data->Reserved[0], pp_data->Reserved[1]);
|
||||
fprintf(file, "# Input caps_info struct:\n");
|
||||
fprintf(file, "pp_data->caps_info[0]->FirstCap = %hu\n", pp_data->caps_info[0].FirstCap);
|
||||
fprintf(file, "pp_data->caps_info[0]->LastCap = %hu\n", pp_data->caps_info[0].LastCap);
|
||||
fprintf(file, "pp_data->caps_info[0]->NumberOfCaps = %hu\n", pp_data->caps_info[0].NumberOfCaps);
|
||||
fprintf(file, "pp_data->caps_info[0]->ReportByteLength = %hu\n", pp_data->caps_info[0].ReportByteLength);
|
||||
fprintf(file, "# Output caps_info struct:\n");
|
||||
fprintf(file, "pp_data->caps_info[1]->FirstCap = %hu\n", pp_data->caps_info[1].FirstCap);
|
||||
fprintf(file, "pp_data->caps_info[1]->LastCap = %hu\n", pp_data->caps_info[1].LastCap);
|
||||
fprintf(file, "pp_data->caps_info[1]->NumberOfCaps = %hu\n", pp_data->caps_info[1].NumberOfCaps);
|
||||
fprintf(file, "pp_data->caps_info[1]->ReportByteLength = %hu\n", pp_data->caps_info[1].ReportByteLength);
|
||||
fprintf(file, "# Feature caps_info struct:\n");
|
||||
fprintf(file, "pp_data->caps_info[2]->FirstCap = %hu\n", pp_data->caps_info[2].FirstCap);
|
||||
fprintf(file, "pp_data->caps_info[2]->LastCap = %hu\n", pp_data->caps_info[2].LastCap);
|
||||
fprintf(file, "pp_data->caps_info[2]->NumberOfCaps = %hu\n", pp_data->caps_info[2].NumberOfCaps);
|
||||
fprintf(file, "pp_data->caps_info[2]->ReportByteLength = %hu\n", pp_data->caps_info[2].ReportByteLength);
|
||||
fprintf(file, "# LinkCollectionArray Offset & Size:\n");
|
||||
fprintf(file, "pp_data->FirstByteOfLinkCollectionArray = 0x%04hX\n", pp_data->FirstByteOfLinkCollectionArray);
|
||||
fprintf(file, "pp_data->NumberLinkCollectionNodes = %hu\n", pp_data->NumberLinkCollectionNodes);
|
||||
|
||||
|
||||
phid_pp_cap pcap = (phid_pp_cap)(((unsigned char*)pp_data) + offsetof(hidp_preparsed_data, caps));
|
||||
fprintf(file, "# Input hid_pp_cap struct:\n");
|
||||
for (int caps_idx = pp_data->caps_info[0].FirstCap; caps_idx < pp_data->caps_info[0].LastCap; caps_idx++) {
|
||||
dump_hid_pp_cap(file, pcap + caps_idx, caps_idx);
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
fprintf(file, "# Output hid_pp_cap struct:\n");
|
||||
for (int caps_idx = pp_data->caps_info[1].FirstCap; caps_idx < pp_data->caps_info[1].LastCap; caps_idx++) {
|
||||
dump_hid_pp_cap(file, pcap + caps_idx, caps_idx);
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
fprintf(file, "# Feature hid_pp_cap struct:\n");
|
||||
for (int caps_idx = pp_data->caps_info[2].FirstCap; caps_idx < pp_data->caps_info[2].LastCap; caps_idx++) {
|
||||
dump_hid_pp_cap(file, pcap + caps_idx, caps_idx);
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
|
||||
phid_pp_link_collection_node pcoll = (phid_pp_link_collection_node)(((unsigned char*)pcap) + pp_data->FirstByteOfLinkCollectionArray);
|
||||
fprintf(file, "# Link Collections:\n");
|
||||
for (int coll_idx = 0; coll_idx < pp_data->NumberLinkCollectionNodes; coll_idx++) {
|
||||
dump_hidp_link_collection_node(file, pcoll + coll_idx, coll_idx);
|
||||
}
|
||||
|
||||
HidD_FreePreparsedData((PHIDP_PREPARSED_DATA) pp_data);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
#define MAX_STR 255
|
||||
|
||||
struct hid_device_info *devs, *cur_dev;
|
||||
|
||||
printf("pp_data_dump tool. Compiled with hidapi version %s, runtime version %s.\n", HID_API_VERSION_STR, hid_version_str());
|
||||
if (hid_version()->major == HID_API_VERSION_MAJOR && hid_version()->minor == HID_API_VERSION_MINOR && hid_version()->patch == HID_API_VERSION_PATCH) {
|
||||
printf("Compile-time version matches runtime version of hidapi.\n\n");
|
||||
}
|
||||
else {
|
||||
printf("Compile-time version is different than runtime version of hidapi.\n]n");
|
||||
}
|
||||
|
||||
if (hid_init())
|
||||
return -1;
|
||||
|
||||
devs = hid_enumerate(0x0, 0x0);
|
||||
cur_dev = devs;
|
||||
while (cur_dev) {
|
||||
printf("Device Found\n type: %04hx %04hx\n path: %s\n serial_number: %ls", cur_dev->vendor_id, cur_dev->product_id, cur_dev->path, cur_dev->serial_number);
|
||||
printf("\n");
|
||||
printf(" Manufacturer: %ls\n", cur_dev->manufacturer_string);
|
||||
printf(" Product: %ls\n", cur_dev->product_string);
|
||||
printf(" Release: %hX\n", cur_dev->release_number);
|
||||
printf(" Interface: %d\n", cur_dev->interface_number);
|
||||
printf(" Usage (page): %02X (%02X)\n", cur_dev->usage, cur_dev->usage_page);
|
||||
|
||||
hid_device *device = hid_open_path(cur_dev->path);
|
||||
if (device) {
|
||||
char filename[MAX_STR];
|
||||
FILE* file;
|
||||
|
||||
sprintf_s(filename, MAX_STR, "%04X_%04X_%04X_%04X.pp_data", cur_dev->vendor_id, cur_dev->product_id, cur_dev->usage, cur_dev->usage_page);
|
||||
errno_t err = fopen_s(&file, filename, "w");
|
||||
if (err == 0) {
|
||||
fprintf(file, "# HIDAPI device info struct:\n");
|
||||
fprintf(file, "dev->vendor_id = 0x%04hX\n", cur_dev->vendor_id);
|
||||
fprintf(file, "dev->product_id = 0x%04hX\n", cur_dev->product_id);
|
||||
fprintf(file, "dev->manufacturer_string = \"%ls\"\n", cur_dev->manufacturer_string);
|
||||
fprintf(file, "dev->product_string = \"%ls\"\n", cur_dev->product_string);
|
||||
fprintf(file, "dev->release_number = 0x%04hX\n", cur_dev->release_number);
|
||||
fprintf(file, "dev->interface_number = %d\n", cur_dev->interface_number);
|
||||
fprintf(file, "dev->usage = 0x%04hX\n", cur_dev->usage);
|
||||
fprintf(file, "dev->usage_page = 0x%04hX\n", cur_dev->usage_page);
|
||||
fprintf(file, "dev->path = \"%s\"\n", cur_dev->path);
|
||||
fprintf(file, "\n# Preparsed Data struct:\n");
|
||||
int res = dump_pp_data(file, device);
|
||||
|
||||
if (res == 0) {
|
||||
printf("Dumped Preparsed Data to %s\n", filename);
|
||||
}
|
||||
else {
|
||||
printf("ERROR: Dump Preparsed Data to %s failed!\n", filename);
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
hid_close(device);
|
||||
}
|
||||
else {
|
||||
printf(" Device: not available.\n");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
cur_dev = cur_dev->next;
|
||||
}
|
||||
hid_free_enumeration(devs);
|
||||
|
||||
|
||||
/* Free static HIDAPI objects. */
|
||||
hid_exit();
|
||||
|
||||
//system("pause");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
add_executable(hid_report_reconstructor_test hid_report_reconstructor_test.c)
|
||||
set_target_properties(hid_report_reconstructor_test
|
||||
PROPERTIES
|
||||
C_STANDARD 11
|
||||
C_STANDARD_REQUIRED TRUE
|
||||
)
|
||||
|
||||
target_link_libraries(hid_report_reconstructor_test
|
||||
PRIVATE hidapi_include hidapi_winapi
|
||||
)
|
||||
|
||||
# Each test case requires 2 files:
|
||||
# <name>.pp_data - textual representation of HIDP_PREPARSED_DATA;
|
||||
# <name>_expected.rpt_desc - reconstructed HID Report Descriptor out of .pp_data file;
|
||||
#
|
||||
# (Non-required by test):
|
||||
# <name>_real.dpt_desc - the original report rescriptor used to create a test case;
|
||||
set(HID_DESCRIPTOR_RECONSTRUCT_TEST_CASES
|
||||
046D_C52F_0001_000C
|
||||
046D_C52F_0001_FF00
|
||||
046D_C52F_0002_0001
|
||||
046D_C52F_0002_FF00
|
||||
17CC_1130_0000_FF01
|
||||
046D_0A37_0001_000C
|
||||
046A_0011_0006_0001
|
||||
046D_C077_0002_0001
|
||||
046D_C283_0004_0001
|
||||
046D_B010_0006_0001
|
||||
046D_B010_0002_FF00
|
||||
046D_B010_0002_0001
|
||||
046D_B010_0001_FF00
|
||||
046D_B010_0001_000C
|
||||
046D_C534_0001_000C
|
||||
046D_C534_0001_FF00
|
||||
046D_C534_0002_0001
|
||||
046D_C534_0002_FF00
|
||||
046D_C534_0006_0001
|
||||
046D_C534_0080_0001
|
||||
047F_C056_0001_000C
|
||||
047F_C056_0003_FFA0
|
||||
047F_C056_0005_000B
|
||||
045E_02FF_0005_0001
|
||||
)
|
||||
|
||||
set(CMAKE_VERSION_SUPPORTS_ENVIRONMENT_MODIFICATION "3.22")
|
||||
|
||||
if(HIDAPI_ENABLE_ASAN AND MSVC)
|
||||
if(CMAKE_VERSION VERSION_LESS CMAKE_VERSION_SUPPORTS_ENVIRONMENT_MODIFICATION)
|
||||
message("CTest/ASAN: Make sure to run ctest from MSVC Command Prompt")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
foreach(TEST_CASE ${HID_DESCRIPTOR_RECONSTRUCT_TEST_CASES})
|
||||
set(TEST_PP_DATA "${CMAKE_CURRENT_LIST_DIR}/data/${TEST_CASE}.pp_data")
|
||||
if(NOT EXISTS "${TEST_PP_DATA}")
|
||||
message(FATAL_ERROR "Missing '${TEST_PP_DATA}' file for '${TEST_CASE}' test case")
|
||||
endif()
|
||||
set(TEST_EXPECTED_DESCRIPTOR "${CMAKE_CURRENT_LIST_DIR}/data/${TEST_CASE}_expected.rpt_desc")
|
||||
if(NOT EXISTS "${TEST_EXPECTED_DESCRIPTOR}")
|
||||
message(FATAL_ERROR "Missing '${TEST_EXPECTED_DESCRIPTOR}' file for '${TEST_CASE}' test case")
|
||||
endif()
|
||||
|
||||
add_test(NAME "WinHidReportReconstructTest_${TEST_CASE}"
|
||||
COMMAND hid_report_reconstructor_test "${TEST_PP_DATA}" "${TEST_EXPECTED_DESCRIPTOR}"
|
||||
WORKING_DIRECTORY "$<TARGET_FILE_DIR:hidapi_winapi>"
|
||||
)
|
||||
if(HIDAPI_ENABLE_ASAN)
|
||||
if(MSVC)
|
||||
if(NOT CMAKE_VERSION VERSION_LESS CMAKE_VERSION_SUPPORTS_ENVIRONMENT_MODIFICATION)
|
||||
get_filename_component(MSVC_BUILD_TOOLS_DIR "${CMAKE_LINKER}" DIRECTORY)
|
||||
set_property(TEST "WinHidReportReconstructTest_${TEST_CASE}" PROPERTY ENVIRONMENT_MODIFICATION "PATH=path_list_append:${MSVC_BUILD_TOOLS_DIR}")
|
||||
endif()
|
||||
endif()
|
||||
set_property(TEST "WinHidReportReconstructTest_${TEST_CASE}" PROPERTY ENVIRONMENT "ASAN_SAVE_DUMPS=AsanDump_${TEST_CASE}.dmp")
|
||||
endif()
|
||||
endforeach()
|
||||
@@ -0,0 +1,420 @@
|
||||
# HIDAPI device info struct:
|
||||
dev->vendor_id = 0x045E
|
||||
dev->product_id = 0x02FF
|
||||
dev->manufacturer_string = ""
|
||||
dev->product_string = "Controller (Xbox One For Windows)"
|
||||
dev->release_number = 0x0000
|
||||
dev->interface_number = -1
|
||||
dev->usage = 0x0005
|
||||
dev->usage_page = 0x0001
|
||||
dev->path = "\\?\HID#VID_045E&PID_02FF&IG_00#7&5ea4a81&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
|
||||
|
||||
# Preparsed Data struct:
|
||||
pp_data->MagicKey = 0x48696450204B4452
|
||||
pp_data->Usage = 0x0005
|
||||
pp_data->UsagePage = 0x0001
|
||||
pp_data->Reserved = 0x00000000
|
||||
# Input caps_info struct:
|
||||
pp_data->caps_info[0]->FirstCap = 0
|
||||
pp_data->caps_info[0]->LastCap = 7
|
||||
pp_data->caps_info[0]->NumberOfCaps = 7
|
||||
pp_data->caps_info[0]->ReportByteLength = 16
|
||||
# Output caps_info struct:
|
||||
pp_data->caps_info[1]->FirstCap = 7
|
||||
pp_data->caps_info[1]->LastCap = 7
|
||||
pp_data->caps_info[1]->NumberOfCaps = 0
|
||||
pp_data->caps_info[1]->ReportByteLength = 0
|
||||
# Feature caps_info struct:
|
||||
pp_data->caps_info[2]->FirstCap = 7
|
||||
pp_data->caps_info[2]->LastCap = 7
|
||||
pp_data->caps_info[2]->NumberOfCaps = 0
|
||||
pp_data->caps_info[2]->ReportByteLength = 0
|
||||
# LinkCollectionArray Offset & Size:
|
||||
pp_data->FirstByteOfLinkCollectionArray = 0x02D8
|
||||
pp_data->NumberLinkCollectionNodes = 4
|
||||
# Input hid_pp_cap struct:
|
||||
pp_data->cap[0]->UsagePage = 0x0001
|
||||
pp_data->cap[0]->ReportID = 0x00
|
||||
pp_data->cap[0]->BitPosition = 0
|
||||
pp_data->cap[0]->BitSize = 16
|
||||
pp_data->cap[0]->ReportCount = 1
|
||||
pp_data->cap[0]->BytePosition = 0x0003
|
||||
pp_data->cap[0]->BitCount = 16
|
||||
pp_data->cap[0]->BitField = 0x02
|
||||
pp_data->cap[0]->NextBytePosition = 0x0005
|
||||
pp_data->cap[0]->LinkCollection = 0x0001
|
||||
pp_data->cap[0]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[0]->LinkUsage = 0x0000
|
||||
pp_data->cap[0]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[0]->IsButtonCap = 0
|
||||
pp_data->cap[0]->IsPadding = 0
|
||||
pp_data->cap[0]->IsAbsolute = 1
|
||||
pp_data->cap[0]->IsRange = 0
|
||||
pp_data->cap[0]->IsAlias = 0
|
||||
pp_data->cap[0]->IsStringRange = 0
|
||||
pp_data->cap[0]->IsDesignatorRange = 0
|
||||
pp_data->cap[0]->Reserved1 = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[0]->NotRange.Usage = 0x0031
|
||||
pp_data->cap[0]->NotRange.Reserved1 = 0x0031
|
||||
pp_data->cap[0]->NotRange.StringIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[0]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[0]->NotRange.DataIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved4 = 0
|
||||
pp_data->cap[0]->NotButton.HasNull = 0
|
||||
pp_data->cap[0]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[0]->NotButton.LogicalMin = 0
|
||||
pp_data->cap[0]->NotButton.LogicalMax = -1
|
||||
pp_data->cap[0]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[0]->NotButton.PhysicalMax = -1
|
||||
pp_data->cap[0]->Units = 0
|
||||
pp_data->cap[0]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[1]->UsagePage = 0x0001
|
||||
pp_data->cap[1]->ReportID = 0x00
|
||||
pp_data->cap[1]->BitPosition = 0
|
||||
pp_data->cap[1]->BitSize = 16
|
||||
pp_data->cap[1]->ReportCount = 1
|
||||
pp_data->cap[1]->BytePosition = 0x0001
|
||||
pp_data->cap[1]->BitCount = 16
|
||||
pp_data->cap[1]->BitField = 0x02
|
||||
pp_data->cap[1]->NextBytePosition = 0x0003
|
||||
pp_data->cap[1]->LinkCollection = 0x0001
|
||||
pp_data->cap[1]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[1]->LinkUsage = 0x0000
|
||||
pp_data->cap[1]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[1]->IsButtonCap = 0
|
||||
pp_data->cap[1]->IsPadding = 0
|
||||
pp_data->cap[1]->IsAbsolute = 1
|
||||
pp_data->cap[1]->IsRange = 0
|
||||
pp_data->cap[1]->IsAlias = 0
|
||||
pp_data->cap[1]->IsStringRange = 0
|
||||
pp_data->cap[1]->IsDesignatorRange = 0
|
||||
pp_data->cap[1]->Reserved1 = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[1]->NotRange.Usage = 0x0030
|
||||
pp_data->cap[1]->NotRange.Reserved1 = 0x0030
|
||||
pp_data->cap[1]->NotRange.StringIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[1]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[1]->NotRange.DataIndex = 1
|
||||
pp_data->cap[1]->NotRange.Reserved4 = 1
|
||||
pp_data->cap[1]->NotButton.HasNull = 0
|
||||
pp_data->cap[1]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[1]->NotButton.LogicalMin = 0
|
||||
pp_data->cap[1]->NotButton.LogicalMax = -1
|
||||
pp_data->cap[1]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[1]->NotButton.PhysicalMax = -1
|
||||
pp_data->cap[1]->Units = 0
|
||||
pp_data->cap[1]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[2]->UsagePage = 0x0001
|
||||
pp_data->cap[2]->ReportID = 0x00
|
||||
pp_data->cap[2]->BitPosition = 0
|
||||
pp_data->cap[2]->BitSize = 16
|
||||
pp_data->cap[2]->ReportCount = 1
|
||||
pp_data->cap[2]->BytePosition = 0x0007
|
||||
pp_data->cap[2]->BitCount = 16
|
||||
pp_data->cap[2]->BitField = 0x02
|
||||
pp_data->cap[2]->NextBytePosition = 0x0009
|
||||
pp_data->cap[2]->LinkCollection = 0x0002
|
||||
pp_data->cap[2]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[2]->LinkUsage = 0x0000
|
||||
pp_data->cap[2]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[2]->IsButtonCap = 0
|
||||
pp_data->cap[2]->IsPadding = 0
|
||||
pp_data->cap[2]->IsAbsolute = 1
|
||||
pp_data->cap[2]->IsRange = 0
|
||||
pp_data->cap[2]->IsAlias = 0
|
||||
pp_data->cap[2]->IsStringRange = 0
|
||||
pp_data->cap[2]->IsDesignatorRange = 0
|
||||
pp_data->cap[2]->Reserved1 = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[2]->NotRange.Usage = 0x0034
|
||||
pp_data->cap[2]->NotRange.Reserved1 = 0x0034
|
||||
pp_data->cap[2]->NotRange.StringIndex = 0
|
||||
pp_data->cap[2]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[2]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[2]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[2]->NotRange.DataIndex = 2
|
||||
pp_data->cap[2]->NotRange.Reserved4 = 2
|
||||
pp_data->cap[2]->NotButton.HasNull = 0
|
||||
pp_data->cap[2]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[2]->NotButton.LogicalMin = 0
|
||||
pp_data->cap[2]->NotButton.LogicalMax = -1
|
||||
pp_data->cap[2]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[2]->NotButton.PhysicalMax = -1
|
||||
pp_data->cap[2]->Units = 0
|
||||
pp_data->cap[2]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[3]->UsagePage = 0x0001
|
||||
pp_data->cap[3]->ReportID = 0x00
|
||||
pp_data->cap[3]->BitPosition = 0
|
||||
pp_data->cap[3]->BitSize = 16
|
||||
pp_data->cap[3]->ReportCount = 1
|
||||
pp_data->cap[3]->BytePosition = 0x0005
|
||||
pp_data->cap[3]->BitCount = 16
|
||||
pp_data->cap[3]->BitField = 0x02
|
||||
pp_data->cap[3]->NextBytePosition = 0x0007
|
||||
pp_data->cap[3]->LinkCollection = 0x0002
|
||||
pp_data->cap[3]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[3]->LinkUsage = 0x0000
|
||||
pp_data->cap[3]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[3]->IsButtonCap = 0
|
||||
pp_data->cap[3]->IsPadding = 0
|
||||
pp_data->cap[3]->IsAbsolute = 1
|
||||
pp_data->cap[3]->IsRange = 0
|
||||
pp_data->cap[3]->IsAlias = 0
|
||||
pp_data->cap[3]->IsStringRange = 0
|
||||
pp_data->cap[3]->IsDesignatorRange = 0
|
||||
pp_data->cap[3]->Reserved1 = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[3]->NotRange.Usage = 0x0033
|
||||
pp_data->cap[3]->NotRange.Reserved1 = 0x0033
|
||||
pp_data->cap[3]->NotRange.StringIndex = 0
|
||||
pp_data->cap[3]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[3]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[3]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[3]->NotRange.DataIndex = 3
|
||||
pp_data->cap[3]->NotRange.Reserved4 = 3
|
||||
pp_data->cap[3]->NotButton.HasNull = 0
|
||||
pp_data->cap[3]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[3]->NotButton.LogicalMin = 0
|
||||
pp_data->cap[3]->NotButton.LogicalMax = -1
|
||||
pp_data->cap[3]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[3]->NotButton.PhysicalMax = -1
|
||||
pp_data->cap[3]->Units = 0
|
||||
pp_data->cap[3]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[4]->UsagePage = 0x0001
|
||||
pp_data->cap[4]->ReportID = 0x00
|
||||
pp_data->cap[4]->BitPosition = 0
|
||||
pp_data->cap[4]->BitSize = 16
|
||||
pp_data->cap[4]->ReportCount = 1
|
||||
pp_data->cap[4]->BytePosition = 0x0009
|
||||
pp_data->cap[4]->BitCount = 16
|
||||
pp_data->cap[4]->BitField = 0x02
|
||||
pp_data->cap[4]->NextBytePosition = 0x000B
|
||||
pp_data->cap[4]->LinkCollection = 0x0003
|
||||
pp_data->cap[4]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[4]->LinkUsage = 0x0000
|
||||
pp_data->cap[4]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[4]->IsButtonCap = 0
|
||||
pp_data->cap[4]->IsPadding = 0
|
||||
pp_data->cap[4]->IsAbsolute = 1
|
||||
pp_data->cap[4]->IsRange = 0
|
||||
pp_data->cap[4]->IsAlias = 0
|
||||
pp_data->cap[4]->IsStringRange = 0
|
||||
pp_data->cap[4]->IsDesignatorRange = 0
|
||||
pp_data->cap[4]->Reserved1 = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[4]->NotRange.Usage = 0x0032
|
||||
pp_data->cap[4]->NotRange.Reserved1 = 0x0032
|
||||
pp_data->cap[4]->NotRange.StringIndex = 0
|
||||
pp_data->cap[4]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[4]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[4]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[4]->NotRange.DataIndex = 4
|
||||
pp_data->cap[4]->NotRange.Reserved4 = 4
|
||||
pp_data->cap[4]->NotButton.HasNull = 0
|
||||
pp_data->cap[4]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[4]->NotButton.LogicalMin = 0
|
||||
pp_data->cap[4]->NotButton.LogicalMax = -1
|
||||
pp_data->cap[4]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[4]->NotButton.PhysicalMax = -1
|
||||
pp_data->cap[4]->Units = 0
|
||||
pp_data->cap[4]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[5]->UsagePage = 0x0009
|
||||
pp_data->cap[5]->ReportID = 0x00
|
||||
pp_data->cap[5]->BitPosition = 0
|
||||
pp_data->cap[5]->BitSize = 1
|
||||
pp_data->cap[5]->ReportCount = 16
|
||||
pp_data->cap[5]->BytePosition = 0x000B
|
||||
pp_data->cap[5]->BitCount = 16
|
||||
pp_data->cap[5]->BitField = 0x02
|
||||
pp_data->cap[5]->NextBytePosition = 0x000D
|
||||
pp_data->cap[5]->LinkCollection = 0x0000
|
||||
pp_data->cap[5]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[5]->LinkUsage = 0x0005
|
||||
pp_data->cap[5]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[5]->IsButtonCap = 1
|
||||
pp_data->cap[5]->IsPadding = 0
|
||||
pp_data->cap[5]->IsAbsolute = 1
|
||||
pp_data->cap[5]->IsRange = 1
|
||||
pp_data->cap[5]->IsAlias = 0
|
||||
pp_data->cap[5]->IsStringRange = 0
|
||||
pp_data->cap[5]->IsDesignatorRange = 0
|
||||
pp_data->cap[5]->Reserved1 = 0x000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[5]->Range.UsageMin = 0x0001
|
||||
pp_data->cap[5]->Range.UsageMax = 0x0010
|
||||
pp_data->cap[5]->Range.StringMin = 0
|
||||
pp_data->cap[5]->Range.StringMax = 0
|
||||
pp_data->cap[5]->Range.DesignatorMin = 0
|
||||
pp_data->cap[5]->Range.DesignatorMax = 0
|
||||
pp_data->cap[5]->Range.DataIndexMin = 5
|
||||
pp_data->cap[5]->Range.DataIndexMax = 20
|
||||
pp_data->cap[5]->Button.LogicalMin = 0
|
||||
pp_data->cap[5]->Button.LogicalMax = 0
|
||||
pp_data->cap[5]->Units = 0
|
||||
pp_data->cap[5]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[6]->UsagePage = 0x0001
|
||||
pp_data->cap[6]->ReportID = 0x00
|
||||
pp_data->cap[6]->BitPosition = 0
|
||||
pp_data->cap[6]->BitSize = 4
|
||||
pp_data->cap[6]->ReportCount = 1
|
||||
pp_data->cap[6]->BytePosition = 0x000D
|
||||
pp_data->cap[6]->BitCount = 4
|
||||
pp_data->cap[6]->BitField = 0x42
|
||||
pp_data->cap[6]->NextBytePosition = 0x000E
|
||||
pp_data->cap[6]->LinkCollection = 0x0000
|
||||
pp_data->cap[6]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[6]->LinkUsage = 0x0005
|
||||
pp_data->cap[6]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[6]->IsButtonCap = 0
|
||||
pp_data->cap[6]->IsPadding = 0
|
||||
pp_data->cap[6]->IsAbsolute = 1
|
||||
pp_data->cap[6]->IsRange = 0
|
||||
pp_data->cap[6]->IsAlias = 0
|
||||
pp_data->cap[6]->IsStringRange = 0
|
||||
pp_data->cap[6]->IsDesignatorRange = 0
|
||||
pp_data->cap[6]->Reserved1 = 0x000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[6]->NotRange.Usage = 0x0039
|
||||
pp_data->cap[6]->NotRange.Reserved1 = 0x0039
|
||||
pp_data->cap[6]->NotRange.StringIndex = 0
|
||||
pp_data->cap[6]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[6]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[6]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[6]->NotRange.DataIndex = 21
|
||||
pp_data->cap[6]->NotRange.Reserved4 = 21
|
||||
pp_data->cap[6]->NotButton.HasNull = 1
|
||||
pp_data->cap[6]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[6]->NotButton.LogicalMin = 1
|
||||
pp_data->cap[6]->NotButton.LogicalMax = 8
|
||||
pp_data->cap[6]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[6]->NotButton.PhysicalMax = 4155
|
||||
pp_data->cap[6]->Units = 14
|
||||
pp_data->cap[6]->UnitsExp = 0
|
||||
|
||||
# Output hid_pp_cap struct:
|
||||
# Feature hid_pp_cap struct:
|
||||
# Link Collections:
|
||||
pp_data->LinkCollectionArray[0]->LinkUsage = 0x0005
|
||||
pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x0001
|
||||
pp_data->LinkCollectionArray[0]->Parent = 0
|
||||
pp_data->LinkCollectionArray[0]->NumberOfChildren = 3
|
||||
pp_data->LinkCollectionArray[0]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[0]->FirstChild = 3
|
||||
pp_data->LinkCollectionArray[0]->CollectionType = 1
|
||||
pp_data->LinkCollectionArray[0]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
|
||||
pp_data->LinkCollectionArray[1]->LinkUsage = 0x0000
|
||||
pp_data->LinkCollectionArray[1]->LinkUsagePage = 0x0001
|
||||
pp_data->LinkCollectionArray[1]->Parent = 0
|
||||
pp_data->LinkCollectionArray[1]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[1]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[1]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[1]->CollectionType = 0
|
||||
pp_data->LinkCollectionArray[1]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[1]->Reserved = 0x00000000
|
||||
pp_data->LinkCollectionArray[2]->LinkUsage = 0x0000
|
||||
pp_data->LinkCollectionArray[2]->LinkUsagePage = 0x0001
|
||||
pp_data->LinkCollectionArray[2]->Parent = 0
|
||||
pp_data->LinkCollectionArray[2]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[2]->NextSibling = 1
|
||||
pp_data->LinkCollectionArray[2]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[2]->CollectionType = 0
|
||||
pp_data->LinkCollectionArray[2]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[2]->Reserved = 0x00000000
|
||||
pp_data->LinkCollectionArray[3]->LinkUsage = 0x0000
|
||||
pp_data->LinkCollectionArray[3]->LinkUsagePage = 0x0001
|
||||
pp_data->LinkCollectionArray[3]->Parent = 0
|
||||
pp_data->LinkCollectionArray[3]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[3]->NextSibling = 2
|
||||
pp_data->LinkCollectionArray[3]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[3]->CollectionType = 0
|
||||
pp_data->LinkCollectionArray[3]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[3]->Reserved = 0x00000000
|
||||
@@ -0,0 +1,12 @@
|
||||
0x05, 0x01, 0x09, 0x05, 0xA1, 0x01, 0x09, 0x00, 0xA1, 0x00,
|
||||
0x09, 0x30, 0x09, 0x31, 0x15, 0x00, 0x25, 0xFF, 0x35, 0x00,
|
||||
0x45, 0xFF, 0x75, 0x10, 0x95, 0x02, 0x81, 0x02, 0xC0, 0x09,
|
||||
0x00, 0xA1, 0x00, 0x09, 0x33, 0x09, 0x34, 0x15, 0x00, 0x25,
|
||||
0xFF, 0x75, 0x10, 0x95, 0x02, 0x81, 0x02, 0xC0, 0x09, 0x00,
|
||||
0xA1, 0x00, 0x09, 0x32, 0x15, 0x00, 0x25, 0xFF, 0x75, 0x10,
|
||||
0x95, 0x01, 0x81, 0x02, 0xC0, 0x05, 0x09, 0x19, 0x01, 0x29,
|
||||
0x10, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x10, 0x45,
|
||||
0x00, 0x81, 0x02, 0x05, 0x01, 0x09, 0x39, 0x15, 0x01, 0x25,
|
||||
0x08, 0x35, 0x00, 0x46, 0x3B, 0x10, 0x65, 0x0E, 0x75, 0x04,
|
||||
0x95, 0x01, 0x81, 0x42, 0x75, 0x04, 0x95, 0x01, 0x81, 0x03,
|
||||
0xC0,
|
||||
@@ -0,0 +1,64 @@
|
||||
// Special cases of this device:
|
||||
// 2 full padding bytes at the end
|
||||
// Multiple child collections inside of the same report (byte position of Input items defines collection order)
|
||||
|
||||
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
||||
0x09, 0x05, // Usage (Game Pad)
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0xA1, 0x00, // Collection (Physical)
|
||||
0x09, 0x30, // Usage (X)
|
||||
0x09, 0x31, // Usage (Y)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x26, 0xFF, 0xFF, // Logical Maximum (-1)
|
||||
0x35, 0x00, // Physical Minimum (0)
|
||||
0x46, 0xFF, 0xFF, // Physical Maximum (-1)
|
||||
0x95, 0x02, // Report Count (2)
|
||||
0x75, 0x10, // Report Size (16)
|
||||
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0xC0, // End Collection
|
||||
0xA1, 0x00, // Collection (Physical)
|
||||
0x09, 0x33, // Usage (Rx)
|
||||
0x09, 0x34, // Usage (Ry)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x26, 0xFF, 0xFF, // Logical Maximum (-1)
|
||||
0x35, 0x00, // Physical Minimum (0)
|
||||
0x46, 0xFF, 0xFF, // Physical Maximum (-1)
|
||||
0x95, 0x02, // Report Count (2)
|
||||
0x75, 0x10, // Report Size (16)
|
||||
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0xC0, // End Collection
|
||||
0xA1, 0x00, // Collection (Physical)
|
||||
0x09, 0x32, // Usage (Z)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x26, 0xFF, 0xFF, // Logical Maximum (-1)
|
||||
0x35, 0x00, // Physical Minimum (0)
|
||||
0x46, 0xFF, 0xFF, // Physical Maximum (-1)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x75, 0x10, // Report Size (16)
|
||||
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0xC0, // End Collection
|
||||
0x05, 0x09, // Usage Page (Button)
|
||||
0x19, 0x01, // Usage Minimum (0x01)
|
||||
0x29, 0x10, // Usage Maximum (0x10)
|
||||
0x95, 0x10, // Report Count (16)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
||||
0x09, 0x39, // Usage (Hat switch)
|
||||
0x15, 0x01, // Logical Minimum (1)
|
||||
0x25, 0x08, // Logical Maximum (8)
|
||||
0x35, 0x00, // Physical Minimum (0)
|
||||
0x46, 0x3B, 0x10, // Physical Maximum (4155)
|
||||
0x66, 0x0E, 0x00, // Unit (None)
|
||||
0x75, 0x04, // Report Size (4)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x81, 0x42, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,Null State)
|
||||
0x75, 0x04, // Report Size (4)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x95, 0x02, // Report Count (2)
|
||||
0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0xC0, // End Collection
|
||||
|
||||
// 120 bytes
|
||||
@@ -0,0 +1,183 @@
|
||||
# HIDAPI device info struct:
|
||||
dev->vendor_id = 0x046A
|
||||
dev->product_id = 0x0011
|
||||
dev->manufacturer_string = "dev->product_string = "dev->release_number = 0x0100
|
||||
dev->interface_number = -1
|
||||
dev->usage = 0x0006
|
||||
dev->usage_page = 0x0001
|
||||
dev->path = "\\?\hid#vid_046a&pid_0011#7&2c7fd0a5&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
|
||||
|
||||
# Preparsed Data struct:
|
||||
pp_data->MagicKey = 0x48696450204B4452
|
||||
pp_data->Usage = 0x0006
|
||||
pp_data->UsagePage = 0x0001
|
||||
pp_data->Reserved = 0x00000000
|
||||
# Input caps_info struct:
|
||||
pp_data->caps_info[0]->FirstCap = 0
|
||||
pp_data->caps_info[0]->LastCap = 2
|
||||
pp_data->caps_info[0]->NumberOfCaps = 2
|
||||
pp_data->caps_info[0]->ReportByteLength = 9
|
||||
# Output caps_info struct:
|
||||
pp_data->caps_info[1]->FirstCap = 2
|
||||
pp_data->caps_info[1]->LastCap = 3
|
||||
pp_data->caps_info[1]->NumberOfCaps = 1
|
||||
pp_data->caps_info[1]->ReportByteLength = 2
|
||||
# Feature caps_info struct:
|
||||
pp_data->caps_info[2]->FirstCap = 3
|
||||
pp_data->caps_info[2]->LastCap = 3
|
||||
pp_data->caps_info[2]->NumberOfCaps = 0
|
||||
pp_data->caps_info[2]->ReportByteLength = 0
|
||||
# LinkCollectionArray Offset & Size:
|
||||
pp_data->FirstByteOfLinkCollectionArray = 0x0138
|
||||
pp_data->NumberLinkCollectionNodes = 1
|
||||
# Input hid_pp_cap struct:
|
||||
pp_data->cap[0]->UsagePage = 0x0007
|
||||
pp_data->cap[0]->ReportID = 0x00
|
||||
pp_data->cap[0]->BitPosition = 0
|
||||
pp_data->cap[0]->BitSize = 1
|
||||
pp_data->cap[0]->ReportCount = 8
|
||||
pp_data->cap[0]->BytePosition = 0x0001
|
||||
pp_data->cap[0]->BitCount = 8
|
||||
pp_data->cap[0]->BitField = 0x02
|
||||
pp_data->cap[0]->NextBytePosition = 0x0002
|
||||
pp_data->cap[0]->LinkCollection = 0x0000
|
||||
pp_data->cap[0]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[0]->LinkUsage = 0x0006
|
||||
pp_data->cap[0]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[0]->IsButtonCap = 1
|
||||
pp_data->cap[0]->IsPadding = 0
|
||||
pp_data->cap[0]->IsAbsolute = 1
|
||||
pp_data->cap[0]->IsRange = 1
|
||||
pp_data->cap[0]->IsAlias = 0
|
||||
pp_data->cap[0]->IsStringRange = 0
|
||||
pp_data->cap[0]->IsDesignatorRange = 0
|
||||
pp_data->cap[0]->Reserved1 = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[0]->Range.UsageMin = 0x00E0
|
||||
pp_data->cap[0]->Range.UsageMax = 0x00E7
|
||||
pp_data->cap[0]->Range.StringMin = 0
|
||||
pp_data->cap[0]->Range.StringMax = 0
|
||||
pp_data->cap[0]->Range.DesignatorMin = 0
|
||||
pp_data->cap[0]->Range.DesignatorMax = 0
|
||||
pp_data->cap[0]->Range.DataIndexMin = 0
|
||||
pp_data->cap[0]->Range.DataIndexMax = 7
|
||||
pp_data->cap[0]->Button.LogicalMin = 0
|
||||
pp_data->cap[0]->Button.LogicalMax = 0
|
||||
pp_data->cap[0]->Units = 0
|
||||
pp_data->cap[0]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[1]->UsagePage = 0x0007
|
||||
pp_data->cap[1]->ReportID = 0x00
|
||||
pp_data->cap[1]->BitPosition = 0
|
||||
pp_data->cap[1]->BitSize = 8
|
||||
pp_data->cap[1]->ReportCount = 6
|
||||
pp_data->cap[1]->BytePosition = 0x0003
|
||||
pp_data->cap[1]->BitCount = 48
|
||||
pp_data->cap[1]->BitField = 0x00
|
||||
pp_data->cap[1]->NextBytePosition = 0x0009
|
||||
pp_data->cap[1]->LinkCollection = 0x0000
|
||||
pp_data->cap[1]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[1]->LinkUsage = 0x0006
|
||||
pp_data->cap[1]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[1]->IsButtonCap = 1
|
||||
pp_data->cap[1]->IsPadding = 0
|
||||
pp_data->cap[1]->IsAbsolute = 1
|
||||
pp_data->cap[1]->IsRange = 1
|
||||
pp_data->cap[1]->IsAlias = 0
|
||||
pp_data->cap[1]->IsStringRange = 0
|
||||
pp_data->cap[1]->IsDesignatorRange = 0
|
||||
pp_data->cap[1]->Reserved1 = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[1]->Range.UsageMin = 0x0000
|
||||
pp_data->cap[1]->Range.UsageMax = 0x00DD
|
||||
pp_data->cap[1]->Range.StringMin = 0
|
||||
pp_data->cap[1]->Range.StringMax = 0
|
||||
pp_data->cap[1]->Range.DesignatorMin = 0
|
||||
pp_data->cap[1]->Range.DesignatorMax = 0
|
||||
pp_data->cap[1]->Range.DataIndexMin = 8
|
||||
pp_data->cap[1]->Range.DataIndexMax = 229
|
||||
pp_data->cap[1]->Button.LogicalMin = 0
|
||||
pp_data->cap[1]->Button.LogicalMax = 221
|
||||
pp_data->cap[1]->Units = 0
|
||||
pp_data->cap[1]->UnitsExp = 0
|
||||
|
||||
# Output hid_pp_cap struct:
|
||||
pp_data->cap[2]->UsagePage = 0x0008
|
||||
pp_data->cap[2]->ReportID = 0x00
|
||||
pp_data->cap[2]->BitPosition = 0
|
||||
pp_data->cap[2]->BitSize = 1
|
||||
pp_data->cap[2]->ReportCount = 3
|
||||
pp_data->cap[2]->BytePosition = 0x0001
|
||||
pp_data->cap[2]->BitCount = 3
|
||||
pp_data->cap[2]->BitField = 0x02
|
||||
pp_data->cap[2]->NextBytePosition = 0x0002
|
||||
pp_data->cap[2]->LinkCollection = 0x0000
|
||||
pp_data->cap[2]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[2]->LinkUsage = 0x0006
|
||||
pp_data->cap[2]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[2]->IsButtonCap = 1
|
||||
pp_data->cap[2]->IsPadding = 0
|
||||
pp_data->cap[2]->IsAbsolute = 1
|
||||
pp_data->cap[2]->IsRange = 1
|
||||
pp_data->cap[2]->IsAlias = 0
|
||||
pp_data->cap[2]->IsStringRange = 0
|
||||
pp_data->cap[2]->IsDesignatorRange = 0
|
||||
pp_data->cap[2]->Reserved1 = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[2]->Range.UsageMin = 0x0001
|
||||
pp_data->cap[2]->Range.UsageMax = 0x0003
|
||||
pp_data->cap[2]->Range.StringMin = 0
|
||||
pp_data->cap[2]->Range.StringMax = 0
|
||||
pp_data->cap[2]->Range.DesignatorMin = 0
|
||||
pp_data->cap[2]->Range.DesignatorMax = 0
|
||||
pp_data->cap[2]->Range.DataIndexMin = 0
|
||||
pp_data->cap[2]->Range.DataIndexMax = 2
|
||||
pp_data->cap[2]->Button.LogicalMin = 0
|
||||
pp_data->cap[2]->Button.LogicalMax = 0
|
||||
pp_data->cap[2]->Units = 0
|
||||
pp_data->cap[2]->UnitsExp = 0
|
||||
|
||||
# Feature hid_pp_cap struct:
|
||||
# Link Collections:
|
||||
pp_data->LinkCollectionArray[0]->LinkUsage = 0x0006
|
||||
pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x0001
|
||||
pp_data->LinkCollectionArray[0]->Parent = 0
|
||||
pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[0]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[0]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[0]->CollectionType = 1
|
||||
pp_data->LinkCollectionArray[0]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
|
||||
@@ -0,0 +1,7 @@
|
||||
0x05, 0x01, 0x09, 0x06, 0xA1, 0x01, 0x05, 0x07, 0x19, 0xE0,
|
||||
0x29, 0xE7, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08,
|
||||
0x81, 0x02, 0x75, 0x08, 0x95, 0x01, 0x81, 0x03, 0x19, 0x00,
|
||||
0x29, 0xDD, 0x15, 0x00, 0x26, 0xDD, 0x00, 0x75, 0x08, 0x95,
|
||||
0x06, 0x81, 0x00, 0x05, 0x08, 0x19, 0x01, 0x29, 0x03, 0x15,
|
||||
0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x03, 0x91, 0x02, 0x75,
|
||||
0x05, 0x95, 0x01, 0x91, 0x03, 0xC0,
|
||||
@@ -0,0 +1,7 @@
|
||||
0x05, 0x01, 0x09, 0x06, 0xA1, 0x01, 0x05, 0x07, 0x19, 0xE0,
|
||||
0x29, 0xE7, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08,
|
||||
0x81, 0x02, 0x75, 0x08, 0x95, 0x01, 0x81, 0x03, 0x19, 0x00,
|
||||
0x29, 0xDD, 0x15, 0x00, 0x26, 0xDD, 0x00, 0x75, 0x08, 0x95,
|
||||
0x06, 0x81, 0x00, 0x05, 0x08, 0x19, 0x01, 0x29, 0x03, 0x15,
|
||||
0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x03, 0x91, 0x02, 0x75,
|
||||
0x05, 0x95, 0x01, 0x91, 0x03, 0xC0,
|
||||
@@ -0,0 +1,532 @@
|
||||
# HIDAPI device info struct:
|
||||
dev->vendor_id = 0x046D
|
||||
dev->product_id = 0x0A37
|
||||
dev->manufacturer_string = "Logitech Inc "
|
||||
dev->product_string = "Logitech USB Headset H540"
|
||||
dev->release_number = 0x0122
|
||||
dev->interface_number = 3
|
||||
dev->usage = 0x0001
|
||||
dev->usage_page = 0x000C
|
||||
dev->path = "\\?\hid#vid_046d&pid_0a37&mi_03#8&1717f300&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
|
||||
|
||||
# Preparsed Data struct:
|
||||
pp_data->MagicKey = 0x48696450204B4452
|
||||
pp_data->Usage = 0x0001
|
||||
pp_data->UsagePage = 0x000C
|
||||
pp_data->Reserved = 0x00000000
|
||||
# Input caps_info struct:
|
||||
pp_data->caps_info[0]->FirstCap = 0
|
||||
pp_data->caps_info[0]->LastCap = 7
|
||||
pp_data->caps_info[0]->NumberOfCaps = 9
|
||||
pp_data->caps_info[0]->ReportByteLength = 33
|
||||
# Output caps_info struct:
|
||||
pp_data->caps_info[1]->FirstCap = 9
|
||||
pp_data->caps_info[1]->LastCap = 12
|
||||
pp_data->caps_info[1]->NumberOfCaps = 3
|
||||
pp_data->caps_info[1]->ReportByteLength = 37
|
||||
# Feature caps_info struct:
|
||||
pp_data->caps_info[2]->FirstCap = 12
|
||||
pp_data->caps_info[2]->LastCap = 12
|
||||
pp_data->caps_info[2]->NumberOfCaps = 0
|
||||
pp_data->caps_info[2]->ReportByteLength = 0
|
||||
# LinkCollectionArray Offset & Size:
|
||||
pp_data->FirstByteOfLinkCollectionArray = 0x04E0
|
||||
pp_data->NumberLinkCollectionNodes = 2
|
||||
# Input hid_pp_cap struct:
|
||||
pp_data->cap[0]->UsagePage = 0x000C
|
||||
pp_data->cap[0]->ReportID = 0x01
|
||||
pp_data->cap[0]->BitPosition = 1
|
||||
pp_data->cap[0]->BitSize = 1
|
||||
pp_data->cap[0]->ReportCount = 1
|
||||
pp_data->cap[0]->BytePosition = 0x0001
|
||||
pp_data->cap[0]->BitCount = 1
|
||||
pp_data->cap[0]->BitField = 0x02
|
||||
pp_data->cap[0]->NextBytePosition = 0x0002
|
||||
pp_data->cap[0]->LinkCollection = 0x0000
|
||||
pp_data->cap[0]->LinkUsagePage = 0x000C
|
||||
pp_data->cap[0]->LinkUsage = 0x0001
|
||||
pp_data->cap[0]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[0]->IsButtonCap = 1
|
||||
pp_data->cap[0]->IsPadding = 0
|
||||
pp_data->cap[0]->IsAbsolute = 1
|
||||
pp_data->cap[0]->IsRange = 0
|
||||
pp_data->cap[0]->IsAlias = 0
|
||||
pp_data->cap[0]->IsStringRange = 0
|
||||
pp_data->cap[0]->IsDesignatorRange = 0
|
||||
pp_data->cap[0]->Reserved1 = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[0]->NotRange.Usage = 0x00EA
|
||||
pp_data->cap[0]->NotRange.Reserved1 = 0x00EA
|
||||
pp_data->cap[0]->NotRange.StringIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[0]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[0]->NotRange.DataIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved4 = 0
|
||||
pp_data->cap[0]->Button.LogicalMin = 0
|
||||
pp_data->cap[0]->Button.LogicalMax = 0
|
||||
pp_data->cap[0]->Units = 0
|
||||
pp_data->cap[0]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[1]->UsagePage = 0x000C
|
||||
pp_data->cap[1]->ReportID = 0x01
|
||||
pp_data->cap[1]->BitPosition = 0
|
||||
pp_data->cap[1]->BitSize = 1
|
||||
pp_data->cap[1]->ReportCount = 1
|
||||
pp_data->cap[1]->BytePosition = 0x0001
|
||||
pp_data->cap[1]->BitCount = 1
|
||||
pp_data->cap[1]->BitField = 0x02
|
||||
pp_data->cap[1]->NextBytePosition = 0x0002
|
||||
pp_data->cap[1]->LinkCollection = 0x0000
|
||||
pp_data->cap[1]->LinkUsagePage = 0x000C
|
||||
pp_data->cap[1]->LinkUsage = 0x0001
|
||||
pp_data->cap[1]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[1]->IsButtonCap = 1
|
||||
pp_data->cap[1]->IsPadding = 0
|
||||
pp_data->cap[1]->IsAbsolute = 1
|
||||
pp_data->cap[1]->IsRange = 0
|
||||
pp_data->cap[1]->IsAlias = 0
|
||||
pp_data->cap[1]->IsStringRange = 0
|
||||
pp_data->cap[1]->IsDesignatorRange = 0
|
||||
pp_data->cap[1]->Reserved1 = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[1]->NotRange.Usage = 0x00E9
|
||||
pp_data->cap[1]->NotRange.Reserved1 = 0x00E9
|
||||
pp_data->cap[1]->NotRange.StringIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[1]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[1]->NotRange.DataIndex = 1
|
||||
pp_data->cap[1]->NotRange.Reserved4 = 1
|
||||
pp_data->cap[1]->Button.LogicalMin = 0
|
||||
pp_data->cap[1]->Button.LogicalMax = 0
|
||||
pp_data->cap[1]->Units = 0
|
||||
pp_data->cap[1]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[2]->UsagePage = 0x000C
|
||||
pp_data->cap[2]->ReportID = 0x01
|
||||
pp_data->cap[2]->BitPosition = 2
|
||||
pp_data->cap[2]->BitSize = 1
|
||||
pp_data->cap[2]->ReportCount = 1
|
||||
pp_data->cap[2]->BytePosition = 0x0001
|
||||
pp_data->cap[2]->BitCount = 1
|
||||
pp_data->cap[2]->BitField = 0x06
|
||||
pp_data->cap[2]->NextBytePosition = 0x0002
|
||||
pp_data->cap[2]->LinkCollection = 0x0000
|
||||
pp_data->cap[2]->LinkUsagePage = 0x000C
|
||||
pp_data->cap[2]->LinkUsage = 0x0001
|
||||
pp_data->cap[2]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[2]->IsButtonCap = 1
|
||||
pp_data->cap[2]->IsPadding = 0
|
||||
pp_data->cap[2]->IsAbsolute = 0
|
||||
pp_data->cap[2]->IsRange = 0
|
||||
pp_data->cap[2]->IsAlias = 0
|
||||
pp_data->cap[2]->IsStringRange = 0
|
||||
pp_data->cap[2]->IsDesignatorRange = 0
|
||||
pp_data->cap[2]->Reserved1 = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[2]->NotRange.Usage = 0x00E2
|
||||
pp_data->cap[2]->NotRange.Reserved1 = 0x00E2
|
||||
pp_data->cap[2]->NotRange.StringIndex = 0
|
||||
pp_data->cap[2]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[2]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[2]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[2]->NotRange.DataIndex = 2
|
||||
pp_data->cap[2]->NotRange.Reserved4 = 2
|
||||
pp_data->cap[2]->Button.LogicalMin = 0
|
||||
pp_data->cap[2]->Button.LogicalMax = 0
|
||||
pp_data->cap[2]->Units = 0
|
||||
pp_data->cap[2]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[3]->UsagePage = 0x0009
|
||||
pp_data->cap[3]->ReportID = 0x01
|
||||
pp_data->cap[3]->BitPosition = 5
|
||||
pp_data->cap[3]->BitSize = 2
|
||||
pp_data->cap[3]->ReportCount = 1
|
||||
pp_data->cap[3]->BytePosition = 0x0001
|
||||
pp_data->cap[3]->BitCount = 2
|
||||
pp_data->cap[3]->BitField = 0x40
|
||||
pp_data->cap[3]->NextBytePosition = 0x0002
|
||||
pp_data->cap[3]->LinkCollection = 0x0001
|
||||
pp_data->cap[3]->LinkUsagePage = 0x000C
|
||||
pp_data->cap[3]->LinkUsage = 0x0036
|
||||
pp_data->cap[3]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[3]->IsButtonCap = 1
|
||||
pp_data->cap[3]->IsPadding = 0
|
||||
pp_data->cap[3]->IsAbsolute = 1
|
||||
pp_data->cap[3]->IsRange = 1
|
||||
pp_data->cap[3]->IsAlias = 0
|
||||
pp_data->cap[3]->IsStringRange = 0
|
||||
pp_data->cap[3]->IsDesignatorRange = 0
|
||||
pp_data->cap[3]->Reserved1 = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[3]->Range.UsageMin = 0x0001
|
||||
pp_data->cap[3]->Range.UsageMax = 0x0002
|
||||
pp_data->cap[3]->Range.StringMin = 0
|
||||
pp_data->cap[3]->Range.StringMax = 0
|
||||
pp_data->cap[3]->Range.DesignatorMin = 0
|
||||
pp_data->cap[3]->Range.DesignatorMax = 0
|
||||
pp_data->cap[3]->Range.DataIndexMin = 3
|
||||
pp_data->cap[3]->Range.DataIndexMax = 4
|
||||
pp_data->cap[3]->Button.LogicalMin = 1
|
||||
pp_data->cap[3]->Button.LogicalMax = 2
|
||||
pp_data->cap[3]->Units = 0
|
||||
pp_data->cap[3]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[4]->UsagePage = 0x000C
|
||||
pp_data->cap[4]->ReportID = 0x02
|
||||
pp_data->cap[4]->BitPosition = 0
|
||||
pp_data->cap[4]->BitSize = 1
|
||||
pp_data->cap[4]->ReportCount = 16
|
||||
pp_data->cap[4]->BytePosition = 0x0001
|
||||
pp_data->cap[4]->BitCount = 16
|
||||
pp_data->cap[4]->BitField = 0x02
|
||||
pp_data->cap[4]->NextBytePosition = 0x0003
|
||||
pp_data->cap[4]->LinkCollection = 0x0000
|
||||
pp_data->cap[4]->LinkUsagePage = 0x000C
|
||||
pp_data->cap[4]->LinkUsage = 0x0001
|
||||
pp_data->cap[4]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[4]->IsButtonCap = 1
|
||||
pp_data->cap[4]->IsPadding = 0
|
||||
pp_data->cap[4]->IsAbsolute = 1
|
||||
pp_data->cap[4]->IsRange = 0
|
||||
pp_data->cap[4]->IsAlias = 0
|
||||
pp_data->cap[4]->IsStringRange = 0
|
||||
pp_data->cap[4]->IsDesignatorRange = 0
|
||||
pp_data->cap[4]->Reserved1 = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[4]->NotRange.Usage = 0x0000
|
||||
pp_data->cap[4]->NotRange.Reserved1 = 0x0000
|
||||
pp_data->cap[4]->NotRange.StringIndex = 0
|
||||
pp_data->cap[4]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[4]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[4]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[4]->NotRange.DataIndex = 5
|
||||
pp_data->cap[4]->NotRange.Reserved4 = 5
|
||||
pp_data->cap[4]->Button.LogicalMin = 0
|
||||
pp_data->cap[4]->Button.LogicalMax = 0
|
||||
pp_data->cap[4]->Units = 0
|
||||
pp_data->cap[4]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[5]->UsagePage = 0x000C
|
||||
pp_data->cap[5]->ReportID = 0x05
|
||||
pp_data->cap[5]->BitPosition = 0
|
||||
pp_data->cap[5]->BitSize = 8
|
||||
pp_data->cap[5]->ReportCount = 32
|
||||
pp_data->cap[5]->BytePosition = 0x0001
|
||||
pp_data->cap[5]->BitCount = 256
|
||||
pp_data->cap[5]->BitField = 0x02
|
||||
pp_data->cap[5]->NextBytePosition = 0x0021
|
||||
pp_data->cap[5]->LinkCollection = 0x0000
|
||||
pp_data->cap[5]->LinkUsagePage = 0x000C
|
||||
pp_data->cap[5]->LinkUsage = 0x0001
|
||||
pp_data->cap[5]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[5]->IsButtonCap = 0
|
||||
pp_data->cap[5]->IsPadding = 0
|
||||
pp_data->cap[5]->IsAbsolute = 1
|
||||
pp_data->cap[5]->IsRange = 0
|
||||
pp_data->cap[5]->IsAlias = 0
|
||||
pp_data->cap[5]->IsStringRange = 0
|
||||
pp_data->cap[5]->IsDesignatorRange = 0
|
||||
pp_data->cap[5]->Reserved1 = 0x000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[5]->NotRange.Usage = 0x0000
|
||||
pp_data->cap[5]->NotRange.Reserved1 = 0x0000
|
||||
pp_data->cap[5]->NotRange.StringIndex = 0
|
||||
pp_data->cap[5]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[5]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[5]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[5]->NotRange.DataIndex = 6
|
||||
pp_data->cap[5]->NotRange.Reserved4 = 6
|
||||
pp_data->cap[5]->NotButton.HasNull = 0
|
||||
pp_data->cap[5]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[5]->NotButton.LogicalMin = 0
|
||||
pp_data->cap[5]->NotButton.LogicalMax = 1
|
||||
pp_data->cap[5]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[5]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[5]->Units = 0
|
||||
pp_data->cap[5]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[6]->UsagePage = 0x000C
|
||||
pp_data->cap[6]->ReportID = 0x07
|
||||
pp_data->cap[6]->BitPosition = 0
|
||||
pp_data->cap[6]->BitSize = 8
|
||||
pp_data->cap[6]->ReportCount = 32
|
||||
pp_data->cap[6]->BytePosition = 0x0001
|
||||
pp_data->cap[6]->BitCount = 256
|
||||
pp_data->cap[6]->BitField = 0x02
|
||||
pp_data->cap[6]->NextBytePosition = 0x0021
|
||||
pp_data->cap[6]->LinkCollection = 0x0000
|
||||
pp_data->cap[6]->LinkUsagePage = 0x000C
|
||||
pp_data->cap[6]->LinkUsage = 0x0001
|
||||
pp_data->cap[6]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[6]->IsButtonCap = 0
|
||||
pp_data->cap[6]->IsPadding = 0
|
||||
pp_data->cap[6]->IsAbsolute = 1
|
||||
pp_data->cap[6]->IsRange = 0
|
||||
pp_data->cap[6]->IsAlias = 0
|
||||
pp_data->cap[6]->IsStringRange = 0
|
||||
pp_data->cap[6]->IsDesignatorRange = 0
|
||||
pp_data->cap[6]->Reserved1 = 0x000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[6]->NotRange.Usage = 0x0000
|
||||
pp_data->cap[6]->NotRange.Reserved1 = 0x0000
|
||||
pp_data->cap[6]->NotRange.StringIndex = 0
|
||||
pp_data->cap[6]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[6]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[6]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[6]->NotRange.DataIndex = 7
|
||||
pp_data->cap[6]->NotRange.Reserved4 = 7
|
||||
pp_data->cap[6]->NotButton.HasNull = 0
|
||||
pp_data->cap[6]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[6]->NotButton.LogicalMin = 0
|
||||
pp_data->cap[6]->NotButton.LogicalMax = 1
|
||||
pp_data->cap[6]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[6]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[6]->Units = 0
|
||||
pp_data->cap[6]->UnitsExp = 0
|
||||
|
||||
# Output hid_pp_cap struct:
|
||||
pp_data->cap[9]->UsagePage = 0x000C
|
||||
pp_data->cap[9]->ReportID = 0x03
|
||||
pp_data->cap[9]->BitPosition = 0
|
||||
pp_data->cap[9]->BitSize = 1
|
||||
pp_data->cap[9]->ReportCount = 16
|
||||
pp_data->cap[9]->BytePosition = 0x0001
|
||||
pp_data->cap[9]->BitCount = 16
|
||||
pp_data->cap[9]->BitField = 0x02
|
||||
pp_data->cap[9]->NextBytePosition = 0x0003
|
||||
pp_data->cap[9]->LinkCollection = 0x0000
|
||||
pp_data->cap[9]->LinkUsagePage = 0x000C
|
||||
pp_data->cap[9]->LinkUsage = 0x0001
|
||||
pp_data->cap[9]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[9]->IsButtonCap = 1
|
||||
pp_data->cap[9]->IsPadding = 0
|
||||
pp_data->cap[9]->IsAbsolute = 1
|
||||
pp_data->cap[9]->IsRange = 0
|
||||
pp_data->cap[9]->IsAlias = 0
|
||||
pp_data->cap[9]->IsStringRange = 0
|
||||
pp_data->cap[9]->IsDesignatorRange = 0
|
||||
pp_data->cap[9]->Reserved1 = 0x000000
|
||||
pp_data->cap[9]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[9]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[9]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[9]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[9]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[9]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[9]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[9]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[9]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[9]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[9]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[9]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[9]->NotRange.Usage = 0x0000
|
||||
pp_data->cap[9]->NotRange.Reserved1 = 0x0000
|
||||
pp_data->cap[9]->NotRange.StringIndex = 0
|
||||
pp_data->cap[9]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[9]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[9]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[9]->NotRange.DataIndex = 0
|
||||
pp_data->cap[9]->NotRange.Reserved4 = 0
|
||||
pp_data->cap[9]->Button.LogicalMin = 0
|
||||
pp_data->cap[9]->Button.LogicalMax = 0
|
||||
pp_data->cap[9]->Units = 0
|
||||
pp_data->cap[9]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[10]->UsagePage = 0x000C
|
||||
pp_data->cap[10]->ReportID = 0x04
|
||||
pp_data->cap[10]->BitPosition = 0
|
||||
pp_data->cap[10]->BitSize = 8
|
||||
pp_data->cap[10]->ReportCount = 36
|
||||
pp_data->cap[10]->BytePosition = 0x0001
|
||||
pp_data->cap[10]->BitCount = 288
|
||||
pp_data->cap[10]->BitField = 0x02
|
||||
pp_data->cap[10]->NextBytePosition = 0x0025
|
||||
pp_data->cap[10]->LinkCollection = 0x0000
|
||||
pp_data->cap[10]->LinkUsagePage = 0x000C
|
||||
pp_data->cap[10]->LinkUsage = 0x0001
|
||||
pp_data->cap[10]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[10]->IsButtonCap = 0
|
||||
pp_data->cap[10]->IsPadding = 0
|
||||
pp_data->cap[10]->IsAbsolute = 1
|
||||
pp_data->cap[10]->IsRange = 0
|
||||
pp_data->cap[10]->IsAlias = 0
|
||||
pp_data->cap[10]->IsStringRange = 0
|
||||
pp_data->cap[10]->IsDesignatorRange = 0
|
||||
pp_data->cap[10]->Reserved1 = 0x000000
|
||||
pp_data->cap[10]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[10]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[10]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[10]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[10]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[10]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[10]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[10]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[10]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[10]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[10]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[10]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[10]->NotRange.Usage = 0x0000
|
||||
pp_data->cap[10]->NotRange.Reserved1 = 0x0000
|
||||
pp_data->cap[10]->NotRange.StringIndex = 0
|
||||
pp_data->cap[10]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[10]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[10]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[10]->NotRange.DataIndex = 1
|
||||
pp_data->cap[10]->NotRange.Reserved4 = 1
|
||||
pp_data->cap[10]->NotButton.HasNull = 0
|
||||
pp_data->cap[10]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[10]->NotButton.LogicalMin = 0
|
||||
pp_data->cap[10]->NotButton.LogicalMax = 1
|
||||
pp_data->cap[10]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[10]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[10]->Units = 0
|
||||
pp_data->cap[10]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[11]->UsagePage = 0x000C
|
||||
pp_data->cap[11]->ReportID = 0x06
|
||||
pp_data->cap[11]->BitPosition = 0
|
||||
pp_data->cap[11]->BitSize = 8
|
||||
pp_data->cap[11]->ReportCount = 36
|
||||
pp_data->cap[11]->BytePosition = 0x0001
|
||||
pp_data->cap[11]->BitCount = 288
|
||||
pp_data->cap[11]->BitField = 0x02
|
||||
pp_data->cap[11]->NextBytePosition = 0x0025
|
||||
pp_data->cap[11]->LinkCollection = 0x0000
|
||||
pp_data->cap[11]->LinkUsagePage = 0x000C
|
||||
pp_data->cap[11]->LinkUsage = 0x0001
|
||||
pp_data->cap[11]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[11]->IsButtonCap = 0
|
||||
pp_data->cap[11]->IsPadding = 0
|
||||
pp_data->cap[11]->IsAbsolute = 1
|
||||
pp_data->cap[11]->IsRange = 0
|
||||
pp_data->cap[11]->IsAlias = 0
|
||||
pp_data->cap[11]->IsStringRange = 0
|
||||
pp_data->cap[11]->IsDesignatorRange = 0
|
||||
pp_data->cap[11]->Reserved1 = 0x000000
|
||||
pp_data->cap[11]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[11]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[11]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[11]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[11]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[11]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[11]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[11]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[11]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[11]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[11]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[11]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[11]->NotRange.Usage = 0x0000
|
||||
pp_data->cap[11]->NotRange.Reserved1 = 0x0000
|
||||
pp_data->cap[11]->NotRange.StringIndex = 0
|
||||
pp_data->cap[11]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[11]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[11]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[11]->NotRange.DataIndex = 2
|
||||
pp_data->cap[11]->NotRange.Reserved4 = 2
|
||||
pp_data->cap[11]->NotButton.HasNull = 0
|
||||
pp_data->cap[11]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[11]->NotButton.LogicalMin = 0
|
||||
pp_data->cap[11]->NotButton.LogicalMax = 1
|
||||
pp_data->cap[11]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[11]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[11]->Units = 0
|
||||
pp_data->cap[11]->UnitsExp = 0
|
||||
|
||||
# Feature hid_pp_cap struct:
|
||||
# Link Collections:
|
||||
pp_data->LinkCollectionArray[0]->LinkUsage = 0x0001
|
||||
pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x000C
|
||||
pp_data->LinkCollectionArray[0]->Parent = 0
|
||||
pp_data->LinkCollectionArray[0]->NumberOfChildren = 1
|
||||
pp_data->LinkCollectionArray[0]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[0]->FirstChild = 1
|
||||
pp_data->LinkCollectionArray[0]->CollectionType = 1
|
||||
pp_data->LinkCollectionArray[0]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
|
||||
pp_data->LinkCollectionArray[1]->LinkUsage = 0x0036
|
||||
pp_data->LinkCollectionArray[1]->LinkUsagePage = 0x000C
|
||||
pp_data->LinkCollectionArray[1]->Parent = 0
|
||||
pp_data->LinkCollectionArray[1]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[1]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[1]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[1]->CollectionType = 2
|
||||
pp_data->LinkCollectionArray[1]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[1]->Reserved = 0x00000000
|
||||
@@ -0,0 +1,16 @@
|
||||
0x05, 0x0C, 0x09, 0x01, 0xA1, 0x01, 0x85, 0x01, 0x09, 0xE9,
|
||||
0x09, 0xEA, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x02,
|
||||
0x81, 0x02, 0x09, 0xE2, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01,
|
||||
0x95, 0x01, 0x81, 0x06, 0x75, 0x02, 0x95, 0x01, 0x81, 0x03,
|
||||
0x09, 0x36, 0xA1, 0x02, 0x05, 0x09, 0x19, 0x01, 0x29, 0x02,
|
||||
0x15, 0x01, 0x25, 0x02, 0x75, 0x02, 0x95, 0x01, 0x81, 0x40,
|
||||
0x75, 0x01, 0x95, 0x01, 0x81, 0x03, 0xC0, 0x85, 0x02, 0x05,
|
||||
0x0C, 0x09, 0x00, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95,
|
||||
0x10, 0x81, 0x02, 0x85, 0x05, 0x09, 0x00, 0x15, 0x00, 0x25,
|
||||
0x01, 0x75, 0x08, 0x95, 0x20, 0x81, 0x02, 0x85, 0x07, 0x09,
|
||||
0x00, 0x15, 0x00, 0x25, 0x01, 0x75, 0x08, 0x95, 0x20, 0x81,
|
||||
0x02, 0x85, 0x03, 0x09, 0x00, 0x15, 0x00, 0x25, 0x01, 0x75,
|
||||
0x01, 0x95, 0x10, 0x91, 0x02, 0x85, 0x04, 0x09, 0x00, 0x15,
|
||||
0x00, 0x25, 0x01, 0x75, 0x08, 0x95, 0x24, 0x91, 0x02, 0x85,
|
||||
0x06, 0x09, 0x00, 0x15, 0x00, 0x25, 0x01, 0x75, 0x08, 0x95,
|
||||
0x24, 0x91, 0x02, 0xC0,
|
||||
@@ -0,0 +1,61 @@
|
||||
Usage Page (Consumer Devices) 05 0C
|
||||
Usage (Consumer Control) 09 01
|
||||
Collection (Application) A1 01
|
||||
Report ID (1) 85 01
|
||||
Logical Minimum (0) 15 00
|
||||
Logical Maximum (1) 25 01
|
||||
Usage (Volume Increment) 09 E9
|
||||
Usage (Volume Decrement) 09 EA
|
||||
Report Size (1) 75 01
|
||||
Report Count (2) 95 02
|
||||
Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
|
||||
Usage (Mute) 09 E2
|
||||
Report Count (1) 95 01
|
||||
Input (Data,Var,Rel,NWrp,Lin,Pref,NNul,Bit) 81 06
|
||||
Usage (Undefined) 09 00
|
||||
Report Count (2) 95 02
|
||||
Input (Cnst,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 03
|
||||
Usage (Function Buttons) 09 36
|
||||
Collection (Logical) A1 02
|
||||
Usage Page (Button) 05 09
|
||||
Usage Minimum (Button 1) 19 01
|
||||
Usage Maximum (Button 2) 29 02
|
||||
Report Size (2) 75 02
|
||||
Report Count (1) 95 01
|
||||
Logical Minimum (1) 15 01
|
||||
Logical Maximum (2) 25 02
|
||||
Input (Data,Ary,Abs) 81 40
|
||||
End Collection C0
|
||||
Usage Page (Consumer Devices) 05 0C
|
||||
Usage (Undefined) 09 00
|
||||
Logical Minimum (0) 15 00
|
||||
Logical Maximum (1) 25 01
|
||||
Report Size (1) 75 01
|
||||
Report Count (1) 95 01
|
||||
Input (Cnst,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 03
|
||||
Report ID (2) 85 02
|
||||
Usage Page (Consumer Devices) 05 0C
|
||||
Usage (Undefined) 09 00
|
||||
Report Count (16) 95 10
|
||||
Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
|
||||
Report ID (3) 85 03
|
||||
Usage (Undefined) 09 00
|
||||
Output (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) 91 02
|
||||
Report ID (4) 85 04
|
||||
Usage (Undefined) 09 00
|
||||
Report Size (8) 75 08
|
||||
Report Count (36) 95 24
|
||||
Output (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) 91 02
|
||||
Report ID (5) 85 05
|
||||
Usage (Undefined) 09 00
|
||||
Report Count (32) 95 20
|
||||
Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
|
||||
Report ID (6) 85 06
|
||||
Usage (Undefined) 09 00
|
||||
Report Count (36) 95 24
|
||||
Output (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) 91 02
|
||||
Report ID (7) 85 07
|
||||
Usage (Undefined) 09 00
|
||||
Report Count (32) 95 20
|
||||
Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
|
||||
End Collection C0
|
||||
@@ -0,0 +1,97 @@
|
||||
# HIDAPI device info struct:
|
||||
dev->vendor_id = 0x046D
|
||||
dev->product_id = 0xB010
|
||||
dev->manufacturer_string = "Logitech"
|
||||
dev->product_string = "Logitech Bluetooth Wireless Mouse"
|
||||
dev->release_number = 0x0000
|
||||
dev->interface_number = -1
|
||||
dev->usage = 0x0001
|
||||
dev->usage_page = 0x000C
|
||||
dev->path = "\\?\hid#{00001124-0000-1000-8000-00805f9b34fb}_vid&0002046d_pid&b010&col02#8&1cf1c1b9&3&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}"
|
||||
|
||||
# Preparsed Data struct:
|
||||
pp_data->MagicKey = 0x48696450204B4452
|
||||
pp_data->Usage = 0x0001
|
||||
pp_data->UsagePage = 0x000C
|
||||
pp_data->Reserved = 0x00000000
|
||||
# Input caps_info struct:
|
||||
pp_data->caps_info[0]->FirstCap = 0
|
||||
pp_data->caps_info[0]->LastCap = 1
|
||||
pp_data->caps_info[0]->NumberOfCaps = 1
|
||||
pp_data->caps_info[0]->ReportByteLength = 2
|
||||
# Output caps_info struct:
|
||||
pp_data->caps_info[1]->FirstCap = 1
|
||||
pp_data->caps_info[1]->LastCap = 1
|
||||
pp_data->caps_info[1]->NumberOfCaps = 0
|
||||
pp_data->caps_info[1]->ReportByteLength = 0
|
||||
# Feature caps_info struct:
|
||||
pp_data->caps_info[2]->FirstCap = 1
|
||||
pp_data->caps_info[2]->LastCap = 1
|
||||
pp_data->caps_info[2]->NumberOfCaps = 0
|
||||
pp_data->caps_info[2]->ReportByteLength = 0
|
||||
# LinkCollectionArray Offset & Size:
|
||||
pp_data->FirstByteOfLinkCollectionArray = 0x0068
|
||||
pp_data->NumberLinkCollectionNodes = 1
|
||||
# Input hid_pp_cap struct:
|
||||
pp_data->cap[0]->UsagePage = 0x0006
|
||||
pp_data->cap[0]->ReportID = 0x03
|
||||
pp_data->cap[0]->BitPosition = 0
|
||||
pp_data->cap[0]->BitSize = 8
|
||||
pp_data->cap[0]->ReportCount = 1
|
||||
pp_data->cap[0]->BytePosition = 0x0001
|
||||
pp_data->cap[0]->BitCount = 8
|
||||
pp_data->cap[0]->BitField = 0x02
|
||||
pp_data->cap[0]->NextBytePosition = 0x0002
|
||||
pp_data->cap[0]->LinkCollection = 0x0000
|
||||
pp_data->cap[0]->LinkUsagePage = 0x000C
|
||||
pp_data->cap[0]->LinkUsage = 0x0001
|
||||
pp_data->cap[0]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[0]->IsButtonCap = 0
|
||||
pp_data->cap[0]->IsPadding = 0
|
||||
pp_data->cap[0]->IsAbsolute = 1
|
||||
pp_data->cap[0]->IsRange = 0
|
||||
pp_data->cap[0]->IsAlias = 0
|
||||
pp_data->cap[0]->IsStringRange = 0
|
||||
pp_data->cap[0]->IsDesignatorRange = 0
|
||||
pp_data->cap[0]->Reserved1 = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[0]->NotRange.Usage = 0x0020
|
||||
pp_data->cap[0]->NotRange.Reserved1 = 0x0020
|
||||
pp_data->cap[0]->NotRange.StringIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[0]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[0]->NotRange.DataIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved4 = 0
|
||||
pp_data->cap[0]->NotButton.HasNull = 0
|
||||
pp_data->cap[0]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[0]->NotButton.LogicalMin = 0
|
||||
pp_data->cap[0]->NotButton.LogicalMax = 100
|
||||
pp_data->cap[0]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[0]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[0]->Units = 0
|
||||
pp_data->cap[0]->UnitsExp = 0
|
||||
|
||||
# Output hid_pp_cap struct:
|
||||
# Feature hid_pp_cap struct:
|
||||
# Link Collections:
|
||||
pp_data->LinkCollectionArray[0]->LinkUsage = 0x0001
|
||||
pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x000C
|
||||
pp_data->LinkCollectionArray[0]->Parent = 0
|
||||
pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[0]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[0]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[0]->CollectionType = 1
|
||||
pp_data->LinkCollectionArray[0]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
|
||||
@@ -0,0 +1,3 @@
|
||||
0x05, 0x0C, 0x09, 0x01, 0xA1, 0x01, 0x85, 0x03, 0x05, 0x06,
|
||||
0x09, 0x20, 0x15, 0x00, 0x25, 0x64, 0x75, 0x08, 0x95, 0x01,
|
||||
0x81, 0x02, 0xC0,
|
||||
@@ -0,0 +1,38 @@
|
||||
|
||||
mac-hid-dump on main ❯ ./mac-hid-dump
|
||||
mac-hid-dump:
|
||||
...
|
||||
046D B010: Unknown - Bluetooth Mouse M557
|
||||
DESCRIPTOR:
|
||||
05 01 09 02 a1 01 85 02 09 01 a1 00 05 09 19 01
|
||||
29 08 15 00 25 01 75 01 95 08 81 02 05 01 09 30
|
||||
09 31 16 01 f8 26 ff 07 75 0c 95 02 81 06 09 38
|
||||
15 81 25 7f 75 08 95 01 81 06 05 0c 0a 38 02 75
|
||||
08 95 01 81 06 c0 c0 05 0c 09 01 a1 01 85 03 05
|
||||
06 09 20 15 00 26 64 00 75 08 95 01 81 02 c0 06
|
||||
00 ff 09 01 a1 01 85 10 75 08 95 06 15 00 26 ff
|
||||
00 09 01 81 00 09 01 91 00 c0 06 00 ff 09 02 a1
|
||||
01 85 11 75 08 95 13 15 00 26 ff 00 09 02 81 00
|
||||
09 02 91 00 c0 05 01 09 06 a1 01 85 04 75 01 95
|
||||
08 05 07 19 e0 29 e7 15 00 25 01 81 02 95 01 75
|
||||
08 81 03 95 05 75 01 05 08 19 01 29 05 91 02 95
|
||||
01 75 03 91 03 95 06 75 08 15 00 26 ff 00 05 07
|
||||
19 00 29 ff 81 00 c0 05 0c 09 01 a1 01 85 05 15
|
||||
00 25 01 75 01 95 02 0a 25 02 0a 24 02 81 02 95
|
||||
01 75 06 81 03 c0
|
||||
(246 bytes)
|
||||
|
||||
Parser output:
|
||||
|
||||
0x05, 0x0C, // Usage Page (Consumer)
|
||||
0x09, 0x01, // Usage (Consumer Control)
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x85, 0x03, // Report ID (3)
|
||||
0x05, 0x06, // Usage Page (Generic Dev Ctrls)
|
||||
0x09, 0x20, // Usage (Battery Strength)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x26, 0x64, 0x00, // Logical Maximum (100)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0xC0, // End Collection
|
||||
@@ -0,0 +1,139 @@
|
||||
# HIDAPI device info struct:
|
||||
dev->vendor_id = 0x046D
|
||||
dev->product_id = 0xB010
|
||||
dev->manufacturer_string = "Logitech"
|
||||
dev->product_string = "Logitech Bluetooth Wireless Mouse"
|
||||
dev->release_number = 0x0000
|
||||
dev->interface_number = -1
|
||||
dev->usage = 0x0001
|
||||
dev->usage_page = 0xFF00
|
||||
dev->path = "\\?\hid#{00001124-0000-1000-8000-00805f9b34fb}_vid&0002046d_pid&b010&col03#8&1cf1c1b9&3&0002#{4d1e55b2-f16f-11cf-88cb-001111000030}"
|
||||
|
||||
# Preparsed Data struct:
|
||||
pp_data->MagicKey = 0x48696450204B4452
|
||||
pp_data->Usage = 0x0001
|
||||
pp_data->UsagePage = 0xFF00
|
||||
pp_data->Reserved = 0x00000000
|
||||
# Input caps_info struct:
|
||||
pp_data->caps_info[0]->FirstCap = 0
|
||||
pp_data->caps_info[0]->LastCap = 1
|
||||
pp_data->caps_info[0]->NumberOfCaps = 1
|
||||
pp_data->caps_info[0]->ReportByteLength = 7
|
||||
# Output caps_info struct:
|
||||
pp_data->caps_info[1]->FirstCap = 1
|
||||
pp_data->caps_info[1]->LastCap = 2
|
||||
pp_data->caps_info[1]->NumberOfCaps = 1
|
||||
pp_data->caps_info[1]->ReportByteLength = 7
|
||||
# Feature caps_info struct:
|
||||
pp_data->caps_info[2]->FirstCap = 2
|
||||
pp_data->caps_info[2]->LastCap = 2
|
||||
pp_data->caps_info[2]->NumberOfCaps = 0
|
||||
pp_data->caps_info[2]->ReportByteLength = 0
|
||||
# LinkCollectionArray Offset & Size:
|
||||
pp_data->FirstByteOfLinkCollectionArray = 0x00D0
|
||||
pp_data->NumberLinkCollectionNodes = 1
|
||||
# Input hid_pp_cap struct:
|
||||
pp_data->cap[0]->UsagePage = 0xFF00
|
||||
pp_data->cap[0]->ReportID = 0x10
|
||||
pp_data->cap[0]->BitPosition = 0
|
||||
pp_data->cap[0]->BitSize = 8
|
||||
pp_data->cap[0]->ReportCount = 6
|
||||
pp_data->cap[0]->BytePosition = 0x0001
|
||||
pp_data->cap[0]->BitCount = 48
|
||||
pp_data->cap[0]->BitField = 0x00
|
||||
pp_data->cap[0]->NextBytePosition = 0x0007
|
||||
pp_data->cap[0]->LinkCollection = 0x0000
|
||||
pp_data->cap[0]->LinkUsagePage = 0xFF00
|
||||
pp_data->cap[0]->LinkUsage = 0x0001
|
||||
pp_data->cap[0]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[0]->IsButtonCap = 1
|
||||
pp_data->cap[0]->IsPadding = 0
|
||||
pp_data->cap[0]->IsAbsolute = 1
|
||||
pp_data->cap[0]->IsRange = 0
|
||||
pp_data->cap[0]->IsAlias = 0
|
||||
pp_data->cap[0]->IsStringRange = 0
|
||||
pp_data->cap[0]->IsDesignatorRange = 0
|
||||
pp_data->cap[0]->Reserved1 = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[0]->NotRange.Usage = 0x0001
|
||||
pp_data->cap[0]->NotRange.Reserved1 = 0x0001
|
||||
pp_data->cap[0]->NotRange.StringIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[0]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[0]->NotRange.DataIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved4 = 0
|
||||
pp_data->cap[0]->Button.LogicalMin = 0
|
||||
pp_data->cap[0]->Button.LogicalMax = 255
|
||||
pp_data->cap[0]->Units = 0
|
||||
pp_data->cap[0]->UnitsExp = 0
|
||||
|
||||
# Output hid_pp_cap struct:
|
||||
pp_data->cap[1]->UsagePage = 0xFF00
|
||||
pp_data->cap[1]->ReportID = 0x10
|
||||
pp_data->cap[1]->BitPosition = 0
|
||||
pp_data->cap[1]->BitSize = 8
|
||||
pp_data->cap[1]->ReportCount = 6
|
||||
pp_data->cap[1]->BytePosition = 0x0001
|
||||
pp_data->cap[1]->BitCount = 48
|
||||
pp_data->cap[1]->BitField = 0x00
|
||||
pp_data->cap[1]->NextBytePosition = 0x0007
|
||||
pp_data->cap[1]->LinkCollection = 0x0000
|
||||
pp_data->cap[1]->LinkUsagePage = 0xFF00
|
||||
pp_data->cap[1]->LinkUsage = 0x0001
|
||||
pp_data->cap[1]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[1]->IsButtonCap = 1
|
||||
pp_data->cap[1]->IsPadding = 0
|
||||
pp_data->cap[1]->IsAbsolute = 1
|
||||
pp_data->cap[1]->IsRange = 0
|
||||
pp_data->cap[1]->IsAlias = 0
|
||||
pp_data->cap[1]->IsStringRange = 0
|
||||
pp_data->cap[1]->IsDesignatorRange = 0
|
||||
pp_data->cap[1]->Reserved1 = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[1]->NotRange.Usage = 0x0001
|
||||
pp_data->cap[1]->NotRange.Reserved1 = 0x0001
|
||||
pp_data->cap[1]->NotRange.StringIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[1]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[1]->NotRange.DataIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved4 = 0
|
||||
pp_data->cap[1]->Button.LogicalMin = 0
|
||||
pp_data->cap[1]->Button.LogicalMax = 255
|
||||
pp_data->cap[1]->Units = 0
|
||||
pp_data->cap[1]->UnitsExp = 0
|
||||
|
||||
# Feature hid_pp_cap struct:
|
||||
# Link Collections:
|
||||
pp_data->LinkCollectionArray[0]->LinkUsage = 0x0001
|
||||
pp_data->LinkCollectionArray[0]->LinkUsagePage = 0xFF00
|
||||
pp_data->LinkCollectionArray[0]->Parent = 0
|
||||
pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[0]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[0]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[0]->CollectionType = 1
|
||||
pp_data->LinkCollectionArray[0]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
|
||||
@@ -0,0 +1,4 @@
|
||||
0x06, 0x00, 0xFF, 0x09, 0x01, 0xA1, 0x01, 0x85, 0x10, 0x09,
|
||||
0x01, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x06,
|
||||
0x81, 0x00, 0x09, 0x01, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
|
||||
0x08, 0x95, 0x06, 0x91, 0x00, 0xC0,
|
||||
@@ -0,0 +1,39 @@
|
||||
|
||||
mac-hid-dump on main ❯ ./mac-hid-dump
|
||||
mac-hid-dump:
|
||||
...
|
||||
046D B010: Unknown - Bluetooth Mouse M557
|
||||
DESCRIPTOR:
|
||||
05 01 09 02 a1 01 85 02 09 01 a1 00 05 09 19 01
|
||||
29 08 15 00 25 01 75 01 95 08 81 02 05 01 09 30
|
||||
09 31 16 01 f8 26 ff 07 75 0c 95 02 81 06 09 38
|
||||
15 81 25 7f 75 08 95 01 81 06 05 0c 0a 38 02 75
|
||||
08 95 01 81 06 c0 c0 05 0c 09 01 a1 01 85 03 05
|
||||
06 09 20 15 00 26 64 00 75 08 95 01 81 02 c0 06
|
||||
00 ff 09 01 a1 01 85 10 75 08 95 06 15 00 26 ff
|
||||
00 09 01 81 00 09 01 91 00 c0 06 00 ff 09 02 a1
|
||||
01 85 11 75 08 95 13 15 00 26 ff 00 09 02 81 00
|
||||
09 02 91 00 c0 05 01 09 06 a1 01 85 04 75 01 95
|
||||
08 05 07 19 e0 29 e7 15 00 25 01 81 02 95 01 75
|
||||
08 81 03 95 05 75 01 05 08 19 01 29 05 91 02 95
|
||||
01 75 03 91 03 95 06 75 08 15 00 26 ff 00 05 07
|
||||
19 00 29 ff 81 00 c0 05 0c 09 01 a1 01 85 05 15
|
||||
00 25 01 75 01 95 02 0a 25 02 0a 24 02 81 02 95
|
||||
01 75 06 81 03 c0
|
||||
(246 bytes)
|
||||
|
||||
Parser output:
|
||||
|
||||
0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
|
||||
0x09, 0x01, // Usage (0x01)
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x85, 0x10, // Report ID (16)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x95, 0x06, // Report Count (6)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x26, 0xFF, 0x00, // Logical Maximum (255)
|
||||
0x09, 0x01, // Usage (0x01)
|
||||
0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x09, 0x01, // Usage (0x01)
|
||||
0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0xC0, // End Collection
|
||||
@@ -0,0 +1,302 @@
|
||||
# HIDAPI device info struct:
|
||||
dev->vendor_id = 0x046D
|
||||
dev->product_id = 0xB010
|
||||
dev->manufacturer_string = "Logitech"
|
||||
dev->product_string = "Logitech Bluetooth Wireless Mouse"
|
||||
dev->release_number = 0x0000
|
||||
dev->interface_number = -1
|
||||
dev->usage = 0x0002
|
||||
dev->usage_page = 0x0001
|
||||
dev->path = "\\?\hid#{00001124-0000-1000-8000-00805f9b34fb}_vid&0002046d_pid&b010&col01#8&1cf1c1b9&3&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
|
||||
|
||||
# Preparsed Data struct:
|
||||
pp_data->MagicKey = 0x48696450204B4452
|
||||
pp_data->Usage = 0x0002
|
||||
pp_data->UsagePage = 0x0001
|
||||
pp_data->Reserved = 0x00000000
|
||||
# Input caps_info struct:
|
||||
pp_data->caps_info[0]->FirstCap = 0
|
||||
pp_data->caps_info[0]->LastCap = 5
|
||||
pp_data->caps_info[0]->NumberOfCaps = 5
|
||||
pp_data->caps_info[0]->ReportByteLength = 7
|
||||
# Output caps_info struct:
|
||||
pp_data->caps_info[1]->FirstCap = 5
|
||||
pp_data->caps_info[1]->LastCap = 5
|
||||
pp_data->caps_info[1]->NumberOfCaps = 0
|
||||
pp_data->caps_info[1]->ReportByteLength = 0
|
||||
# Feature caps_info struct:
|
||||
pp_data->caps_info[2]->FirstCap = 5
|
||||
pp_data->caps_info[2]->LastCap = 5
|
||||
pp_data->caps_info[2]->NumberOfCaps = 0
|
||||
pp_data->caps_info[2]->ReportByteLength = 0
|
||||
# LinkCollectionArray Offset & Size:
|
||||
pp_data->FirstByteOfLinkCollectionArray = 0x0208
|
||||
pp_data->NumberLinkCollectionNodes = 2
|
||||
# Input hid_pp_cap struct:
|
||||
pp_data->cap[0]->UsagePage = 0x0009
|
||||
pp_data->cap[0]->ReportID = 0x02
|
||||
pp_data->cap[0]->BitPosition = 0
|
||||
pp_data->cap[0]->BitSize = 1
|
||||
pp_data->cap[0]->ReportCount = 8
|
||||
pp_data->cap[0]->BytePosition = 0x0001
|
||||
pp_data->cap[0]->BitCount = 8
|
||||
pp_data->cap[0]->BitField = 0x02
|
||||
pp_data->cap[0]->NextBytePosition = 0x0002
|
||||
pp_data->cap[0]->LinkCollection = 0x0001
|
||||
pp_data->cap[0]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[0]->LinkUsage = 0x0001
|
||||
pp_data->cap[0]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[0]->IsButtonCap = 1
|
||||
pp_data->cap[0]->IsPadding = 0
|
||||
pp_data->cap[0]->IsAbsolute = 1
|
||||
pp_data->cap[0]->IsRange = 1
|
||||
pp_data->cap[0]->IsAlias = 0
|
||||
pp_data->cap[0]->IsStringRange = 0
|
||||
pp_data->cap[0]->IsDesignatorRange = 0
|
||||
pp_data->cap[0]->Reserved1 = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[0]->Range.UsageMin = 0x0001
|
||||
pp_data->cap[0]->Range.UsageMax = 0x0008
|
||||
pp_data->cap[0]->Range.StringMin = 0
|
||||
pp_data->cap[0]->Range.StringMax = 0
|
||||
pp_data->cap[0]->Range.DesignatorMin = 0
|
||||
pp_data->cap[0]->Range.DesignatorMax = 0
|
||||
pp_data->cap[0]->Range.DataIndexMin = 0
|
||||
pp_data->cap[0]->Range.DataIndexMax = 7
|
||||
pp_data->cap[0]->Button.LogicalMin = 0
|
||||
pp_data->cap[0]->Button.LogicalMax = 0
|
||||
pp_data->cap[0]->Units = 0
|
||||
pp_data->cap[0]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[1]->UsagePage = 0x0001
|
||||
pp_data->cap[1]->ReportID = 0x02
|
||||
pp_data->cap[1]->BitPosition = 4
|
||||
pp_data->cap[1]->BitSize = 12
|
||||
pp_data->cap[1]->ReportCount = 1
|
||||
pp_data->cap[1]->BytePosition = 0x0003
|
||||
pp_data->cap[1]->BitCount = 12
|
||||
pp_data->cap[1]->BitField = 0x06
|
||||
pp_data->cap[1]->NextBytePosition = 0x0005
|
||||
pp_data->cap[1]->LinkCollection = 0x0001
|
||||
pp_data->cap[1]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[1]->LinkUsage = 0x0001
|
||||
pp_data->cap[1]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[1]->IsButtonCap = 0
|
||||
pp_data->cap[1]->IsPadding = 0
|
||||
pp_data->cap[1]->IsAbsolute = 0
|
||||
pp_data->cap[1]->IsRange = 0
|
||||
pp_data->cap[1]->IsAlias = 0
|
||||
pp_data->cap[1]->IsStringRange = 0
|
||||
pp_data->cap[1]->IsDesignatorRange = 0
|
||||
pp_data->cap[1]->Reserved1 = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[1]->NotRange.Usage = 0x0031
|
||||
pp_data->cap[1]->NotRange.Reserved1 = 0x0031
|
||||
pp_data->cap[1]->NotRange.StringIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[1]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[1]->NotRange.DataIndex = 8
|
||||
pp_data->cap[1]->NotRange.Reserved4 = 8
|
||||
pp_data->cap[1]->NotButton.HasNull = 0
|
||||
pp_data->cap[1]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[1]->NotButton.LogicalMin = -2047
|
||||
pp_data->cap[1]->NotButton.LogicalMax = 2047
|
||||
pp_data->cap[1]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[1]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[1]->Units = 0
|
||||
pp_data->cap[1]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[2]->UsagePage = 0x0001
|
||||
pp_data->cap[2]->ReportID = 0x02
|
||||
pp_data->cap[2]->BitPosition = 0
|
||||
pp_data->cap[2]->BitSize = 12
|
||||
pp_data->cap[2]->ReportCount = 1
|
||||
pp_data->cap[2]->BytePosition = 0x0002
|
||||
pp_data->cap[2]->BitCount = 12
|
||||
pp_data->cap[2]->BitField = 0x06
|
||||
pp_data->cap[2]->NextBytePosition = 0x0004
|
||||
pp_data->cap[2]->LinkCollection = 0x0001
|
||||
pp_data->cap[2]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[2]->LinkUsage = 0x0001
|
||||
pp_data->cap[2]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[2]->IsButtonCap = 0
|
||||
pp_data->cap[2]->IsPadding = 0
|
||||
pp_data->cap[2]->IsAbsolute = 0
|
||||
pp_data->cap[2]->IsRange = 0
|
||||
pp_data->cap[2]->IsAlias = 0
|
||||
pp_data->cap[2]->IsStringRange = 0
|
||||
pp_data->cap[2]->IsDesignatorRange = 0
|
||||
pp_data->cap[2]->Reserved1 = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[2]->NotRange.Usage = 0x0030
|
||||
pp_data->cap[2]->NotRange.Reserved1 = 0x0030
|
||||
pp_data->cap[2]->NotRange.StringIndex = 0
|
||||
pp_data->cap[2]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[2]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[2]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[2]->NotRange.DataIndex = 9
|
||||
pp_data->cap[2]->NotRange.Reserved4 = 9
|
||||
pp_data->cap[2]->NotButton.HasNull = 0
|
||||
pp_data->cap[2]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[2]->NotButton.LogicalMin = -2047
|
||||
pp_data->cap[2]->NotButton.LogicalMax = 2047
|
||||
pp_data->cap[2]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[2]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[2]->Units = 0
|
||||
pp_data->cap[2]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[3]->UsagePage = 0x0001
|
||||
pp_data->cap[3]->ReportID = 0x02
|
||||
pp_data->cap[3]->BitPosition = 0
|
||||
pp_data->cap[3]->BitSize = 8
|
||||
pp_data->cap[3]->ReportCount = 1
|
||||
pp_data->cap[3]->BytePosition = 0x0005
|
||||
pp_data->cap[3]->BitCount = 8
|
||||
pp_data->cap[3]->BitField = 0x06
|
||||
pp_data->cap[3]->NextBytePosition = 0x0006
|
||||
pp_data->cap[3]->LinkCollection = 0x0001
|
||||
pp_data->cap[3]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[3]->LinkUsage = 0x0001
|
||||
pp_data->cap[3]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[3]->IsButtonCap = 0
|
||||
pp_data->cap[3]->IsPadding = 0
|
||||
pp_data->cap[3]->IsAbsolute = 0
|
||||
pp_data->cap[3]->IsRange = 0
|
||||
pp_data->cap[3]->IsAlias = 0
|
||||
pp_data->cap[3]->IsStringRange = 0
|
||||
pp_data->cap[3]->IsDesignatorRange = 0
|
||||
pp_data->cap[3]->Reserved1 = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[3]->NotRange.Usage = 0x0038
|
||||
pp_data->cap[3]->NotRange.Reserved1 = 0x0038
|
||||
pp_data->cap[3]->NotRange.StringIndex = 0
|
||||
pp_data->cap[3]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[3]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[3]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[3]->NotRange.DataIndex = 10
|
||||
pp_data->cap[3]->NotRange.Reserved4 = 10
|
||||
pp_data->cap[3]->NotButton.HasNull = 0
|
||||
pp_data->cap[3]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[3]->NotButton.LogicalMin = -127
|
||||
pp_data->cap[3]->NotButton.LogicalMax = 127
|
||||
pp_data->cap[3]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[3]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[3]->Units = 0
|
||||
pp_data->cap[3]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[4]->UsagePage = 0x000C
|
||||
pp_data->cap[4]->ReportID = 0x02
|
||||
pp_data->cap[4]->BitPosition = 0
|
||||
pp_data->cap[4]->BitSize = 8
|
||||
pp_data->cap[4]->ReportCount = 1
|
||||
pp_data->cap[4]->BytePosition = 0x0006
|
||||
pp_data->cap[4]->BitCount = 8
|
||||
pp_data->cap[4]->BitField = 0x06
|
||||
pp_data->cap[4]->NextBytePosition = 0x0007
|
||||
pp_data->cap[4]->LinkCollection = 0x0001
|
||||
pp_data->cap[4]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[4]->LinkUsage = 0x0001
|
||||
pp_data->cap[4]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[4]->IsButtonCap = 0
|
||||
pp_data->cap[4]->IsPadding = 0
|
||||
pp_data->cap[4]->IsAbsolute = 0
|
||||
pp_data->cap[4]->IsRange = 0
|
||||
pp_data->cap[4]->IsAlias = 0
|
||||
pp_data->cap[4]->IsStringRange = 0
|
||||
pp_data->cap[4]->IsDesignatorRange = 0
|
||||
pp_data->cap[4]->Reserved1 = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[4]->NotRange.Usage = 0x0238
|
||||
pp_data->cap[4]->NotRange.Reserved1 = 0x0238
|
||||
pp_data->cap[4]->NotRange.StringIndex = 0
|
||||
pp_data->cap[4]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[4]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[4]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[4]->NotRange.DataIndex = 11
|
||||
pp_data->cap[4]->NotRange.Reserved4 = 11
|
||||
pp_data->cap[4]->NotButton.HasNull = 0
|
||||
pp_data->cap[4]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[4]->NotButton.LogicalMin = -127
|
||||
pp_data->cap[4]->NotButton.LogicalMax = 127
|
||||
pp_data->cap[4]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[4]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[4]->Units = 0
|
||||
pp_data->cap[4]->UnitsExp = 0
|
||||
|
||||
# Output hid_pp_cap struct:
|
||||
# Feature hid_pp_cap struct:
|
||||
# Link Collections:
|
||||
pp_data->LinkCollectionArray[0]->LinkUsage = 0x0002
|
||||
pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x0001
|
||||
pp_data->LinkCollectionArray[0]->Parent = 0
|
||||
pp_data->LinkCollectionArray[0]->NumberOfChildren = 1
|
||||
pp_data->LinkCollectionArray[0]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[0]->FirstChild = 1
|
||||
pp_data->LinkCollectionArray[0]->CollectionType = 1
|
||||
pp_data->LinkCollectionArray[0]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
|
||||
pp_data->LinkCollectionArray[1]->LinkUsage = 0x0001
|
||||
pp_data->LinkCollectionArray[1]->LinkUsagePage = 0x0001
|
||||
pp_data->LinkCollectionArray[1]->Parent = 0
|
||||
pp_data->LinkCollectionArray[1]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[1]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[1]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[1]->CollectionType = 0
|
||||
pp_data->LinkCollectionArray[1]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[1]->Reserved = 0x00000000
|
||||
@@ -0,0 +1,8 @@
|
||||
0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01, 0xA1, 0x00,
|
||||
0x85, 0x02, 0x05, 0x09, 0x19, 0x01, 0x29, 0x08, 0x15, 0x00,
|
||||
0x25, 0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02, 0x05, 0x01,
|
||||
0x09, 0x30, 0x09, 0x31, 0x16, 0x01, 0xF8, 0x26, 0xFF, 0x07,
|
||||
0x75, 0x0C, 0x95, 0x02, 0x81, 0x06, 0x09, 0x38, 0x15, 0x81,
|
||||
0x25, 0x7F, 0x75, 0x08, 0x95, 0x01, 0x81, 0x06, 0x05, 0x0C,
|
||||
0x0A, 0x38, 0x02, 0x15, 0x81, 0x25, 0x7F, 0x75, 0x08, 0x95,
|
||||
0x01, 0x81, 0x06, 0xC0, 0xC0,
|
||||
@@ -0,0 +1,61 @@
|
||||
|
||||
mac-hid-dump on main ❯ ./mac-hid-dump
|
||||
mac-hid-dump:
|
||||
...
|
||||
046D B010: Unknown - Bluetooth Mouse M557
|
||||
DESCRIPTOR:
|
||||
05 01 09 02 a1 01 85 02 09 01 a1 00 05 09 19 01
|
||||
29 08 15 00 25 01 75 01 95 08 81 02 05 01 09 30
|
||||
09 31 16 01 f8 26 ff 07 75 0c 95 02 81 06 09 38
|
||||
15 81 25 7f 75 08 95 01 81 06 05 0c 0a 38 02 75
|
||||
08 95 01 81 06 c0 c0 05 0c 09 01 a1 01 85 03 05
|
||||
06 09 20 15 00 26 64 00 75 08 95 01 81 02 c0 06
|
||||
00 ff 09 01 a1 01 85 10 75 08 95 06 15 00 26 ff
|
||||
00 09 01 81 00 09 01 91 00 c0 06 00 ff 09 02 a1
|
||||
01 85 11 75 08 95 13 15 00 26 ff 00 09 02 81 00
|
||||
09 02 91 00 c0 05 01 09 06 a1 01 85 04 75 01 95
|
||||
08 05 07 19 e0 29 e7 15 00 25 01 81 02 95 01 75
|
||||
08 81 03 95 05 75 01 05 08 19 01 29 05 91 02 95
|
||||
01 75 03 91 03 95 06 75 08 15 00 26 ff 00 05 07
|
||||
19 00 29 ff 81 00 c0 05 0c 09 01 a1 01 85 05 15
|
||||
00 25 01 75 01 95 02 0a 25 02 0a 24 02 81 02 95
|
||||
01 75 06 81 03 c0
|
||||
(246 bytes)
|
||||
|
||||
Parser output:
|
||||
|
||||
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
||||
0x09, 0x02, // Usage (Mouse)
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x85, 0x02, // Report ID (2)
|
||||
0x09, 0x01, // Usage (Pointer)
|
||||
0xA1, 0x00, // Collection (Physical)
|
||||
0x05, 0x09, // Usage Page (Button)
|
||||
0x19, 0x01, // Usage Minimum (0x01)
|
||||
0x29, 0x08, // Usage Maximum (0x08)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x25, 0x01, // Logical Maximum (1)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x95, 0x08, // Report Count (8)
|
||||
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
||||
0x09, 0x30, // Usage (X)
|
||||
0x09, 0x31, // Usage (Y)
|
||||
0x16, 0x01, 0xF8, // Logical Minimum (-2047)
|
||||
0x26, 0xFF, 0x07, // Logical Maximum (2047)
|
||||
0x75, 0x0C, // Report Size (12)
|
||||
0x95, 0x02, // Report Count (2)
|
||||
0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x09, 0x38, // Usage (Wheel)
|
||||
0x15, 0x81, // Logical Minimum (-127)
|
||||
0x25, 0x7F, // Logical Maximum (127)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x05, 0x0C, // Usage Page (Consumer)
|
||||
0x0A, 0x38, 0x02, // Usage (AC Pan)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0xC0, // End Collection
|
||||
0xC0, // End Collection
|
||||
@@ -0,0 +1,139 @@
|
||||
# HIDAPI device info struct:
|
||||
dev->vendor_id = 0x046D
|
||||
dev->product_id = 0xB010
|
||||
dev->manufacturer_string = "Logitech"
|
||||
dev->product_string = "Logitech Bluetooth Wireless Mouse"
|
||||
dev->release_number = 0x0000
|
||||
dev->interface_number = -1
|
||||
dev->usage = 0x0002
|
||||
dev->usage_page = 0xFF00
|
||||
dev->path = "\\?\hid#{00001124-0000-1000-8000-00805f9b34fb}_vid&0002046d_pid&b010&col04#8&1cf1c1b9&3&0003#{4d1e55b2-f16f-11cf-88cb-001111000030}"
|
||||
|
||||
# Preparsed Data struct:
|
||||
pp_data->MagicKey = 0x48696450204B4452
|
||||
pp_data->Usage = 0x0002
|
||||
pp_data->UsagePage = 0xFF00
|
||||
pp_data->Reserved = 0x00000000
|
||||
# Input caps_info struct:
|
||||
pp_data->caps_info[0]->FirstCap = 0
|
||||
pp_data->caps_info[0]->LastCap = 1
|
||||
pp_data->caps_info[0]->NumberOfCaps = 1
|
||||
pp_data->caps_info[0]->ReportByteLength = 20
|
||||
# Output caps_info struct:
|
||||
pp_data->caps_info[1]->FirstCap = 1
|
||||
pp_data->caps_info[1]->LastCap = 2
|
||||
pp_data->caps_info[1]->NumberOfCaps = 1
|
||||
pp_data->caps_info[1]->ReportByteLength = 20
|
||||
# Feature caps_info struct:
|
||||
pp_data->caps_info[2]->FirstCap = 2
|
||||
pp_data->caps_info[2]->LastCap = 2
|
||||
pp_data->caps_info[2]->NumberOfCaps = 0
|
||||
pp_data->caps_info[2]->ReportByteLength = 0
|
||||
# LinkCollectionArray Offset & Size:
|
||||
pp_data->FirstByteOfLinkCollectionArray = 0x00D0
|
||||
pp_data->NumberLinkCollectionNodes = 1
|
||||
# Input hid_pp_cap struct:
|
||||
pp_data->cap[0]->UsagePage = 0xFF00
|
||||
pp_data->cap[0]->ReportID = 0x11
|
||||
pp_data->cap[0]->BitPosition = 0
|
||||
pp_data->cap[0]->BitSize = 8
|
||||
pp_data->cap[0]->ReportCount = 19
|
||||
pp_data->cap[0]->BytePosition = 0x0001
|
||||
pp_data->cap[0]->BitCount = 152
|
||||
pp_data->cap[0]->BitField = 0x00
|
||||
pp_data->cap[0]->NextBytePosition = 0x0014
|
||||
pp_data->cap[0]->LinkCollection = 0x0000
|
||||
pp_data->cap[0]->LinkUsagePage = 0xFF00
|
||||
pp_data->cap[0]->LinkUsage = 0x0002
|
||||
pp_data->cap[0]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[0]->IsButtonCap = 1
|
||||
pp_data->cap[0]->IsPadding = 0
|
||||
pp_data->cap[0]->IsAbsolute = 1
|
||||
pp_data->cap[0]->IsRange = 0
|
||||
pp_data->cap[0]->IsAlias = 0
|
||||
pp_data->cap[0]->IsStringRange = 0
|
||||
pp_data->cap[0]->IsDesignatorRange = 0
|
||||
pp_data->cap[0]->Reserved1 = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[0]->NotRange.Usage = 0x0002
|
||||
pp_data->cap[0]->NotRange.Reserved1 = 0x0002
|
||||
pp_data->cap[0]->NotRange.StringIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[0]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[0]->NotRange.DataIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved4 = 0
|
||||
pp_data->cap[0]->Button.LogicalMin = 0
|
||||
pp_data->cap[0]->Button.LogicalMax = 255
|
||||
pp_data->cap[0]->Units = 0
|
||||
pp_data->cap[0]->UnitsExp = 0
|
||||
|
||||
# Output hid_pp_cap struct:
|
||||
pp_data->cap[1]->UsagePage = 0xFF00
|
||||
pp_data->cap[1]->ReportID = 0x11
|
||||
pp_data->cap[1]->BitPosition = 0
|
||||
pp_data->cap[1]->BitSize = 8
|
||||
pp_data->cap[1]->ReportCount = 19
|
||||
pp_data->cap[1]->BytePosition = 0x0001
|
||||
pp_data->cap[1]->BitCount = 152
|
||||
pp_data->cap[1]->BitField = 0x00
|
||||
pp_data->cap[1]->NextBytePosition = 0x0014
|
||||
pp_data->cap[1]->LinkCollection = 0x0000
|
||||
pp_data->cap[1]->LinkUsagePage = 0xFF00
|
||||
pp_data->cap[1]->LinkUsage = 0x0002
|
||||
pp_data->cap[1]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[1]->IsButtonCap = 1
|
||||
pp_data->cap[1]->IsPadding = 0
|
||||
pp_data->cap[1]->IsAbsolute = 1
|
||||
pp_data->cap[1]->IsRange = 0
|
||||
pp_data->cap[1]->IsAlias = 0
|
||||
pp_data->cap[1]->IsStringRange = 0
|
||||
pp_data->cap[1]->IsDesignatorRange = 0
|
||||
pp_data->cap[1]->Reserved1 = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[1]->NotRange.Usage = 0x0002
|
||||
pp_data->cap[1]->NotRange.Reserved1 = 0x0002
|
||||
pp_data->cap[1]->NotRange.StringIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[1]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[1]->NotRange.DataIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved4 = 0
|
||||
pp_data->cap[1]->Button.LogicalMin = 0
|
||||
pp_data->cap[1]->Button.LogicalMax = 255
|
||||
pp_data->cap[1]->Units = 0
|
||||
pp_data->cap[1]->UnitsExp = 0
|
||||
|
||||
# Feature hid_pp_cap struct:
|
||||
# Link Collections:
|
||||
pp_data->LinkCollectionArray[0]->LinkUsage = 0x0002
|
||||
pp_data->LinkCollectionArray[0]->LinkUsagePage = 0xFF00
|
||||
pp_data->LinkCollectionArray[0]->Parent = 0
|
||||
pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[0]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[0]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[0]->CollectionType = 1
|
||||
pp_data->LinkCollectionArray[0]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
|
||||
@@ -0,0 +1,4 @@
|
||||
0x06, 0x00, 0xFF, 0x09, 0x02, 0xA1, 0x01, 0x85, 0x11, 0x09,
|
||||
0x02, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x13,
|
||||
0x81, 0x00, 0x09, 0x02, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
|
||||
0x08, 0x95, 0x13, 0x91, 0x00, 0xC0,
|
||||
@@ -0,0 +1,39 @@
|
||||
|
||||
mac-hid-dump on main ❯ ./mac-hid-dump
|
||||
mac-hid-dump:
|
||||
...
|
||||
046D B010: Unknown - Bluetooth Mouse M557
|
||||
DESCRIPTOR:
|
||||
05 01 09 02 a1 01 85 02 09 01 a1 00 05 09 19 01
|
||||
29 08 15 00 25 01 75 01 95 08 81 02 05 01 09 30
|
||||
09 31 16 01 f8 26 ff 07 75 0c 95 02 81 06 09 38
|
||||
15 81 25 7f 75 08 95 01 81 06 05 0c 0a 38 02 75
|
||||
08 95 01 81 06 c0 c0 05 0c 09 01 a1 01 85 03 05
|
||||
06 09 20 15 00 26 64 00 75 08 95 01 81 02 c0 06
|
||||
00 ff 09 01 a1 01 85 10 75 08 95 06 15 00 26 ff
|
||||
00 09 01 81 00 09 01 91 00 c0 06 00 ff 09 02 a1
|
||||
01 85 11 75 08 95 13 15 00 26 ff 00 09 02 81 00
|
||||
09 02 91 00 c0 05 01 09 06 a1 01 85 04 75 01 95
|
||||
08 05 07 19 e0 29 e7 15 00 25 01 81 02 95 01 75
|
||||
08 81 03 95 05 75 01 05 08 19 01 29 05 91 02 95
|
||||
01 75 03 91 03 95 06 75 08 15 00 26 ff 00 05 07
|
||||
19 00 29 ff 81 00 c0 05 0c 09 01 a1 01 85 05 15
|
||||
00 25 01 75 01 95 02 0a 25 02 0a 24 02 81 02 95
|
||||
01 75 06 81 03 c0
|
||||
(246 bytes)
|
||||
|
||||
Parser output:
|
||||
|
||||
0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
|
||||
0x09, 0x02, // Usage (0x02)
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x85, 0x11, // Report ID (17)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x95, 0x13, // Report Count (19)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x26, 0xFF, 0x00, // Logical Maximum (255)
|
||||
0x09, 0x02, // Usage (0x02)
|
||||
0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x09, 0x02, // Usage (0x02)
|
||||
0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0xC0, // End Collection
|
||||
@@ -0,0 +1,185 @@
|
||||
# HIDAPI device info struct:
|
||||
dev->vendor_id = 0x046D
|
||||
dev->product_id = 0xB010
|
||||
dev->manufacturer_string = "Logitech"
|
||||
dev->product_string = "Logitech Bluetooth Wireless Mouse"
|
||||
dev->release_number = 0x0000
|
||||
dev->interface_number = -1
|
||||
dev->usage = 0x0006
|
||||
dev->usage_page = 0x0001
|
||||
dev->path = "\\?\hid#{00001124-0000-1000-8000-00805f9b34fb}_vid&0002046d_pid&b010&col05#8&1cf1c1b9&3&0004#{4d1e55b2-f16f-11cf-88cb-001111000030}\kbd"
|
||||
|
||||
# Preparsed Data struct:
|
||||
pp_data->MagicKey = 0x48696450204B4452
|
||||
pp_data->Usage = 0x0006
|
||||
pp_data->UsagePage = 0x0001
|
||||
pp_data->Reserved = 0x00000000
|
||||
# Input caps_info struct:
|
||||
pp_data->caps_info[0]->FirstCap = 0
|
||||
pp_data->caps_info[0]->LastCap = 2
|
||||
pp_data->caps_info[0]->NumberOfCaps = 2
|
||||
pp_data->caps_info[0]->ReportByteLength = 9
|
||||
# Output caps_info struct:
|
||||
pp_data->caps_info[1]->FirstCap = 2
|
||||
pp_data->caps_info[1]->LastCap = 3
|
||||
pp_data->caps_info[1]->NumberOfCaps = 1
|
||||
pp_data->caps_info[1]->ReportByteLength = 2
|
||||
# Feature caps_info struct:
|
||||
pp_data->caps_info[2]->FirstCap = 3
|
||||
pp_data->caps_info[2]->LastCap = 3
|
||||
pp_data->caps_info[2]->NumberOfCaps = 0
|
||||
pp_data->caps_info[2]->ReportByteLength = 0
|
||||
# LinkCollectionArray Offset & Size:
|
||||
pp_data->FirstByteOfLinkCollectionArray = 0x0138
|
||||
pp_data->NumberLinkCollectionNodes = 1
|
||||
# Input hid_pp_cap struct:
|
||||
pp_data->cap[0]->UsagePage = 0x0007
|
||||
pp_data->cap[0]->ReportID = 0x04
|
||||
pp_data->cap[0]->BitPosition = 0
|
||||
pp_data->cap[0]->BitSize = 1
|
||||
pp_data->cap[0]->ReportCount = 8
|
||||
pp_data->cap[0]->BytePosition = 0x0001
|
||||
pp_data->cap[0]->BitCount = 8
|
||||
pp_data->cap[0]->BitField = 0x02
|
||||
pp_data->cap[0]->NextBytePosition = 0x0002
|
||||
pp_data->cap[0]->LinkCollection = 0x0000
|
||||
pp_data->cap[0]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[0]->LinkUsage = 0x0006
|
||||
pp_data->cap[0]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[0]->IsButtonCap = 1
|
||||
pp_data->cap[0]->IsPadding = 0
|
||||
pp_data->cap[0]->IsAbsolute = 1
|
||||
pp_data->cap[0]->IsRange = 1
|
||||
pp_data->cap[0]->IsAlias = 0
|
||||
pp_data->cap[0]->IsStringRange = 0
|
||||
pp_data->cap[0]->IsDesignatorRange = 0
|
||||
pp_data->cap[0]->Reserved1 = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[0]->Range.UsageMin = 0x00E0
|
||||
pp_data->cap[0]->Range.UsageMax = 0x00E7
|
||||
pp_data->cap[0]->Range.StringMin = 0
|
||||
pp_data->cap[0]->Range.StringMax = 0
|
||||
pp_data->cap[0]->Range.DesignatorMin = 0
|
||||
pp_data->cap[0]->Range.DesignatorMax = 0
|
||||
pp_data->cap[0]->Range.DataIndexMin = 0
|
||||
pp_data->cap[0]->Range.DataIndexMax = 7
|
||||
pp_data->cap[0]->Button.LogicalMin = 0
|
||||
pp_data->cap[0]->Button.LogicalMax = 0
|
||||
pp_data->cap[0]->Units = 0
|
||||
pp_data->cap[0]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[1]->UsagePage = 0x0007
|
||||
pp_data->cap[1]->ReportID = 0x04
|
||||
pp_data->cap[1]->BitPosition = 0
|
||||
pp_data->cap[1]->BitSize = 8
|
||||
pp_data->cap[1]->ReportCount = 6
|
||||
pp_data->cap[1]->BytePosition = 0x0003
|
||||
pp_data->cap[1]->BitCount = 48
|
||||
pp_data->cap[1]->BitField = 0x00
|
||||
pp_data->cap[1]->NextBytePosition = 0x0009
|
||||
pp_data->cap[1]->LinkCollection = 0x0000
|
||||
pp_data->cap[1]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[1]->LinkUsage = 0x0006
|
||||
pp_data->cap[1]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[1]->IsButtonCap = 1
|
||||
pp_data->cap[1]->IsPadding = 0
|
||||
pp_data->cap[1]->IsAbsolute = 1
|
||||
pp_data->cap[1]->IsRange = 1
|
||||
pp_data->cap[1]->IsAlias = 0
|
||||
pp_data->cap[1]->IsStringRange = 0
|
||||
pp_data->cap[1]->IsDesignatorRange = 0
|
||||
pp_data->cap[1]->Reserved1 = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[1]->Range.UsageMin = 0x0000
|
||||
pp_data->cap[1]->Range.UsageMax = 0x00FF
|
||||
pp_data->cap[1]->Range.StringMin = 0
|
||||
pp_data->cap[1]->Range.StringMax = 0
|
||||
pp_data->cap[1]->Range.DesignatorMin = 0
|
||||
pp_data->cap[1]->Range.DesignatorMax = 0
|
||||
pp_data->cap[1]->Range.DataIndexMin = 8
|
||||
pp_data->cap[1]->Range.DataIndexMax = 263
|
||||
pp_data->cap[1]->Button.LogicalMin = 0
|
||||
pp_data->cap[1]->Button.LogicalMax = 255
|
||||
pp_data->cap[1]->Units = 0
|
||||
pp_data->cap[1]->UnitsExp = 0
|
||||
|
||||
# Output hid_pp_cap struct:
|
||||
pp_data->cap[2]->UsagePage = 0x0008
|
||||
pp_data->cap[2]->ReportID = 0x04
|
||||
pp_data->cap[2]->BitPosition = 0
|
||||
pp_data->cap[2]->BitSize = 1
|
||||
pp_data->cap[2]->ReportCount = 5
|
||||
pp_data->cap[2]->BytePosition = 0x0001
|
||||
pp_data->cap[2]->BitCount = 5
|
||||
pp_data->cap[2]->BitField = 0x02
|
||||
pp_data->cap[2]->NextBytePosition = 0x0002
|
||||
pp_data->cap[2]->LinkCollection = 0x0000
|
||||
pp_data->cap[2]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[2]->LinkUsage = 0x0006
|
||||
pp_data->cap[2]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[2]->IsButtonCap = 1
|
||||
pp_data->cap[2]->IsPadding = 0
|
||||
pp_data->cap[2]->IsAbsolute = 1
|
||||
pp_data->cap[2]->IsRange = 1
|
||||
pp_data->cap[2]->IsAlias = 0
|
||||
pp_data->cap[2]->IsStringRange = 0
|
||||
pp_data->cap[2]->IsDesignatorRange = 0
|
||||
pp_data->cap[2]->Reserved1 = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[2]->Range.UsageMin = 0x0001
|
||||
pp_data->cap[2]->Range.UsageMax = 0x0005
|
||||
pp_data->cap[2]->Range.StringMin = 0
|
||||
pp_data->cap[2]->Range.StringMax = 0
|
||||
pp_data->cap[2]->Range.DesignatorMin = 0
|
||||
pp_data->cap[2]->Range.DesignatorMax = 0
|
||||
pp_data->cap[2]->Range.DataIndexMin = 0
|
||||
pp_data->cap[2]->Range.DataIndexMax = 4
|
||||
pp_data->cap[2]->Button.LogicalMin = 0
|
||||
pp_data->cap[2]->Button.LogicalMax = 0
|
||||
pp_data->cap[2]->Units = 0
|
||||
pp_data->cap[2]->UnitsExp = 0
|
||||
|
||||
# Feature hid_pp_cap struct:
|
||||
# Link Collections:
|
||||
pp_data->LinkCollectionArray[0]->LinkUsage = 0x0006
|
||||
pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x0001
|
||||
pp_data->LinkCollectionArray[0]->Parent = 0
|
||||
pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[0]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[0]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[0]->CollectionType = 1
|
||||
pp_data->LinkCollectionArray[0]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
|
||||
@@ -0,0 +1,7 @@
|
||||
0x05, 0x01, 0x09, 0x06, 0xA1, 0x01, 0x85, 0x04, 0x05, 0x07,
|
||||
0x19, 0xE0, 0x29, 0xE7, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01,
|
||||
0x95, 0x08, 0x81, 0x02, 0x75, 0x08, 0x95, 0x01, 0x81, 0x03,
|
||||
0x19, 0x00, 0x29, 0xFF, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
|
||||
0x08, 0x95, 0x06, 0x81, 0x00, 0x05, 0x08, 0x19, 0x01, 0x29,
|
||||
0x05, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x05, 0x91,
|
||||
0x02, 0x75, 0x03, 0x95, 0x01, 0x91, 0x03, 0xC0,
|
||||
@@ -0,0 +1,58 @@
|
||||
|
||||
mac-hid-dump on main ❯ ./mac-hid-dump
|
||||
mac-hid-dump:
|
||||
...
|
||||
046D B010: Unknown - Bluetooth Mouse M557
|
||||
DESCRIPTOR:
|
||||
05 01 09 02 a1 01 85 02 09 01 a1 00 05 09 19 01
|
||||
29 08 15 00 25 01 75 01 95 08 81 02 05 01 09 30
|
||||
09 31 16 01 f8 26 ff 07 75 0c 95 02 81 06 09 38
|
||||
15 81 25 7f 75 08 95 01 81 06 05 0c 0a 38 02 75
|
||||
08 95 01 81 06 c0 c0 05 0c 09 01 a1 01 85 03 05
|
||||
06 09 20 15 00 26 64 00 75 08 95 01 81 02 c0 06
|
||||
00 ff 09 01 a1 01 85 10 75 08 95 06 15 00 26 ff
|
||||
00 09 01 81 00 09 01 91 00 c0 06 00 ff 09 02 a1
|
||||
01 85 11 75 08 95 13 15 00 26 ff 00 09 02 81 00
|
||||
09 02 91 00 c0 05 01 09 06 a1 01 85 04 75 01 95
|
||||
08 05 07 19 e0 29 e7 15 00 25 01 81 02 95 01 75
|
||||
08 81 03 95 05 75 01 05 08 19 01 29 05 91 02 95
|
||||
01 75 03 91 03 95 06 75 08 15 00 26 ff 00 05 07
|
||||
19 00 29 ff 81 00 c0 05 0c 09 01 a1 01 85 05 15
|
||||
00 25 01 75 01 95 02 0a 25 02 0a 24 02 81 02 95
|
||||
01 75 06 81 03 c0
|
||||
(246 bytes)
|
||||
|
||||
Parser output:
|
||||
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
||||
0x09, 0x06, // Usage (Keyboard)
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x85, 0x04, // Report ID (4)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x95, 0x08, // Report Count (8)
|
||||
0x05, 0x07, // Usage Page (Kbrd/Keypad)
|
||||
0x19, 0xE0, // Usage Minimum (0xE0)
|
||||
0x29, 0xE7, // Usage Maximum (0xE7)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x25, 0x01, // Logical Maximum (1)
|
||||
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x95, 0x05, // Report Count (5)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x05, 0x08, // Usage Page (LEDs)
|
||||
0x19, 0x01, // Usage Minimum (Num Lock)
|
||||
0x29, 0x05, // Usage Maximum (Kana)
|
||||
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x75, 0x03, // Report Size (3)
|
||||
0x91, 0x03, // Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0x95, 0x06, // Report Count (6)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x26, 0xFF, 0x00, // Logical Maximum (255)
|
||||
0x05, 0x07, // Usage Page (Kbrd/Keypad)
|
||||
0x19, 0x00, // Usage Minimum (0x00)
|
||||
0x29, 0xFF, // Usage Maximum (0xFF)
|
||||
0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0xC0, // End Collection
|
||||
@@ -0,0 +1,252 @@
|
||||
# HIDAPI device info struct:
|
||||
dev->vendor_id = 0x046D
|
||||
dev->product_id = 0xC077
|
||||
dev->manufacturer_string = "Logitech"
|
||||
dev->product_string = "USB Optical Mouse"
|
||||
dev->release_number = 0x7200
|
||||
dev->interface_number = -1
|
||||
dev->usage = 0x0002
|
||||
dev->usage_page = 0x0001
|
||||
dev->path = "\\?\hid#vid_046d&pid_c077#7&1875dbae&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
|
||||
|
||||
# Preparsed Data struct:
|
||||
pp_data->MagicKey = 0x48696450204B4452
|
||||
pp_data->Usage = 0x0002
|
||||
pp_data->UsagePage = 0x0001
|
||||
pp_data->Reserved = 0x00000000
|
||||
# Input caps_info struct:
|
||||
pp_data->caps_info[0]->FirstCap = 0
|
||||
pp_data->caps_info[0]->LastCap = 4
|
||||
pp_data->caps_info[0]->NumberOfCaps = 4
|
||||
pp_data->caps_info[0]->ReportByteLength = 5
|
||||
# Output caps_info struct:
|
||||
pp_data->caps_info[1]->FirstCap = 4
|
||||
pp_data->caps_info[1]->LastCap = 4
|
||||
pp_data->caps_info[1]->NumberOfCaps = 0
|
||||
pp_data->caps_info[1]->ReportByteLength = 0
|
||||
# Feature caps_info struct:
|
||||
pp_data->caps_info[2]->FirstCap = 4
|
||||
pp_data->caps_info[2]->LastCap = 4
|
||||
pp_data->caps_info[2]->NumberOfCaps = 0
|
||||
pp_data->caps_info[2]->ReportByteLength = 0
|
||||
# LinkCollectionArray Offset & Size:
|
||||
pp_data->FirstByteOfLinkCollectionArray = 0x01A0
|
||||
pp_data->NumberLinkCollectionNodes = 2
|
||||
# Input hid_pp_cap struct:
|
||||
pp_data->cap[0]->UsagePage = 0x0009
|
||||
pp_data->cap[0]->ReportID = 0x00
|
||||
pp_data->cap[0]->BitPosition = 0
|
||||
pp_data->cap[0]->BitSize = 1
|
||||
pp_data->cap[0]->ReportCount = 8
|
||||
pp_data->cap[0]->BytePosition = 0x0001
|
||||
pp_data->cap[0]->BitCount = 8
|
||||
pp_data->cap[0]->BitField = 0x02
|
||||
pp_data->cap[0]->NextBytePosition = 0x0002
|
||||
pp_data->cap[0]->LinkCollection = 0x0001
|
||||
pp_data->cap[0]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[0]->LinkUsage = 0x0001
|
||||
pp_data->cap[0]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[0]->IsButtonCap = 1
|
||||
pp_data->cap[0]->IsPadding = 0
|
||||
pp_data->cap[0]->IsAbsolute = 1
|
||||
pp_data->cap[0]->IsRange = 1
|
||||
pp_data->cap[0]->IsAlias = 0
|
||||
pp_data->cap[0]->IsStringRange = 0
|
||||
pp_data->cap[0]->IsDesignatorRange = 0
|
||||
pp_data->cap[0]->Reserved1 = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[0]->Range.UsageMin = 0x0001
|
||||
pp_data->cap[0]->Range.UsageMax = 0x0003
|
||||
pp_data->cap[0]->Range.StringMin = 0
|
||||
pp_data->cap[0]->Range.StringMax = 0
|
||||
pp_data->cap[0]->Range.DesignatorMin = 0
|
||||
pp_data->cap[0]->Range.DesignatorMax = 0
|
||||
pp_data->cap[0]->Range.DataIndexMin = 0
|
||||
pp_data->cap[0]->Range.DataIndexMax = 2
|
||||
pp_data->cap[0]->Button.LogicalMin = 0
|
||||
pp_data->cap[0]->Button.LogicalMax = 0
|
||||
pp_data->cap[0]->Units = 0
|
||||
pp_data->cap[0]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[1]->UsagePage = 0x0001
|
||||
pp_data->cap[1]->ReportID = 0x00
|
||||
pp_data->cap[1]->BitPosition = 0
|
||||
pp_data->cap[1]->BitSize = 8
|
||||
pp_data->cap[1]->ReportCount = 1
|
||||
pp_data->cap[1]->BytePosition = 0x0004
|
||||
pp_data->cap[1]->BitCount = 8
|
||||
pp_data->cap[1]->BitField = 0x06
|
||||
pp_data->cap[1]->NextBytePosition = 0x0005
|
||||
pp_data->cap[1]->LinkCollection = 0x0001
|
||||
pp_data->cap[1]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[1]->LinkUsage = 0x0001
|
||||
pp_data->cap[1]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[1]->IsButtonCap = 0
|
||||
pp_data->cap[1]->IsPadding = 0
|
||||
pp_data->cap[1]->IsAbsolute = 0
|
||||
pp_data->cap[1]->IsRange = 0
|
||||
pp_data->cap[1]->IsAlias = 0
|
||||
pp_data->cap[1]->IsStringRange = 0
|
||||
pp_data->cap[1]->IsDesignatorRange = 0
|
||||
pp_data->cap[1]->Reserved1 = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[1]->NotRange.Usage = 0x0038
|
||||
pp_data->cap[1]->NotRange.Reserved1 = 0x0038
|
||||
pp_data->cap[1]->NotRange.StringIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[1]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[1]->NotRange.DataIndex = 3
|
||||
pp_data->cap[1]->NotRange.Reserved4 = 3
|
||||
pp_data->cap[1]->NotButton.HasNull = 0
|
||||
pp_data->cap[1]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[1]->NotButton.LogicalMin = -127
|
||||
pp_data->cap[1]->NotButton.LogicalMax = 127
|
||||
pp_data->cap[1]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[1]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[1]->Units = 0
|
||||
pp_data->cap[1]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[2]->UsagePage = 0x0001
|
||||
pp_data->cap[2]->ReportID = 0x00
|
||||
pp_data->cap[2]->BitPosition = 0
|
||||
pp_data->cap[2]->BitSize = 8
|
||||
pp_data->cap[2]->ReportCount = 1
|
||||
pp_data->cap[2]->BytePosition = 0x0003
|
||||
pp_data->cap[2]->BitCount = 8
|
||||
pp_data->cap[2]->BitField = 0x06
|
||||
pp_data->cap[2]->NextBytePosition = 0x0004
|
||||
pp_data->cap[2]->LinkCollection = 0x0001
|
||||
pp_data->cap[2]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[2]->LinkUsage = 0x0001
|
||||
pp_data->cap[2]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[2]->IsButtonCap = 0
|
||||
pp_data->cap[2]->IsPadding = 0
|
||||
pp_data->cap[2]->IsAbsolute = 0
|
||||
pp_data->cap[2]->IsRange = 0
|
||||
pp_data->cap[2]->IsAlias = 0
|
||||
pp_data->cap[2]->IsStringRange = 0
|
||||
pp_data->cap[2]->IsDesignatorRange = 0
|
||||
pp_data->cap[2]->Reserved1 = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[2]->NotRange.Usage = 0x0031
|
||||
pp_data->cap[2]->NotRange.Reserved1 = 0x0031
|
||||
pp_data->cap[2]->NotRange.StringIndex = 0
|
||||
pp_data->cap[2]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[2]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[2]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[2]->NotRange.DataIndex = 4
|
||||
pp_data->cap[2]->NotRange.Reserved4 = 4
|
||||
pp_data->cap[2]->NotButton.HasNull = 0
|
||||
pp_data->cap[2]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[2]->NotButton.LogicalMin = -127
|
||||
pp_data->cap[2]->NotButton.LogicalMax = 127
|
||||
pp_data->cap[2]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[2]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[2]->Units = 0
|
||||
pp_data->cap[2]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[3]->UsagePage = 0x0001
|
||||
pp_data->cap[3]->ReportID = 0x00
|
||||
pp_data->cap[3]->BitPosition = 0
|
||||
pp_data->cap[3]->BitSize = 8
|
||||
pp_data->cap[3]->ReportCount = 1
|
||||
pp_data->cap[3]->BytePosition = 0x0002
|
||||
pp_data->cap[3]->BitCount = 8
|
||||
pp_data->cap[3]->BitField = 0x06
|
||||
pp_data->cap[3]->NextBytePosition = 0x0003
|
||||
pp_data->cap[3]->LinkCollection = 0x0001
|
||||
pp_data->cap[3]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[3]->LinkUsage = 0x0001
|
||||
pp_data->cap[3]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[3]->IsButtonCap = 0
|
||||
pp_data->cap[3]->IsPadding = 0
|
||||
pp_data->cap[3]->IsAbsolute = 0
|
||||
pp_data->cap[3]->IsRange = 0
|
||||
pp_data->cap[3]->IsAlias = 0
|
||||
pp_data->cap[3]->IsStringRange = 0
|
||||
pp_data->cap[3]->IsDesignatorRange = 0
|
||||
pp_data->cap[3]->Reserved1 = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[3]->NotRange.Usage = 0x0030
|
||||
pp_data->cap[3]->NotRange.Reserved1 = 0x0030
|
||||
pp_data->cap[3]->NotRange.StringIndex = 0
|
||||
pp_data->cap[3]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[3]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[3]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[3]->NotRange.DataIndex = 5
|
||||
pp_data->cap[3]->NotRange.Reserved4 = 5
|
||||
pp_data->cap[3]->NotButton.HasNull = 0
|
||||
pp_data->cap[3]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[3]->NotButton.LogicalMin = -127
|
||||
pp_data->cap[3]->NotButton.LogicalMax = 127
|
||||
pp_data->cap[3]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[3]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[3]->Units = 0
|
||||
pp_data->cap[3]->UnitsExp = 0
|
||||
|
||||
# Output hid_pp_cap struct:
|
||||
# Feature hid_pp_cap struct:
|
||||
# Link Collections:
|
||||
pp_data->LinkCollectionArray[0]->LinkUsage = 0x0002
|
||||
pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x0001
|
||||
pp_data->LinkCollectionArray[0]->Parent = 0
|
||||
pp_data->LinkCollectionArray[0]->NumberOfChildren = 1
|
||||
pp_data->LinkCollectionArray[0]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[0]->FirstChild = 1
|
||||
pp_data->LinkCollectionArray[0]->CollectionType = 1
|
||||
pp_data->LinkCollectionArray[0]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
|
||||
pp_data->LinkCollectionArray[1]->LinkUsage = 0x0001
|
||||
pp_data->LinkCollectionArray[1]->LinkUsagePage = 0x0001
|
||||
pp_data->LinkCollectionArray[1]->Parent = 0
|
||||
pp_data->LinkCollectionArray[1]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[1]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[1]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[1]->CollectionType = 0
|
||||
pp_data->LinkCollectionArray[1]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[1]->Reserved = 0x00000000
|
||||
@@ -0,0 +1,5 @@
|
||||
0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01, 0xA1, 0x00,
|
||||
0x05, 0x09, 0x19, 0x01, 0x29, 0x03, 0x15, 0x00, 0x25, 0x01,
|
||||
0x75, 0x01, 0x95, 0x08, 0x81, 0x02, 0x05, 0x01, 0x09, 0x30,
|
||||
0x09, 0x31, 0x09, 0x38, 0x15, 0x81, 0x25, 0x7F, 0x75, 0x08,
|
||||
0x95, 0x03, 0x81, 0x06, 0xC0, 0xC0,
|
||||
@@ -0,0 +1,24 @@
|
||||
Usage Page (Generic Desktop) 05 01
|
||||
Usage (Mouse) 09 02
|
||||
Collection (Application) A1 01
|
||||
Usage (Pointer) 09 01
|
||||
Collection (Physical) A1 00
|
||||
Usage Page (Button) 05 09
|
||||
Usage Minimum (Button 1) 19 01
|
||||
Usage Maximum (Button 3) 29 03
|
||||
Logical Minimum (0) 15 00
|
||||
Logical Maximum (1) 25 01
|
||||
Report Count (8) 95 08
|
||||
Report Size (1) 75 01
|
||||
Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
|
||||
Usage Page (Generic Desktop) 05 01
|
||||
Usage (X) 09 30
|
||||
Usage (Y) 09 31
|
||||
Usage (Wheel) 09 38
|
||||
Logical Minimum (-127) 15 81
|
||||
Logical Maximum (127) 25 7F
|
||||
Report Size (8) 75 08
|
||||
Report Count (3) 95 03
|
||||
Input (Data,Var,Rel,NWrp,Lin,Pref,NNul,Bit) 81 06
|
||||
End Collection C0
|
||||
End Collection C0
|
||||
@@ -0,0 +1,520 @@
|
||||
# HIDAPI device info struct:
|
||||
dev->vendor_id = 0x046D
|
||||
dev->product_id = 0xC283
|
||||
dev->manufacturer_string = "Logitech Inc."
|
||||
dev->product_string = "WingMan Force 3D"
|
||||
dev->release_number = 0x0106
|
||||
dev->interface_number = -1
|
||||
dev->usage = 0x0004
|
||||
dev->usage_page = 0x0001
|
||||
dev->path = "\\?\hid#vid_046d&pid_c283#7&d7fb4bf&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
|
||||
|
||||
# Preparsed Data struct:
|
||||
pp_data->MagicKey = 0x48696450204B4452
|
||||
pp_data->Usage = 0x0004
|
||||
pp_data->UsagePage = 0x0001
|
||||
pp_data->Reserved = 0x00000000
|
||||
# Input caps_info struct:
|
||||
pp_data->caps_info[0]->FirstCap = 0
|
||||
pp_data->caps_info[0]->LastCap = 8
|
||||
pp_data->caps_info[0]->NumberOfCaps = 8
|
||||
pp_data->caps_info[0]->ReportByteLength = 8
|
||||
# Output caps_info struct:
|
||||
pp_data->caps_info[1]->FirstCap = 8
|
||||
pp_data->caps_info[1]->LastCap = 9
|
||||
pp_data->caps_info[1]->NumberOfCaps = 1
|
||||
pp_data->caps_info[1]->ReportByteLength = 9
|
||||
# Feature caps_info struct:
|
||||
pp_data->caps_info[2]->FirstCap = 9
|
||||
pp_data->caps_info[2]->LastCap = 9
|
||||
pp_data->caps_info[2]->NumberOfCaps = 0
|
||||
pp_data->caps_info[2]->ReportByteLength = 0
|
||||
# LinkCollectionArray Offset & Size:
|
||||
pp_data->FirstByteOfLinkCollectionArray = 0x03A8
|
||||
pp_data->NumberLinkCollectionNodes = 4
|
||||
# Input hid_pp_cap struct:
|
||||
pp_data->cap[0]->UsagePage = 0x0001
|
||||
pp_data->cap[0]->ReportID = 0x00
|
||||
pp_data->cap[0]->BitPosition = 0
|
||||
pp_data->cap[0]->BitSize = 8
|
||||
pp_data->cap[0]->ReportCount = 1
|
||||
pp_data->cap[0]->BytePosition = 0x0002
|
||||
pp_data->cap[0]->BitCount = 8
|
||||
pp_data->cap[0]->BitField = 0x02
|
||||
pp_data->cap[0]->NextBytePosition = 0x0003
|
||||
pp_data->cap[0]->LinkCollection = 0x0002
|
||||
pp_data->cap[0]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[0]->LinkUsage = 0x0001
|
||||
pp_data->cap[0]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[0]->IsButtonCap = 0
|
||||
pp_data->cap[0]->IsPadding = 0
|
||||
pp_data->cap[0]->IsAbsolute = 1
|
||||
pp_data->cap[0]->IsRange = 0
|
||||
pp_data->cap[0]->IsAlias = 0
|
||||
pp_data->cap[0]->IsStringRange = 0
|
||||
pp_data->cap[0]->IsDesignatorRange = 0
|
||||
pp_data->cap[0]->Reserved1 = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[0]->NotRange.Usage = 0x0031
|
||||
pp_data->cap[0]->NotRange.Reserved1 = 0x0031
|
||||
pp_data->cap[0]->NotRange.StringIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[0]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[0]->NotRange.DataIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved4 = 0
|
||||
pp_data->cap[0]->NotButton.HasNull = 0
|
||||
pp_data->cap[0]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[0]->NotButton.LogicalMin = 0
|
||||
pp_data->cap[0]->NotButton.LogicalMax = 255
|
||||
pp_data->cap[0]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[0]->NotButton.PhysicalMax = 255
|
||||
pp_data->cap[0]->Units = 0
|
||||
pp_data->cap[0]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[1]->UsagePage = 0x0001
|
||||
pp_data->cap[1]->ReportID = 0x00
|
||||
pp_data->cap[1]->BitPosition = 0
|
||||
pp_data->cap[1]->BitSize = 8
|
||||
pp_data->cap[1]->ReportCount = 1
|
||||
pp_data->cap[1]->BytePosition = 0x0001
|
||||
pp_data->cap[1]->BitCount = 8
|
||||
pp_data->cap[1]->BitField = 0x02
|
||||
pp_data->cap[1]->NextBytePosition = 0x0002
|
||||
pp_data->cap[1]->LinkCollection = 0x0002
|
||||
pp_data->cap[1]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[1]->LinkUsage = 0x0001
|
||||
pp_data->cap[1]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[1]->IsButtonCap = 0
|
||||
pp_data->cap[1]->IsPadding = 0
|
||||
pp_data->cap[1]->IsAbsolute = 1
|
||||
pp_data->cap[1]->IsRange = 0
|
||||
pp_data->cap[1]->IsAlias = 0
|
||||
pp_data->cap[1]->IsStringRange = 0
|
||||
pp_data->cap[1]->IsDesignatorRange = 0
|
||||
pp_data->cap[1]->Reserved1 = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[1]->NotRange.Usage = 0x0030
|
||||
pp_data->cap[1]->NotRange.Reserved1 = 0x0030
|
||||
pp_data->cap[1]->NotRange.StringIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[1]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[1]->NotRange.DataIndex = 1
|
||||
pp_data->cap[1]->NotRange.Reserved4 = 1
|
||||
pp_data->cap[1]->NotButton.HasNull = 0
|
||||
pp_data->cap[1]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[1]->NotButton.LogicalMin = 0
|
||||
pp_data->cap[1]->NotButton.LogicalMax = 255
|
||||
pp_data->cap[1]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[1]->NotButton.PhysicalMax = 255
|
||||
pp_data->cap[1]->Units = 0
|
||||
pp_data->cap[1]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[2]->UsagePage = 0xFF00
|
||||
pp_data->cap[2]->ReportID = 0x00
|
||||
pp_data->cap[2]->BitPosition = 0
|
||||
pp_data->cap[2]->BitSize = 4
|
||||
pp_data->cap[2]->ReportCount = 1
|
||||
pp_data->cap[2]->BytePosition = 0x0003
|
||||
pp_data->cap[2]->BitCount = 4
|
||||
pp_data->cap[2]->BitField = 0x02
|
||||
pp_data->cap[2]->NextBytePosition = 0x0004
|
||||
pp_data->cap[2]->LinkCollection = 0x0002
|
||||
pp_data->cap[2]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[2]->LinkUsage = 0x0001
|
||||
pp_data->cap[2]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[2]->IsButtonCap = 0
|
||||
pp_data->cap[2]->IsPadding = 0
|
||||
pp_data->cap[2]->IsAbsolute = 1
|
||||
pp_data->cap[2]->IsRange = 0
|
||||
pp_data->cap[2]->IsAlias = 0
|
||||
pp_data->cap[2]->IsStringRange = 0
|
||||
pp_data->cap[2]->IsDesignatorRange = 0
|
||||
pp_data->cap[2]->Reserved1 = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[2]->NotRange.Usage = 0x0001
|
||||
pp_data->cap[2]->NotRange.Reserved1 = 0x0001
|
||||
pp_data->cap[2]->NotRange.StringIndex = 0
|
||||
pp_data->cap[2]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[2]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[2]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[2]->NotRange.DataIndex = 2
|
||||
pp_data->cap[2]->NotRange.Reserved4 = 2
|
||||
pp_data->cap[2]->NotButton.HasNull = 0
|
||||
pp_data->cap[2]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[2]->NotButton.LogicalMin = 0
|
||||
pp_data->cap[2]->NotButton.LogicalMax = 15
|
||||
pp_data->cap[2]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[2]->NotButton.PhysicalMax = 255
|
||||
pp_data->cap[2]->Units = 0
|
||||
pp_data->cap[2]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[3]->UsagePage = 0x0001
|
||||
pp_data->cap[3]->ReportID = 0x00
|
||||
pp_data->cap[3]->BitPosition = 4
|
||||
pp_data->cap[3]->BitSize = 4
|
||||
pp_data->cap[3]->ReportCount = 1
|
||||
pp_data->cap[3]->BytePosition = 0x0003
|
||||
pp_data->cap[3]->BitCount = 4
|
||||
pp_data->cap[3]->BitField = 0x42
|
||||
pp_data->cap[3]->NextBytePosition = 0x0004
|
||||
pp_data->cap[3]->LinkCollection = 0x0002
|
||||
pp_data->cap[3]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[3]->LinkUsage = 0x0001
|
||||
pp_data->cap[3]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[3]->IsButtonCap = 0
|
||||
pp_data->cap[3]->IsPadding = 0
|
||||
pp_data->cap[3]->IsAbsolute = 1
|
||||
pp_data->cap[3]->IsRange = 0
|
||||
pp_data->cap[3]->IsAlias = 0
|
||||
pp_data->cap[3]->IsStringRange = 0
|
||||
pp_data->cap[3]->IsDesignatorRange = 0
|
||||
pp_data->cap[3]->Reserved1 = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[3]->NotRange.Usage = 0x0039
|
||||
pp_data->cap[3]->NotRange.Reserved1 = 0x0039
|
||||
pp_data->cap[3]->NotRange.StringIndex = 0
|
||||
pp_data->cap[3]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[3]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[3]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[3]->NotRange.DataIndex = 3
|
||||
pp_data->cap[3]->NotRange.Reserved4 = 3
|
||||
pp_data->cap[3]->NotButton.HasNull = 1
|
||||
pp_data->cap[3]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[3]->NotButton.LogicalMin = 0
|
||||
pp_data->cap[3]->NotButton.LogicalMax = 7
|
||||
pp_data->cap[3]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[3]->NotButton.PhysicalMax = 315
|
||||
pp_data->cap[3]->Units = 20
|
||||
pp_data->cap[3]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[4]->UsagePage = 0x0001
|
||||
pp_data->cap[4]->ReportID = 0x00
|
||||
pp_data->cap[4]->BitPosition = 0
|
||||
pp_data->cap[4]->BitSize = 8
|
||||
pp_data->cap[4]->ReportCount = 1
|
||||
pp_data->cap[4]->BytePosition = 0x0004
|
||||
pp_data->cap[4]->BitCount = 8
|
||||
pp_data->cap[4]->BitField = 0x02
|
||||
pp_data->cap[4]->NextBytePosition = 0x0005
|
||||
pp_data->cap[4]->LinkCollection = 0x0002
|
||||
pp_data->cap[4]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[4]->LinkUsage = 0x0001
|
||||
pp_data->cap[4]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[4]->IsButtonCap = 0
|
||||
pp_data->cap[4]->IsPadding = 0
|
||||
pp_data->cap[4]->IsAbsolute = 1
|
||||
pp_data->cap[4]->IsRange = 0
|
||||
pp_data->cap[4]->IsAlias = 0
|
||||
pp_data->cap[4]->IsStringRange = 0
|
||||
pp_data->cap[4]->IsDesignatorRange = 0
|
||||
pp_data->cap[4]->Reserved1 = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[4]->NotRange.Usage = 0x0035
|
||||
pp_data->cap[4]->NotRange.Reserved1 = 0x0035
|
||||
pp_data->cap[4]->NotRange.StringIndex = 0
|
||||
pp_data->cap[4]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[4]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[4]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[4]->NotRange.DataIndex = 4
|
||||
pp_data->cap[4]->NotRange.Reserved4 = 4
|
||||
pp_data->cap[4]->NotButton.HasNull = 0
|
||||
pp_data->cap[4]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[4]->NotButton.LogicalMin = 0
|
||||
pp_data->cap[4]->NotButton.LogicalMax = 255
|
||||
pp_data->cap[4]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[4]->NotButton.PhysicalMax = 255
|
||||
pp_data->cap[4]->Units = 20
|
||||
pp_data->cap[4]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[5]->UsagePage = 0x0009
|
||||
pp_data->cap[5]->ReportID = 0x00
|
||||
pp_data->cap[5]->BitPosition = 0
|
||||
pp_data->cap[5]->BitSize = 1
|
||||
pp_data->cap[5]->ReportCount = 7
|
||||
pp_data->cap[5]->BytePosition = 0x0005
|
||||
pp_data->cap[5]->BitCount = 7
|
||||
pp_data->cap[5]->BitField = 0x02
|
||||
pp_data->cap[5]->NextBytePosition = 0x0006
|
||||
pp_data->cap[5]->LinkCollection = 0x0001
|
||||
pp_data->cap[5]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[5]->LinkUsage = 0x0000
|
||||
pp_data->cap[5]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[5]->IsButtonCap = 1
|
||||
pp_data->cap[5]->IsPadding = 0
|
||||
pp_data->cap[5]->IsAbsolute = 1
|
||||
pp_data->cap[5]->IsRange = 1
|
||||
pp_data->cap[5]->IsAlias = 0
|
||||
pp_data->cap[5]->IsStringRange = 0
|
||||
pp_data->cap[5]->IsDesignatorRange = 0
|
||||
pp_data->cap[5]->Reserved1 = 0x000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[5]->Range.UsageMin = 0x0001
|
||||
pp_data->cap[5]->Range.UsageMax = 0x0007
|
||||
pp_data->cap[5]->Range.StringMin = 0
|
||||
pp_data->cap[5]->Range.StringMax = 0
|
||||
pp_data->cap[5]->Range.DesignatorMin = 0
|
||||
pp_data->cap[5]->Range.DesignatorMax = 0
|
||||
pp_data->cap[5]->Range.DataIndexMin = 5
|
||||
pp_data->cap[5]->Range.DataIndexMax = 11
|
||||
pp_data->cap[5]->Button.LogicalMin = 0
|
||||
pp_data->cap[5]->Button.LogicalMax = 0
|
||||
pp_data->cap[5]->Units = 0
|
||||
pp_data->cap[5]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[6]->UsagePage = 0x0001
|
||||
pp_data->cap[6]->ReportID = 0x00
|
||||
pp_data->cap[6]->BitPosition = 0
|
||||
pp_data->cap[6]->BitSize = 8
|
||||
pp_data->cap[6]->ReportCount = 1
|
||||
pp_data->cap[6]->BytePosition = 0x0006
|
||||
pp_data->cap[6]->BitCount = 8
|
||||
pp_data->cap[6]->BitField = 0x02
|
||||
pp_data->cap[6]->NextBytePosition = 0x0007
|
||||
pp_data->cap[6]->LinkCollection = 0x0001
|
||||
pp_data->cap[6]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[6]->LinkUsage = 0x0000
|
||||
pp_data->cap[6]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[6]->IsButtonCap = 0
|
||||
pp_data->cap[6]->IsPadding = 0
|
||||
pp_data->cap[6]->IsAbsolute = 1
|
||||
pp_data->cap[6]->IsRange = 0
|
||||
pp_data->cap[6]->IsAlias = 0
|
||||
pp_data->cap[6]->IsStringRange = 0
|
||||
pp_data->cap[6]->IsDesignatorRange = 0
|
||||
pp_data->cap[6]->Reserved1 = 0x000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[6]->NotRange.Usage = 0x0036
|
||||
pp_data->cap[6]->NotRange.Reserved1 = 0x0036
|
||||
pp_data->cap[6]->NotRange.StringIndex = 0
|
||||
pp_data->cap[6]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[6]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[6]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[6]->NotRange.DataIndex = 12
|
||||
pp_data->cap[6]->NotRange.Reserved4 = 12
|
||||
pp_data->cap[6]->NotButton.HasNull = 0
|
||||
pp_data->cap[6]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[6]->NotButton.LogicalMin = 0
|
||||
pp_data->cap[6]->NotButton.LogicalMax = 255
|
||||
pp_data->cap[6]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[6]->NotButton.PhysicalMax = 255
|
||||
pp_data->cap[6]->Units = 0
|
||||
pp_data->cap[6]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[7]->UsagePage = 0xFF00
|
||||
pp_data->cap[7]->ReportID = 0x00
|
||||
pp_data->cap[7]->BitPosition = 0
|
||||
pp_data->cap[7]->BitSize = 8
|
||||
pp_data->cap[7]->ReportCount = 1
|
||||
pp_data->cap[7]->BytePosition = 0x0007
|
||||
pp_data->cap[7]->BitCount = 8
|
||||
pp_data->cap[7]->BitField = 0x02
|
||||
pp_data->cap[7]->NextBytePosition = 0x0008
|
||||
pp_data->cap[7]->LinkCollection = 0x0001
|
||||
pp_data->cap[7]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[7]->LinkUsage = 0x0000
|
||||
pp_data->cap[7]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[7]->IsButtonCap = 0
|
||||
pp_data->cap[7]->IsPadding = 0
|
||||
pp_data->cap[7]->IsAbsolute = 1
|
||||
pp_data->cap[7]->IsRange = 0
|
||||
pp_data->cap[7]->IsAlias = 0
|
||||
pp_data->cap[7]->IsStringRange = 0
|
||||
pp_data->cap[7]->IsDesignatorRange = 0
|
||||
pp_data->cap[7]->Reserved1 = 0x000000
|
||||
pp_data->cap[7]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[7]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[7]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[7]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[7]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[7]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[7]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[7]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[7]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[7]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[7]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[7]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[7]->NotRange.Usage = 0x0001
|
||||
pp_data->cap[7]->NotRange.Reserved1 = 0x0001
|
||||
pp_data->cap[7]->NotRange.StringIndex = 0
|
||||
pp_data->cap[7]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[7]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[7]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[7]->NotRange.DataIndex = 13
|
||||
pp_data->cap[7]->NotRange.Reserved4 = 13
|
||||
pp_data->cap[7]->NotButton.HasNull = 0
|
||||
pp_data->cap[7]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[7]->NotButton.LogicalMin = 0
|
||||
pp_data->cap[7]->NotButton.LogicalMax = 255
|
||||
pp_data->cap[7]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[7]->NotButton.PhysicalMax = 255
|
||||
pp_data->cap[7]->Units = 0
|
||||
pp_data->cap[7]->UnitsExp = 0
|
||||
|
||||
# Output hid_pp_cap struct:
|
||||
pp_data->cap[8]->UsagePage = 0xFF00
|
||||
pp_data->cap[8]->ReportID = 0x00
|
||||
pp_data->cap[8]->BitPosition = 0
|
||||
pp_data->cap[8]->BitSize = 8
|
||||
pp_data->cap[8]->ReportCount = 8
|
||||
pp_data->cap[8]->BytePosition = 0x0001
|
||||
pp_data->cap[8]->BitCount = 64
|
||||
pp_data->cap[8]->BitField = 0x02
|
||||
pp_data->cap[8]->NextBytePosition = 0x0009
|
||||
pp_data->cap[8]->LinkCollection = 0x0003
|
||||
pp_data->cap[8]->LinkUsagePage = 0xFF00
|
||||
pp_data->cap[8]->LinkUsage = 0x0000
|
||||
pp_data->cap[8]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[8]->IsButtonCap = 0
|
||||
pp_data->cap[8]->IsPadding = 0
|
||||
pp_data->cap[8]->IsAbsolute = 1
|
||||
pp_data->cap[8]->IsRange = 0
|
||||
pp_data->cap[8]->IsAlias = 0
|
||||
pp_data->cap[8]->IsStringRange = 0
|
||||
pp_data->cap[8]->IsDesignatorRange = 0
|
||||
pp_data->cap[8]->Reserved1 = 0x000000
|
||||
pp_data->cap[8]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[8]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[8]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[8]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[8]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[8]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[8]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[8]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[8]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[8]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[8]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[8]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[8]->NotRange.Usage = 0x0002
|
||||
pp_data->cap[8]->NotRange.Reserved1 = 0x0002
|
||||
pp_data->cap[8]->NotRange.StringIndex = 0
|
||||
pp_data->cap[8]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[8]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[8]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[8]->NotRange.DataIndex = 0
|
||||
pp_data->cap[8]->NotRange.Reserved4 = 0
|
||||
pp_data->cap[8]->NotButton.HasNull = 0
|
||||
pp_data->cap[8]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[8]->NotButton.LogicalMin = 0
|
||||
pp_data->cap[8]->NotButton.LogicalMax = 255
|
||||
pp_data->cap[8]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[8]->NotButton.PhysicalMax = 255
|
||||
pp_data->cap[8]->Units = 0
|
||||
pp_data->cap[8]->UnitsExp = 0
|
||||
|
||||
# Feature hid_pp_cap struct:
|
||||
# Link Collections:
|
||||
pp_data->LinkCollectionArray[0]->LinkUsage = 0x0004
|
||||
pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x0001
|
||||
pp_data->LinkCollectionArray[0]->Parent = 0
|
||||
pp_data->LinkCollectionArray[0]->NumberOfChildren = 2
|
||||
pp_data->LinkCollectionArray[0]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[0]->FirstChild = 3
|
||||
pp_data->LinkCollectionArray[0]->CollectionType = 1
|
||||
pp_data->LinkCollectionArray[0]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
|
||||
pp_data->LinkCollectionArray[1]->LinkUsage = 0x0000
|
||||
pp_data->LinkCollectionArray[1]->LinkUsagePage = 0x0001
|
||||
pp_data->LinkCollectionArray[1]->Parent = 0
|
||||
pp_data->LinkCollectionArray[1]->NumberOfChildren = 1
|
||||
pp_data->LinkCollectionArray[1]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[1]->FirstChild = 2
|
||||
pp_data->LinkCollectionArray[1]->CollectionType = 2
|
||||
pp_data->LinkCollectionArray[1]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[1]->Reserved = 0x00000000
|
||||
pp_data->LinkCollectionArray[2]->LinkUsage = 0x0001
|
||||
pp_data->LinkCollectionArray[2]->LinkUsagePage = 0x0001
|
||||
pp_data->LinkCollectionArray[2]->Parent = 1
|
||||
pp_data->LinkCollectionArray[2]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[2]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[2]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[2]->CollectionType = 0
|
||||
pp_data->LinkCollectionArray[2]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[2]->Reserved = 0x00000000
|
||||
pp_data->LinkCollectionArray[3]->LinkUsage = 0x0000
|
||||
pp_data->LinkCollectionArray[3]->LinkUsagePage = 0xFF00
|
||||
pp_data->LinkCollectionArray[3]->Parent = 0
|
||||
pp_data->LinkCollectionArray[3]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[3]->NextSibling = 1
|
||||
pp_data->LinkCollectionArray[3]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[3]->CollectionType = 2
|
||||
pp_data->LinkCollectionArray[3]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[3]->Reserved = 0x00000000
|
||||
@@ -0,0 +1,18 @@
|
||||
0x05, 0x01, 0x09, 0x04, 0xA1, 0x01, 0x09, 0x00, 0xA1, 0x02,
|
||||
0x09, 0x01, 0xA1, 0x00, 0x09, 0x30, 0x09, 0x31, 0x15, 0x00,
|
||||
0x26, 0xFF, 0x00, 0x35, 0x00, 0x46, 0xFF, 0x00, 0x75, 0x08,
|
||||
0x95, 0x02, 0x81, 0x02, 0x06, 0x00, 0xFF, 0x09, 0x01, 0x15,
|
||||
0x00, 0x25, 0x0F, 0x75, 0x04, 0x95, 0x01, 0x81, 0x02, 0x05,
|
||||
0x01, 0x09, 0x39, 0x15, 0x00, 0x25, 0x07, 0x35, 0x00, 0x46,
|
||||
0x3B, 0x01, 0x65, 0x14, 0x75, 0x04, 0x95, 0x01, 0x81, 0x42,
|
||||
0x09, 0x35, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x35, 0x00, 0x46,
|
||||
0xFF, 0x00, 0x75, 0x08, 0x95, 0x01, 0x81, 0x02, 0xC0, 0x05,
|
||||
0x09, 0x19, 0x01, 0x29, 0x07, 0x15, 0x00, 0x25, 0x01, 0x75,
|
||||
0x01, 0x95, 0x07, 0x45, 0x00, 0x65, 0x00, 0x81, 0x02, 0x75,
|
||||
0x01, 0x95, 0x01, 0x81, 0x03, 0x05, 0x01, 0x09, 0x36, 0x15,
|
||||
0x00, 0x26, 0xFF, 0x00, 0x35, 0x00, 0x46, 0xFF, 0x00, 0x75,
|
||||
0x08, 0x95, 0x01, 0x81, 0x02, 0x06, 0x00, 0xFF, 0x09, 0x01,
|
||||
0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x01, 0x81,
|
||||
0x02, 0xC0, 0x09, 0x00, 0xA1, 0x02, 0x09, 0x02, 0x15, 0x00,
|
||||
0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x08, 0x91, 0x02, 0xC0,
|
||||
0xC0,
|
||||
@@ -0,0 +1,18 @@
|
||||
0x05, 0x01, 0x09, 0x04, 0xA1, 0x01, 0x09, 0x00, 0xA1, 0x02,
|
||||
0x09, 0x01, 0xA1, 0x00, 0x09, 0x30, 0x09, 0x31, 0x15, 0x00,
|
||||
0x26, 0xFF, 0x00, 0x35, 0x00, 0x46, 0xFF, 0x00, 0x75, 0x08,
|
||||
0x95, 0x02, 0x81, 0x02, 0x06, 0x00, 0xFF, 0x09, 0x01, 0x15,
|
||||
0x00, 0x25, 0x0F, 0x75, 0x04, 0x95, 0x01, 0x81, 0x02, 0x05,
|
||||
0x01, 0x09, 0x39, 0x15, 0x00, 0x25, 0x07, 0x35, 0x00, 0x46,
|
||||
0x3B, 0x01, 0x65, 0x14, 0x75, 0x04, 0x95, 0x01, 0x81, 0x42,
|
||||
0x09, 0x35, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x35, 0x00, 0x46,
|
||||
0xFF, 0x00, 0x75, 0x08, 0x95, 0x01, 0x81, 0x02, 0xC0, 0x05,
|
||||
0x09, 0x19, 0x01, 0x29, 0x07, 0x15, 0x00, 0x25, 0x01, 0x75,
|
||||
0x01, 0x95, 0x07, 0x45, 0x00, 0x65, 0x00, 0x81, 0x02, 0x75,
|
||||
0x01, 0x95, 0x01, 0x81, 0x03, 0x05, 0x01, 0x09, 0x36, 0x15,
|
||||
0x00, 0x26, 0xFF, 0x00, 0x35, 0x00, 0x46, 0xFF, 0x00, 0x75,
|
||||
0x08, 0x95, 0x01, 0x81, 0x02, 0x06, 0x00, 0xFF, 0x09, 0x01,
|
||||
0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x01, 0x81,
|
||||
0x02, 0xC0, 0x09, 0x00, 0xA1, 0x02, 0x09, 0x02, 0x15, 0x00,
|
||||
0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x08, 0x91, 0x02, 0xC0,
|
||||
0xC0,
|
||||
@@ -0,0 +1,93 @@
|
||||
# HIDAPI device info struct:
|
||||
dev->vendor_id = 0x046D
|
||||
dev->product_id = 0xC52F
|
||||
dev->manufacturer_string = "Logitech"
|
||||
dev->product_string = "USB Receiver"
|
||||
dev->release_number = 0x2200
|
||||
dev->interface_number = 1
|
||||
dev->usage = 0x0001
|
||||
dev->usage_page = 0x000C
|
||||
dev->path = "\\?\hid#vid_046d&pid_c52f&mi_01&col01#8&28ca146b&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
|
||||
|
||||
# Preparsed Data struct:
|
||||
pp_data->MagicKey = 0x48696450204B4452
|
||||
pp_data->Usage = 0x0001
|
||||
pp_data->UsagePage = 0x000C
|
||||
pp_data->Reserved = 0x00000000
|
||||
# Input caps_info struct:
|
||||
pp_data->caps_info[0]->FirstCap = 0
|
||||
pp_data->caps_info[0]->LastCap = 1
|
||||
pp_data->caps_info[0]->NumberOfCaps = 1
|
||||
pp_data->caps_info[0]->ReportByteLength = 5
|
||||
# Output caps_info struct:
|
||||
pp_data->caps_info[1]->FirstCap = 1
|
||||
pp_data->caps_info[1]->LastCap = 1
|
||||
pp_data->caps_info[1]->NumberOfCaps = 0
|
||||
pp_data->caps_info[1]->ReportByteLength = 0
|
||||
# Feature caps_info struct:
|
||||
pp_data->caps_info[2]->FirstCap = 1
|
||||
pp_data->caps_info[2]->LastCap = 1
|
||||
pp_data->caps_info[2]->NumberOfCaps = 0
|
||||
pp_data->caps_info[2]->ReportByteLength = 0
|
||||
# LinkCollectionArray Offset & Size:
|
||||
pp_data->FirstByteOfLinkCollectionArray = 0x0068
|
||||
pp_data->NumberLinkCollectionNodes = 1
|
||||
# Input hid_pp_cap struct:
|
||||
pp_data->cap[0]->UsagePage = 0x000C
|
||||
pp_data->cap[0]->ReportID = 0x03
|
||||
pp_data->cap[0]->BitPosition = 0
|
||||
pp_data->cap[0]->BitSize = 16
|
||||
pp_data->cap[0]->ReportCount = 2
|
||||
pp_data->cap[0]->BytePosition = 0x0001
|
||||
pp_data->cap[0]->BitCount = 32
|
||||
pp_data->cap[0]->BitField = 0x00
|
||||
pp_data->cap[0]->NextBytePosition = 0x0005
|
||||
pp_data->cap[0]->LinkCollection = 0x0000
|
||||
pp_data->cap[0]->LinkUsagePage = 0x000C
|
||||
pp_data->cap[0]->LinkUsage = 0x0001
|
||||
pp_data->cap[0]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[0]->IsButtonCap = 1
|
||||
pp_data->cap[0]->IsPadding = 0
|
||||
pp_data->cap[0]->IsAbsolute = 1
|
||||
pp_data->cap[0]->IsRange = 1
|
||||
pp_data->cap[0]->IsAlias = 0
|
||||
pp_data->cap[0]->IsStringRange = 0
|
||||
pp_data->cap[0]->IsDesignatorRange = 0
|
||||
pp_data->cap[0]->Reserved1 = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[0]->Range.UsageMin = 0x0001
|
||||
pp_data->cap[0]->Range.UsageMax = 0x028C
|
||||
pp_data->cap[0]->Range.StringMin = 0
|
||||
pp_data->cap[0]->Range.StringMax = 0
|
||||
pp_data->cap[0]->Range.DesignatorMin = 0
|
||||
pp_data->cap[0]->Range.DesignatorMax = 0
|
||||
pp_data->cap[0]->Range.DataIndexMin = 0
|
||||
pp_data->cap[0]->Range.DataIndexMax = 651
|
||||
pp_data->cap[0]->Button.LogicalMin = 1
|
||||
pp_data->cap[0]->Button.LogicalMax = 652
|
||||
pp_data->cap[0]->Units = 0
|
||||
pp_data->cap[0]->UnitsExp = 0
|
||||
|
||||
# Output hid_pp_cap struct:
|
||||
# Feature hid_pp_cap struct:
|
||||
# Link Collections:
|
||||
pp_data->LinkCollectionArray[0]->LinkUsage = 0x0001
|
||||
pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x000C
|
||||
pp_data->LinkCollectionArray[0]->Parent = 0
|
||||
pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[0]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[0]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[0]->CollectionType = 1
|
||||
pp_data->LinkCollectionArray[0]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
|
||||
@@ -0,0 +1,3 @@
|
||||
0x05, 0x0C, 0x09, 0x01, 0xA1, 0x01, 0x85, 0x03, 0x19, 0x01,
|
||||
0x2A, 0x8C, 0x02, 0x15, 0x01, 0x26, 0x8C, 0x02, 0x75, 0x10,
|
||||
0x95, 0x02, 0x81, 0x00, 0xC0,
|
||||
@@ -0,0 +1,12 @@
|
||||
Usage Page (Consumer Devices) 05 0C
|
||||
Usage (Consumer Control) 09 01
|
||||
Collection (Application) A1 01
|
||||
Report ID (3) 85 03
|
||||
Report Size (16) 75 10
|
||||
Report Count (2) 95 02
|
||||
Logical Minimum (1) 15 01
|
||||
Logical Maximum (652) 26 8C 02
|
||||
Usage Minimum (Consumer Control) 19 01
|
||||
Usage Maximum (AC Send) 2A 8C 02
|
||||
Input (Data,Ary,Abs) 81 00
|
||||
End Collection C0
|
||||
@@ -0,0 +1,139 @@
|
||||
# HIDAPI device info struct:
|
||||
dev->vendor_id = 0x046D
|
||||
dev->product_id = 0xC52F
|
||||
dev->manufacturer_string = "Logitech"
|
||||
dev->product_string = "USB Receiver"
|
||||
dev->release_number = 0x2200
|
||||
dev->interface_number = 1
|
||||
dev->usage = 0x0001
|
||||
dev->usage_page = 0xFF00
|
||||
dev->path = "\\?\hid#vid_046d&pid_c52f&mi_01&col02#8&28ca146b&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}"
|
||||
|
||||
# Preparsed Data struct:
|
||||
pp_data->MagicKey = 0x48696450204B4452
|
||||
pp_data->Usage = 0x0001
|
||||
pp_data->UsagePage = 0xFF00
|
||||
pp_data->Reserved = 0x00000000
|
||||
# Input caps_info struct:
|
||||
pp_data->caps_info[0]->FirstCap = 0
|
||||
pp_data->caps_info[0]->LastCap = 1
|
||||
pp_data->caps_info[0]->NumberOfCaps = 1
|
||||
pp_data->caps_info[0]->ReportByteLength = 7
|
||||
# Output caps_info struct:
|
||||
pp_data->caps_info[1]->FirstCap = 1
|
||||
pp_data->caps_info[1]->LastCap = 2
|
||||
pp_data->caps_info[1]->NumberOfCaps = 1
|
||||
pp_data->caps_info[1]->ReportByteLength = 7
|
||||
# Feature caps_info struct:
|
||||
pp_data->caps_info[2]->FirstCap = 2
|
||||
pp_data->caps_info[2]->LastCap = 2
|
||||
pp_data->caps_info[2]->NumberOfCaps = 0
|
||||
pp_data->caps_info[2]->ReportByteLength = 0
|
||||
# LinkCollectionArray Offset & Size:
|
||||
pp_data->FirstByteOfLinkCollectionArray = 0x00D0
|
||||
pp_data->NumberLinkCollectionNodes = 1
|
||||
# Input hid_pp_cap struct:
|
||||
pp_data->cap[0]->UsagePage = 0xFF00
|
||||
pp_data->cap[0]->ReportID = 0x10
|
||||
pp_data->cap[0]->BitPosition = 0
|
||||
pp_data->cap[0]->BitSize = 8
|
||||
pp_data->cap[0]->ReportCount = 6
|
||||
pp_data->cap[0]->BytePosition = 0x0001
|
||||
pp_data->cap[0]->BitCount = 48
|
||||
pp_data->cap[0]->BitField = 0x00
|
||||
pp_data->cap[0]->NextBytePosition = 0x0007
|
||||
pp_data->cap[0]->LinkCollection = 0x0000
|
||||
pp_data->cap[0]->LinkUsagePage = 0xFF00
|
||||
pp_data->cap[0]->LinkUsage = 0x0001
|
||||
pp_data->cap[0]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[0]->IsButtonCap = 1
|
||||
pp_data->cap[0]->IsPadding = 0
|
||||
pp_data->cap[0]->IsAbsolute = 1
|
||||
pp_data->cap[0]->IsRange = 0
|
||||
pp_data->cap[0]->IsAlias = 0
|
||||
pp_data->cap[0]->IsStringRange = 0
|
||||
pp_data->cap[0]->IsDesignatorRange = 0
|
||||
pp_data->cap[0]->Reserved1 = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[0]->NotRange.Usage = 0x0001
|
||||
pp_data->cap[0]->NotRange.Reserved1 = 0x0001
|
||||
pp_data->cap[0]->NotRange.StringIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[0]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[0]->NotRange.DataIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved4 = 0
|
||||
pp_data->cap[0]->Button.LogicalMin = 0
|
||||
pp_data->cap[0]->Button.LogicalMax = 255
|
||||
pp_data->cap[0]->Units = 0
|
||||
pp_data->cap[0]->UnitsExp = 0
|
||||
|
||||
# Output hid_pp_cap struct:
|
||||
pp_data->cap[1]->UsagePage = 0xFF00
|
||||
pp_data->cap[1]->ReportID = 0x10
|
||||
pp_data->cap[1]->BitPosition = 0
|
||||
pp_data->cap[1]->BitSize = 8
|
||||
pp_data->cap[1]->ReportCount = 6
|
||||
pp_data->cap[1]->BytePosition = 0x0001
|
||||
pp_data->cap[1]->BitCount = 48
|
||||
pp_data->cap[1]->BitField = 0x00
|
||||
pp_data->cap[1]->NextBytePosition = 0x0007
|
||||
pp_data->cap[1]->LinkCollection = 0x0000
|
||||
pp_data->cap[1]->LinkUsagePage = 0xFF00
|
||||
pp_data->cap[1]->LinkUsage = 0x0001
|
||||
pp_data->cap[1]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[1]->IsButtonCap = 1
|
||||
pp_data->cap[1]->IsPadding = 0
|
||||
pp_data->cap[1]->IsAbsolute = 1
|
||||
pp_data->cap[1]->IsRange = 0
|
||||
pp_data->cap[1]->IsAlias = 0
|
||||
pp_data->cap[1]->IsStringRange = 0
|
||||
pp_data->cap[1]->IsDesignatorRange = 0
|
||||
pp_data->cap[1]->Reserved1 = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[1]->NotRange.Usage = 0x0001
|
||||
pp_data->cap[1]->NotRange.Reserved1 = 0x0001
|
||||
pp_data->cap[1]->NotRange.StringIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[1]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[1]->NotRange.DataIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved4 = 0
|
||||
pp_data->cap[1]->Button.LogicalMin = 0
|
||||
pp_data->cap[1]->Button.LogicalMax = 255
|
||||
pp_data->cap[1]->Units = 0
|
||||
pp_data->cap[1]->UnitsExp = 0
|
||||
|
||||
# Feature hid_pp_cap struct:
|
||||
# Link Collections:
|
||||
pp_data->LinkCollectionArray[0]->LinkUsage = 0x0001
|
||||
pp_data->LinkCollectionArray[0]->LinkUsagePage = 0xFF00
|
||||
pp_data->LinkCollectionArray[0]->Parent = 0
|
||||
pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[0]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[0]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[0]->CollectionType = 1
|
||||
pp_data->LinkCollectionArray[0]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
|
||||
@@ -0,0 +1,4 @@
|
||||
0x06, 0x00, 0xFF, 0x09, 0x01, 0xA1, 0x01, 0x85, 0x10, 0x09,
|
||||
0x01, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x06,
|
||||
0x81, 0x00, 0x09, 0x01, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
|
||||
0x08, 0x95, 0x06, 0x91, 0x00, 0xC0,
|
||||
@@ -0,0 +1,13 @@
|
||||
Usage Page (Vendor-Defined 1) 06 00 FF
|
||||
Usage (Vendor-Defined 1) 09 01
|
||||
Collection (Application) A1 01
|
||||
Report ID (16) 85 10
|
||||
Report Size (8) 75 08
|
||||
Report Count (6) 95 06
|
||||
Logical Minimum (0) 15 00
|
||||
Logical Maximum (255) 26 FF 00
|
||||
Usage (Vendor-Defined 1) 09 01
|
||||
Input (Data,Ary,Abs) 81 00
|
||||
Usage (Vendor-Defined 1) 09 01
|
||||
Output (Data,Ary,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) 91 00
|
||||
End Collection C0
|
||||
@@ -0,0 +1,302 @@
|
||||
# HIDAPI device info struct:
|
||||
dev->vendor_id = 0x046D
|
||||
dev->product_id = 0xC52F
|
||||
dev->manufacturer_string = "Logitech"
|
||||
dev->product_string = "USB Receiver"
|
||||
dev->release_number = 0x2200
|
||||
dev->interface_number = 0
|
||||
dev->usage = 0x0002
|
||||
dev->usage_page = 0x0001
|
||||
dev->path = "\\?\hid#vid_046d&pid_c52f&mi_00#8&1599f82d&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
|
||||
|
||||
# Preparsed Data struct:
|
||||
pp_data->MagicKey = 0x48696450204B4452
|
||||
pp_data->Usage = 0x0002
|
||||
pp_data->UsagePage = 0x0001
|
||||
pp_data->Reserved = 0x00000000
|
||||
# Input caps_info struct:
|
||||
pp_data->caps_info[0]->FirstCap = 0
|
||||
pp_data->caps_info[0]->LastCap = 5
|
||||
pp_data->caps_info[0]->NumberOfCaps = 5
|
||||
pp_data->caps_info[0]->ReportByteLength = 9
|
||||
# Output caps_info struct:
|
||||
pp_data->caps_info[1]->FirstCap = 5
|
||||
pp_data->caps_info[1]->LastCap = 5
|
||||
pp_data->caps_info[1]->NumberOfCaps = 0
|
||||
pp_data->caps_info[1]->ReportByteLength = 0
|
||||
# Feature caps_info struct:
|
||||
pp_data->caps_info[2]->FirstCap = 5
|
||||
pp_data->caps_info[2]->LastCap = 5
|
||||
pp_data->caps_info[2]->NumberOfCaps = 0
|
||||
pp_data->caps_info[2]->ReportByteLength = 0
|
||||
# LinkCollectionArray Offset & Size:
|
||||
pp_data->FirstByteOfLinkCollectionArray = 0x0208
|
||||
pp_data->NumberLinkCollectionNodes = 2
|
||||
# Input hid_pp_cap struct:
|
||||
pp_data->cap[0]->UsagePage = 0x0009
|
||||
pp_data->cap[0]->ReportID = 0x00
|
||||
pp_data->cap[0]->BitPosition = 0
|
||||
pp_data->cap[0]->BitSize = 1
|
||||
pp_data->cap[0]->ReportCount = 16
|
||||
pp_data->cap[0]->BytePosition = 0x0001
|
||||
pp_data->cap[0]->BitCount = 16
|
||||
pp_data->cap[0]->BitField = 0x02
|
||||
pp_data->cap[0]->NextBytePosition = 0x0003
|
||||
pp_data->cap[0]->LinkCollection = 0x0001
|
||||
pp_data->cap[0]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[0]->LinkUsage = 0x0001
|
||||
pp_data->cap[0]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[0]->IsButtonCap = 1
|
||||
pp_data->cap[0]->IsPadding = 0
|
||||
pp_data->cap[0]->IsAbsolute = 1
|
||||
pp_data->cap[0]->IsRange = 1
|
||||
pp_data->cap[0]->IsAlias = 0
|
||||
pp_data->cap[0]->IsStringRange = 0
|
||||
pp_data->cap[0]->IsDesignatorRange = 0
|
||||
pp_data->cap[0]->Reserved1 = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[0]->Range.UsageMin = 0x0001
|
||||
pp_data->cap[0]->Range.UsageMax = 0x0010
|
||||
pp_data->cap[0]->Range.StringMin = 0
|
||||
pp_data->cap[0]->Range.StringMax = 0
|
||||
pp_data->cap[0]->Range.DesignatorMin = 0
|
||||
pp_data->cap[0]->Range.DesignatorMax = 0
|
||||
pp_data->cap[0]->Range.DataIndexMin = 0
|
||||
pp_data->cap[0]->Range.DataIndexMax = 15
|
||||
pp_data->cap[0]->Button.LogicalMin = 0
|
||||
pp_data->cap[0]->Button.LogicalMax = 0
|
||||
pp_data->cap[0]->Units = 0
|
||||
pp_data->cap[0]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[1]->UsagePage = 0x0001
|
||||
pp_data->cap[1]->ReportID = 0x00
|
||||
pp_data->cap[1]->BitPosition = 0
|
||||
pp_data->cap[1]->BitSize = 16
|
||||
pp_data->cap[1]->ReportCount = 1
|
||||
pp_data->cap[1]->BytePosition = 0x0005
|
||||
pp_data->cap[1]->BitCount = 16
|
||||
pp_data->cap[1]->BitField = 0x06
|
||||
pp_data->cap[1]->NextBytePosition = 0x0007
|
||||
pp_data->cap[1]->LinkCollection = 0x0001
|
||||
pp_data->cap[1]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[1]->LinkUsage = 0x0001
|
||||
pp_data->cap[1]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[1]->IsButtonCap = 0
|
||||
pp_data->cap[1]->IsPadding = 0
|
||||
pp_data->cap[1]->IsAbsolute = 0
|
||||
pp_data->cap[1]->IsRange = 0
|
||||
pp_data->cap[1]->IsAlias = 0
|
||||
pp_data->cap[1]->IsStringRange = 0
|
||||
pp_data->cap[1]->IsDesignatorRange = 0
|
||||
pp_data->cap[1]->Reserved1 = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[1]->NotRange.Usage = 0x0031
|
||||
pp_data->cap[1]->NotRange.Reserved1 = 0x0031
|
||||
pp_data->cap[1]->NotRange.StringIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[1]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[1]->NotRange.DataIndex = 16
|
||||
pp_data->cap[1]->NotRange.Reserved4 = 16
|
||||
pp_data->cap[1]->NotButton.HasNull = 0
|
||||
pp_data->cap[1]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[1]->NotButton.LogicalMin = -32767
|
||||
pp_data->cap[1]->NotButton.LogicalMax = 32767
|
||||
pp_data->cap[1]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[1]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[1]->Units = 0
|
||||
pp_data->cap[1]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[2]->UsagePage = 0x0001
|
||||
pp_data->cap[2]->ReportID = 0x00
|
||||
pp_data->cap[2]->BitPosition = 0
|
||||
pp_data->cap[2]->BitSize = 16
|
||||
pp_data->cap[2]->ReportCount = 1
|
||||
pp_data->cap[2]->BytePosition = 0x0003
|
||||
pp_data->cap[2]->BitCount = 16
|
||||
pp_data->cap[2]->BitField = 0x06
|
||||
pp_data->cap[2]->NextBytePosition = 0x0005
|
||||
pp_data->cap[2]->LinkCollection = 0x0001
|
||||
pp_data->cap[2]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[2]->LinkUsage = 0x0001
|
||||
pp_data->cap[2]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[2]->IsButtonCap = 0
|
||||
pp_data->cap[2]->IsPadding = 0
|
||||
pp_data->cap[2]->IsAbsolute = 0
|
||||
pp_data->cap[2]->IsRange = 0
|
||||
pp_data->cap[2]->IsAlias = 0
|
||||
pp_data->cap[2]->IsStringRange = 0
|
||||
pp_data->cap[2]->IsDesignatorRange = 0
|
||||
pp_data->cap[2]->Reserved1 = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[2]->NotRange.Usage = 0x0030
|
||||
pp_data->cap[2]->NotRange.Reserved1 = 0x0030
|
||||
pp_data->cap[2]->NotRange.StringIndex = 0
|
||||
pp_data->cap[2]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[2]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[2]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[2]->NotRange.DataIndex = 17
|
||||
pp_data->cap[2]->NotRange.Reserved4 = 17
|
||||
pp_data->cap[2]->NotButton.HasNull = 0
|
||||
pp_data->cap[2]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[2]->NotButton.LogicalMin = -32767
|
||||
pp_data->cap[2]->NotButton.LogicalMax = 32767
|
||||
pp_data->cap[2]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[2]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[2]->Units = 0
|
||||
pp_data->cap[2]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[3]->UsagePage = 0x0001
|
||||
pp_data->cap[3]->ReportID = 0x00
|
||||
pp_data->cap[3]->BitPosition = 0
|
||||
pp_data->cap[3]->BitSize = 8
|
||||
pp_data->cap[3]->ReportCount = 1
|
||||
pp_data->cap[3]->BytePosition = 0x0007
|
||||
pp_data->cap[3]->BitCount = 8
|
||||
pp_data->cap[3]->BitField = 0x06
|
||||
pp_data->cap[3]->NextBytePosition = 0x0008
|
||||
pp_data->cap[3]->LinkCollection = 0x0001
|
||||
pp_data->cap[3]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[3]->LinkUsage = 0x0001
|
||||
pp_data->cap[3]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[3]->IsButtonCap = 0
|
||||
pp_data->cap[3]->IsPadding = 0
|
||||
pp_data->cap[3]->IsAbsolute = 0
|
||||
pp_data->cap[3]->IsRange = 0
|
||||
pp_data->cap[3]->IsAlias = 0
|
||||
pp_data->cap[3]->IsStringRange = 0
|
||||
pp_data->cap[3]->IsDesignatorRange = 0
|
||||
pp_data->cap[3]->Reserved1 = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[3]->NotRange.Usage = 0x0038
|
||||
pp_data->cap[3]->NotRange.Reserved1 = 0x0038
|
||||
pp_data->cap[3]->NotRange.StringIndex = 0
|
||||
pp_data->cap[3]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[3]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[3]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[3]->NotRange.DataIndex = 18
|
||||
pp_data->cap[3]->NotRange.Reserved4 = 18
|
||||
pp_data->cap[3]->NotButton.HasNull = 0
|
||||
pp_data->cap[3]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[3]->NotButton.LogicalMin = -127
|
||||
pp_data->cap[3]->NotButton.LogicalMax = 127
|
||||
pp_data->cap[3]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[3]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[3]->Units = 0
|
||||
pp_data->cap[3]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[4]->UsagePage = 0x000C
|
||||
pp_data->cap[4]->ReportID = 0x00
|
||||
pp_data->cap[4]->BitPosition = 0
|
||||
pp_data->cap[4]->BitSize = 8
|
||||
pp_data->cap[4]->ReportCount = 1
|
||||
pp_data->cap[4]->BytePosition = 0x0008
|
||||
pp_data->cap[4]->BitCount = 8
|
||||
pp_data->cap[4]->BitField = 0x06
|
||||
pp_data->cap[4]->NextBytePosition = 0x0009
|
||||
pp_data->cap[4]->LinkCollection = 0x0001
|
||||
pp_data->cap[4]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[4]->LinkUsage = 0x0001
|
||||
pp_data->cap[4]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[4]->IsButtonCap = 0
|
||||
pp_data->cap[4]->IsPadding = 0
|
||||
pp_data->cap[4]->IsAbsolute = 0
|
||||
pp_data->cap[4]->IsRange = 0
|
||||
pp_data->cap[4]->IsAlias = 0
|
||||
pp_data->cap[4]->IsStringRange = 0
|
||||
pp_data->cap[4]->IsDesignatorRange = 0
|
||||
pp_data->cap[4]->Reserved1 = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[4]->NotRange.Usage = 0x0238
|
||||
pp_data->cap[4]->NotRange.Reserved1 = 0x0238
|
||||
pp_data->cap[4]->NotRange.StringIndex = 0
|
||||
pp_data->cap[4]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[4]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[4]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[4]->NotRange.DataIndex = 19
|
||||
pp_data->cap[4]->NotRange.Reserved4 = 19
|
||||
pp_data->cap[4]->NotButton.HasNull = 0
|
||||
pp_data->cap[4]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[4]->NotButton.LogicalMin = -127
|
||||
pp_data->cap[4]->NotButton.LogicalMax = 127
|
||||
pp_data->cap[4]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[4]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[4]->Units = 0
|
||||
pp_data->cap[4]->UnitsExp = 0
|
||||
|
||||
# Output hid_pp_cap struct:
|
||||
# Feature hid_pp_cap struct:
|
||||
# Link Collections:
|
||||
pp_data->LinkCollectionArray[0]->LinkUsage = 0x0002
|
||||
pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x0001
|
||||
pp_data->LinkCollectionArray[0]->Parent = 0
|
||||
pp_data->LinkCollectionArray[0]->NumberOfChildren = 1
|
||||
pp_data->LinkCollectionArray[0]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[0]->FirstChild = 1
|
||||
pp_data->LinkCollectionArray[0]->CollectionType = 1
|
||||
pp_data->LinkCollectionArray[0]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
|
||||
pp_data->LinkCollectionArray[1]->LinkUsage = 0x0001
|
||||
pp_data->LinkCollectionArray[1]->LinkUsagePage = 0x0001
|
||||
pp_data->LinkCollectionArray[1]->Parent = 0
|
||||
pp_data->LinkCollectionArray[1]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[1]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[1]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[1]->CollectionType = 0
|
||||
pp_data->LinkCollectionArray[1]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[1]->Reserved = 0x00000000
|
||||
@@ -0,0 +1,8 @@
|
||||
0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01, 0xA1, 0x00,
|
||||
0x05, 0x09, 0x19, 0x01, 0x29, 0x10, 0x15, 0x00, 0x25, 0x01,
|
||||
0x75, 0x01, 0x95, 0x10, 0x81, 0x02, 0x05, 0x01, 0x09, 0x30,
|
||||
0x09, 0x31, 0x16, 0x01, 0x80, 0x26, 0xFF, 0x7F, 0x75, 0x10,
|
||||
0x95, 0x02, 0x81, 0x06, 0x09, 0x38, 0x15, 0x81, 0x25, 0x7F,
|
||||
0x75, 0x08, 0x95, 0x01, 0x81, 0x06, 0x05, 0x0C, 0x0A, 0x38,
|
||||
0x02, 0x15, 0x81, 0x25, 0x7F, 0x75, 0x08, 0x95, 0x01, 0x81,
|
||||
0x06, 0xC0, 0xC0,
|
||||
@@ -0,0 +1,33 @@
|
||||
Usage Page (Generic Desktop) 05 01
|
||||
Usage (Mouse) 09 02
|
||||
Collection (Application) A1 01
|
||||
Usage (Pointer) 09 01
|
||||
Collection (Physical) A1 00
|
||||
Usage Page (Button) 05 09
|
||||
Usage Minimum (Button 1) 19 01
|
||||
Usage Maximum (Button 16) 29 10
|
||||
Logical Minimum (0) 15 00
|
||||
Logical Maximum (1) 25 01
|
||||
Report Count (16) 95 10
|
||||
Report Size (1) 75 01
|
||||
Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
|
||||
Usage Page (Generic Desktop) 05 01
|
||||
Logical Minimum (-32767) 16 01 80
|
||||
Logical Maximum (32767) 26 FF 7F
|
||||
Report Size (16) 75 10
|
||||
Report Count (2) 95 02
|
||||
Usage (X) 09 30
|
||||
Usage (Y) 09 31
|
||||
Input (Data,Var,Rel,NWrp,Lin,Pref,NNul,Bit) 81 06
|
||||
Logical Minimum (-127) 15 81
|
||||
Logical Maximum (127) 25 7F
|
||||
Report Size (8) 75 08
|
||||
Report Count (1) 95 01
|
||||
Usage (Wheel) 09 38
|
||||
Input (Data,Var,Rel,NWrp,Lin,Pref,NNul,Bit) 81 06
|
||||
Usage Page (Consumer Devices) 05 0C
|
||||
Usage (AC Pan) 0A 38 02
|
||||
Report Count (1) 95 01
|
||||
Input (Data,Var,Rel,NWrp,Lin,Pref,NNul,Bit) 81 06
|
||||
End Collection C0
|
||||
End Collection C0
|
||||
@@ -0,0 +1,139 @@
|
||||
# HIDAPI device info struct:
|
||||
dev->vendor_id = 0x046D
|
||||
dev->product_id = 0xC52F
|
||||
dev->manufacturer_string = "Logitech"
|
||||
dev->product_string = "USB Receiver"
|
||||
dev->release_number = 0x2200
|
||||
dev->interface_number = 1
|
||||
dev->usage = 0x0002
|
||||
dev->usage_page = 0xFF00
|
||||
dev->path = "\\?\hid#vid_046d&pid_c52f&mi_01&col03#8&28ca146b&0&0002#{4d1e55b2-f16f-11cf-88cb-001111000030}"
|
||||
|
||||
# Preparsed Data struct:
|
||||
pp_data->MagicKey = 0x48696450204B4452
|
||||
pp_data->Usage = 0x0002
|
||||
pp_data->UsagePage = 0xFF00
|
||||
pp_data->Reserved = 0x00000000
|
||||
# Input caps_info struct:
|
||||
pp_data->caps_info[0]->FirstCap = 0
|
||||
pp_data->caps_info[0]->LastCap = 1
|
||||
pp_data->caps_info[0]->NumberOfCaps = 1
|
||||
pp_data->caps_info[0]->ReportByteLength = 20
|
||||
# Output caps_info struct:
|
||||
pp_data->caps_info[1]->FirstCap = 1
|
||||
pp_data->caps_info[1]->LastCap = 2
|
||||
pp_data->caps_info[1]->NumberOfCaps = 1
|
||||
pp_data->caps_info[1]->ReportByteLength = 20
|
||||
# Feature caps_info struct:
|
||||
pp_data->caps_info[2]->FirstCap = 2
|
||||
pp_data->caps_info[2]->LastCap = 2
|
||||
pp_data->caps_info[2]->NumberOfCaps = 0
|
||||
pp_data->caps_info[2]->ReportByteLength = 0
|
||||
# LinkCollectionArray Offset & Size:
|
||||
pp_data->FirstByteOfLinkCollectionArray = 0x00D0
|
||||
pp_data->NumberLinkCollectionNodes = 1
|
||||
# Input hid_pp_cap struct:
|
||||
pp_data->cap[0]->UsagePage = 0xFF00
|
||||
pp_data->cap[0]->ReportID = 0x11
|
||||
pp_data->cap[0]->BitPosition = 0
|
||||
pp_data->cap[0]->BitSize = 8
|
||||
pp_data->cap[0]->ReportCount = 19
|
||||
pp_data->cap[0]->BytePosition = 0x0001
|
||||
pp_data->cap[0]->BitCount = 152
|
||||
pp_data->cap[0]->BitField = 0x00
|
||||
pp_data->cap[0]->NextBytePosition = 0x0014
|
||||
pp_data->cap[0]->LinkCollection = 0x0000
|
||||
pp_data->cap[0]->LinkUsagePage = 0xFF00
|
||||
pp_data->cap[0]->LinkUsage = 0x0002
|
||||
pp_data->cap[0]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[0]->IsButtonCap = 1
|
||||
pp_data->cap[0]->IsPadding = 0
|
||||
pp_data->cap[0]->IsAbsolute = 1
|
||||
pp_data->cap[0]->IsRange = 0
|
||||
pp_data->cap[0]->IsAlias = 0
|
||||
pp_data->cap[0]->IsStringRange = 0
|
||||
pp_data->cap[0]->IsDesignatorRange = 0
|
||||
pp_data->cap[0]->Reserved1 = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[0]->NotRange.Usage = 0x0002
|
||||
pp_data->cap[0]->NotRange.Reserved1 = 0x0002
|
||||
pp_data->cap[0]->NotRange.StringIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[0]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[0]->NotRange.DataIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved4 = 0
|
||||
pp_data->cap[0]->Button.LogicalMin = 0
|
||||
pp_data->cap[0]->Button.LogicalMax = 255
|
||||
pp_data->cap[0]->Units = 0
|
||||
pp_data->cap[0]->UnitsExp = 0
|
||||
|
||||
# Output hid_pp_cap struct:
|
||||
pp_data->cap[1]->UsagePage = 0xFF00
|
||||
pp_data->cap[1]->ReportID = 0x11
|
||||
pp_data->cap[1]->BitPosition = 0
|
||||
pp_data->cap[1]->BitSize = 8
|
||||
pp_data->cap[1]->ReportCount = 19
|
||||
pp_data->cap[1]->BytePosition = 0x0001
|
||||
pp_data->cap[1]->BitCount = 152
|
||||
pp_data->cap[1]->BitField = 0x00
|
||||
pp_data->cap[1]->NextBytePosition = 0x0014
|
||||
pp_data->cap[1]->LinkCollection = 0x0000
|
||||
pp_data->cap[1]->LinkUsagePage = 0xFF00
|
||||
pp_data->cap[1]->LinkUsage = 0x0002
|
||||
pp_data->cap[1]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[1]->IsButtonCap = 1
|
||||
pp_data->cap[1]->IsPadding = 0
|
||||
pp_data->cap[1]->IsAbsolute = 1
|
||||
pp_data->cap[1]->IsRange = 0
|
||||
pp_data->cap[1]->IsAlias = 0
|
||||
pp_data->cap[1]->IsStringRange = 0
|
||||
pp_data->cap[1]->IsDesignatorRange = 0
|
||||
pp_data->cap[1]->Reserved1 = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[1]->NotRange.Usage = 0x0002
|
||||
pp_data->cap[1]->NotRange.Reserved1 = 0x0002
|
||||
pp_data->cap[1]->NotRange.StringIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[1]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[1]->NotRange.DataIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved4 = 0
|
||||
pp_data->cap[1]->Button.LogicalMin = 0
|
||||
pp_data->cap[1]->Button.LogicalMax = 255
|
||||
pp_data->cap[1]->Units = 0
|
||||
pp_data->cap[1]->UnitsExp = 0
|
||||
|
||||
# Feature hid_pp_cap struct:
|
||||
# Link Collections:
|
||||
pp_data->LinkCollectionArray[0]->LinkUsage = 0x0002
|
||||
pp_data->LinkCollectionArray[0]->LinkUsagePage = 0xFF00
|
||||
pp_data->LinkCollectionArray[0]->Parent = 0
|
||||
pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[0]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[0]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[0]->CollectionType = 1
|
||||
pp_data->LinkCollectionArray[0]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
|
||||
@@ -0,0 +1,4 @@
|
||||
0x06, 0x00, 0xFF, 0x09, 0x02, 0xA1, 0x01, 0x85, 0x11, 0x09,
|
||||
0x02, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x13,
|
||||
0x81, 0x00, 0x09, 0x02, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
|
||||
0x08, 0x95, 0x13, 0x91, 0x00, 0xC0,
|
||||
@@ -0,0 +1,13 @@
|
||||
Usage Page (Vendor-Defined 1) 06 00 FF
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Collection (Application) A1 01
|
||||
Report ID (17) 85 11
|
||||
Report Size (8) 75 08
|
||||
Report Count (19) 95 13
|
||||
Logical Minimum (0) 15 00
|
||||
Logical Maximum (255) 26 FF 00
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Input (Data,Ary,Abs) 81 00
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Output (Data,Ary,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) 91 00
|
||||
End Collection C0
|
||||
@@ -0,0 +1,93 @@
|
||||
# HIDAPI device info struct:
|
||||
dev->vendor_id = 0x046D
|
||||
dev->product_id = 0xC534
|
||||
dev->manufacturer_string = "Logitech"
|
||||
dev->product_string = "USB Receiver"
|
||||
dev->release_number = 0x2901
|
||||
dev->interface_number = 1
|
||||
dev->usage = 0x0001
|
||||
dev->usage_page = 0x000C
|
||||
dev->path = "\\?\hid#vid_046d&pid_c534&mi_01&col02#7&1ebb799e&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}"
|
||||
|
||||
# Preparsed Data struct:
|
||||
pp_data->MagicKey = 0x48696450204B4452
|
||||
pp_data->Usage = 0x0001
|
||||
pp_data->UsagePage = 0x000C
|
||||
pp_data->Reserved = 0x00000000
|
||||
# Input caps_info struct:
|
||||
pp_data->caps_info[0]->FirstCap = 0
|
||||
pp_data->caps_info[0]->LastCap = 1
|
||||
pp_data->caps_info[0]->NumberOfCaps = 1
|
||||
pp_data->caps_info[0]->ReportByteLength = 5
|
||||
# Output caps_info struct:
|
||||
pp_data->caps_info[1]->FirstCap = 1
|
||||
pp_data->caps_info[1]->LastCap = 1
|
||||
pp_data->caps_info[1]->NumberOfCaps = 0
|
||||
pp_data->caps_info[1]->ReportByteLength = 0
|
||||
# Feature caps_info struct:
|
||||
pp_data->caps_info[2]->FirstCap = 1
|
||||
pp_data->caps_info[2]->LastCap = 1
|
||||
pp_data->caps_info[2]->NumberOfCaps = 0
|
||||
pp_data->caps_info[2]->ReportByteLength = 0
|
||||
# LinkCollectionArray Offset & Size:
|
||||
pp_data->FirstByteOfLinkCollectionArray = 0x0068
|
||||
pp_data->NumberLinkCollectionNodes = 1
|
||||
# Input hid_pp_cap struct:
|
||||
pp_data->cap[0]->UsagePage = 0x000C
|
||||
pp_data->cap[0]->ReportID = 0x03
|
||||
pp_data->cap[0]->BitPosition = 0
|
||||
pp_data->cap[0]->BitSize = 16
|
||||
pp_data->cap[0]->ReportCount = 2
|
||||
pp_data->cap[0]->BytePosition = 0x0001
|
||||
pp_data->cap[0]->BitCount = 32
|
||||
pp_data->cap[0]->BitField = 0x00
|
||||
pp_data->cap[0]->NextBytePosition = 0x0005
|
||||
pp_data->cap[0]->LinkCollection = 0x0000
|
||||
pp_data->cap[0]->LinkUsagePage = 0x000C
|
||||
pp_data->cap[0]->LinkUsage = 0x0001
|
||||
pp_data->cap[0]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[0]->IsButtonCap = 1
|
||||
pp_data->cap[0]->IsPadding = 0
|
||||
pp_data->cap[0]->IsAbsolute = 1
|
||||
pp_data->cap[0]->IsRange = 1
|
||||
pp_data->cap[0]->IsAlias = 0
|
||||
pp_data->cap[0]->IsStringRange = 0
|
||||
pp_data->cap[0]->IsDesignatorRange = 0
|
||||
pp_data->cap[0]->Reserved1 = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[0]->Range.UsageMin = 0x0001
|
||||
pp_data->cap[0]->Range.UsageMax = 0x028C
|
||||
pp_data->cap[0]->Range.StringMin = 0
|
||||
pp_data->cap[0]->Range.StringMax = 0
|
||||
pp_data->cap[0]->Range.DesignatorMin = 0
|
||||
pp_data->cap[0]->Range.DesignatorMax = 0
|
||||
pp_data->cap[0]->Range.DataIndexMin = 0
|
||||
pp_data->cap[0]->Range.DataIndexMax = 651
|
||||
pp_data->cap[0]->Button.LogicalMin = 1
|
||||
pp_data->cap[0]->Button.LogicalMax = 652
|
||||
pp_data->cap[0]->Units = 0
|
||||
pp_data->cap[0]->UnitsExp = 0
|
||||
|
||||
# Output hid_pp_cap struct:
|
||||
# Feature hid_pp_cap struct:
|
||||
# Link Collections:
|
||||
pp_data->LinkCollectionArray[0]->LinkUsage = 0x0001
|
||||
pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x000C
|
||||
pp_data->LinkCollectionArray[0]->Parent = 0
|
||||
pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[0]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[0]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[0]->CollectionType = 1
|
||||
pp_data->LinkCollectionArray[0]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
|
||||
@@ -0,0 +1,3 @@
|
||||
0x05, 0x0C, 0x09, 0x01, 0xA1, 0x01, 0x85, 0x03, 0x19, 0x01,
|
||||
0x2A, 0x8C, 0x02, 0x15, 0x01, 0x26, 0x8C, 0x02, 0x75, 0x10,
|
||||
0x95, 0x02, 0x81, 0x00, 0xC0,
|
||||
@@ -0,0 +1,18 @@
|
||||
macOS USB prober output for Logitech USB Receiver
|
||||
05 0C 09 01 A1 01
|
||||
85 03 75 10 95 02 15 01 26 8C 02 19 01 2A 8C 02 81 00
|
||||
C0
|
||||
|
||||
Parser output:
|
||||
0x05, 0x0C, // Usage Page (Consumer)
|
||||
0x09, 0x01, // Usage (Consumer Control)
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x85, 0x03, // Report ID (3)
|
||||
0x75, 0x10, // Report Size (16)
|
||||
0x95, 0x02, // Report Count (2)
|
||||
0x15, 0x01, // Logical Minimum (1)
|
||||
0x26, 0x8C, 0x02, // Logical Maximum (652)
|
||||
0x19, 0x01, // Usage Minimum (Consumer Control)
|
||||
0x2A, 0x8C, 0x02, // Usage Maximum (AC Send)
|
||||
0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0xC0, // End Collection
|
||||
@@ -0,0 +1,139 @@
|
||||
# HIDAPI device info struct:
|
||||
dev->vendor_id = 0x046D
|
||||
dev->product_id = 0xC534
|
||||
dev->manufacturer_string = "Logitech"
|
||||
dev->product_string = "USB Receiver"
|
||||
dev->release_number = 0x2901
|
||||
dev->interface_number = 1
|
||||
dev->usage = 0x0001
|
||||
dev->usage_page = 0xFF00
|
||||
dev->path = "\\?\hid#vid_046d&pid_c534&mi_01&col04#7&1ebb799e&0&0003#{4d1e55b2-f16f-11cf-88cb-001111000030}"
|
||||
|
||||
# Preparsed Data struct:
|
||||
pp_data->MagicKey = 0x48696450204B4452
|
||||
pp_data->Usage = 0x0001
|
||||
pp_data->UsagePage = 0xFF00
|
||||
pp_data->Reserved = 0x00000000
|
||||
# Input caps_info struct:
|
||||
pp_data->caps_info[0]->FirstCap = 0
|
||||
pp_data->caps_info[0]->LastCap = 1
|
||||
pp_data->caps_info[0]->NumberOfCaps = 1
|
||||
pp_data->caps_info[0]->ReportByteLength = 7
|
||||
# Output caps_info struct:
|
||||
pp_data->caps_info[1]->FirstCap = 1
|
||||
pp_data->caps_info[1]->LastCap = 2
|
||||
pp_data->caps_info[1]->NumberOfCaps = 1
|
||||
pp_data->caps_info[1]->ReportByteLength = 7
|
||||
# Feature caps_info struct:
|
||||
pp_data->caps_info[2]->FirstCap = 2
|
||||
pp_data->caps_info[2]->LastCap = 2
|
||||
pp_data->caps_info[2]->NumberOfCaps = 0
|
||||
pp_data->caps_info[2]->ReportByteLength = 0
|
||||
# LinkCollectionArray Offset & Size:
|
||||
pp_data->FirstByteOfLinkCollectionArray = 0x00D0
|
||||
pp_data->NumberLinkCollectionNodes = 1
|
||||
# Input hid_pp_cap struct:
|
||||
pp_data->cap[0]->UsagePage = 0xFF00
|
||||
pp_data->cap[0]->ReportID = 0x10
|
||||
pp_data->cap[0]->BitPosition = 0
|
||||
pp_data->cap[0]->BitSize = 8
|
||||
pp_data->cap[0]->ReportCount = 6
|
||||
pp_data->cap[0]->BytePosition = 0x0001
|
||||
pp_data->cap[0]->BitCount = 48
|
||||
pp_data->cap[0]->BitField = 0x00
|
||||
pp_data->cap[0]->NextBytePosition = 0x0007
|
||||
pp_data->cap[0]->LinkCollection = 0x0000
|
||||
pp_data->cap[0]->LinkUsagePage = 0xFF00
|
||||
pp_data->cap[0]->LinkUsage = 0x0001
|
||||
pp_data->cap[0]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[0]->IsButtonCap = 1
|
||||
pp_data->cap[0]->IsPadding = 0
|
||||
pp_data->cap[0]->IsAbsolute = 1
|
||||
pp_data->cap[0]->IsRange = 0
|
||||
pp_data->cap[0]->IsAlias = 0
|
||||
pp_data->cap[0]->IsStringRange = 0
|
||||
pp_data->cap[0]->IsDesignatorRange = 0
|
||||
pp_data->cap[0]->Reserved1 = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[0]->NotRange.Usage = 0x0001
|
||||
pp_data->cap[0]->NotRange.Reserved1 = 0x0001
|
||||
pp_data->cap[0]->NotRange.StringIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[0]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[0]->NotRange.DataIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved4 = 0
|
||||
pp_data->cap[0]->Button.LogicalMin = 0
|
||||
pp_data->cap[0]->Button.LogicalMax = 255
|
||||
pp_data->cap[0]->Units = 0
|
||||
pp_data->cap[0]->UnitsExp = 0
|
||||
|
||||
# Output hid_pp_cap struct:
|
||||
pp_data->cap[1]->UsagePage = 0xFF00
|
||||
pp_data->cap[1]->ReportID = 0x10
|
||||
pp_data->cap[1]->BitPosition = 0
|
||||
pp_data->cap[1]->BitSize = 8
|
||||
pp_data->cap[1]->ReportCount = 6
|
||||
pp_data->cap[1]->BytePosition = 0x0001
|
||||
pp_data->cap[1]->BitCount = 48
|
||||
pp_data->cap[1]->BitField = 0x00
|
||||
pp_data->cap[1]->NextBytePosition = 0x0007
|
||||
pp_data->cap[1]->LinkCollection = 0x0000
|
||||
pp_data->cap[1]->LinkUsagePage = 0xFF00
|
||||
pp_data->cap[1]->LinkUsage = 0x0001
|
||||
pp_data->cap[1]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[1]->IsButtonCap = 1
|
||||
pp_data->cap[1]->IsPadding = 0
|
||||
pp_data->cap[1]->IsAbsolute = 1
|
||||
pp_data->cap[1]->IsRange = 0
|
||||
pp_data->cap[1]->IsAlias = 0
|
||||
pp_data->cap[1]->IsStringRange = 0
|
||||
pp_data->cap[1]->IsDesignatorRange = 0
|
||||
pp_data->cap[1]->Reserved1 = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[1]->NotRange.Usage = 0x0001
|
||||
pp_data->cap[1]->NotRange.Reserved1 = 0x0001
|
||||
pp_data->cap[1]->NotRange.StringIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[1]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[1]->NotRange.DataIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved4 = 0
|
||||
pp_data->cap[1]->Button.LogicalMin = 0
|
||||
pp_data->cap[1]->Button.LogicalMax = 255
|
||||
pp_data->cap[1]->Units = 0
|
||||
pp_data->cap[1]->UnitsExp = 0
|
||||
|
||||
# Feature hid_pp_cap struct:
|
||||
# Link Collections:
|
||||
pp_data->LinkCollectionArray[0]->LinkUsage = 0x0001
|
||||
pp_data->LinkCollectionArray[0]->LinkUsagePage = 0xFF00
|
||||
pp_data->LinkCollectionArray[0]->Parent = 0
|
||||
pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[0]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[0]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[0]->CollectionType = 1
|
||||
pp_data->LinkCollectionArray[0]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
|
||||
@@ -0,0 +1,4 @@
|
||||
0x06, 0x00, 0xFF, 0x09, 0x01, 0xA1, 0x01, 0x85, 0x10, 0x09,
|
||||
0x01, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x06,
|
||||
0x81, 0x00, 0x09, 0x01, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
|
||||
0x08, 0x95, 0x06, 0x91, 0x00, 0xC0,
|
||||
@@ -0,0 +1,20 @@
|
||||
macOS USB prober output for Logitech USB Receiver
|
||||
|
||||
06 00 FF 09 01 A1 01 85 10 75 08 95 06
|
||||
15 00 26 FF 00 09 01 81
|
||||
00 09 01 91 00 C0
|
||||
|
||||
Parser Output:
|
||||
0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
|
||||
0x09, 0x01, // Usage (0x01)
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x85, 0x10, // Report ID (16)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x95, 0x06, // Report Count (6)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x26, 0xFF, 0x00, // Logical Maximum (255)
|
||||
0x09, 0x01, // Usage (0x01)
|
||||
0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x09, 0x01, // Usage (0x01)
|
||||
0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0xC0, // End Collection
|
||||
@@ -0,0 +1,302 @@
|
||||
# HIDAPI device info struct:
|
||||
dev->vendor_id = 0x046D
|
||||
dev->product_id = 0xC534
|
||||
dev->manufacturer_string = "Logitech"
|
||||
dev->product_string = "USB Receiver"
|
||||
dev->release_number = 0x2901
|
||||
dev->interface_number = 1
|
||||
dev->usage = 0x0002
|
||||
dev->usage_page = 0x0001
|
||||
dev->path = "\\?\hid#vid_046d&pid_c534&mi_01&col01#7&1ebb799e&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
|
||||
|
||||
# Preparsed Data struct:
|
||||
pp_data->MagicKey = 0x48696450204B4452
|
||||
pp_data->Usage = 0x0002
|
||||
pp_data->UsagePage = 0x0001
|
||||
pp_data->Reserved = 0x00000000
|
||||
# Input caps_info struct:
|
||||
pp_data->caps_info[0]->FirstCap = 0
|
||||
pp_data->caps_info[0]->LastCap = 5
|
||||
pp_data->caps_info[0]->NumberOfCaps = 5
|
||||
pp_data->caps_info[0]->ReportByteLength = 8
|
||||
# Output caps_info struct:
|
||||
pp_data->caps_info[1]->FirstCap = 5
|
||||
pp_data->caps_info[1]->LastCap = 5
|
||||
pp_data->caps_info[1]->NumberOfCaps = 0
|
||||
pp_data->caps_info[1]->ReportByteLength = 0
|
||||
# Feature caps_info struct:
|
||||
pp_data->caps_info[2]->FirstCap = 5
|
||||
pp_data->caps_info[2]->LastCap = 5
|
||||
pp_data->caps_info[2]->NumberOfCaps = 0
|
||||
pp_data->caps_info[2]->ReportByteLength = 0
|
||||
# LinkCollectionArray Offset & Size:
|
||||
pp_data->FirstByteOfLinkCollectionArray = 0x0208
|
||||
pp_data->NumberLinkCollectionNodes = 2
|
||||
# Input hid_pp_cap struct:
|
||||
pp_data->cap[0]->UsagePage = 0x0009
|
||||
pp_data->cap[0]->ReportID = 0x02
|
||||
pp_data->cap[0]->BitPosition = 0
|
||||
pp_data->cap[0]->BitSize = 1
|
||||
pp_data->cap[0]->ReportCount = 16
|
||||
pp_data->cap[0]->BytePosition = 0x0001
|
||||
pp_data->cap[0]->BitCount = 16
|
||||
pp_data->cap[0]->BitField = 0x02
|
||||
pp_data->cap[0]->NextBytePosition = 0x0003
|
||||
pp_data->cap[0]->LinkCollection = 0x0001
|
||||
pp_data->cap[0]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[0]->LinkUsage = 0x0001
|
||||
pp_data->cap[0]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[0]->IsButtonCap = 1
|
||||
pp_data->cap[0]->IsPadding = 0
|
||||
pp_data->cap[0]->IsAbsolute = 1
|
||||
pp_data->cap[0]->IsRange = 1
|
||||
pp_data->cap[0]->IsAlias = 0
|
||||
pp_data->cap[0]->IsStringRange = 0
|
||||
pp_data->cap[0]->IsDesignatorRange = 0
|
||||
pp_data->cap[0]->Reserved1 = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[0]->Range.UsageMin = 0x0001
|
||||
pp_data->cap[0]->Range.UsageMax = 0x0010
|
||||
pp_data->cap[0]->Range.StringMin = 0
|
||||
pp_data->cap[0]->Range.StringMax = 0
|
||||
pp_data->cap[0]->Range.DesignatorMin = 0
|
||||
pp_data->cap[0]->Range.DesignatorMax = 0
|
||||
pp_data->cap[0]->Range.DataIndexMin = 0
|
||||
pp_data->cap[0]->Range.DataIndexMax = 15
|
||||
pp_data->cap[0]->Button.LogicalMin = 0
|
||||
pp_data->cap[0]->Button.LogicalMax = 0
|
||||
pp_data->cap[0]->Units = 0
|
||||
pp_data->cap[0]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[1]->UsagePage = 0x0001
|
||||
pp_data->cap[1]->ReportID = 0x02
|
||||
pp_data->cap[1]->BitPosition = 4
|
||||
pp_data->cap[1]->BitSize = 12
|
||||
pp_data->cap[1]->ReportCount = 1
|
||||
pp_data->cap[1]->BytePosition = 0x0004
|
||||
pp_data->cap[1]->BitCount = 12
|
||||
pp_data->cap[1]->BitField = 0x06
|
||||
pp_data->cap[1]->NextBytePosition = 0x0006
|
||||
pp_data->cap[1]->LinkCollection = 0x0001
|
||||
pp_data->cap[1]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[1]->LinkUsage = 0x0001
|
||||
pp_data->cap[1]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[1]->IsButtonCap = 0
|
||||
pp_data->cap[1]->IsPadding = 0
|
||||
pp_data->cap[1]->IsAbsolute = 0
|
||||
pp_data->cap[1]->IsRange = 0
|
||||
pp_data->cap[1]->IsAlias = 0
|
||||
pp_data->cap[1]->IsStringRange = 0
|
||||
pp_data->cap[1]->IsDesignatorRange = 0
|
||||
pp_data->cap[1]->Reserved1 = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[1]->NotRange.Usage = 0x0031
|
||||
pp_data->cap[1]->NotRange.Reserved1 = 0x0031
|
||||
pp_data->cap[1]->NotRange.StringIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[1]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[1]->NotRange.DataIndex = 16
|
||||
pp_data->cap[1]->NotRange.Reserved4 = 16
|
||||
pp_data->cap[1]->NotButton.HasNull = 0
|
||||
pp_data->cap[1]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[1]->NotButton.LogicalMin = -2047
|
||||
pp_data->cap[1]->NotButton.LogicalMax = 2047
|
||||
pp_data->cap[1]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[1]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[1]->Units = 0
|
||||
pp_data->cap[1]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[2]->UsagePage = 0x0001
|
||||
pp_data->cap[2]->ReportID = 0x02
|
||||
pp_data->cap[2]->BitPosition = 0
|
||||
pp_data->cap[2]->BitSize = 12
|
||||
pp_data->cap[2]->ReportCount = 1
|
||||
pp_data->cap[2]->BytePosition = 0x0003
|
||||
pp_data->cap[2]->BitCount = 12
|
||||
pp_data->cap[2]->BitField = 0x06
|
||||
pp_data->cap[2]->NextBytePosition = 0x0005
|
||||
pp_data->cap[2]->LinkCollection = 0x0001
|
||||
pp_data->cap[2]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[2]->LinkUsage = 0x0001
|
||||
pp_data->cap[2]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[2]->IsButtonCap = 0
|
||||
pp_data->cap[2]->IsPadding = 0
|
||||
pp_data->cap[2]->IsAbsolute = 0
|
||||
pp_data->cap[2]->IsRange = 0
|
||||
pp_data->cap[2]->IsAlias = 0
|
||||
pp_data->cap[2]->IsStringRange = 0
|
||||
pp_data->cap[2]->IsDesignatorRange = 0
|
||||
pp_data->cap[2]->Reserved1 = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[2]->NotRange.Usage = 0x0030
|
||||
pp_data->cap[2]->NotRange.Reserved1 = 0x0030
|
||||
pp_data->cap[2]->NotRange.StringIndex = 0
|
||||
pp_data->cap[2]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[2]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[2]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[2]->NotRange.DataIndex = 17
|
||||
pp_data->cap[2]->NotRange.Reserved4 = 17
|
||||
pp_data->cap[2]->NotButton.HasNull = 0
|
||||
pp_data->cap[2]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[2]->NotButton.LogicalMin = -2047
|
||||
pp_data->cap[2]->NotButton.LogicalMax = 2047
|
||||
pp_data->cap[2]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[2]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[2]->Units = 0
|
||||
pp_data->cap[2]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[3]->UsagePage = 0x0001
|
||||
pp_data->cap[3]->ReportID = 0x02
|
||||
pp_data->cap[3]->BitPosition = 0
|
||||
pp_data->cap[3]->BitSize = 8
|
||||
pp_data->cap[3]->ReportCount = 1
|
||||
pp_data->cap[3]->BytePosition = 0x0006
|
||||
pp_data->cap[3]->BitCount = 8
|
||||
pp_data->cap[3]->BitField = 0x06
|
||||
pp_data->cap[3]->NextBytePosition = 0x0007
|
||||
pp_data->cap[3]->LinkCollection = 0x0001
|
||||
pp_data->cap[3]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[3]->LinkUsage = 0x0001
|
||||
pp_data->cap[3]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[3]->IsButtonCap = 0
|
||||
pp_data->cap[3]->IsPadding = 0
|
||||
pp_data->cap[3]->IsAbsolute = 0
|
||||
pp_data->cap[3]->IsRange = 0
|
||||
pp_data->cap[3]->IsAlias = 0
|
||||
pp_data->cap[3]->IsStringRange = 0
|
||||
pp_data->cap[3]->IsDesignatorRange = 0
|
||||
pp_data->cap[3]->Reserved1 = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[3]->NotRange.Usage = 0x0038
|
||||
pp_data->cap[3]->NotRange.Reserved1 = 0x0038
|
||||
pp_data->cap[3]->NotRange.StringIndex = 0
|
||||
pp_data->cap[3]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[3]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[3]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[3]->NotRange.DataIndex = 18
|
||||
pp_data->cap[3]->NotRange.Reserved4 = 18
|
||||
pp_data->cap[3]->NotButton.HasNull = 0
|
||||
pp_data->cap[3]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[3]->NotButton.LogicalMin = -127
|
||||
pp_data->cap[3]->NotButton.LogicalMax = 127
|
||||
pp_data->cap[3]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[3]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[3]->Units = 0
|
||||
pp_data->cap[3]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[4]->UsagePage = 0x000C
|
||||
pp_data->cap[4]->ReportID = 0x02
|
||||
pp_data->cap[4]->BitPosition = 0
|
||||
pp_data->cap[4]->BitSize = 8
|
||||
pp_data->cap[4]->ReportCount = 1
|
||||
pp_data->cap[4]->BytePosition = 0x0007
|
||||
pp_data->cap[4]->BitCount = 8
|
||||
pp_data->cap[4]->BitField = 0x06
|
||||
pp_data->cap[4]->NextBytePosition = 0x0008
|
||||
pp_data->cap[4]->LinkCollection = 0x0001
|
||||
pp_data->cap[4]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[4]->LinkUsage = 0x0001
|
||||
pp_data->cap[4]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[4]->IsButtonCap = 0
|
||||
pp_data->cap[4]->IsPadding = 0
|
||||
pp_data->cap[4]->IsAbsolute = 0
|
||||
pp_data->cap[4]->IsRange = 0
|
||||
pp_data->cap[4]->IsAlias = 0
|
||||
pp_data->cap[4]->IsStringRange = 0
|
||||
pp_data->cap[4]->IsDesignatorRange = 0
|
||||
pp_data->cap[4]->Reserved1 = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[4]->NotRange.Usage = 0x0238
|
||||
pp_data->cap[4]->NotRange.Reserved1 = 0x0238
|
||||
pp_data->cap[4]->NotRange.StringIndex = 0
|
||||
pp_data->cap[4]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[4]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[4]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[4]->NotRange.DataIndex = 19
|
||||
pp_data->cap[4]->NotRange.Reserved4 = 19
|
||||
pp_data->cap[4]->NotButton.HasNull = 0
|
||||
pp_data->cap[4]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[4]->NotButton.LogicalMin = -127
|
||||
pp_data->cap[4]->NotButton.LogicalMax = 127
|
||||
pp_data->cap[4]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[4]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[4]->Units = 0
|
||||
pp_data->cap[4]->UnitsExp = 0
|
||||
|
||||
# Output hid_pp_cap struct:
|
||||
# Feature hid_pp_cap struct:
|
||||
# Link Collections:
|
||||
pp_data->LinkCollectionArray[0]->LinkUsage = 0x0002
|
||||
pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x0001
|
||||
pp_data->LinkCollectionArray[0]->Parent = 0
|
||||
pp_data->LinkCollectionArray[0]->NumberOfChildren = 1
|
||||
pp_data->LinkCollectionArray[0]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[0]->FirstChild = 1
|
||||
pp_data->LinkCollectionArray[0]->CollectionType = 1
|
||||
pp_data->LinkCollectionArray[0]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
|
||||
pp_data->LinkCollectionArray[1]->LinkUsage = 0x0001
|
||||
pp_data->LinkCollectionArray[1]->LinkUsagePage = 0x0001
|
||||
pp_data->LinkCollectionArray[1]->Parent = 0
|
||||
pp_data->LinkCollectionArray[1]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[1]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[1]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[1]->CollectionType = 0
|
||||
pp_data->LinkCollectionArray[1]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[1]->Reserved = 0x00000000
|
||||
@@ -0,0 +1,8 @@
|
||||
0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01, 0xA1, 0x00,
|
||||
0x85, 0x02, 0x05, 0x09, 0x19, 0x01, 0x29, 0x10, 0x15, 0x00,
|
||||
0x25, 0x01, 0x75, 0x01, 0x95, 0x10, 0x81, 0x02, 0x05, 0x01,
|
||||
0x09, 0x30, 0x09, 0x31, 0x16, 0x01, 0xF8, 0x26, 0xFF, 0x07,
|
||||
0x75, 0x0C, 0x95, 0x02, 0x81, 0x06, 0x09, 0x38, 0x15, 0x81,
|
||||
0x25, 0x7F, 0x75, 0x08, 0x95, 0x01, 0x81, 0x06, 0x05, 0x0C,
|
||||
0x0A, 0x38, 0x02, 0x15, 0x81, 0x25, 0x7F, 0x75, 0x08, 0x95,
|
||||
0x01, 0x81, 0x06, 0xC0, 0xC0,
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
05 01 09 02 A1 01 85 02 09 01 A1 00 05 09 19 01
|
||||
29 10 15 00 25 01 95 10 75 01 81 02 05 01 16 01
|
||||
F8 26 FF 07 75 0C 95 02 09 30 09 31 81 06 15 81
|
||||
25 7F 75 08 95 01 09 38 81 06 05 0C 0A 38 02 95
|
||||
01 81 06 C0 C0
|
||||
|
||||
Parser Output:
|
||||
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
||||
0x09, 0x02, // Usage (Mouse)
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x85, 0x02, // Report ID (2)
|
||||
0x09, 0x01, // Usage (Pointer)
|
||||
0xA1, 0x00, // Collection (Physical)
|
||||
0x05, 0x09, // Usage Page (Button)
|
||||
0x19, 0x01, // Usage Minimum (0x01)
|
||||
0x29, 0x10, // Usage Maximum (0x10)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x25, 0x01, // Logical Maximum (1)
|
||||
0x95, 0x10, // Report Count (16)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
||||
0x16, 0x01, 0xF8, // Logical Minimum (-2047)
|
||||
0x26, 0xFF, 0x07, // Logical Maximum (2047)
|
||||
0x75, 0x0C, // Report Size (12)
|
||||
0x95, 0x02, // Report Count (2)
|
||||
0x09, 0x30, // Usage (X)
|
||||
0x09, 0x31, // Usage (Y)
|
||||
0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x15, 0x81, // Logical Minimum (-127)
|
||||
0x25, 0x7F, // Logical Maximum (127)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x09, 0x38, // Usage (Wheel)
|
||||
0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x05, 0x0C, // Usage Page (Consumer)
|
||||
0x0A, 0x38, 0x02, // Usage (AC Pan)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0xC0, // End Collection
|
||||
0xC0, // End Collection
|
||||
|
||||
// 69 bytes
|
||||
@@ -0,0 +1,139 @@
|
||||
# HIDAPI device info struct:
|
||||
dev->vendor_id = 0x046D
|
||||
dev->product_id = 0xC534
|
||||
dev->manufacturer_string = "Logitech"
|
||||
dev->product_string = "USB Receiver"
|
||||
dev->release_number = 0x2901
|
||||
dev->interface_number = 1
|
||||
dev->usage = 0x0002
|
||||
dev->usage_page = 0xFF00
|
||||
dev->path = "\\?\hid#vid_046d&pid_c534&mi_01&col05#7&1ebb799e&0&0004#{4d1e55b2-f16f-11cf-88cb-001111000030}"
|
||||
|
||||
# Preparsed Data struct:
|
||||
pp_data->MagicKey = 0x48696450204B4452
|
||||
pp_data->Usage = 0x0002
|
||||
pp_data->UsagePage = 0xFF00
|
||||
pp_data->Reserved = 0x00000000
|
||||
# Input caps_info struct:
|
||||
pp_data->caps_info[0]->FirstCap = 0
|
||||
pp_data->caps_info[0]->LastCap = 1
|
||||
pp_data->caps_info[0]->NumberOfCaps = 1
|
||||
pp_data->caps_info[0]->ReportByteLength = 20
|
||||
# Output caps_info struct:
|
||||
pp_data->caps_info[1]->FirstCap = 1
|
||||
pp_data->caps_info[1]->LastCap = 2
|
||||
pp_data->caps_info[1]->NumberOfCaps = 1
|
||||
pp_data->caps_info[1]->ReportByteLength = 20
|
||||
# Feature caps_info struct:
|
||||
pp_data->caps_info[2]->FirstCap = 2
|
||||
pp_data->caps_info[2]->LastCap = 2
|
||||
pp_data->caps_info[2]->NumberOfCaps = 0
|
||||
pp_data->caps_info[2]->ReportByteLength = 0
|
||||
# LinkCollectionArray Offset & Size:
|
||||
pp_data->FirstByteOfLinkCollectionArray = 0x00D0
|
||||
pp_data->NumberLinkCollectionNodes = 1
|
||||
# Input hid_pp_cap struct:
|
||||
pp_data->cap[0]->UsagePage = 0xFF00
|
||||
pp_data->cap[0]->ReportID = 0x11
|
||||
pp_data->cap[0]->BitPosition = 0
|
||||
pp_data->cap[0]->BitSize = 8
|
||||
pp_data->cap[0]->ReportCount = 19
|
||||
pp_data->cap[0]->BytePosition = 0x0001
|
||||
pp_data->cap[0]->BitCount = 152
|
||||
pp_data->cap[0]->BitField = 0x00
|
||||
pp_data->cap[0]->NextBytePosition = 0x0014
|
||||
pp_data->cap[0]->LinkCollection = 0x0000
|
||||
pp_data->cap[0]->LinkUsagePage = 0xFF00
|
||||
pp_data->cap[0]->LinkUsage = 0x0002
|
||||
pp_data->cap[0]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[0]->IsButtonCap = 1
|
||||
pp_data->cap[0]->IsPadding = 0
|
||||
pp_data->cap[0]->IsAbsolute = 1
|
||||
pp_data->cap[0]->IsRange = 0
|
||||
pp_data->cap[0]->IsAlias = 0
|
||||
pp_data->cap[0]->IsStringRange = 0
|
||||
pp_data->cap[0]->IsDesignatorRange = 0
|
||||
pp_data->cap[0]->Reserved1 = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[0]->NotRange.Usage = 0x0002
|
||||
pp_data->cap[0]->NotRange.Reserved1 = 0x0002
|
||||
pp_data->cap[0]->NotRange.StringIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[0]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[0]->NotRange.DataIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved4 = 0
|
||||
pp_data->cap[0]->Button.LogicalMin = 0
|
||||
pp_data->cap[0]->Button.LogicalMax = 255
|
||||
pp_data->cap[0]->Units = 0
|
||||
pp_data->cap[0]->UnitsExp = 0
|
||||
|
||||
# Output hid_pp_cap struct:
|
||||
pp_data->cap[1]->UsagePage = 0xFF00
|
||||
pp_data->cap[1]->ReportID = 0x11
|
||||
pp_data->cap[1]->BitPosition = 0
|
||||
pp_data->cap[1]->BitSize = 8
|
||||
pp_data->cap[1]->ReportCount = 19
|
||||
pp_data->cap[1]->BytePosition = 0x0001
|
||||
pp_data->cap[1]->BitCount = 152
|
||||
pp_data->cap[1]->BitField = 0x00
|
||||
pp_data->cap[1]->NextBytePosition = 0x0014
|
||||
pp_data->cap[1]->LinkCollection = 0x0000
|
||||
pp_data->cap[1]->LinkUsagePage = 0xFF00
|
||||
pp_data->cap[1]->LinkUsage = 0x0002
|
||||
pp_data->cap[1]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[1]->IsButtonCap = 1
|
||||
pp_data->cap[1]->IsPadding = 0
|
||||
pp_data->cap[1]->IsAbsolute = 1
|
||||
pp_data->cap[1]->IsRange = 0
|
||||
pp_data->cap[1]->IsAlias = 0
|
||||
pp_data->cap[1]->IsStringRange = 0
|
||||
pp_data->cap[1]->IsDesignatorRange = 0
|
||||
pp_data->cap[1]->Reserved1 = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[1]->NotRange.Usage = 0x0002
|
||||
pp_data->cap[1]->NotRange.Reserved1 = 0x0002
|
||||
pp_data->cap[1]->NotRange.StringIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[1]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[1]->NotRange.DataIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved4 = 0
|
||||
pp_data->cap[1]->Button.LogicalMin = 0
|
||||
pp_data->cap[1]->Button.LogicalMax = 255
|
||||
pp_data->cap[1]->Units = 0
|
||||
pp_data->cap[1]->UnitsExp = 0
|
||||
|
||||
# Feature hid_pp_cap struct:
|
||||
# Link Collections:
|
||||
pp_data->LinkCollectionArray[0]->LinkUsage = 0x0002
|
||||
pp_data->LinkCollectionArray[0]->LinkUsagePage = 0xFF00
|
||||
pp_data->LinkCollectionArray[0]->Parent = 0
|
||||
pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[0]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[0]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[0]->CollectionType = 1
|
||||
pp_data->LinkCollectionArray[0]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
|
||||
@@ -0,0 +1,4 @@
|
||||
0x06, 0x00, 0xFF, 0x09, 0x02, 0xA1, 0x01, 0x85, 0x11, 0x09,
|
||||
0x02, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75, 0x08, 0x95, 0x13,
|
||||
0x81, 0x00, 0x09, 0x02, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
|
||||
0x08, 0x95, 0x13, 0x91, 0x00, 0xC0,
|
||||
@@ -0,0 +1,22 @@
|
||||
macOS USB prober output for Logitech USB Receiver
|
||||
|
||||
06 00 FF 09 02 A1 01 85 11
|
||||
75 08 95 13 15 00 26 FF
|
||||
00 09 02 81 00 09 02 91 00 C0
|
||||
|
||||
Parser output:
|
||||
0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
|
||||
0x09, 0x02, // Usage (0x02)
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x85, 0x11, // Report ID (17)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x95, 0x13, // Report Count (19)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x26, 0xFF, 0x00, // Logical Maximum (255)
|
||||
0x09, 0x02, // Usage (0x02)
|
||||
0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x09, 0x02, // Usage (0x02)
|
||||
0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0xC0, // End Collection
|
||||
|
||||
// 27 bytes
|
||||
@@ -0,0 +1,185 @@
|
||||
# HIDAPI device info struct:
|
||||
dev->vendor_id = 0x046D
|
||||
dev->product_id = 0xC534
|
||||
dev->manufacturer_string = "Logitech"
|
||||
dev->product_string = "USB Receiver"
|
||||
dev->release_number = 0x2901
|
||||
dev->interface_number = 0
|
||||
dev->usage = 0x0006
|
||||
dev->usage_page = 0x0001
|
||||
dev->path = "\\?\hid#vid_046d&pid_c534&mi_00#7&51bc424&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}\kbd"
|
||||
|
||||
# Preparsed Data struct:
|
||||
pp_data->MagicKey = 0x48696450204B4452
|
||||
pp_data->Usage = 0x0006
|
||||
pp_data->UsagePage = 0x0001
|
||||
pp_data->Reserved = 0x00000000
|
||||
# Input caps_info struct:
|
||||
pp_data->caps_info[0]->FirstCap = 0
|
||||
pp_data->caps_info[0]->LastCap = 2
|
||||
pp_data->caps_info[0]->NumberOfCaps = 2
|
||||
pp_data->caps_info[0]->ReportByteLength = 9
|
||||
# Output caps_info struct:
|
||||
pp_data->caps_info[1]->FirstCap = 2
|
||||
pp_data->caps_info[1]->LastCap = 3
|
||||
pp_data->caps_info[1]->NumberOfCaps = 1
|
||||
pp_data->caps_info[1]->ReportByteLength = 2
|
||||
# Feature caps_info struct:
|
||||
pp_data->caps_info[2]->FirstCap = 3
|
||||
pp_data->caps_info[2]->LastCap = 3
|
||||
pp_data->caps_info[2]->NumberOfCaps = 0
|
||||
pp_data->caps_info[2]->ReportByteLength = 0
|
||||
# LinkCollectionArray Offset & Size:
|
||||
pp_data->FirstByteOfLinkCollectionArray = 0x0138
|
||||
pp_data->NumberLinkCollectionNodes = 1
|
||||
# Input hid_pp_cap struct:
|
||||
pp_data->cap[0]->UsagePage = 0x0007
|
||||
pp_data->cap[0]->ReportID = 0x00
|
||||
pp_data->cap[0]->BitPosition = 0
|
||||
pp_data->cap[0]->BitSize = 1
|
||||
pp_data->cap[0]->ReportCount = 8
|
||||
pp_data->cap[0]->BytePosition = 0x0001
|
||||
pp_data->cap[0]->BitCount = 8
|
||||
pp_data->cap[0]->BitField = 0x02
|
||||
pp_data->cap[0]->NextBytePosition = 0x0002
|
||||
pp_data->cap[0]->LinkCollection = 0x0000
|
||||
pp_data->cap[0]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[0]->LinkUsage = 0x0006
|
||||
pp_data->cap[0]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[0]->IsButtonCap = 1
|
||||
pp_data->cap[0]->IsPadding = 0
|
||||
pp_data->cap[0]->IsAbsolute = 1
|
||||
pp_data->cap[0]->IsRange = 1
|
||||
pp_data->cap[0]->IsAlias = 0
|
||||
pp_data->cap[0]->IsStringRange = 0
|
||||
pp_data->cap[0]->IsDesignatorRange = 0
|
||||
pp_data->cap[0]->Reserved1 = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[0]->Range.UsageMin = 0x00E0
|
||||
pp_data->cap[0]->Range.UsageMax = 0x00E7
|
||||
pp_data->cap[0]->Range.StringMin = 0
|
||||
pp_data->cap[0]->Range.StringMax = 0
|
||||
pp_data->cap[0]->Range.DesignatorMin = 0
|
||||
pp_data->cap[0]->Range.DesignatorMax = 0
|
||||
pp_data->cap[0]->Range.DataIndexMin = 0
|
||||
pp_data->cap[0]->Range.DataIndexMax = 7
|
||||
pp_data->cap[0]->Button.LogicalMin = 0
|
||||
pp_data->cap[0]->Button.LogicalMax = 0
|
||||
pp_data->cap[0]->Units = 0
|
||||
pp_data->cap[0]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[1]->UsagePage = 0x0007
|
||||
pp_data->cap[1]->ReportID = 0x00
|
||||
pp_data->cap[1]->BitPosition = 0
|
||||
pp_data->cap[1]->BitSize = 8
|
||||
pp_data->cap[1]->ReportCount = 6
|
||||
pp_data->cap[1]->BytePosition = 0x0003
|
||||
pp_data->cap[1]->BitCount = 48
|
||||
pp_data->cap[1]->BitField = 0x00
|
||||
pp_data->cap[1]->NextBytePosition = 0x0009
|
||||
pp_data->cap[1]->LinkCollection = 0x0000
|
||||
pp_data->cap[1]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[1]->LinkUsage = 0x0006
|
||||
pp_data->cap[1]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[1]->IsButtonCap = 1
|
||||
pp_data->cap[1]->IsPadding = 0
|
||||
pp_data->cap[1]->IsAbsolute = 1
|
||||
pp_data->cap[1]->IsRange = 1
|
||||
pp_data->cap[1]->IsAlias = 0
|
||||
pp_data->cap[1]->IsStringRange = 0
|
||||
pp_data->cap[1]->IsDesignatorRange = 0
|
||||
pp_data->cap[1]->Reserved1 = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[1]->Range.UsageMin = 0x0000
|
||||
pp_data->cap[1]->Range.UsageMax = 0x00A4
|
||||
pp_data->cap[1]->Range.StringMin = 0
|
||||
pp_data->cap[1]->Range.StringMax = 0
|
||||
pp_data->cap[1]->Range.DesignatorMin = 0
|
||||
pp_data->cap[1]->Range.DesignatorMax = 0
|
||||
pp_data->cap[1]->Range.DataIndexMin = 8
|
||||
pp_data->cap[1]->Range.DataIndexMax = 172
|
||||
pp_data->cap[1]->Button.LogicalMin = 0
|
||||
pp_data->cap[1]->Button.LogicalMax = 164
|
||||
pp_data->cap[1]->Units = 0
|
||||
pp_data->cap[1]->UnitsExp = 0
|
||||
|
||||
# Output hid_pp_cap struct:
|
||||
pp_data->cap[2]->UsagePage = 0x0008
|
||||
pp_data->cap[2]->ReportID = 0x00
|
||||
pp_data->cap[2]->BitPosition = 0
|
||||
pp_data->cap[2]->BitSize = 1
|
||||
pp_data->cap[2]->ReportCount = 5
|
||||
pp_data->cap[2]->BytePosition = 0x0001
|
||||
pp_data->cap[2]->BitCount = 5
|
||||
pp_data->cap[2]->BitField = 0x02
|
||||
pp_data->cap[2]->NextBytePosition = 0x0002
|
||||
pp_data->cap[2]->LinkCollection = 0x0000
|
||||
pp_data->cap[2]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[2]->LinkUsage = 0x0006
|
||||
pp_data->cap[2]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[2]->IsButtonCap = 1
|
||||
pp_data->cap[2]->IsPadding = 0
|
||||
pp_data->cap[2]->IsAbsolute = 1
|
||||
pp_data->cap[2]->IsRange = 1
|
||||
pp_data->cap[2]->IsAlias = 0
|
||||
pp_data->cap[2]->IsStringRange = 0
|
||||
pp_data->cap[2]->IsDesignatorRange = 0
|
||||
pp_data->cap[2]->Reserved1 = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[2]->Range.UsageMin = 0x0001
|
||||
pp_data->cap[2]->Range.UsageMax = 0x0005
|
||||
pp_data->cap[2]->Range.StringMin = 0
|
||||
pp_data->cap[2]->Range.StringMax = 0
|
||||
pp_data->cap[2]->Range.DesignatorMin = 0
|
||||
pp_data->cap[2]->Range.DesignatorMax = 0
|
||||
pp_data->cap[2]->Range.DataIndexMin = 0
|
||||
pp_data->cap[2]->Range.DataIndexMax = 4
|
||||
pp_data->cap[2]->Button.LogicalMin = 0
|
||||
pp_data->cap[2]->Button.LogicalMax = 0
|
||||
pp_data->cap[2]->Units = 0
|
||||
pp_data->cap[2]->UnitsExp = 0
|
||||
|
||||
# Feature hid_pp_cap struct:
|
||||
# Link Collections:
|
||||
pp_data->LinkCollectionArray[0]->LinkUsage = 0x0006
|
||||
pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x0001
|
||||
pp_data->LinkCollectionArray[0]->Parent = 0
|
||||
pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[0]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[0]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[0]->CollectionType = 1
|
||||
pp_data->LinkCollectionArray[0]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
|
||||
@@ -0,0 +1,7 @@
|
||||
0x05, 0x01, 0x09, 0x06, 0xA1, 0x01, 0x05, 0x07, 0x19, 0xE0,
|
||||
0x29, 0xE7, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08,
|
||||
0x81, 0x02, 0x75, 0x08, 0x95, 0x01, 0x81, 0x03, 0x19, 0x00,
|
||||
0x29, 0xA4, 0x15, 0x00, 0x26, 0xA4, 0x00, 0x75, 0x08, 0x95,
|
||||
0x06, 0x81, 0x00, 0x05, 0x08, 0x19, 0x01, 0x29, 0x05, 0x15,
|
||||
0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x05, 0x91, 0x02, 0x75,
|
||||
0x03, 0x95, 0x01, 0x91, 0x03, 0xC0,
|
||||
@@ -0,0 +1,42 @@
|
||||
macOS USB prober output for Logitech USB Receiver
|
||||
|
||||
|
||||
Type: 0x22 (Report Descriptor)
|
||||
Length (and contents): 59
|
||||
Raw Descriptor (hex) 0000: 05 01 09 06 A1 01 05 07 19 E0 29 E7 15 00 25 01
|
||||
Raw Descriptor (hex) 0010: 75 01 95 08 81 02 81 03 95 05 05 08 19 01 29 05
|
||||
Raw Descriptor (hex) 0020: 91 02 95 01 75 03 91 01 95 06 75 08 15 00 26 A4
|
||||
Raw Descriptor (hex) 0030: 00 05 07 19 00 2A A4 00 81 00 C0
|
||||
|
||||
Parser output:
|
||||
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
||||
0x09, 0x06, // Usage (Keyboard)
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x05, 0x07, // Usage Page (Kbrd/Keypad)
|
||||
0x19, 0xE0, // Usage Minimum (0xE0)
|
||||
0x29, 0xE7, // Usage Maximum (0xE7)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x25, 0x01, // Logical Maximum (1)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x95, 0x08, // Report Count (8)
|
||||
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x95, 0x05, // Report Count (5)
|
||||
0x05, 0x08, // Usage Page (LEDs)
|
||||
0x19, 0x01, // Usage Minimum (Num Lock)
|
||||
0x29, 0x05, // Usage Maximum (Kana)
|
||||
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x75, 0x03, // Report Size (3)
|
||||
0x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0x95, 0x06, // Report Count (6)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x26, 0xA4, 0x00, // Logical Maximum (164)
|
||||
0x05, 0x07, // Usage Page (Kbrd/Keypad)
|
||||
0x19, 0x00, // Usage Minimum (0x00)
|
||||
0x2A, 0xA4, 0x00, // Usage Maximum (0xA4)
|
||||
0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0xC0, // End Collection
|
||||
|
||||
// 59 bytes
|
||||
@@ -0,0 +1,185 @@
|
||||
# HIDAPI device info struct:
|
||||
dev->vendor_id = 0x046D
|
||||
dev->product_id = 0xC534
|
||||
dev->manufacturer_string = "Logitech"
|
||||
dev->product_string = "USB Receiver"
|
||||
dev->release_number = 0x2901
|
||||
dev->interface_number = 1
|
||||
dev->usage = 0x0080
|
||||
dev->usage_page = 0x0001
|
||||
dev->path = "\\?\hid#vid_046d&pid_c534&mi_01&col03#7&1ebb799e&0&0002#{4d1e55b2-f16f-11cf-88cb-001111000030}"
|
||||
|
||||
# Preparsed Data struct:
|
||||
pp_data->MagicKey = 0x48696450204B4452
|
||||
pp_data->Usage = 0x0080
|
||||
pp_data->UsagePage = 0x0001
|
||||
pp_data->Reserved = 0x00038000
|
||||
# Input caps_info struct:
|
||||
pp_data->caps_info[0]->FirstCap = 0
|
||||
pp_data->caps_info[0]->LastCap = 3
|
||||
pp_data->caps_info[0]->NumberOfCaps = 3
|
||||
pp_data->caps_info[0]->ReportByteLength = 2
|
||||
# Output caps_info struct:
|
||||
pp_data->caps_info[1]->FirstCap = 3
|
||||
pp_data->caps_info[1]->LastCap = 3
|
||||
pp_data->caps_info[1]->NumberOfCaps = 0
|
||||
pp_data->caps_info[1]->ReportByteLength = 0
|
||||
# Feature caps_info struct:
|
||||
pp_data->caps_info[2]->FirstCap = 3
|
||||
pp_data->caps_info[2]->LastCap = 3
|
||||
pp_data->caps_info[2]->NumberOfCaps = 0
|
||||
pp_data->caps_info[2]->ReportByteLength = 0
|
||||
# LinkCollectionArray Offset & Size:
|
||||
pp_data->FirstByteOfLinkCollectionArray = 0x0138
|
||||
pp_data->NumberLinkCollectionNodes = 1
|
||||
# Input hid_pp_cap struct:
|
||||
pp_data->cap[0]->UsagePage = 0x0001
|
||||
pp_data->cap[0]->ReportID = 0x04
|
||||
pp_data->cap[0]->BitPosition = 0
|
||||
pp_data->cap[0]->BitSize = 2
|
||||
pp_data->cap[0]->ReportCount = 1
|
||||
pp_data->cap[0]->BytePosition = 0x0001
|
||||
pp_data->cap[0]->BitCount = 2
|
||||
pp_data->cap[0]->BitField = 0x60
|
||||
pp_data->cap[0]->NextBytePosition = 0x0002
|
||||
pp_data->cap[0]->LinkCollection = 0x0000
|
||||
pp_data->cap[0]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[0]->LinkUsage = 0x0080
|
||||
pp_data->cap[0]->IsMultipleItemsForArray = 1
|
||||
pp_data->cap[0]->IsButtonCap = 1
|
||||
pp_data->cap[0]->IsPadding = 0
|
||||
pp_data->cap[0]->IsAbsolute = 1
|
||||
pp_data->cap[0]->IsRange = 0
|
||||
pp_data->cap[0]->IsAlias = 0
|
||||
pp_data->cap[0]->IsStringRange = 0
|
||||
pp_data->cap[0]->IsDesignatorRange = 0
|
||||
pp_data->cap[0]->Reserved1 = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[0]->NotRange.Usage = 0x0083
|
||||
pp_data->cap[0]->NotRange.Reserved1 = 0x0083
|
||||
pp_data->cap[0]->NotRange.StringIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[0]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[0]->NotRange.DataIndex = 2
|
||||
pp_data->cap[0]->NotRange.Reserved4 = 2
|
||||
pp_data->cap[0]->Button.LogicalMin = 1
|
||||
pp_data->cap[0]->Button.LogicalMax = 3
|
||||
pp_data->cap[0]->Units = 0
|
||||
pp_data->cap[0]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[1]->UsagePage = 0x0001
|
||||
pp_data->cap[1]->ReportID = 0x04
|
||||
pp_data->cap[1]->BitPosition = 0
|
||||
pp_data->cap[1]->BitSize = 2
|
||||
pp_data->cap[1]->ReportCount = 1
|
||||
pp_data->cap[1]->BytePosition = 0x0001
|
||||
pp_data->cap[1]->BitCount = 2
|
||||
pp_data->cap[1]->BitField = 0x60
|
||||
pp_data->cap[1]->NextBytePosition = 0x0002
|
||||
pp_data->cap[1]->LinkCollection = 0x0000
|
||||
pp_data->cap[1]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[1]->LinkUsage = 0x0080
|
||||
pp_data->cap[1]->IsMultipleItemsForArray = 1
|
||||
pp_data->cap[1]->IsButtonCap = 1
|
||||
pp_data->cap[1]->IsPadding = 0
|
||||
pp_data->cap[1]->IsAbsolute = 1
|
||||
pp_data->cap[1]->IsRange = 0
|
||||
pp_data->cap[1]->IsAlias = 0
|
||||
pp_data->cap[1]->IsStringRange = 0
|
||||
pp_data->cap[1]->IsDesignatorRange = 0
|
||||
pp_data->cap[1]->Reserved1 = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[1]->NotRange.Usage = 0x0081
|
||||
pp_data->cap[1]->NotRange.Reserved1 = 0x0081
|
||||
pp_data->cap[1]->NotRange.StringIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[1]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[1]->NotRange.DataIndex = 1
|
||||
pp_data->cap[1]->NotRange.Reserved4 = 1
|
||||
pp_data->cap[1]->Button.LogicalMin = 1
|
||||
pp_data->cap[1]->Button.LogicalMax = 3
|
||||
pp_data->cap[1]->Units = 0
|
||||
pp_data->cap[1]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[2]->UsagePage = 0x0001
|
||||
pp_data->cap[2]->ReportID = 0x04
|
||||
pp_data->cap[2]->BitPosition = 0
|
||||
pp_data->cap[2]->BitSize = 2
|
||||
pp_data->cap[2]->ReportCount = 1
|
||||
pp_data->cap[2]->BytePosition = 0x0001
|
||||
pp_data->cap[2]->BitCount = 2
|
||||
pp_data->cap[2]->BitField = 0x60
|
||||
pp_data->cap[2]->NextBytePosition = 0x0002
|
||||
pp_data->cap[2]->LinkCollection = 0x0000
|
||||
pp_data->cap[2]->LinkUsagePage = 0x0001
|
||||
pp_data->cap[2]->LinkUsage = 0x0080
|
||||
pp_data->cap[2]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[2]->IsButtonCap = 1
|
||||
pp_data->cap[2]->IsPadding = 0
|
||||
pp_data->cap[2]->IsAbsolute = 1
|
||||
pp_data->cap[2]->IsRange = 0
|
||||
pp_data->cap[2]->IsAlias = 0
|
||||
pp_data->cap[2]->IsStringRange = 0
|
||||
pp_data->cap[2]->IsDesignatorRange = 0
|
||||
pp_data->cap[2]->Reserved1 = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[2]->NotRange.Usage = 0x0082
|
||||
pp_data->cap[2]->NotRange.Reserved1 = 0x0082
|
||||
pp_data->cap[2]->NotRange.StringIndex = 0
|
||||
pp_data->cap[2]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[2]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[2]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[2]->NotRange.DataIndex = 0
|
||||
pp_data->cap[2]->NotRange.Reserved4 = 0
|
||||
pp_data->cap[2]->Button.LogicalMin = 1
|
||||
pp_data->cap[2]->Button.LogicalMax = 3
|
||||
pp_data->cap[2]->Units = 0
|
||||
pp_data->cap[2]->UnitsExp = 0
|
||||
|
||||
# Output hid_pp_cap struct:
|
||||
# Feature hid_pp_cap struct:
|
||||
# Link Collections:
|
||||
pp_data->LinkCollectionArray[0]->LinkUsage = 0x0080
|
||||
pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x0001
|
||||
pp_data->LinkCollectionArray[0]->Parent = 0
|
||||
pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[0]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[0]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[0]->CollectionType = 1
|
||||
pp_data->LinkCollectionArray[0]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
|
||||
@@ -0,0 +1,4 @@
|
||||
0x05, 0x01, 0x09, 0x80, 0xA1, 0x01, 0x85, 0x04, 0x09, 0x82,
|
||||
0x09, 0x81, 0x09, 0x83, 0x15, 0x01, 0x25, 0x03, 0x75, 0x02,
|
||||
0x95, 0x01, 0x81, 0x60, 0x75, 0x06, 0x95, 0x01, 0x81, 0x03,
|
||||
0xC0,
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
05 01 09 80 A1 01 85 04 75 02 95 01 15 01 25 03
|
||||
09 82 09 81 09 83 81 60 75 06 81 03 C0
|
||||
|
||||
Parser output:
|
||||
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
||||
0x09, 0x80, // Usage (Sys Control)
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x85, 0x04, // Report ID (4)
|
||||
0x75, 0x02, // Report Size (2)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x15, 0x01, // Logical Minimum (1)
|
||||
0x25, 0x03, // Logical Maximum (3)
|
||||
0x09, 0x82, // Usage (Sys Sleep)
|
||||
0x09, 0x81, // Usage (Sys Power Down)
|
||||
0x09, 0x83, // Usage (Sys Wake Up)
|
||||
0x81, 0x60, // Input (Data,Array,Abs,No Wrap,Linear,No Preferred State,Null State)
|
||||
0x75, 0x06, // Report Size (6)
|
||||
0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0xC0, // End Collection
|
||||
|
||||
// 29 bytes
|
||||
@@ -0,0 +1,385 @@
|
||||
# HIDAPI device info struct:
|
||||
dev->vendor_id = 0x047F
|
||||
dev->product_id = 0xC056
|
||||
dev->manufacturer_string = "Plantronics"
|
||||
dev->product_string = "Plantronics Blackwire 3220 Series"
|
||||
dev->release_number = 0x0210
|
||||
dev->interface_number = 3
|
||||
dev->usage = 0x0001
|
||||
dev->usage_page = 0x000C
|
||||
dev->path = "\\?\hid#vid_047f&pid_c056&mi_03&col01#f&39e6f119&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}"
|
||||
|
||||
# Preparsed Data struct:
|
||||
pp_data->MagicKey = 0x48696450204B4452
|
||||
pp_data->Usage = 0x0001
|
||||
pp_data->UsagePage = 0x000C
|
||||
pp_data->Reserved = 0x00000000
|
||||
# Input caps_info struct:
|
||||
pp_data->caps_info[0]->FirstCap = 0
|
||||
pp_data->caps_info[0]->LastCap = 5
|
||||
pp_data->caps_info[0]->NumberOfCaps = 5
|
||||
pp_data->caps_info[0]->ReportByteLength = 33
|
||||
# Output caps_info struct:
|
||||
pp_data->caps_info[1]->FirstCap = 5
|
||||
pp_data->caps_info[1]->LastCap = 7
|
||||
pp_data->caps_info[1]->NumberOfCaps = 2
|
||||
pp_data->caps_info[1]->ReportByteLength = 37
|
||||
# Feature caps_info struct:
|
||||
pp_data->caps_info[2]->FirstCap = 7
|
||||
pp_data->caps_info[2]->LastCap = 7
|
||||
pp_data->caps_info[2]->NumberOfCaps = 0
|
||||
pp_data->caps_info[2]->ReportByteLength = 0
|
||||
# LinkCollectionArray Offset & Size:
|
||||
pp_data->FirstByteOfLinkCollectionArray = 0x02D8
|
||||
pp_data->NumberLinkCollectionNodes = 1
|
||||
# Input hid_pp_cap struct:
|
||||
pp_data->cap[0]->UsagePage = 0x000C
|
||||
pp_data->cap[0]->ReportID = 0x01
|
||||
pp_data->cap[0]->BitPosition = 1
|
||||
pp_data->cap[0]->BitSize = 1
|
||||
pp_data->cap[0]->ReportCount = 1
|
||||
pp_data->cap[0]->BytePosition = 0x0001
|
||||
pp_data->cap[0]->BitCount = 1
|
||||
pp_data->cap[0]->BitField = 0x06
|
||||
pp_data->cap[0]->NextBytePosition = 0x0002
|
||||
pp_data->cap[0]->LinkCollection = 0x0000
|
||||
pp_data->cap[0]->LinkUsagePage = 0x000C
|
||||
pp_data->cap[0]->LinkUsage = 0x0001
|
||||
pp_data->cap[0]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[0]->IsButtonCap = 1
|
||||
pp_data->cap[0]->IsPadding = 0
|
||||
pp_data->cap[0]->IsAbsolute = 0
|
||||
pp_data->cap[0]->IsRange = 0
|
||||
pp_data->cap[0]->IsAlias = 0
|
||||
pp_data->cap[0]->IsStringRange = 0
|
||||
pp_data->cap[0]->IsDesignatorRange = 0
|
||||
pp_data->cap[0]->Reserved1 = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[0]->NotRange.Usage = 0x00EA
|
||||
pp_data->cap[0]->NotRange.Reserved1 = 0x00EA
|
||||
pp_data->cap[0]->NotRange.StringIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[0]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[0]->NotRange.DataIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved4 = 0
|
||||
pp_data->cap[0]->Button.LogicalMin = 0
|
||||
pp_data->cap[0]->Button.LogicalMax = 0
|
||||
pp_data->cap[0]->Units = 0
|
||||
pp_data->cap[0]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[1]->UsagePage = 0x000C
|
||||
pp_data->cap[1]->ReportID = 0x01
|
||||
pp_data->cap[1]->BitPosition = 0
|
||||
pp_data->cap[1]->BitSize = 1
|
||||
pp_data->cap[1]->ReportCount = 1
|
||||
pp_data->cap[1]->BytePosition = 0x0001
|
||||
pp_data->cap[1]->BitCount = 1
|
||||
pp_data->cap[1]->BitField = 0x06
|
||||
pp_data->cap[1]->NextBytePosition = 0x0002
|
||||
pp_data->cap[1]->LinkCollection = 0x0000
|
||||
pp_data->cap[1]->LinkUsagePage = 0x000C
|
||||
pp_data->cap[1]->LinkUsage = 0x0001
|
||||
pp_data->cap[1]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[1]->IsButtonCap = 1
|
||||
pp_data->cap[1]->IsPadding = 0
|
||||
pp_data->cap[1]->IsAbsolute = 0
|
||||
pp_data->cap[1]->IsRange = 0
|
||||
pp_data->cap[1]->IsAlias = 0
|
||||
pp_data->cap[1]->IsStringRange = 0
|
||||
pp_data->cap[1]->IsDesignatorRange = 0
|
||||
pp_data->cap[1]->Reserved1 = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[1]->NotRange.Usage = 0x00E9
|
||||
pp_data->cap[1]->NotRange.Reserved1 = 0x00E9
|
||||
pp_data->cap[1]->NotRange.StringIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[1]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[1]->NotRange.DataIndex = 1
|
||||
pp_data->cap[1]->NotRange.Reserved4 = 1
|
||||
pp_data->cap[1]->Button.LogicalMin = 0
|
||||
pp_data->cap[1]->Button.LogicalMax = 0
|
||||
pp_data->cap[1]->Units = 0
|
||||
pp_data->cap[1]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[2]->UsagePage = 0x000C
|
||||
pp_data->cap[2]->ReportID = 0x02
|
||||
pp_data->cap[2]->BitPosition = 0
|
||||
pp_data->cap[2]->BitSize = 1
|
||||
pp_data->cap[2]->ReportCount = 16
|
||||
pp_data->cap[2]->BytePosition = 0x0001
|
||||
pp_data->cap[2]->BitCount = 16
|
||||
pp_data->cap[2]->BitField = 0x02
|
||||
pp_data->cap[2]->NextBytePosition = 0x0003
|
||||
pp_data->cap[2]->LinkCollection = 0x0000
|
||||
pp_data->cap[2]->LinkUsagePage = 0x000C
|
||||
pp_data->cap[2]->LinkUsage = 0x0001
|
||||
pp_data->cap[2]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[2]->IsButtonCap = 1
|
||||
pp_data->cap[2]->IsPadding = 0
|
||||
pp_data->cap[2]->IsAbsolute = 1
|
||||
pp_data->cap[2]->IsRange = 0
|
||||
pp_data->cap[2]->IsAlias = 0
|
||||
pp_data->cap[2]->IsStringRange = 0
|
||||
pp_data->cap[2]->IsDesignatorRange = 0
|
||||
pp_data->cap[2]->Reserved1 = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[2]->NotRange.Usage = 0x0000
|
||||
pp_data->cap[2]->NotRange.Reserved1 = 0x0000
|
||||
pp_data->cap[2]->NotRange.StringIndex = 0
|
||||
pp_data->cap[2]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[2]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[2]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[2]->NotRange.DataIndex = 2
|
||||
pp_data->cap[2]->NotRange.Reserved4 = 2
|
||||
pp_data->cap[2]->Button.LogicalMin = 0
|
||||
pp_data->cap[2]->Button.LogicalMax = 0
|
||||
pp_data->cap[2]->Units = 0
|
||||
pp_data->cap[2]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[3]->UsagePage = 0x000C
|
||||
pp_data->cap[3]->ReportID = 0x05
|
||||
pp_data->cap[3]->BitPosition = 0
|
||||
pp_data->cap[3]->BitSize = 8
|
||||
pp_data->cap[3]->ReportCount = 32
|
||||
pp_data->cap[3]->BytePosition = 0x0001
|
||||
pp_data->cap[3]->BitCount = 256
|
||||
pp_data->cap[3]->BitField = 0x02
|
||||
pp_data->cap[3]->NextBytePosition = 0x0021
|
||||
pp_data->cap[3]->LinkCollection = 0x0000
|
||||
pp_data->cap[3]->LinkUsagePage = 0x000C
|
||||
pp_data->cap[3]->LinkUsage = 0x0001
|
||||
pp_data->cap[3]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[3]->IsButtonCap = 0
|
||||
pp_data->cap[3]->IsPadding = 0
|
||||
pp_data->cap[3]->IsAbsolute = 1
|
||||
pp_data->cap[3]->IsRange = 0
|
||||
pp_data->cap[3]->IsAlias = 0
|
||||
pp_data->cap[3]->IsStringRange = 0
|
||||
pp_data->cap[3]->IsDesignatorRange = 0
|
||||
pp_data->cap[3]->Reserved1 = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[3]->NotRange.Usage = 0x0000
|
||||
pp_data->cap[3]->NotRange.Reserved1 = 0x0000
|
||||
pp_data->cap[3]->NotRange.StringIndex = 0
|
||||
pp_data->cap[3]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[3]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[3]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[3]->NotRange.DataIndex = 3
|
||||
pp_data->cap[3]->NotRange.Reserved4 = 3
|
||||
pp_data->cap[3]->NotButton.HasNull = 0
|
||||
pp_data->cap[3]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[3]->NotButton.LogicalMin = 0
|
||||
pp_data->cap[3]->NotButton.LogicalMax = 1
|
||||
pp_data->cap[3]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[3]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[3]->Units = 0
|
||||
pp_data->cap[3]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[4]->UsagePage = 0x000C
|
||||
pp_data->cap[4]->ReportID = 0x07
|
||||
pp_data->cap[4]->BitPosition = 0
|
||||
pp_data->cap[4]->BitSize = 8
|
||||
pp_data->cap[4]->ReportCount = 32
|
||||
pp_data->cap[4]->BytePosition = 0x0001
|
||||
pp_data->cap[4]->BitCount = 256
|
||||
pp_data->cap[4]->BitField = 0x02
|
||||
pp_data->cap[4]->NextBytePosition = 0x0021
|
||||
pp_data->cap[4]->LinkCollection = 0x0000
|
||||
pp_data->cap[4]->LinkUsagePage = 0x000C
|
||||
pp_data->cap[4]->LinkUsage = 0x0001
|
||||
pp_data->cap[4]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[4]->IsButtonCap = 0
|
||||
pp_data->cap[4]->IsPadding = 0
|
||||
pp_data->cap[4]->IsAbsolute = 1
|
||||
pp_data->cap[4]->IsRange = 0
|
||||
pp_data->cap[4]->IsAlias = 0
|
||||
pp_data->cap[4]->IsStringRange = 0
|
||||
pp_data->cap[4]->IsDesignatorRange = 0
|
||||
pp_data->cap[4]->Reserved1 = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[4]->NotRange.Usage = 0x0000
|
||||
pp_data->cap[4]->NotRange.Reserved1 = 0x0000
|
||||
pp_data->cap[4]->NotRange.StringIndex = 0
|
||||
pp_data->cap[4]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[4]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[4]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[4]->NotRange.DataIndex = 4
|
||||
pp_data->cap[4]->NotRange.Reserved4 = 4
|
||||
pp_data->cap[4]->NotButton.HasNull = 0
|
||||
pp_data->cap[4]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[4]->NotButton.LogicalMin = 0
|
||||
pp_data->cap[4]->NotButton.LogicalMax = 1
|
||||
pp_data->cap[4]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[4]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[4]->Units = 0
|
||||
pp_data->cap[4]->UnitsExp = 0
|
||||
|
||||
# Output hid_pp_cap struct:
|
||||
pp_data->cap[5]->UsagePage = 0x000C
|
||||
pp_data->cap[5]->ReportID = 0x04
|
||||
pp_data->cap[5]->BitPosition = 0
|
||||
pp_data->cap[5]->BitSize = 8
|
||||
pp_data->cap[5]->ReportCount = 36
|
||||
pp_data->cap[5]->BytePosition = 0x0001
|
||||
pp_data->cap[5]->BitCount = 288
|
||||
pp_data->cap[5]->BitField = 0x02
|
||||
pp_data->cap[5]->NextBytePosition = 0x0025
|
||||
pp_data->cap[5]->LinkCollection = 0x0000
|
||||
pp_data->cap[5]->LinkUsagePage = 0x000C
|
||||
pp_data->cap[5]->LinkUsage = 0x0001
|
||||
pp_data->cap[5]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[5]->IsButtonCap = 0
|
||||
pp_data->cap[5]->IsPadding = 0
|
||||
pp_data->cap[5]->IsAbsolute = 1
|
||||
pp_data->cap[5]->IsRange = 0
|
||||
pp_data->cap[5]->IsAlias = 0
|
||||
pp_data->cap[5]->IsStringRange = 0
|
||||
pp_data->cap[5]->IsDesignatorRange = 0
|
||||
pp_data->cap[5]->Reserved1 = 0x000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[5]->NotRange.Usage = 0x0000
|
||||
pp_data->cap[5]->NotRange.Reserved1 = 0x0000
|
||||
pp_data->cap[5]->NotRange.StringIndex = 0
|
||||
pp_data->cap[5]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[5]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[5]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[5]->NotRange.DataIndex = 0
|
||||
pp_data->cap[5]->NotRange.Reserved4 = 0
|
||||
pp_data->cap[5]->NotButton.HasNull = 0
|
||||
pp_data->cap[5]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[5]->NotButton.LogicalMin = 0
|
||||
pp_data->cap[5]->NotButton.LogicalMax = 1
|
||||
pp_data->cap[5]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[5]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[5]->Units = 0
|
||||
pp_data->cap[5]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[6]->UsagePage = 0x000C
|
||||
pp_data->cap[6]->ReportID = 0x06
|
||||
pp_data->cap[6]->BitPosition = 0
|
||||
pp_data->cap[6]->BitSize = 8
|
||||
pp_data->cap[6]->ReportCount = 36
|
||||
pp_data->cap[6]->BytePosition = 0x0001
|
||||
pp_data->cap[6]->BitCount = 288
|
||||
pp_data->cap[6]->BitField = 0x02
|
||||
pp_data->cap[6]->NextBytePosition = 0x0025
|
||||
pp_data->cap[6]->LinkCollection = 0x0000
|
||||
pp_data->cap[6]->LinkUsagePage = 0x000C
|
||||
pp_data->cap[6]->LinkUsage = 0x0001
|
||||
pp_data->cap[6]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[6]->IsButtonCap = 0
|
||||
pp_data->cap[6]->IsPadding = 0
|
||||
pp_data->cap[6]->IsAbsolute = 1
|
||||
pp_data->cap[6]->IsRange = 0
|
||||
pp_data->cap[6]->IsAlias = 0
|
||||
pp_data->cap[6]->IsStringRange = 0
|
||||
pp_data->cap[6]->IsDesignatorRange = 0
|
||||
pp_data->cap[6]->Reserved1 = 0x000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[6]->NotRange.Usage = 0x0000
|
||||
pp_data->cap[6]->NotRange.Reserved1 = 0x0000
|
||||
pp_data->cap[6]->NotRange.StringIndex = 0
|
||||
pp_data->cap[6]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[6]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[6]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[6]->NotRange.DataIndex = 1
|
||||
pp_data->cap[6]->NotRange.Reserved4 = 1
|
||||
pp_data->cap[6]->NotButton.HasNull = 0
|
||||
pp_data->cap[6]->NotButton.Reserved4 = 0x000000
|
||||
pp_data->cap[6]->NotButton.LogicalMin = 0
|
||||
pp_data->cap[6]->NotButton.LogicalMax = 1
|
||||
pp_data->cap[6]->NotButton.PhysicalMin = 0
|
||||
pp_data->cap[6]->NotButton.PhysicalMax = 0
|
||||
pp_data->cap[6]->Units = 0
|
||||
pp_data->cap[6]->UnitsExp = 0
|
||||
|
||||
# Feature hid_pp_cap struct:
|
||||
# Link Collections:
|
||||
pp_data->LinkCollectionArray[0]->LinkUsage = 0x0001
|
||||
pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x000C
|
||||
pp_data->LinkCollectionArray[0]->Parent = 0
|
||||
pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[0]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[0]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[0]->CollectionType = 1
|
||||
pp_data->LinkCollectionArray[0]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
|
||||
@@ -0,0 +1,10 @@
|
||||
0x05, 0x0C, 0x09, 0x01, 0xA1, 0x01, 0x85, 0x01, 0x09, 0xE9,
|
||||
0x09, 0xEA, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x02,
|
||||
0x81, 0x06, 0x75, 0x06, 0x95, 0x01, 0x81, 0x03, 0x85, 0x02,
|
||||
0x09, 0x00, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x10,
|
||||
0x81, 0x02, 0x85, 0x05, 0x09, 0x00, 0x15, 0x00, 0x25, 0x01,
|
||||
0x75, 0x08, 0x95, 0x20, 0x81, 0x02, 0x85, 0x07, 0x09, 0x00,
|
||||
0x15, 0x00, 0x25, 0x01, 0x75, 0x08, 0x95, 0x20, 0x81, 0x02,
|
||||
0x85, 0x04, 0x09, 0x00, 0x15, 0x00, 0x25, 0x01, 0x75, 0x08,
|
||||
0x95, 0x24, 0x91, 0x02, 0x85, 0x06, 0x09, 0x00, 0x15, 0x00,
|
||||
0x25, 0x01, 0x75, 0x08, 0x95, 0x24, 0x91, 0x02, 0xC0,
|
||||
@@ -0,0 +1,47 @@
|
||||
macOS USB Prober about 0x047F/0xC056 "Plantronics Blackwire 3220 Series"
|
||||
05 0C 09 01 A1 01 85 01 15 00 25 01 09 E9 09 EA
|
||||
75 01 95 02 81 06 95 06 81 01 85 02 05 0C 09 00
|
||||
95 10 81 02 85 04 09 00 75 08 95 24 91 02 85 05
|
||||
09 00 95 20 81 02 85 06 09 00 95 24 91 02 85 07
|
||||
09 00 95 20 81 02 C0
|
||||
|
||||
# Parser output:
|
||||
|
||||
0x05, 0x0C, // Usage Page (Consumer)
|
||||
0x09, 0x01, // Usage (Consumer Control)
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x85, 0x01, // Report ID (1)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x25, 0x01, // Logical Maximum (1)
|
||||
0x09, 0xE9, // Usage (Volume Increment)
|
||||
0x09, 0xEA, // Usage (Volume Decrement)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x95, 0x02, // Report Count (2)
|
||||
0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x95, 0x06, // Report Count (6)
|
||||
0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x85, 0x02, // Report ID (2)
|
||||
0x05, 0x0C, // Usage Page (Consumer)
|
||||
0x09, 0x00, // Usage (Unassigned)
|
||||
0x95, 0x10, // Report Count (16)
|
||||
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x85, 0x04, // Report ID (4)
|
||||
0x09, 0x00, // Usage (Unassigned)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x95, 0x24, // Report Count (36)
|
||||
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0x85, 0x05, // Report ID (5)
|
||||
0x09, 0x00, // Usage (Unassigned)
|
||||
0x95, 0x20, // Report Count (32)
|
||||
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x85, 0x06, // Report ID (6)
|
||||
0x09, 0x00, // Usage (Unassigned)
|
||||
0x95, 0x24, // Report Count (36)
|
||||
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0x85, 0x07, // Report ID (7)
|
||||
0x09, 0x00, // Usage (Unassigned)
|
||||
0x95, 0x20, // Report Count (32)
|
||||
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0xC0, // End Collection
|
||||
|
||||
// 71 bytes
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,24 @@
|
||||
0x06, 0xA0, 0xFF, 0x09, 0x03, 0xA1, 0x01, 0x85, 0x03, 0x09,
|
||||
0x30, 0x15, 0x00, 0x25, 0x01, 0x75, 0x08, 0x95, 0x20, 0x81,
|
||||
0x02, 0x85, 0x14, 0x09, 0xB1, 0x09, 0xB2, 0x09, 0xB5, 0x09,
|
||||
0xB7, 0x09, 0xB3, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95,
|
||||
0x05, 0x81, 0x06, 0x75, 0x03, 0x95, 0x01, 0x81, 0x03, 0x85,
|
||||
0x15, 0x09, 0x8C, 0x15, 0x00, 0x27, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0x75, 0x10, 0x95, 0x01, 0x81, 0x22, 0x85, 0x1F, 0x09, 0x9C,
|
||||
0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x01, 0x81, 0x06,
|
||||
0x75, 0x07, 0x95, 0x01, 0x81, 0x03, 0x85, 0x03, 0x09, 0x30,
|
||||
0x15, 0x00, 0x25, 0x01, 0x75, 0x08, 0x95, 0x20, 0x91, 0x02,
|
||||
0x85, 0x19, 0x09, 0x8D, 0x09, 0x8F, 0x09, 0x9E, 0x09, 0xDC,
|
||||
0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x04, 0x91, 0x22,
|
||||
0x09, 0xD2, 0x09, 0xD9, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01,
|
||||
0x95, 0x02, 0x91, 0x06, 0x75, 0x02, 0x95, 0x01, 0x91, 0x03,
|
||||
0x85, 0x1A, 0x09, 0xB5, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01,
|
||||
0x95, 0x01, 0x91, 0x22, 0x75, 0x07, 0x95, 0x01, 0x91, 0x03,
|
||||
0x85, 0x1B, 0x09, 0xCF, 0x09, 0xB5, 0x15, 0x00, 0x25, 0x01,
|
||||
0x75, 0x01, 0x95, 0x02, 0xB1, 0x22, 0x09, 0xDE, 0x15, 0x00,
|
||||
0x25, 0x01, 0x75, 0x01, 0x95, 0x01, 0xB1, 0x23, 0x09, 0xD8,
|
||||
0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x01, 0xB1, 0x22,
|
||||
0x75, 0x04, 0x95, 0x01, 0xB1, 0x03, 0x09, 0x09, 0x09, 0x17,
|
||||
0x09, 0x18, 0x09, 0x1E, 0x09, 0x20, 0x09, 0x2A, 0x15, 0x00,
|
||||
0x25, 0x01, 0x75, 0x01, 0x95, 0x06, 0xB1, 0x22, 0x75, 0x02,
|
||||
0x95, 0x01, 0xB1, 0x03, 0xC0,
|
||||
@@ -0,0 +1,113 @@
|
||||
macOS USB Prober about 0x047F/0xC056 "Plantronics Blackwire 3220 Series"
|
||||
06 A0 FF 09 03 A1 01 85 03 09 30 75
|
||||
08 95 20 91 02 85 03 09 30 75 08 95 20 81 02 85
|
||||
14 09 B1 09 B2 09 B5 09 B7 09 B3 15 00 25 01 75
|
||||
01 95 05 81 06 95 03 81 01 85 15 09 8C 15 00 27
|
||||
FF FF 00 00 75 10 95 01 81 22 85 19 09 8D 09 8F
|
||||
09 9E 09 DC 15 00 25 01 75 01 95 04 91 22 09 D2
|
||||
09 D9 15 00 25 01 75 01 95 02 91 06 95 02 91 01
|
||||
85 1A 09 B5 15 00 25 01 75 01 95 01 91 22 95 07
|
||||
91 01 85 1B 09 CF 09 B5 75 01 95 02 B1 22 09 DE
|
||||
75 01 95 01 B1 23 09 D8 95 01 B1 22 95 04 B1 01
|
||||
09 09 09 17 09 18 09 1E 09 20 09 2A 75 01 95 06
|
||||
B1 22 95 02 B1 01 85 1F 09 9C 75 01 95 01 81 06
|
||||
95 07 81 01 C0
|
||||
|
||||
Parser output:
|
||||
0x06, 0xA0, 0xFF, // Usage Page (Vendor Defined 0xFFA0)
|
||||
0x09, 0x03, // Usage (0x03)
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x85, 0x03, // Report ID (3)
|
||||
0x09, 0x30, // Usage (0x30)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x95, 0x20, // Report Count (32)
|
||||
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0x85, 0x03, // Report ID (3)
|
||||
0x09, 0x30, // Usage (0x30)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x95, 0x20, // Report Count (32)
|
||||
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x85, 0x14, // Report ID (20)
|
||||
0x09, 0xB1, // Usage (0xB1)
|
||||
0x09, 0xB2, // Usage (0xB2)
|
||||
0x09, 0xB5, // Usage (0xB5)
|
||||
0x09, 0xB7, // Usage (0xB7)
|
||||
0x09, 0xB3, // Usage (0xB3)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x25, 0x01, // Logical Maximum (1)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x95, 0x05, // Report Count (5)
|
||||
0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x95, 0x03, // Report Count (3)
|
||||
0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x85, 0x15, // Report ID (21)
|
||||
0x09, 0x8C, // Usage (0x8C)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x27, 0xFF, 0xFF, 0x00, 0x00, // Logical Maximum (65534)
|
||||
0x75, 0x10, // Report Size (16)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x81, 0x22, // Input (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position)
|
||||
0x85, 0x19, // Report ID (25)
|
||||
0x09, 0x8D, // Usage (0x8D)
|
||||
0x09, 0x8F, // Usage (0x8F)
|
||||
0x09, 0x9E, // Usage (0x9E)
|
||||
0x09, 0xDC, // Usage (0xDC)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x25, 0x01, // Logical Maximum (1)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x95, 0x04, // Report Count (4)
|
||||
0x91, 0x22, // Output (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
|
||||
0x09, 0xD2, // Usage (0xD2)
|
||||
0x09, 0xD9, // Usage (0xD9)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x25, 0x01, // Logical Maximum (1)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x95, 0x02, // Report Count (2)
|
||||
0x91, 0x06, // Output (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0x95, 0x02, // Report Count (2)
|
||||
0x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0x85, 0x1A, // Report ID (26)
|
||||
0x09, 0xB5, // Usage (0xB5)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x25, 0x01, // Logical Maximum (1)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x91, 0x22, // Output (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
|
||||
0x95, 0x07, // Report Count (7)
|
||||
0x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0x85, 0x1B, // Report ID (27)
|
||||
0x09, 0xCF, // Usage (0xCF)
|
||||
0x09, 0xB5, // Usage (0xB5)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x95, 0x02, // Report Count (2)
|
||||
0xB1, 0x22, // Feature (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
|
||||
0x09, 0xDE, // Usage (0xDE)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0xB1, 0x23, // Feature (Const,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
|
||||
0x09, 0xD8, // Usage (0xD8)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0xB1, 0x22, // Feature (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
|
||||
0x95, 0x04, // Report Count (4)
|
||||
0xB1, 0x01, // Feature (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0x09, 0x09, // Usage (0x09)
|
||||
0x09, 0x17, // Usage (0x17)
|
||||
0x09, 0x18, // Usage (0x18)
|
||||
0x09, 0x1E, // Usage (0x1E)
|
||||
0x09, 0x20, // Usage (0x20)
|
||||
0x09, 0x2A, // Usage (0x2A)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x95, 0x06, // Report Count (6)
|
||||
0xB1, 0x22, // Feature (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
|
||||
0x95, 0x02, // Report Count (2)
|
||||
0xB1, 0x01, // Feature (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0x85, 0x1F, // Report ID (31)
|
||||
0x09, 0x9C, // Usage (0x9C)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x95, 0x07, // Report Count (7)
|
||||
0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0xC0, // End Collection
|
||||
|
||||
// 193 bytes
|
||||
@@ -0,0 +1,461 @@
|
||||
# HIDAPI device info struct:
|
||||
dev->vendor_id = 0x047F
|
||||
dev->product_id = 0xC056
|
||||
dev->manufacturer_string = "Plantronics"
|
||||
dev->product_string = "Plantronics Blackwire 3220 Series"
|
||||
dev->release_number = 0x0210
|
||||
dev->interface_number = 3
|
||||
dev->usage = 0x0005
|
||||
dev->usage_page = 0x000B
|
||||
dev->path = "\\?\hid#vid_047f&pid_c056&mi_03&col02#f&39e6f119&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}"
|
||||
|
||||
# Preparsed Data struct:
|
||||
pp_data->MagicKey = 0x48696450204B4452
|
||||
pp_data->Usage = 0x0005
|
||||
pp_data->UsagePage = 0x000B
|
||||
pp_data->Reserved = 0x00000000
|
||||
# Input caps_info struct:
|
||||
pp_data->caps_info[0]->FirstCap = 0
|
||||
pp_data->caps_info[0]->LastCap = 3
|
||||
pp_data->caps_info[0]->NumberOfCaps = 3
|
||||
pp_data->caps_info[0]->ReportByteLength = 2
|
||||
# Output caps_info struct:
|
||||
pp_data->caps_info[1]->FirstCap = 3
|
||||
pp_data->caps_info[1]->LastCap = 9
|
||||
pp_data->caps_info[1]->NumberOfCaps = 6
|
||||
pp_data->caps_info[1]->ReportByteLength = 2
|
||||
# Feature caps_info struct:
|
||||
pp_data->caps_info[2]->FirstCap = 9
|
||||
pp_data->caps_info[2]->LastCap = 9
|
||||
pp_data->caps_info[2]->NumberOfCaps = 0
|
||||
pp_data->caps_info[2]->ReportByteLength = 0
|
||||
# LinkCollectionArray Offset & Size:
|
||||
pp_data->FirstByteOfLinkCollectionArray = 0x03A8
|
||||
pp_data->NumberLinkCollectionNodes = 1
|
||||
# Input hid_pp_cap struct:
|
||||
pp_data->cap[0]->UsagePage = 0x000B
|
||||
pp_data->cap[0]->ReportID = 0x08
|
||||
pp_data->cap[0]->BitPosition = 0
|
||||
pp_data->cap[0]->BitSize = 1
|
||||
pp_data->cap[0]->ReportCount = 1
|
||||
pp_data->cap[0]->BytePosition = 0x0001
|
||||
pp_data->cap[0]->BitCount = 1
|
||||
pp_data->cap[0]->BitField = 0x06
|
||||
pp_data->cap[0]->NextBytePosition = 0x0002
|
||||
pp_data->cap[0]->LinkCollection = 0x0000
|
||||
pp_data->cap[0]->LinkUsagePage = 0x000B
|
||||
pp_data->cap[0]->LinkUsage = 0x0005
|
||||
pp_data->cap[0]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[0]->IsButtonCap = 1
|
||||
pp_data->cap[0]->IsPadding = 0
|
||||
pp_data->cap[0]->IsAbsolute = 0
|
||||
pp_data->cap[0]->IsRange = 0
|
||||
pp_data->cap[0]->IsAlias = 0
|
||||
pp_data->cap[0]->IsStringRange = 0
|
||||
pp_data->cap[0]->IsDesignatorRange = 0
|
||||
pp_data->cap[0]->Reserved1 = 0x000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[0]->NotRange.Usage = 0x002F
|
||||
pp_data->cap[0]->NotRange.Reserved1 = 0x002F
|
||||
pp_data->cap[0]->NotRange.StringIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[0]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[0]->NotRange.DataIndex = 0
|
||||
pp_data->cap[0]->NotRange.Reserved4 = 0
|
||||
pp_data->cap[0]->Button.LogicalMin = 0
|
||||
pp_data->cap[0]->Button.LogicalMax = 0
|
||||
pp_data->cap[0]->Units = 0
|
||||
pp_data->cap[0]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[1]->UsagePage = 0x000B
|
||||
pp_data->cap[1]->ReportID = 0x08
|
||||
pp_data->cap[1]->BitPosition = 2
|
||||
pp_data->cap[1]->BitSize = 1
|
||||
pp_data->cap[1]->ReportCount = 1
|
||||
pp_data->cap[1]->BytePosition = 0x0001
|
||||
pp_data->cap[1]->BitCount = 1
|
||||
pp_data->cap[1]->BitField = 0x22
|
||||
pp_data->cap[1]->NextBytePosition = 0x0002
|
||||
pp_data->cap[1]->LinkCollection = 0x0000
|
||||
pp_data->cap[1]->LinkUsagePage = 0x000B
|
||||
pp_data->cap[1]->LinkUsage = 0x0005
|
||||
pp_data->cap[1]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[1]->IsButtonCap = 1
|
||||
pp_data->cap[1]->IsPadding = 0
|
||||
pp_data->cap[1]->IsAbsolute = 1
|
||||
pp_data->cap[1]->IsRange = 0
|
||||
pp_data->cap[1]->IsAlias = 0
|
||||
pp_data->cap[1]->IsStringRange = 0
|
||||
pp_data->cap[1]->IsDesignatorRange = 0
|
||||
pp_data->cap[1]->Reserved1 = 0x000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[1]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[1]->NotRange.Usage = 0x0021
|
||||
pp_data->cap[1]->NotRange.Reserved1 = 0x0021
|
||||
pp_data->cap[1]->NotRange.StringIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[1]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[1]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[1]->NotRange.DataIndex = 1
|
||||
pp_data->cap[1]->NotRange.Reserved4 = 1
|
||||
pp_data->cap[1]->Button.LogicalMin = 0
|
||||
pp_data->cap[1]->Button.LogicalMax = 0
|
||||
pp_data->cap[1]->Units = 0
|
||||
pp_data->cap[1]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[2]->UsagePage = 0x000B
|
||||
pp_data->cap[2]->ReportID = 0x08
|
||||
pp_data->cap[2]->BitPosition = 1
|
||||
pp_data->cap[2]->BitSize = 1
|
||||
pp_data->cap[2]->ReportCount = 1
|
||||
pp_data->cap[2]->BytePosition = 0x0001
|
||||
pp_data->cap[2]->BitCount = 1
|
||||
pp_data->cap[2]->BitField = 0x22
|
||||
pp_data->cap[2]->NextBytePosition = 0x0002
|
||||
pp_data->cap[2]->LinkCollection = 0x0000
|
||||
pp_data->cap[2]->LinkUsagePage = 0x000B
|
||||
pp_data->cap[2]->LinkUsage = 0x0005
|
||||
pp_data->cap[2]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[2]->IsButtonCap = 1
|
||||
pp_data->cap[2]->IsPadding = 0
|
||||
pp_data->cap[2]->IsAbsolute = 1
|
||||
pp_data->cap[2]->IsRange = 0
|
||||
pp_data->cap[2]->IsAlias = 0
|
||||
pp_data->cap[2]->IsStringRange = 0
|
||||
pp_data->cap[2]->IsDesignatorRange = 0
|
||||
pp_data->cap[2]->Reserved1 = 0x000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[2]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[2]->NotRange.Usage = 0x0020
|
||||
pp_data->cap[2]->NotRange.Reserved1 = 0x0020
|
||||
pp_data->cap[2]->NotRange.StringIndex = 0
|
||||
pp_data->cap[2]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[2]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[2]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[2]->NotRange.DataIndex = 2
|
||||
pp_data->cap[2]->NotRange.Reserved4 = 2
|
||||
pp_data->cap[2]->Button.LogicalMin = 0
|
||||
pp_data->cap[2]->Button.LogicalMax = 0
|
||||
pp_data->cap[2]->Units = 0
|
||||
pp_data->cap[2]->UnitsExp = 0
|
||||
|
||||
# Output hid_pp_cap struct:
|
||||
pp_data->cap[3]->UsagePage = 0x0008
|
||||
pp_data->cap[3]->ReportID = 0x09
|
||||
pp_data->cap[3]->BitPosition = 0
|
||||
pp_data->cap[3]->BitSize = 1
|
||||
pp_data->cap[3]->ReportCount = 1
|
||||
pp_data->cap[3]->BytePosition = 0x0001
|
||||
pp_data->cap[3]->BitCount = 1
|
||||
pp_data->cap[3]->BitField = 0x22
|
||||
pp_data->cap[3]->NextBytePosition = 0x0002
|
||||
pp_data->cap[3]->LinkCollection = 0x0000
|
||||
pp_data->cap[3]->LinkUsagePage = 0x000B
|
||||
pp_data->cap[3]->LinkUsage = 0x0005
|
||||
pp_data->cap[3]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[3]->IsButtonCap = 1
|
||||
pp_data->cap[3]->IsPadding = 0
|
||||
pp_data->cap[3]->IsAbsolute = 1
|
||||
pp_data->cap[3]->IsRange = 0
|
||||
pp_data->cap[3]->IsAlias = 0
|
||||
pp_data->cap[3]->IsStringRange = 0
|
||||
pp_data->cap[3]->IsDesignatorRange = 0
|
||||
pp_data->cap[3]->Reserved1 = 0x000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[3]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[3]->NotRange.Usage = 0x0009
|
||||
pp_data->cap[3]->NotRange.Reserved1 = 0x0009
|
||||
pp_data->cap[3]->NotRange.StringIndex = 0
|
||||
pp_data->cap[3]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[3]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[3]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[3]->NotRange.DataIndex = 0
|
||||
pp_data->cap[3]->NotRange.Reserved4 = 0
|
||||
pp_data->cap[3]->Button.LogicalMin = 0
|
||||
pp_data->cap[3]->Button.LogicalMax = 0
|
||||
pp_data->cap[3]->Units = 0
|
||||
pp_data->cap[3]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[4]->UsagePage = 0x0008
|
||||
pp_data->cap[4]->ReportID = 0x17
|
||||
pp_data->cap[4]->BitPosition = 0
|
||||
pp_data->cap[4]->BitSize = 1
|
||||
pp_data->cap[4]->ReportCount = 1
|
||||
pp_data->cap[4]->BytePosition = 0x0001
|
||||
pp_data->cap[4]->BitCount = 1
|
||||
pp_data->cap[4]->BitField = 0x22
|
||||
pp_data->cap[4]->NextBytePosition = 0x0002
|
||||
pp_data->cap[4]->LinkCollection = 0x0000
|
||||
pp_data->cap[4]->LinkUsagePage = 0x000B
|
||||
pp_data->cap[4]->LinkUsage = 0x0005
|
||||
pp_data->cap[4]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[4]->IsButtonCap = 1
|
||||
pp_data->cap[4]->IsPadding = 0
|
||||
pp_data->cap[4]->IsAbsolute = 1
|
||||
pp_data->cap[4]->IsRange = 0
|
||||
pp_data->cap[4]->IsAlias = 0
|
||||
pp_data->cap[4]->IsStringRange = 0
|
||||
pp_data->cap[4]->IsDesignatorRange = 0
|
||||
pp_data->cap[4]->Reserved1 = 0x000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[4]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[4]->NotRange.Usage = 0x0017
|
||||
pp_data->cap[4]->NotRange.Reserved1 = 0x0017
|
||||
pp_data->cap[4]->NotRange.StringIndex = 0
|
||||
pp_data->cap[4]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[4]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[4]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[4]->NotRange.DataIndex = 1
|
||||
pp_data->cap[4]->NotRange.Reserved4 = 1
|
||||
pp_data->cap[4]->Button.LogicalMin = 0
|
||||
pp_data->cap[4]->Button.LogicalMax = 0
|
||||
pp_data->cap[4]->Units = 0
|
||||
pp_data->cap[4]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[5]->UsagePage = 0x0008
|
||||
pp_data->cap[5]->ReportID = 0x18
|
||||
pp_data->cap[5]->BitPosition = 0
|
||||
pp_data->cap[5]->BitSize = 1
|
||||
pp_data->cap[5]->ReportCount = 1
|
||||
pp_data->cap[5]->BytePosition = 0x0001
|
||||
pp_data->cap[5]->BitCount = 1
|
||||
pp_data->cap[5]->BitField = 0x22
|
||||
pp_data->cap[5]->NextBytePosition = 0x0002
|
||||
pp_data->cap[5]->LinkCollection = 0x0000
|
||||
pp_data->cap[5]->LinkUsagePage = 0x000B
|
||||
pp_data->cap[5]->LinkUsage = 0x0005
|
||||
pp_data->cap[5]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[5]->IsButtonCap = 1
|
||||
pp_data->cap[5]->IsPadding = 0
|
||||
pp_data->cap[5]->IsAbsolute = 1
|
||||
pp_data->cap[5]->IsRange = 0
|
||||
pp_data->cap[5]->IsAlias = 0
|
||||
pp_data->cap[5]->IsStringRange = 0
|
||||
pp_data->cap[5]->IsDesignatorRange = 0
|
||||
pp_data->cap[5]->Reserved1 = 0x000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[5]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[5]->NotRange.Usage = 0x0018
|
||||
pp_data->cap[5]->NotRange.Reserved1 = 0x0018
|
||||
pp_data->cap[5]->NotRange.StringIndex = 0
|
||||
pp_data->cap[5]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[5]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[5]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[5]->NotRange.DataIndex = 2
|
||||
pp_data->cap[5]->NotRange.Reserved4 = 2
|
||||
pp_data->cap[5]->Button.LogicalMin = 0
|
||||
pp_data->cap[5]->Button.LogicalMax = 0
|
||||
pp_data->cap[5]->Units = 0
|
||||
pp_data->cap[5]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[6]->UsagePage = 0x0008
|
||||
pp_data->cap[6]->ReportID = 0x1E
|
||||
pp_data->cap[6]->BitPosition = 0
|
||||
pp_data->cap[6]->BitSize = 1
|
||||
pp_data->cap[6]->ReportCount = 1
|
||||
pp_data->cap[6]->BytePosition = 0x0001
|
||||
pp_data->cap[6]->BitCount = 1
|
||||
pp_data->cap[6]->BitField = 0x22
|
||||
pp_data->cap[6]->NextBytePosition = 0x0002
|
||||
pp_data->cap[6]->LinkCollection = 0x0000
|
||||
pp_data->cap[6]->LinkUsagePage = 0x000B
|
||||
pp_data->cap[6]->LinkUsage = 0x0005
|
||||
pp_data->cap[6]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[6]->IsButtonCap = 1
|
||||
pp_data->cap[6]->IsPadding = 0
|
||||
pp_data->cap[6]->IsAbsolute = 1
|
||||
pp_data->cap[6]->IsRange = 0
|
||||
pp_data->cap[6]->IsAlias = 0
|
||||
pp_data->cap[6]->IsStringRange = 0
|
||||
pp_data->cap[6]->IsDesignatorRange = 0
|
||||
pp_data->cap[6]->Reserved1 = 0x000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[6]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[6]->NotRange.Usage = 0x001E
|
||||
pp_data->cap[6]->NotRange.Reserved1 = 0x001E
|
||||
pp_data->cap[6]->NotRange.StringIndex = 0
|
||||
pp_data->cap[6]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[6]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[6]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[6]->NotRange.DataIndex = 3
|
||||
pp_data->cap[6]->NotRange.Reserved4 = 3
|
||||
pp_data->cap[6]->Button.LogicalMin = 0
|
||||
pp_data->cap[6]->Button.LogicalMax = 0
|
||||
pp_data->cap[6]->Units = 0
|
||||
pp_data->cap[6]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[7]->UsagePage = 0x0008
|
||||
pp_data->cap[7]->ReportID = 0x20
|
||||
pp_data->cap[7]->BitPosition = 0
|
||||
pp_data->cap[7]->BitSize = 1
|
||||
pp_data->cap[7]->ReportCount = 1
|
||||
pp_data->cap[7]->BytePosition = 0x0001
|
||||
pp_data->cap[7]->BitCount = 1
|
||||
pp_data->cap[7]->BitField = 0x22
|
||||
pp_data->cap[7]->NextBytePosition = 0x0002
|
||||
pp_data->cap[7]->LinkCollection = 0x0000
|
||||
pp_data->cap[7]->LinkUsagePage = 0x000B
|
||||
pp_data->cap[7]->LinkUsage = 0x0005
|
||||
pp_data->cap[7]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[7]->IsButtonCap = 1
|
||||
pp_data->cap[7]->IsPadding = 0
|
||||
pp_data->cap[7]->IsAbsolute = 1
|
||||
pp_data->cap[7]->IsRange = 0
|
||||
pp_data->cap[7]->IsAlias = 0
|
||||
pp_data->cap[7]->IsStringRange = 0
|
||||
pp_data->cap[7]->IsDesignatorRange = 0
|
||||
pp_data->cap[7]->Reserved1 = 0x000
|
||||
pp_data->cap[7]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[7]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[7]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[7]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[7]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[7]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[7]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[7]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[7]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[7]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[7]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[7]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[7]->NotRange.Usage = 0x0020
|
||||
pp_data->cap[7]->NotRange.Reserved1 = 0x0020
|
||||
pp_data->cap[7]->NotRange.StringIndex = 0
|
||||
pp_data->cap[7]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[7]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[7]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[7]->NotRange.DataIndex = 4
|
||||
pp_data->cap[7]->NotRange.Reserved4 = 4
|
||||
pp_data->cap[7]->Button.LogicalMin = 0
|
||||
pp_data->cap[7]->Button.LogicalMax = 0
|
||||
pp_data->cap[7]->Units = 0
|
||||
pp_data->cap[7]->UnitsExp = 0
|
||||
|
||||
pp_data->cap[8]->UsagePage = 0x0008
|
||||
pp_data->cap[8]->ReportID = 0x2A
|
||||
pp_data->cap[8]->BitPosition = 0
|
||||
pp_data->cap[8]->BitSize = 1
|
||||
pp_data->cap[8]->ReportCount = 1
|
||||
pp_data->cap[8]->BytePosition = 0x0001
|
||||
pp_data->cap[8]->BitCount = 1
|
||||
pp_data->cap[8]->BitField = 0x22
|
||||
pp_data->cap[8]->NextBytePosition = 0x0002
|
||||
pp_data->cap[8]->LinkCollection = 0x0000
|
||||
pp_data->cap[8]->LinkUsagePage = 0x000B
|
||||
pp_data->cap[8]->LinkUsage = 0x0005
|
||||
pp_data->cap[8]->IsMultipleItemsForArray = 0
|
||||
pp_data->cap[8]->IsButtonCap = 1
|
||||
pp_data->cap[8]->IsPadding = 0
|
||||
pp_data->cap[8]->IsAbsolute = 1
|
||||
pp_data->cap[8]->IsRange = 0
|
||||
pp_data->cap[8]->IsAlias = 0
|
||||
pp_data->cap[8]->IsStringRange = 0
|
||||
pp_data->cap[8]->IsDesignatorRange = 0
|
||||
pp_data->cap[8]->Reserved1 = 0x000
|
||||
pp_data->cap[8]->pp_cap->UnknownTokens[0].Token = 0x00
|
||||
pp_data->cap[8]->pp_cap->UnknownTokens[0].Reserved = 0x000000
|
||||
pp_data->cap[8]->pp_cap->UnknownTokens[0].BitField = 0x00000000
|
||||
pp_data->cap[8]->pp_cap->UnknownTokens[1].Token = 0x00
|
||||
pp_data->cap[8]->pp_cap->UnknownTokens[1].Reserved = 0x000000
|
||||
pp_data->cap[8]->pp_cap->UnknownTokens[1].BitField = 0x00000000
|
||||
pp_data->cap[8]->pp_cap->UnknownTokens[2].Token = 0x00
|
||||
pp_data->cap[8]->pp_cap->UnknownTokens[2].Reserved = 0x000000
|
||||
pp_data->cap[8]->pp_cap->UnknownTokens[2].BitField = 0x00000000
|
||||
pp_data->cap[8]->pp_cap->UnknownTokens[3].Token = 0x00
|
||||
pp_data->cap[8]->pp_cap->UnknownTokens[3].Reserved = 0x000000
|
||||
pp_data->cap[8]->pp_cap->UnknownTokens[3].BitField = 0x00000000
|
||||
pp_data->cap[8]->NotRange.Usage = 0x002A
|
||||
pp_data->cap[8]->NotRange.Reserved1 = 0x002A
|
||||
pp_data->cap[8]->NotRange.StringIndex = 0
|
||||
pp_data->cap[8]->NotRange.Reserved2 = 0
|
||||
pp_data->cap[8]->NotRange.DesignatorIndex = 0
|
||||
pp_data->cap[8]->NotRange.Reserved3 = 0
|
||||
pp_data->cap[8]->NotRange.DataIndex = 5
|
||||
pp_data->cap[8]->NotRange.Reserved4 = 5
|
||||
pp_data->cap[8]->Button.LogicalMin = 0
|
||||
pp_data->cap[8]->Button.LogicalMax = 0
|
||||
pp_data->cap[8]->Units = 0
|
||||
pp_data->cap[8]->UnitsExp = 0
|
||||
|
||||
# Feature hid_pp_cap struct:
|
||||
# Link Collections:
|
||||
pp_data->LinkCollectionArray[0]->LinkUsage = 0x0005
|
||||
pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x000B
|
||||
pp_data->LinkCollectionArray[0]->Parent = 0
|
||||
pp_data->LinkCollectionArray[0]->NumberOfChildren = 0
|
||||
pp_data->LinkCollectionArray[0]->NextSibling = 0
|
||||
pp_data->LinkCollectionArray[0]->FirstChild = 0
|
||||
pp_data->LinkCollectionArray[0]->CollectionType = 1
|
||||
pp_data->LinkCollectionArray[0]->IsAlias = 0
|
||||
pp_data->LinkCollectionArray[0]->Reserved = 0x00000000
|
||||
@@ -0,0 +1,17 @@
|
||||
0x05, 0x0B, 0x09, 0x05, 0xA1, 0x01, 0x85, 0x08, 0x09, 0x2F,
|
||||
0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x01, 0x81, 0x06,
|
||||
0x09, 0x20, 0x09, 0x21, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01,
|
||||
0x95, 0x02, 0x81, 0x22, 0x75, 0x05, 0x95, 0x01, 0x81, 0x03,
|
||||
0x85, 0x09, 0x05, 0x08, 0x09, 0x09, 0x15, 0x00, 0x25, 0x01,
|
||||
0x75, 0x01, 0x95, 0x01, 0x91, 0x22, 0x75, 0x07, 0x95, 0x01,
|
||||
0x91, 0x03, 0x85, 0x17, 0x09, 0x17, 0x15, 0x00, 0x25, 0x01,
|
||||
0x75, 0x01, 0x95, 0x01, 0x91, 0x22, 0x75, 0x07, 0x95, 0x01,
|
||||
0x91, 0x03, 0x85, 0x18, 0x09, 0x18, 0x15, 0x00, 0x25, 0x01,
|
||||
0x75, 0x01, 0x95, 0x01, 0x91, 0x22, 0x75, 0x07, 0x95, 0x01,
|
||||
0x91, 0x03, 0x85, 0x1E, 0x09, 0x1E, 0x15, 0x00, 0x25, 0x01,
|
||||
0x75, 0x01, 0x95, 0x01, 0x91, 0x22, 0x75, 0x07, 0x95, 0x01,
|
||||
0x91, 0x03, 0x85, 0x20, 0x09, 0x20, 0x15, 0x00, 0x25, 0x01,
|
||||
0x75, 0x01, 0x95, 0x01, 0x91, 0x22, 0x75, 0x07, 0x95, 0x01,
|
||||
0x91, 0x03, 0x85, 0x2A, 0x09, 0x2A, 0x15, 0x00, 0x25, 0x01,
|
||||
0x75, 0x01, 0x95, 0x01, 0x91, 0x22, 0x75, 0x07, 0x95, 0x01,
|
||||
0x91, 0x03, 0xC0,
|
||||
@@ -0,0 +1,68 @@
|
||||
macOS USB Prober about 0x047F/0xC056 "Plantronics Blackwire 3220 Series"
|
||||
05 0B 09 05 A1 01 85 08 15
|
||||
00 25 01 09 2F 75 01 95 01 81 06 09 20 09 21 75
|
||||
01 95 02 81 22 95 05 81 01 05 08 85 09 09 09 95
|
||||
01 91 22 95 07 91 01 85 17 09 17 95 01 91 22 95
|
||||
07 91 01 85 18 09 18 95 01 91 22 95 07 91 01 85
|
||||
1E 09 1E 95 01 91 22 95 07 91 01 85 20 09 20 95
|
||||
01 91 22 95 07 91 01 85 2A 09 2A 95 01 91 22 95
|
||||
07 91 01 C0
|
||||
|
||||
Parser output:
|
||||
0x05, 0x0B, // Usage Page (Telephony)
|
||||
0x09, 0x05, // Usage (Headset)
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x85, 0x08, // Report ID (8)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x25, 0x01, // Logical Maximum (1)
|
||||
0x09, 0x2F, // Usage (Phone Mute)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x09, 0x20, // Usage (Hook Switch)
|
||||
0x09, 0x21, // Usage (Flash)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x95, 0x02, // Report Count (2)
|
||||
0x81, 0x22, // Input (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position)
|
||||
0x95, 0x05, // Report Count (5)
|
||||
0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x05, 0x08, // Usage Page (LEDs)
|
||||
0x85, 0x09, // Report ID (9)
|
||||
0x09, 0x09, // Usage (Mute)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x91, 0x22, // Output (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
|
||||
0x95, 0x07, // Report Count (7)
|
||||
0x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0x85, 0x17, // Report ID (23)
|
||||
0x09, 0x17, // Usage (Off-Hook)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x91, 0x22, // Output (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
|
||||
0x95, 0x07, // Report Count (7)
|
||||
0x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0x85, 0x18, // Report ID (24)
|
||||
0x09, 0x18, // Usage (Ring)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x91, 0x22, // Output (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
|
||||
0x95, 0x07, // Report Count (7)
|
||||
0x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0x85, 0x1E, // Report ID (30)
|
||||
0x09, 0x1E, // Usage (Speaker)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x91, 0x22, // Output (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
|
||||
0x95, 0x07, // Report Count (7)
|
||||
0x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0x85, 0x20, // Report ID (32)
|
||||
0x09, 0x20, // Usage (Hold)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x91, 0x22, // Output (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
|
||||
0x95, 0x07, // Report Count (7)
|
||||
0x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0x85, 0x2A, // Report ID (42)
|
||||
0x09, 0x2A, // Usage (On-Line)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x91, 0x22, // Output (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position,Non-volatile)
|
||||
0x95, 0x07, // Report Count (7)
|
||||
0x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
|
||||
0xC0, // End Collection
|
||||
|
||||
// 109 bytes
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,75 @@
|
||||
0x06, 0x01, 0xFF, 0x09, 0x00, 0xA1, 0x01, 0x09, 0x01, 0xA1,
|
||||
0x02, 0x85, 0x01, 0x09, 0x03, 0x09, 0x03, 0x09, 0x03, 0x09,
|
||||
0x03, 0x15, 0x00, 0x25, 0x0F, 0x75, 0x04, 0x95, 0x04, 0x81,
|
||||
0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09,
|
||||
0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09,
|
||||
0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09,
|
||||
0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09,
|
||||
0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09,
|
||||
0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09,
|
||||
0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09,
|
||||
0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09,
|
||||
0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09,
|
||||
0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x02, 0x09, 0x0B, 0x09,
|
||||
0x0B, 0x09, 0x0B, 0x09, 0x0B, 0x09, 0x0B, 0x09, 0x0B, 0x09,
|
||||
0x0B, 0x09, 0x0B, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95,
|
||||
0x38, 0x81, 0x02, 0xC0, 0x09, 0x02, 0xA1, 0x02, 0x85, 0x02,
|
||||
0x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04,
|
||||
0x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04,
|
||||
0x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04,
|
||||
0x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04,
|
||||
0x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04, 0x09, 0x04,
|
||||
0x09, 0x04, 0x15, 0x00, 0x26, 0xFF, 0x0F, 0x75, 0x10, 0x95,
|
||||
0x1A, 0x81, 0x02, 0xC0, 0x09, 0x80, 0xA1, 0x02, 0x85, 0x80,
|
||||
0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
|
||||
0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
|
||||
0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
|
||||
0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
|
||||
0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
|
||||
0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
|
||||
0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
|
||||
0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
|
||||
0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
|
||||
0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
|
||||
0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
|
||||
0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
|
||||
0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
|
||||
0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
|
||||
0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
|
||||
0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
|
||||
0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
|
||||
0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81,
|
||||
0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x15, 0x00,
|
||||
0x25, 0x7F, 0x75, 0x08, 0x95, 0x5E, 0x91, 0x02, 0xC0, 0x09,
|
||||
0x80, 0xA1, 0x02, 0x85, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09,
|
||||
0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09,
|
||||
0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09,
|
||||
0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09,
|
||||
0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09,
|
||||
0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09,
|
||||
0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09,
|
||||
0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09, 0x81, 0x09,
|
||||
0x81, 0x09, 0x81, 0x09, 0x81, 0x15, 0x00, 0x25, 0x7F, 0x75,
|
||||
0x08, 0x95, 0x28, 0x91, 0x02, 0xC0, 0x09, 0xD0, 0xA1, 0x02,
|
||||
0x85, 0xD0, 0x09, 0xD1, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
|
||||
0x08, 0x95, 0x20, 0xB1, 0x82, 0xC0, 0x09, 0xD0, 0xA1, 0x02,
|
||||
0x85, 0xD1, 0x09, 0xD1, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
|
||||
0x08, 0x95, 0x20, 0xB1, 0x82, 0xC0, 0x09, 0xD0, 0xA1, 0x02,
|
||||
0x85, 0xD2, 0x09, 0xD1, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
|
||||
0x08, 0x95, 0x20, 0xB1, 0x82, 0xC0, 0x09, 0xD0, 0xA1, 0x02,
|
||||
0x85, 0xD3, 0x09, 0xD1, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
|
||||
0x08, 0x95, 0x20, 0xB1, 0x82, 0xC0, 0x09, 0xD0, 0xA1, 0x02,
|
||||
0x85, 0xD4, 0x09, 0xD1, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
|
||||
0x08, 0x95, 0x20, 0xB1, 0x82, 0xC0, 0x09, 0xD0, 0xA1, 0x02,
|
||||
0x85, 0xD5, 0x09, 0xD1, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
|
||||
0x08, 0x95, 0x20, 0xB1, 0x82, 0xC0, 0x09, 0xD0, 0xA1, 0x02,
|
||||
0x85, 0xD6, 0x09, 0xD1, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
|
||||
0x08, 0x95, 0x20, 0xB1, 0x82, 0xC0, 0x09, 0xD0, 0xA1, 0x02,
|
||||
0x85, 0xD8, 0x09, 0xD1, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
|
||||
0x08, 0x95, 0x20, 0xB1, 0x82, 0xC0, 0x09, 0xD0, 0xA1, 0x02,
|
||||
0x85, 0xD9, 0x09, 0xD1, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
|
||||
0x08, 0x95, 0x20, 0xB1, 0x82, 0xC0, 0x09, 0xD0, 0xA1, 0x02,
|
||||
0x85, 0xF1, 0x09, 0xD1, 0x15, 0x00, 0x26, 0xFF, 0x00, 0x75,
|
||||
0x08, 0x95, 0x02, 0xB1, 0x82, 0xC0, 0x09, 0xD0, 0xA1, 0x02,
|
||||
0x85, 0xF3, 0x09, 0xD1, 0x15, 0x00, 0x25, 0x7F, 0x75, 0x08,
|
||||
0x95, 0x02, 0xB1, 0x82, 0xC0, 0xC0,
|
||||
@@ -0,0 +1,381 @@
|
||||
Usage Page (Vendor-Defined 2) 06 01 FF
|
||||
Usage (Undefined) 09 00
|
||||
Collection (Application) A1 01
|
||||
Usage (Vendor-Defined 1) 09 01
|
||||
Collection (Logical) A1 02
|
||||
Report ID (1) 85 01
|
||||
Usage (Vendor-Defined 3) 09 03
|
||||
Usage (Vendor-Defined 3) 09 03
|
||||
Usage (Vendor-Defined 3) 09 03
|
||||
Usage (Vendor-Defined 3) 09 03
|
||||
Logical Minimum (0) 15 00
|
||||
Logical Maximum (15) 25 0F
|
||||
Report Size (4) 75 04
|
||||
Report Count (4) 95 04
|
||||
Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Logical Minimum (0) 15 00
|
||||
Logical Maximum (1) 25 01
|
||||
Report Size (1) 75 01
|
||||
Report Count (48) 95 30
|
||||
Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
|
||||
Usage (Vendor-Defined 11) 09 0B
|
||||
Usage (Vendor-Defined 11) 09 0B
|
||||
Usage (Vendor-Defined 11) 09 0B
|
||||
Usage (Vendor-Defined 11) 09 0B
|
||||
Usage (Vendor-Defined 11) 09 0B
|
||||
Usage (Vendor-Defined 11) 09 0B
|
||||
Usage (Vendor-Defined 11) 09 0B
|
||||
Usage (Vendor-Defined 11) 09 0B
|
||||
Logical Minimum (0) 15 00
|
||||
Logical Maximum (1) 25 01
|
||||
Report Size (1) 75 01
|
||||
Report Count (8) 95 08
|
||||
Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
|
||||
End Collection C0
|
||||
Usage (Vendor-Defined 2) 09 02
|
||||
Collection (Logical) A1 02
|
||||
Report ID (2) 85 02
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Usage (Vendor-Defined 4) 09 04
|
||||
Logical Minimum (0) 15 00
|
||||
Logical Maximum (4095) 26 FF 0F
|
||||
Report Size (16) 75 10
|
||||
Report Count (26) 95 1A
|
||||
Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
|
||||
End Collection C0
|
||||
Usage (Vendor-Defined 128) 09 80
|
||||
Collection (Logical) A1 02
|
||||
Report ID (128) 85 80
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Logical Minimum (0) 15 00
|
||||
Logical Maximum (127) 25 7F
|
||||
Report Count (94) 95 5E
|
||||
Report Size (8) 75 08
|
||||
Output (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) 91 02
|
||||
End Collection C0
|
||||
Usage (Vendor-Defined 128) 09 80
|
||||
Collection (Logical) A1 02
|
||||
Report ID (129) 85 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Usage (Vendor-Defined 129) 09 81
|
||||
Logical Minimum (0) 15 00
|
||||
Logical Maximum (127) 25 7F
|
||||
Report Count (40) 95 28
|
||||
Report Size (8) 75 08
|
||||
Output (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) 91 02
|
||||
End Collection C0
|
||||
Usage (Vendor-Defined 208) 09 D0
|
||||
Collection (Logical) A1 02
|
||||
Report ID (208) 85 D0
|
||||
Usage (Vendor-Defined 209) 09 D1
|
||||
Logical Minimum (0) 15 00
|
||||
Logical Maximum (255) 26 FF 00
|
||||
Report Size (8) 75 08
|
||||
Report Count (32) 95 20
|
||||
Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,Vol,Bit) B1 82
|
||||
End Collection C0
|
||||
Usage (Vendor-Defined 208) 09 D0
|
||||
Collection (Logical) A1 02
|
||||
Report ID (209) 85 D1
|
||||
Usage (Vendor-Defined 209) 09 D1
|
||||
Logical Minimum (0) 15 00
|
||||
Logical Maximum (255) 26 FF 00
|
||||
Report Size (8) 75 08
|
||||
Report Count (32) 95 20
|
||||
Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,Vol,Bit) B1 82
|
||||
End Collection C0
|
||||
Usage (Vendor-Defined 208) 09 D0
|
||||
Collection (Logical) A1 02
|
||||
Report ID (210) 85 D2
|
||||
Usage (Vendor-Defined 209) 09 D1
|
||||
Logical Minimum (0) 15 00
|
||||
Logical Maximum (255) 26 FF 00
|
||||
Report Size (8) 75 08
|
||||
Report Count (32) 95 20
|
||||
Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,Vol,Bit) B1 82
|
||||
End Collection C0
|
||||
Usage (Vendor-Defined 208) 09 D0
|
||||
Collection (Logical) A1 02
|
||||
Report ID (211) 85 D3
|
||||
Usage (Vendor-Defined 209) 09 D1
|
||||
Logical Minimum (0) 15 00
|
||||
Logical Maximum (255) 26 FF 00
|
||||
Report Size (8) 75 08
|
||||
Report Count (32) 95 20
|
||||
Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,Vol,Bit) B1 82
|
||||
End Collection C0
|
||||
Usage (Vendor-Defined 208) 09 D0
|
||||
Collection (Logical) A1 02
|
||||
Report ID (212) 85 D4
|
||||
Usage (Vendor-Defined 209) 09 D1
|
||||
Logical Minimum (0) 15 00
|
||||
Logical Maximum (255) 26 FF 00
|
||||
Report Size (8) 75 08
|
||||
Report Count (32) 95 20
|
||||
Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,Vol,Bit) B1 82
|
||||
End Collection C0
|
||||
Usage (Vendor-Defined 208) 09 D0
|
||||
Collection (Logical) A1 02
|
||||
Report ID (213) 85 D5
|
||||
Usage (Vendor-Defined 209) 09 D1
|
||||
Logical Minimum (0) 15 00
|
||||
Logical Maximum (255) 26 FF 00
|
||||
Report Size (8) 75 08
|
||||
Report Count (32) 95 20
|
||||
Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,Vol,Bit) B1 82
|
||||
End Collection C0
|
||||
Usage (Vendor-Defined 208) 09 D0
|
||||
Collection (Logical) A1 02
|
||||
Report ID (214) 85 D6
|
||||
Usage (Vendor-Defined 209) 09 D1
|
||||
Logical Minimum (0) 15 00
|
||||
Logical Maximum (255) 26 FF 00
|
||||
Report Size (8) 75 08
|
||||
Report Count (32) 95 20
|
||||
Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,Vol,Bit) B1 82
|
||||
End Collection C0
|
||||
Usage (Vendor-Defined 208) 09 D0
|
||||
Collection (Logical) A1 02
|
||||
Report ID (216) 85 D8
|
||||
Usage (Vendor-Defined 209) 09 D1
|
||||
Logical Minimum (0) 15 00
|
||||
Logical Maximum (255) 26 FF 00
|
||||
Report Size (8) 75 08
|
||||
Report Count (32) 95 20
|
||||
Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,Vol,Bit) B1 82
|
||||
End Collection C0
|
||||
Usage (Vendor-Defined 208) 09 D0
|
||||
Collection (Logical) A1 02
|
||||
Report ID (217) 85 D9
|
||||
Usage (Vendor-Defined 209) 09 D1
|
||||
Logical Minimum (0) 15 00
|
||||
Logical Maximum (255) 26 FF 00
|
||||
Report Size (8) 75 08
|
||||
Report Count (32) 95 20
|
||||
Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,Vol,Bit) B1 82
|
||||
End Collection C0
|
||||
Usage (Vendor-Defined 208) 09 D0
|
||||
Collection (Logical) A1 02
|
||||
Report ID (241) 85 F1
|
||||
Usage (Vendor-Defined 209) 09 D1
|
||||
Logical Minimum (0) 15 00
|
||||
Logical Maximum (255) 26 FF 00
|
||||
Report Size (8) 75 08
|
||||
Report Count (2) 95 02
|
||||
Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,Vol,Bit) B1 82
|
||||
End Collection C0
|
||||
Usage (Vendor-Defined 208) 09 D0
|
||||
Collection (Logical) A1 02
|
||||
Report ID (243) 85 F3
|
||||
Usage (Vendor-Defined 209) 09 D1
|
||||
Logical Minimum (0) 15 00
|
||||
Logical Maximum (127) 25 7F
|
||||
Report Size (8) 75 08
|
||||
Report Count (2) 95 02
|
||||
Feature (Data,Var,Abs,NWrp,Lin,Pref,NNul,Vol,Bit) B1 82
|
||||
End Collection C0
|
||||
End Collection C0
|
||||
@@ -0,0 +1,560 @@
|
||||
#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;
|
||||
errno_t err = fopen_s(&file, filename, "r");
|
||||
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "ERROR: Couldn't open file '%s' for reading: %s\n", filename, strerror(err));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char line[256];
|
||||
|
||||
{
|
||||
unsigned short vendor_id = 0;
|
||||
unsigned short product_id = 0;
|
||||
unsigned short usage = 0;
|
||||
unsigned short usage_page = 0;
|
||||
unsigned short release_number = 0;
|
||||
int interface_number = -1;
|
||||
BOOLEAN header_read_success = FALSE;
|
||||
char manufacturer_string[128];
|
||||
manufacturer_string[0] = '\0';
|
||||
char product_string[128];
|
||||
product_string[0] = '\0';
|
||||
// char path[128];
|
||||
// path[0] = '\0';
|
||||
|
||||
while (fgets(line, sizeof(line), file) != NULL) {
|
||||
if (line[0] == '\r' || line[0] == '\n') {
|
||||
line[0] = '\0';
|
||||
}
|
||||
if (line[0] == '\0') {
|
||||
// read the 'metadata' only until the first empty line
|
||||
header_read_success = TRUE;
|
||||
break;
|
||||
}
|
||||
if (sscanf(line, "dev->vendor_id = 0x%04hX\n", &vendor_id)) continue;
|
||||
if (sscanf(line, "dev->product_id = 0x%04hX\n", &product_id)) continue;
|
||||
if (sscanf(line, "dev->usage_page = 0x%04hX\n", &usage_page)) continue;
|
||||
if (sscanf(line, "dev->usage = 0x%04hX\n", &usage)) continue;
|
||||
if (sscanf(line, "dev->manufacturer_string = \"%127[^\"\n]", manufacturer_string)) continue;
|
||||
if (sscanf(line, "dev->product_string = \"%127[^\"\n]", product_string)) continue;
|
||||
if (sscanf(line, "dev->release_number = 0x%04hX\n", &release_number)) continue;
|
||||
if (sscanf(line, "dev->interface_number = %d\n", &interface_number)) continue;
|
||||
// if (sscanf(line, "dev->path = \"%127[^\"]\n", path)) continue;
|
||||
}
|
||||
if (!header_read_success) {
|
||||
fprintf(stderr, "ERROR: Couldn't read PP Data header (missing newline)\n");
|
||||
return NULL;
|
||||
}
|
||||
printf("'Virtual' Device Read: %04hx %04hx\n", vendor_id, product_id);
|
||||
if (manufacturer_string[0] != '\0') {
|
||||
printf(" Manufacturer: %s\n", manufacturer_string);
|
||||
}
|
||||
if (product_string[0] != '\0') {
|
||||
printf(" Product: %s\n", product_string);
|
||||
}
|
||||
printf(" Release: %hx\n", release_number);
|
||||
printf(" Interface: %d\n", interface_number);
|
||||
printf(" Usage (page): 0x%hx (0x%hx)\n", usage, usage_page);
|
||||
}
|
||||
|
||||
hidp_preparsed_data static_pp_data;
|
||||
memset(&static_pp_data, 0, sizeof(static_pp_data));
|
||||
hidp_preparsed_data *pp_data = &static_pp_data;
|
||||
|
||||
unsigned int rt_idx;
|
||||
unsigned int caps_idx;
|
||||
unsigned int token_idx;
|
||||
unsigned int coll_idx;
|
||||
USAGE temp_usage;
|
||||
BOOLEAN temp_boolean[3];
|
||||
UCHAR temp_uchar[3];
|
||||
USHORT temp_ushort;
|
||||
ULONG temp_ulong;
|
||||
LONG temp_long;
|
||||
|
||||
USHORT FirstByteOfLinkCollectionArray = 0;
|
||||
USHORT NumberLinkCollectionNodes = 0;
|
||||
|
||||
while (fgets(line, sizeof(line), file) != NULL) {
|
||||
if (line[0] == '#')
|
||||
continue;
|
||||
|
||||
if (FirstByteOfLinkCollectionArray != 0 && NumberLinkCollectionNodes != 0) {
|
||||
size_t size_of_preparsed_data = offsetof(hidp_preparsed_data, caps) + FirstByteOfLinkCollectionArray + (NumberLinkCollectionNodes * sizeof(hid_pp_link_collection_node));
|
||||
pp_data->FirstByteOfLinkCollectionArray = FirstByteOfLinkCollectionArray;
|
||||
pp_data->NumberLinkCollectionNodes = NumberLinkCollectionNodes;
|
||||
FirstByteOfLinkCollectionArray = 0;
|
||||
NumberLinkCollectionNodes = 0;
|
||||
pp_data = malloc(size_of_preparsed_data);
|
||||
memcpy(pp_data, &static_pp_data, sizeof(static_pp_data));
|
||||
}
|
||||
|
||||
if (sscanf(line, "pp_data->MagicKey = 0x%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX\n", &pp_data->MagicKey[0], &pp_data->MagicKey[1], &pp_data->MagicKey[2], &pp_data->MagicKey[3], &pp_data->MagicKey[4], &pp_data->MagicKey[5], &pp_data->MagicKey[6], &pp_data->MagicKey[7])) continue;
|
||||
if (sscanf(line, "pp_data->Usage = 0x%04hX\n", &pp_data->Usage)) continue;
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
pp_data->caps_info[rt_idx].ReportByteLength = temp_ushort;
|
||||
continue;
|
||||
}
|
||||
fprintf(stderr, "Ignorring unimplemented caps_info field: %s", line);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sscanf(line, "pp_data->FirstByteOfLinkCollectionArray = 0x%04hX\n", &FirstByteOfLinkCollectionArray)) {
|
||||
continue;
|
||||
}
|
||||
if (sscanf(line, "pp_data->NumberLinkCollectionNodes = %hu\n", &NumberLinkCollectionNodes)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sscanf(line, "pp_data->cap[%d]", &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;
|
||||
}
|
||||
if ((caps_idx + 1) * sizeof(hid_pp_cap) > pp_data->FirstByteOfLinkCollectionArray) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
pp_data->caps[caps_idx].ReportSize = temp_ushort;
|
||||
continue;
|
||||
}
|
||||
if (sscanf(line, "pp_data->cap[%d]->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) {
|
||||
pp_data->caps[caps_idx].BytePosition = temp_ushort;
|
||||
continue;
|
||||
}
|
||||
if (sscanf(line, "pp_data->cap[%d]->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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
pp_data->caps[caps_idx].UnknownTokens[token_idx].BitField = temp_ulong;
|
||||
continue;
|
||||
}
|
||||
fprintf(stderr, "Ignorring unimplemented pp_data->cap[]->pp_cap->UnknownTokens field: %s", line);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Range
|
||||
if (sscanf(line, "pp_data->cap[%d]->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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
pp_data->caps[caps_idx].Units = temp_ulong;
|
||||
continue;
|
||||
}
|
||||
if (sscanf(line, "pp_data->cap[%d]->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) {
|
||||
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;
|
||||
}
|
||||
fprintf(stderr, "Ignorring unimplemented cap field: %s", line);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sscanf(line, "pp_data->LinkCollectionArray[%d]", &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;
|
||||
}
|
||||
if (coll_idx >= pp_data->NumberLinkCollectionNodes) {
|
||||
fprintf(stderr, "Error reading pp_data file (%s): the LinkCollection index (%u) is out of boundary (%hu)\n", line, coll_idx, pp_data->NumberLinkCollectionNodes);
|
||||
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) {
|
||||
pcoll[coll_idx].LinkUsage = temp_usage;
|
||||
continue;
|
||||
}
|
||||
if (sscanf(line, "pp_data->LinkCollectionArray[%d]->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) {
|
||||
pcoll[coll_idx].Parent = temp_ushort;
|
||||
continue;
|
||||
}
|
||||
if (sscanf(line, "pp_data->LinkCollectionArray[%d]->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) {
|
||||
pcoll[coll_idx].NextSibling = temp_ushort;
|
||||
continue;
|
||||
}
|
||||
if (sscanf(line, "pp_data->LinkCollectionArray[%d]->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) {
|
||||
pcoll[coll_idx].CollectionType = temp_ulong;
|
||||
continue;
|
||||
}
|
||||
if (sscanf(line, "pp_data->LinkCollectionArray[%d]->IsAlias = %ld\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) {
|
||||
pcoll[coll_idx].Reserved = temp_ulong;
|
||||
continue;
|
||||
}
|
||||
fprintf(stderr, "Ignorring unimplemented LinkCollectionArray field: %s", line);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//end:
|
||||
fclose(file);
|
||||
|
||||
if (pp_data == &static_pp_data) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pp_data;
|
||||
}
|
||||
|
||||
static BOOLEAN read_hex_data_from_text_file(const char *filename, unsigned char *data_out, size_t data_size, size_t *actual_read)
|
||||
{
|
||||
size_t read_index = 0;
|
||||
FILE* file = NULL;
|
||||
errno_t err = fopen_s(&file, filename, "r");
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "ERROR: Couldn't open file '%s' for reading: %s\n", filename, strerror(err));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN result = TRUE;
|
||||
unsigned int val;
|
||||
char buf[16];
|
||||
while (fscanf(file, "%15s", buf) == 1) {
|
||||
if (sscanf(buf, "0x%X", &val) != 1) {
|
||||
fprintf(stderr, "Invalid HEX text ('%s') file, got %s\n", filename, buf);
|
||||
result = FALSE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (read_index >= data_size) {
|
||||
fprintf(stderr, "Buffer for file read is too small. Got only %zu bytes to read '%s'\n", data_size, filename);
|
||||
result = FALSE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (val > (unsigned char)-1) {
|
||||
fprintf(stderr, "Invalid HEX text ('%s') file, got a value of: %u\n", filename, val);
|
||||
result = FALSE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
data_out[read_index] = (unsigned char) val;
|
||||
|
||||
read_index++;
|
||||
}
|
||||
|
||||
if (!feof(file)) {
|
||||
fprintf(stderr, "Invalid HEX text ('%s') file - failed to read all values\n", filename);
|
||||
result = FALSE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
*actual_read = read_index;
|
||||
|
||||
end:
|
||||
fclose(file);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "Expected 2 arguments for the test ('<>.pp_data' and '<>_expected.rpt_desc'), got: %d\n", argc - 1);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("Checking: '%s' / '%s'\n", argv[1], argv[2]);
|
||||
|
||||
hidp_preparsed_data *pp_data = alloc_preparsed_data_from_file(argv[1]);
|
||||
if (pp_data == NULL) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
int result = EXIT_SUCCESS;
|
||||
|
||||
unsigned char report_descriptor[HID_API_MAX_REPORT_DESCRIPTOR_SIZE];
|
||||
|
||||
int res = hid_winapi_descriptor_reconstruct_pp_data(pp_data, report_descriptor, sizeof(report_descriptor));
|
||||
|
||||
if (res < 0) {
|
||||
result = EXIT_FAILURE;
|
||||
fprintf(stderr, "Failed to reconstruct descriptor");
|
||||
goto end;
|
||||
}
|
||||
size_t report_descriptor_size = (size_t) res;
|
||||
|
||||
unsigned char expected_report_descriptor[HID_API_MAX_REPORT_DESCRIPTOR_SIZE];
|
||||
size_t expected_report_descriptor_size = 0;
|
||||
if (!read_hex_data_from_text_file(argv[2], expected_report_descriptor, sizeof(expected_report_descriptor), &expected_report_descriptor_size)) {
|
||||
result = EXIT_FAILURE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (report_descriptor_size == expected_report_descriptor_size) {
|
||||
if (memcmp(report_descriptor, expected_report_descriptor, report_descriptor_size) == 0) {
|
||||
printf("Reconstructed Report Descriptor matches the expected descriptor\n");
|
||||
goto end;
|
||||
}
|
||||
else {
|
||||
result = EXIT_FAILURE;
|
||||
fprintf(stderr, "Reconstructed Report Descriptor has different content than expected\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = EXIT_FAILURE;
|
||||
fprintf(stderr, "Reconstructed Report Descriptor has different size: %zu when expected %zu\n", report_descriptor_size, expected_report_descriptor_size);
|
||||
}
|
||||
|
||||
printf(" Reconstructed Report Descriptor:\n");
|
||||
for (int i = 0; i < res; i++) {
|
||||
printf("0x%02X, ", report_descriptor[i]);
|
||||
}
|
||||
printf("\n");
|
||||
fflush(stdout);
|
||||
|
||||
end:
|
||||
free(pp_data);
|
||||
return result;
|
||||
}
|
||||
Reference in New Issue
Block a user