/******************************************************* 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 #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