hidclass.sys: Simplify signed / unsigned item value parsing.
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
978e03ea94
commit
e7423a054d
|
@ -256,29 +256,6 @@ static void debug_print_preparsed(WINE_HIDP_PREPARSED_DATA *data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int getValue(int bsize, int source, BOOL allow_negative)
|
|
||||||
{
|
|
||||||
int mask = 0xff;
|
|
||||||
int negative = 0x80;
|
|
||||||
int outofrange = 0x100;
|
|
||||||
int value;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
if (bsize == 4)
|
|
||||||
return source;
|
|
||||||
|
|
||||||
for (i = 1; i < bsize; i++)
|
|
||||||
{
|
|
||||||
mask = (mask<<8) + 0xff;
|
|
||||||
negative = (negative<<8);
|
|
||||||
outofrange = (outofrange<<8);
|
|
||||||
}
|
|
||||||
value = (source&mask);
|
|
||||||
if (allow_negative && value&negative)
|
|
||||||
value = -1 * (outofrange - value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void parse_io_feature(unsigned int bSize, int itemVal, int bTag,
|
static void parse_io_feature(unsigned int bSize, int itemVal, int bTag,
|
||||||
unsigned int *feature_index,
|
unsigned int *feature_index,
|
||||||
struct feature *feature)
|
struct feature *feature)
|
||||||
|
@ -342,17 +319,35 @@ static int parse_descriptor(BYTE *descriptor, unsigned int index, unsigned int l
|
||||||
int usages_top = 0;
|
int usages_top = 0;
|
||||||
USAGE usages[256];
|
USAGE usages[256];
|
||||||
int i;
|
int i;
|
||||||
|
UINT32 value;
|
||||||
|
INT32 signed_value;
|
||||||
|
|
||||||
for (i = index; i < length;)
|
for (i = index; i < length;)
|
||||||
{
|
{
|
||||||
BYTE b0 = descriptor[i++];
|
BYTE b0 = descriptor[i++];
|
||||||
int bSize = b0 & 0x03;
|
int size = b0 & 0x03;
|
||||||
int bType = (b0 >> 2) & 0x03;
|
int bType = (b0 >> 2) & 0x03;
|
||||||
int bTag = (b0 >> 4) & 0x0F;
|
int bTag = (b0 >> 4) & 0x0F;
|
||||||
|
|
||||||
bSize = (bSize == 3) ? 4 : bSize;
|
if (size == 3) size = 4;
|
||||||
if (bType == TAG_TYPE_RESERVED && bTag == 0x0F && bSize == 2 &&
|
if (length - i < size)
|
||||||
i + 2 < length)
|
{
|
||||||
|
ERR("Need %d bytes to read item value\n", size);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size == 0) signed_value = value = 0;
|
||||||
|
else if (size == 1) signed_value = (INT8)(value = *(UINT8 *)(descriptor + i));
|
||||||
|
else if (size == 2) signed_value = (INT16)(value = *(UINT16 *)(descriptor + i));
|
||||||
|
else if (size == 4) signed_value = (INT32)(value = *(UINT32 *)(descriptor + i));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ERR("Unexpected item value size %d.\n", size);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
i += size;
|
||||||
|
|
||||||
|
if (bType == TAG_TYPE_RESERVED && bTag == 0x0F && size == 2)
|
||||||
{
|
{
|
||||||
/* Long data items: Should be unused */
|
/* Long data items: Should be unused */
|
||||||
ERR("Long Data Item, should be unused\n");
|
ERR("Long Data Item, should be unused\n");
|
||||||
|
@ -360,19 +355,9 @@ static int parse_descriptor(BYTE *descriptor, unsigned int index, unsigned int l
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int bSizeActual = 0;
|
|
||||||
int itemVal = 0;
|
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
|
|
||||||
for (j = 0; j < bSize; j++)
|
TRACE(" 0x%x[%i], type %i , tag %i, size %i, val %i\n",b0,i-size-1,bType, bTag, size, value );
|
||||||
{
|
|
||||||
if (i + j < length)
|
|
||||||
{
|
|
||||||
itemVal += descriptor[i + j] << (8 * j);
|
|
||||||
bSizeActual++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TRACE(" 0x%x[%i], type %i , tag %i, size %i, val %i\n",b0,i-1,bType, bTag, bSize, itemVal );
|
|
||||||
|
|
||||||
if (bType == TAG_TYPE_MAIN)
|
if (bType == TAG_TYPE_MAIN)
|
||||||
{
|
{
|
||||||
|
@ -392,7 +377,7 @@ static int parse_descriptor(BYTE *descriptor, unsigned int index, unsigned int l
|
||||||
feature->type = HidP_Output;
|
feature->type = HidP_Output;
|
||||||
else
|
else
|
||||||
feature->type = HidP_Feature;
|
feature->type = HidP_Feature;
|
||||||
parse_io_feature(bSize, itemVal, bTag, feature_index, feature);
|
parse_io_feature(size, value, bTag, feature_index, feature);
|
||||||
if (j < usages_top)
|
if (j < usages_top)
|
||||||
caps->NotRange.Usage = usages[j];
|
caps->NotRange.Usage = usages[j];
|
||||||
feature->caps = *caps;
|
feature->caps = *caps;
|
||||||
|
@ -429,9 +414,9 @@ static int parse_descriptor(BYTE *descriptor, unsigned int index, unsigned int l
|
||||||
list_init(&subcollection->collections);
|
list_init(&subcollection->collections);
|
||||||
new_caps(caps);
|
new_caps(caps);
|
||||||
|
|
||||||
parse_collection(bSize, itemVal, subcollection);
|
parse_collection(size, value, subcollection);
|
||||||
|
|
||||||
if ((i = parse_descriptor(descriptor, i+1, length, feature_index, collection_index, subcollection, caps, stack)) < 0) return i;
|
if ((i = parse_descriptor(descriptor, i, length, feature_index, collection_index, subcollection, caps, stack)) < 0) return i;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case TAG_MAIN_END_COLLECTION:
|
case TAG_MAIN_END_COLLECTION:
|
||||||
|
@ -446,34 +431,34 @@ static int parse_descriptor(BYTE *descriptor, unsigned int index, unsigned int l
|
||||||
switch(bTag)
|
switch(bTag)
|
||||||
{
|
{
|
||||||
case TAG_GLOBAL_USAGE_PAGE:
|
case TAG_GLOBAL_USAGE_PAGE:
|
||||||
caps->UsagePage = getValue(bSize, itemVal, FALSE);
|
caps->UsagePage = value;
|
||||||
break;
|
break;
|
||||||
case TAG_GLOBAL_LOGICAL_MINIMUM:
|
case TAG_GLOBAL_LOGICAL_MINIMUM:
|
||||||
caps->LogicalMin = getValue(bSize, itemVal, TRUE);
|
caps->LogicalMin = signed_value;
|
||||||
break;
|
break;
|
||||||
case TAG_GLOBAL_LOGICAL_MAXIMUM:
|
case TAG_GLOBAL_LOGICAL_MAXIMUM:
|
||||||
caps->LogicalMax = getValue(bSize, itemVal, TRUE);
|
caps->LogicalMax = signed_value;
|
||||||
break;
|
break;
|
||||||
case TAG_GLOBAL_PHYSICAL_MINIMUM:
|
case TAG_GLOBAL_PHYSICAL_MINIMUM:
|
||||||
caps->PhysicalMin = getValue(bSize, itemVal, TRUE);
|
caps->PhysicalMin = signed_value;
|
||||||
break;
|
break;
|
||||||
case TAG_GLOBAL_PHYSICAL_MAXIMUM:
|
case TAG_GLOBAL_PHYSICAL_MAXIMUM:
|
||||||
caps->PhysicalMax = getValue(bSize, itemVal, TRUE);
|
caps->PhysicalMax = signed_value;
|
||||||
break;
|
break;
|
||||||
case TAG_GLOBAL_UNIT_EXPONENT:
|
case TAG_GLOBAL_UNIT_EXPONENT:
|
||||||
caps->UnitsExp = getValue(bSize, itemVal, TRUE);
|
caps->UnitsExp = signed_value;
|
||||||
break;
|
break;
|
||||||
case TAG_GLOBAL_UNIT:
|
case TAG_GLOBAL_UNIT:
|
||||||
caps->Units = getValue(bSize, itemVal, TRUE);
|
caps->Units = signed_value;
|
||||||
break;
|
break;
|
||||||
case TAG_GLOBAL_REPORT_SIZE:
|
case TAG_GLOBAL_REPORT_SIZE:
|
||||||
caps->BitSize = getValue(bSize, itemVal, FALSE);
|
caps->BitSize = value;
|
||||||
break;
|
break;
|
||||||
case TAG_GLOBAL_REPORT_ID:
|
case TAG_GLOBAL_REPORT_ID:
|
||||||
caps->ReportID = getValue(bSize, itemVal, FALSE);
|
caps->ReportID = value;
|
||||||
break;
|
break;
|
||||||
case TAG_GLOBAL_REPORT_COUNT:
|
case TAG_GLOBAL_REPORT_COUNT:
|
||||||
caps->ReportCount = getValue(bSize, itemVal, FALSE);
|
caps->ReportCount = value;
|
||||||
break;
|
break;
|
||||||
case TAG_GLOBAL_PUSH:
|
case TAG_GLOBAL_PUSH:
|
||||||
{
|
{
|
||||||
|
@ -521,44 +506,44 @@ static int parse_descriptor(BYTE *descriptor, unsigned int index, unsigned int l
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
usages[usages_top++] = getValue(bSize, itemVal, FALSE);
|
usages[usages_top++] = value;
|
||||||
caps->IsRange = FALSE;
|
caps->IsRange = FALSE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TAG_LOCAL_USAGE_MINIMUM:
|
case TAG_LOCAL_USAGE_MINIMUM:
|
||||||
caps->Range.UsageMin = getValue(bSize, itemVal, FALSE);
|
caps->Range.UsageMin = value;
|
||||||
caps->IsRange = TRUE;
|
caps->IsRange = TRUE;
|
||||||
break;
|
break;
|
||||||
case TAG_LOCAL_USAGE_MAXIMUM:
|
case TAG_LOCAL_USAGE_MAXIMUM:
|
||||||
caps->Range.UsageMax = getValue(bSize, itemVal, FALSE);
|
caps->Range.UsageMax = value;
|
||||||
caps->IsRange = TRUE;
|
caps->IsRange = TRUE;
|
||||||
break;
|
break;
|
||||||
case TAG_LOCAL_DESIGNATOR_INDEX:
|
case TAG_LOCAL_DESIGNATOR_INDEX:
|
||||||
caps->NotRange.DesignatorIndex = getValue(bSize, itemVal, FALSE);
|
caps->NotRange.DesignatorIndex = value;
|
||||||
caps->IsDesignatorRange = FALSE;
|
caps->IsDesignatorRange = FALSE;
|
||||||
break;
|
break;
|
||||||
case TAG_LOCAL_DESIGNATOR_MINIMUM:
|
case TAG_LOCAL_DESIGNATOR_MINIMUM:
|
||||||
caps->Range.DesignatorMin = getValue(bSize, itemVal, FALSE);
|
caps->Range.DesignatorMin = value;
|
||||||
caps->IsDesignatorRange = TRUE;
|
caps->IsDesignatorRange = TRUE;
|
||||||
break;
|
break;
|
||||||
case TAG_LOCAL_DESIGNATOR_MAXIMUM:
|
case TAG_LOCAL_DESIGNATOR_MAXIMUM:
|
||||||
caps->Range.DesignatorMax = getValue(bSize, itemVal, FALSE);
|
caps->Range.DesignatorMax = value;
|
||||||
caps->IsDesignatorRange = TRUE;
|
caps->IsDesignatorRange = TRUE;
|
||||||
break;
|
break;
|
||||||
case TAG_LOCAL_STRING_INDEX:
|
case TAG_LOCAL_STRING_INDEX:
|
||||||
caps->NotRange.StringIndex = getValue(bSize, itemVal, FALSE);
|
caps->NotRange.StringIndex = value;
|
||||||
caps->IsStringRange = FALSE;
|
caps->IsStringRange = FALSE;
|
||||||
break;
|
break;
|
||||||
case TAG_LOCAL_STRING_MINIMUM:
|
case TAG_LOCAL_STRING_MINIMUM:
|
||||||
caps->Range.StringMin = getValue(bSize, itemVal, FALSE);
|
caps->Range.StringMin = value;
|
||||||
caps->IsStringRange = TRUE;
|
caps->IsStringRange = TRUE;
|
||||||
break;
|
break;
|
||||||
case TAG_LOCAL_STRING_MAXIMUM:
|
case TAG_LOCAL_STRING_MAXIMUM:
|
||||||
caps->Range.StringMax = getValue(bSize, itemVal, FALSE);
|
caps->Range.StringMax = value;
|
||||||
caps->IsStringRange = TRUE;
|
caps->IsStringRange = TRUE;
|
||||||
break;
|
break;
|
||||||
case TAG_LOCAL_DELIMITER:
|
case TAG_LOCAL_DELIMITER:
|
||||||
FIXME("delimiter %d not implemented!\n", itemVal);
|
FIXME("delimiter %d not implemented!\n", value);
|
||||||
return -1;
|
return -1;
|
||||||
default:
|
default:
|
||||||
ERR("Unknown (bTag: 0x%x, bType: 0x%x)\n", bTag, bType);
|
ERR("Unknown (bTag: 0x%x, bType: 0x%x)\n", bTag, bType);
|
||||||
|
@ -570,8 +555,6 @@ static int parse_descriptor(BYTE *descriptor, unsigned int index, unsigned int l
|
||||||
ERR("Unknown (bTag: 0x%x, bType: 0x%x)\n", bTag, bType);
|
ERR("Unknown (bTag: 0x%x, bType: 0x%x)\n", bTag, bType);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
i += bSize;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
|
|
Loading…
Reference in New Issue