Skip to content

Commit b0eca5d

Browse files
Joop-Schilderbenedekkupper
authored andcommitted
Enable more lenient parsing of report descriptor on Windows.
HidSharp has trouble parsing some report descriptors on Windows. This makes some devices unusable with HidSharp. By discarding report items which overlap or report items having undefined usage values (0) we enable more lenient parsing. This makes HidSharp usable with more devices.
1 parent 8af1b03 commit b0eca5d

2 files changed

Lines changed: 29 additions & 6 deletions

File tree

HidSharp/Platform/Windows/WinHidDevice.ReportDescriptorReconstructor.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,6 @@ void AddButtonGlobalItems(int bitCount)
6969

7070
void PadReport(MainItemTag mainItemTag, int padToBit, ref int currentBit)
7171
{
72-
if (currentBit > padToBit) { throw new NotImplementedException(); } // Overlapping...
73-
7472
// Padding...
7573
int paddingBitCount = padToBit - currentBit;
7674
if (paddingBitCount > 0)
@@ -195,11 +193,20 @@ the capability array contains only one capability structure that describes one b
195193
var reportItems = report.Where(x => x.BitOffset != maxBit).OrderBy(x => x.BitOffset).ToArray();
196194
foreach (var reportItem in reportItems)
197195
{
198-
var button = reportItem.Button;
199196
var item = reportItem.Item;
200197
int startBit = reportItem.BitOffset;
201198
int bitCount = reportItem.ReportCount * reportItem.ReportSize;
202-
if (currentBit > startBit) { throw new NotImplementedException(); } // Overlapping...
199+
200+
// This usage value is of no use.
201+
if (item.UsageIndex == 0)
202+
{
203+
continue;
204+
}
205+
// This report item overlaps another.
206+
if (currentBit > startBit)
207+
{
208+
break;
209+
}
203210

204211
SetCollection(item.LinkCollection);
205212
PadReport(mainItemTag, startBit, ref currentBit);
@@ -218,7 +225,7 @@ the capability array contains only one capability structure that describes one b
218225
_builder.AddLocalItem(LocalItemTag.Usage, usageMin);
219226
}
220227

221-
if (button)
228+
if (reportItem.Button)
222229
{
223230
AddButtonGlobalItems(reportItem.ReportCount);
224231
}

HidSharp/Reports/Input/DeviceItemInputParser.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,19 @@ public bool TryParseReport(byte[] buffer, int offset, Report report)
121121
var rangeOfElementsByIndexOfDataItem = _rangesOfElementsByIndexOfDataItem[reportIndex];
122122
report.Read(buffer, offset, (reportBuffer, bitOffset, dataItem, indexOfDataItem) =>
123123
{
124+
// This usage value is of no use.
125+
if (dataItem.Usages.GetAllValues().FirstOrDefault() == 0)
126+
{
127+
return;
128+
}
129+
124130
int dataItemStartElement = rangeOfElementsByIndexOfDataItem[indexOfDataItem];
125131
int dataItemEndElement = rangeOfElementsByIndexOfDataItem[indexOfDataItem + 1];
126-
if (dataItemStartElement == dataItemEndElement) { return; } // We skipped this one.
132+
// We skipped this one.
133+
if (dataItemStartElement == dataItemEndElement)
134+
{
135+
return;
136+
}
127137

128138
int elementCount = dataItem.ElementCount;
129139
for (int elementIndex = 0; elementIndex < elementCount; elementIndex++)
@@ -132,6 +142,12 @@ public bool TryParseReport(byte[] buffer, int offset, Report report)
132142
if (dataItem.TryReadValue(reportBuffer, bitOffset, elementIndex, out newDataValue))
133143
{
134144
int indexOfElement = dataItemStartElement + newDataValue.DataIndex;
145+
// This index is out of bounds.
146+
if (indexOfElement >= _newDataValues.Count())
147+
{
148+
continue;
149+
}
150+
135151
_newDataValues[indexOfElement] = newDataValue;
136152
}
137153
}

0 commit comments

Comments
 (0)