Simple Directmedia Layer
1## pp_data_dump.exe for Windows 2 3 4pp_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. 5 6The 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. 7 8pp_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 9``` 10<vendor_id>_<product_id>_<usage>_<usage_table>.pp_data 11``` 12for each top-level collection, of each connected HID device. 13 14 15## File content 16 17The content of such a .pp_data file looks like the struct, which HIDAPI uses internally to represent the Preparsed Data. 18 19*NOTE: 20Windows parses HID report descriptors into opaque `_HIDP_PREPARSED_DATA` objects. 21The internal structure of `_HIDP_PREPARSED_DATA` is reserved for internal system use.\ 22Microsoft 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.* 23 24``` 25# HIDAPI device info struct: 26dev->vendor_id = 0x046D 27dev->product_id = 0xB010 28dev->manufacturer_string = "Logitech" 29dev->product_string = "Logitech Bluetooth Wireless Mouse" 30dev->release_number = 0x0000 31dev->interface_number = -1 32dev->usage = 0x0001 33dev->usage_page = 0x000C 34dev->path = "\\?\hid#{00001124-0000-1000-8000-00805f9b34fb}_vid&0002046d_pid&b010&col02#8&1cf1c1b9&3&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}" 35 36# Preparsed Data struct: 37pp_data->MagicKey = 0x48696450204B4452 38pp_data->Usage = 0x0001 39pp_data->UsagePage = 0x000C 40pp_data->Reserved = 0x00000000 41# Input caps_info struct: 42pp_data->caps_info[0]->FirstCap = 0 43pp_data->caps_info[0]->LastCap = 1 44pp_data->caps_info[0]->NumberOfCaps = 1 45pp_data->caps_info[0]->ReportByteLength = 2 46# Output caps_info struct: 47pp_data->caps_info[1]->FirstCap = 1 48pp_data->caps_info[1]->LastCap = 1 49pp_data->caps_info[1]->NumberOfCaps = 0 50pp_data->caps_info[1]->ReportByteLength = 0 51# Feature caps_info struct: 52pp_data->caps_info[2]->FirstCap = 1 53pp_data->caps_info[2]->LastCap = 1 54pp_data->caps_info[2]->NumberOfCaps = 0 55pp_data->caps_info[2]->ReportByteLength = 0 56# LinkCollectionArray Offset & Size: 57pp_data->FirstByteOfLinkCollectionArray = 0x0068 58pp_data->NumberLinkCollectionNodes = 1 59# Input hid_pp_cap struct: 60pp_data->cap[0]->UsagePage = 0x0006 61pp_data->cap[0]->ReportID = 0x03 62pp_data->cap[0]->BitPosition = 0 63pp_data->cap[0]->BitSize = 8 64pp_data->cap[0]->ReportCount = 1 65pp_data->cap[0]->BytePosition = 0x0001 66pp_data->cap[0]->BitCount = 8 67pp_data->cap[0]->BitField = 0x02 68pp_data->cap[0]->NextBytePosition = 0x0002 69pp_data->cap[0]->LinkCollection = 0x0000 70pp_data->cap[0]->LinkUsagePage = 0x000C 71pp_data->cap[0]->LinkUsage = 0x0001 72pp_data->cap[0]->IsMultipleItemsForArray = 0 73pp_data->cap[0]->IsButtonCap = 0 74pp_data->cap[0]->IsPadding = 0 75pp_data->cap[0]->IsAbsolute = 1 76pp_data->cap[0]->IsRange = 0 77pp_data->cap[0]->IsAlias = 0 78pp_data->cap[0]->IsStringRange = 0 79pp_data->cap[0]->IsDesignatorRange = 0 80pp_data->cap[0]->Reserved1 = 0x000000 81pp_data->cap[0]->pp_cap->UnknownTokens[0].Token = 0x00 82pp_data->cap[0]->pp_cap->UnknownTokens[0].Reserved = 0x000000 83pp_data->cap[0]->pp_cap->UnknownTokens[0].BitField = 0x00000000 84pp_data->cap[0]->pp_cap->UnknownTokens[1].Token = 0x00 85pp_data->cap[0]->pp_cap->UnknownTokens[1].Reserved = 0x000000 86pp_data->cap[0]->pp_cap->UnknownTokens[1].BitField = 0x00000000 87pp_data->cap[0]->pp_cap->UnknownTokens[2].Token = 0x00 88pp_data->cap[0]->pp_cap->UnknownTokens[2].Reserved = 0x000000 89pp_data->cap[0]->pp_cap->UnknownTokens[2].BitField = 0x00000000 90pp_data->cap[0]->pp_cap->UnknownTokens[3].Token = 0x00 91pp_data->cap[0]->pp_cap->UnknownTokens[3].Reserved = 0x000000 92pp_data->cap[0]->pp_cap->UnknownTokens[3].BitField = 0x00000000 93pp_data->cap[0]->NotRange.Usage = 0x0020 94pp_data->cap[0]->NotRange.Reserved1 = 0x0020 95pp_data->cap[0]->NotRange.StringIndex = 0 96pp_data->cap[0]->NotRange.Reserved2 = 0 97pp_data->cap[0]->NotRange.DesignatorIndex = 0 98pp_data->cap[0]->NotRange.Reserved3 = 0 99pp_data->cap[0]->NotRange.DataIndex = 0 100pp_data->cap[0]->NotRange.Reserved4 = 0 101pp_data->cap[0]->NotButton.HasNull = 0 102pp_data->cap[0]->NotButton.Reserved4 = 0x000000 103pp_data->cap[0]->NotButton.LogicalMin = 0 104pp_data->cap[0]->NotButton.LogicalMax = 100 105pp_data->cap[0]->NotButton.PhysicalMin = 0 106pp_data->cap[0]->NotButton.PhysicalMax = 0 107pp_data->cap[0]->Units = 0 108pp_data->cap[0]->UnitsExp = 0 109 110# Output hid_pp_cap struct: 111# Feature hid_pp_cap struct: 112# Link Collections: 113pp_data->LinkCollectionArray[0]->LinkUsage = 0x0001 114pp_data->LinkCollectionArray[0]->LinkUsagePage = 0x000C 115pp_data->LinkCollectionArray[0]->Parent = 0 116pp_data->LinkCollectionArray[0]->NumberOfChildren = 0 117pp_data->LinkCollectionArray[0]->NextSibling = 0 118pp_data->LinkCollectionArray[0]->FirstChild = 0 119pp_data->LinkCollectionArray[0]->CollectionType = 1 120pp_data->LinkCollectionArray[0]->IsAlias = 0 121pp_data->LinkCollectionArray[0]->Reserved = 0x00000000 122```