BOOLEAN FillDeviceInfo()

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;
}