in XInput_Scp/pnp.cpp [263:649]
BOOLEAN FillDeviceInfo(IN PHID_DEVICE HidDevice)
{
ULONG numValues;
USHORT numCaps;
PHIDP_BUTTON_CAPS buttonCaps;
PHIDP_VALUE_CAPS valueCaps;
PHID_DATA data;
ULONG i;
USAGE usage;
UINT dataIdx;
ULONG newFeatureDataLength;
ULONG tmpSum;
HidDevice->InputReportBuffer = (PCHAR) calloc(HidDevice->Caps.InputReportByteLength, sizeof(CHAR));
HidDevice->InputButtonCaps = buttonCaps = (PHIDP_BUTTON_CAPS) calloc(HidDevice->Caps.NumberInputButtonCaps, sizeof(HIDP_BUTTON_CAPS));
if (buttonCaps == NULL)
{
return FALSE;
}
HidDevice->InputValueCaps = valueCaps = (PHIDP_VALUE_CAPS) calloc(HidDevice->Caps.NumberInputValueCaps, sizeof(HIDP_VALUE_CAPS));
if (valueCaps == NULL)
{
return FALSE;
}
numCaps = HidDevice->Caps.NumberInputButtonCaps;
if(numCaps > 0)
{
if(HidP_GetButtonCaps(HidP_Input, buttonCaps, &numCaps, HidDevice->Ppd) != HIDP_STATUS_SUCCESS)
{
return FALSE;
}
}
numCaps = HidDevice->Caps.NumberInputValueCaps;
if(numCaps > 0)
{
if(HidP_GetValueCaps(HidP_Input, valueCaps, &numCaps, HidDevice->Ppd) != HIDP_STATUS_SUCCESS)
{
return FALSE;
}
}
numValues = 0;
for (i = 0; i < HidDevice->Caps.NumberInputValueCaps; i++, valueCaps++)
{
if (valueCaps->IsRange)
{
numValues += valueCaps->Range.UsageMax - valueCaps->Range.UsageMin + 1;
if(valueCaps->Range.UsageMin >= valueCaps->Range.UsageMax + (HidDevice->Caps).NumberInputButtonCaps)
{
return FALSE;
}
}
else
{
numValues++;
}
}
valueCaps = HidDevice->InputValueCaps;
HidDevice->InputDataLength = HidDevice->Caps.NumberInputButtonCaps + numValues;
HidDevice->InputData = data = (PHID_DATA) calloc(HidDevice->InputDataLength, sizeof(HID_DATA));
if (data == NULL)
{
return FALSE;
}
dataIdx = 0;
for (i = 0; i < HidDevice->Caps.NumberInputButtonCaps; i++, data++, buttonCaps++, dataIdx++)
{
data->IsButtonData = TRUE;
data->Status = HIDP_STATUS_SUCCESS;
data->UsagePage = buttonCaps->UsagePage;
if (buttonCaps->IsRange)
{
data->ButtonData.UsageMin = buttonCaps->Range.UsageMin;
data->ButtonData.UsageMax = buttonCaps->Range.UsageMax;
}
else
{
data->ButtonData.UsageMin = data->ButtonData.UsageMax = buttonCaps->NotRange.Usage;
}
data->ButtonData.MaxUsageLength = HidP_MaxUsageListLength(HidP_Input, buttonCaps->UsagePage, HidDevice->Ppd);
data->ButtonData.Usages = (PUSAGE) calloc(data->ButtonData.MaxUsageLength, sizeof(USAGE));
data->ReportID = buttonCaps->ReportID;
}
for (i = 0; i < HidDevice->Caps.NumberInputValueCaps ; i++, valueCaps++)
{
if (valueCaps->IsRange)
{
for (usage = valueCaps->Range.UsageMin; usage <= valueCaps->Range.UsageMax; usage++)
{
if(dataIdx >= HidDevice->InputDataLength)
{
return FALSE;
}
data->IsButtonData = FALSE;
data->Status = HIDP_STATUS_SUCCESS;
data->UsagePage = valueCaps->UsagePage;
data->ValueData.Usage = usage;
data->ReportID = valueCaps->ReportID;
data++; dataIdx++;
}
}
else
{
if(dataIdx >= HidDevice->InputDataLength)
{
return FALSE;
}
data->IsButtonData = FALSE;
data->Status = HIDP_STATUS_SUCCESS;
data->UsagePage = valueCaps->UsagePage;
data->ValueData.Usage = valueCaps->NotRange.Usage;
data->ReportID = valueCaps->ReportID;
data++; dataIdx++;
}
}
HidDevice->OutputReportBuffer = (PCHAR) calloc(HidDevice->Caps.OutputReportByteLength, sizeof(CHAR));
HidDevice->OutputButtonCaps = buttonCaps = (PHIDP_BUTTON_CAPS) calloc(HidDevice->Caps.NumberOutputButtonCaps, sizeof(HIDP_BUTTON_CAPS));
if (buttonCaps == NULL)
{
return FALSE;
}
HidDevice->OutputValueCaps = valueCaps = (PHIDP_VALUE_CAPS) calloc(HidDevice->Caps.NumberOutputValueCaps, sizeof(HIDP_VALUE_CAPS));
if (valueCaps == NULL)
{
return FALSE;
}
numCaps = HidDevice->Caps.NumberOutputButtonCaps;
if(numCaps > 0)
{
if(HidP_GetButtonCaps(HidP_Output, buttonCaps, &numCaps, HidDevice->Ppd) != HIDP_STATUS_SUCCESS)
{
return FALSE;
}
}
numCaps = HidDevice->Caps.NumberOutputValueCaps;
if(numCaps > 0)
{
if(HidP_GetValueCaps(HidP_Output, valueCaps, &numCaps, HidDevice->Ppd) != HIDP_STATUS_SUCCESS)
{
return FALSE;
}
}
numValues = 0;
for (i = 0; i < HidDevice->Caps.NumberOutputValueCaps; i++, valueCaps++)
{
if (valueCaps->IsRange)
{
numValues += valueCaps->Range.UsageMax - valueCaps->Range.UsageMin + 1;
}
else
{
numValues++;
}
}
valueCaps = HidDevice->OutputValueCaps;
HidDevice->OutputDataLength = HidDevice->Caps.NumberOutputButtonCaps + numValues;
HidDevice->OutputData = data = (PHID_DATA) calloc(HidDevice->OutputDataLength, sizeof(HID_DATA));
if (data == NULL)
{
return FALSE;
}
for (i = 0; i < HidDevice->Caps.NumberOutputButtonCaps; i++, data++, buttonCaps++)
{
if (i >= HidDevice->OutputDataLength)
{
return FALSE;
}
if(FAILED(ULongAdd(HidDevice->Caps.NumberOutputButtonCaps, valueCaps->Range.UsageMax, &tmpSum)))
{
return FALSE;
}
if(valueCaps->Range.UsageMin == tmpSum)
{
return FALSE;
}
data->IsButtonData = TRUE;
data->Status = HIDP_STATUS_SUCCESS;
data->UsagePage = buttonCaps->UsagePage;
if (buttonCaps->IsRange)
{
data->ButtonData.UsageMin = buttonCaps->Range.UsageMin;
data->ButtonData.UsageMax = buttonCaps->Range.UsageMax;
}
else
{
data->ButtonData.UsageMin = data->ButtonData.UsageMax = buttonCaps->NotRange.Usage;
}
data->ButtonData.MaxUsageLength = HidP_MaxUsageListLength(HidP_Output, buttonCaps->UsagePage, HidDevice->Ppd);
data->ButtonData.Usages = (PUSAGE) calloc(data->ButtonData.MaxUsageLength, sizeof(USAGE));
data->ReportID = buttonCaps->ReportID;
}
for (i = 0; i < HidDevice->Caps.NumberOutputValueCaps ; i++, valueCaps++)
{
if (valueCaps->IsRange)
{
for (usage = valueCaps->Range.UsageMin; usage <= valueCaps->Range.UsageMax; usage++)
{
data->IsButtonData = FALSE;
data->Status = HIDP_STATUS_SUCCESS;
data->UsagePage = valueCaps->UsagePage;
data->ValueData.Usage = usage;
data->ReportID = valueCaps->ReportID;
data++;
}
}
else
{
data->IsButtonData = FALSE;
data->Status = HIDP_STATUS_SUCCESS;
data->UsagePage = valueCaps->UsagePage;
data->ValueData.Usage = valueCaps->NotRange.Usage;
data->ReportID = valueCaps->ReportID;
data++;
}
}
HidDevice->FeatureReportBuffer = (PCHAR) calloc(HidDevice->Caps.FeatureReportByteLength, sizeof(CHAR));
HidDevice->FeatureButtonCaps = buttonCaps = (PHIDP_BUTTON_CAPS) calloc(HidDevice->Caps.NumberFeatureButtonCaps, sizeof(HIDP_BUTTON_CAPS));
if (buttonCaps == NULL)
{
return FALSE;
}
HidDevice->FeatureValueCaps = valueCaps = (PHIDP_VALUE_CAPS) calloc(HidDevice->Caps.NumberFeatureValueCaps, sizeof(HIDP_VALUE_CAPS));
if (valueCaps == NULL)
{
return FALSE;
}
numCaps = HidDevice->Caps.NumberFeatureButtonCaps;
if(numCaps > 0)
{
if(HidP_GetButtonCaps(HidP_Feature, buttonCaps, &numCaps, HidDevice->Ppd) != HIDP_STATUS_SUCCESS)
{
return FALSE;
}
}
numCaps = HidDevice->Caps.NumberFeatureValueCaps;
if(numCaps > 0)
{
if(HidP_GetValueCaps(HidP_Feature, valueCaps, &numCaps, HidDevice->Ppd) != HIDP_STATUS_SUCCESS)
{
return FALSE;
}
}
numValues = 0;
for (i = 0; i < HidDevice->Caps.NumberFeatureValueCaps; i++, valueCaps++)
{
if (valueCaps->IsRange)
{
numValues += valueCaps->Range.UsageMax - valueCaps->Range.UsageMin + 1;
}
else
{
numValues++;
}
}
valueCaps = HidDevice->FeatureValueCaps;
if(FAILED(ULongAdd(HidDevice->Caps.NumberFeatureButtonCaps, numValues, &newFeatureDataLength)))
{
return FALSE;
}
HidDevice->FeatureDataLength = newFeatureDataLength;
HidDevice->FeatureData = data = (PHID_DATA) calloc(HidDevice->FeatureDataLength, sizeof(HID_DATA));
if (data == NULL)
{
return FALSE;
}
dataIdx = 0;
for (i = 0; i < HidDevice->Caps.NumberFeatureButtonCaps; i++, data++, buttonCaps++, dataIdx++)
{
data->IsButtonData = TRUE;
data->Status = HIDP_STATUS_SUCCESS;
data->UsagePage = buttonCaps->UsagePage;
if (buttonCaps->IsRange)
{
data->ButtonData.UsageMin = buttonCaps->Range.UsageMin;
data->ButtonData.UsageMax = buttonCaps->Range.UsageMax;
}
else
{
data->ButtonData.UsageMin = data->ButtonData.UsageMax = buttonCaps->NotRange.Usage;
}
data->ButtonData.MaxUsageLength = HidP_MaxUsageListLength(HidP_Feature, buttonCaps->UsagePage, HidDevice->Ppd);
data->ButtonData.Usages = (PUSAGE) calloc(data->ButtonData.MaxUsageLength, sizeof(USAGE));
data->ReportID = buttonCaps->ReportID;
}
for (i = 0; i < HidDevice->Caps.NumberFeatureValueCaps ; i++, valueCaps++)
{
if (valueCaps->IsRange)
{
for (usage = valueCaps->Range.UsageMin; usage <= valueCaps->Range.UsageMax; usage++)
{
if(dataIdx >= HidDevice->FeatureDataLength)
{
return FALSE;
}
data->IsButtonData = FALSE;
data->Status = HIDP_STATUS_SUCCESS;
data->UsagePage = valueCaps->UsagePage;
data->ValueData.Usage = usage;
data->ReportID = valueCaps->ReportID;
data++; dataIdx++;
}
}
else
{
if(dataIdx >= HidDevice->FeatureDataLength)
{
return FALSE;
}
data->IsButtonData = FALSE;
data->Status = HIDP_STATUS_SUCCESS;
data->UsagePage = valueCaps->UsagePage;
data->ValueData.Usage = valueCaps->NotRange.Usage;
data->ReportID = valueCaps->ReportID;
data++; dataIdx++;
}
}
return TRUE;
}