|
|
#include <stdio.h>
#include <windows.h>
#include <basetyps.h>
#include <stdlib.h>
#include <string.h>
#include <wtypes.h>
#include <wtypes.h>
#include "hidsdi.h"
#include "hid.h"
#define INSTRUCTIONS "\nCommands:\n" \
"\t?,h Display this message\n" \ "\t<N> Enter device number \n" \ "\tL LOOP read \n" \ "\tx exit\n"
#define PROMPT "Command!>"
void PrintDeviceinfo(PHID_DEVICE HidDevices, LONG ulCount);
int __cdecl main(int argc, char **argv) { PHID_DEVICE HidDevices, pWalk; LONG ulCount; BOOL bReturn, bDone, bOK; int uiLoop; PHID_DEVICE pDevice; PHID_DATA pData; unsigned uLoop; char sz[256], cCode; int i; DWORD dwDelay=100; bDone = FALSE; bReturn=FindKnownHidDevices(&HidDevices,&ulCount); printf("\n"); if(argc > 1) dwDelay = atoi(argv[1]); if(!bReturn) { printf("Error FindKnownHidDevices returned FALSE\n"); exit(0); } pDevice = HidDevices; if(!pDevice){ printf("Hid Devices are not availabel\n"); exit(0); } PrintDeviceinfo(HidDevices, ulCount);
printf (INSTRUCTIONS);
while (!bDone) { printf (PROMPT); if (gets (sz) == NULL) { sz[0] = 'x'; sz[1] = '\0'; } cCode = sz[0]; // if user types a blank before the command, too bad
switch (cCode) { case 'h': case '?': printf (INSTRUCTIONS); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6' : case '7': case '8': case '9':{ if( cCode - '0' >= ulCount ) { printf("Error invalid input try again\n"); continue; } pDevice = HidDevices + cCode - '0' ; Read(pDevice); pData=pDevice->InputData;
for(uLoop=0;uLoop<pDevice->InputDataLength;uLoop++) { ReportToString(pData); pData++; } /*end for*/
break; } case 'L': // loop read
printf ("Loop read device %d\n", pDevice->HidDevice); Sleep(1000); for (i = 0; i < 1000; i++) { if(!Read(pDevice)) // printf("Read returned false\n");
pData=pDevice->InputData; printf("-------------------------------------------\n"); for(uLoop=0;uLoop<pDevice->InputDataLength;uLoop++) { ReportToString(pData); pData++; } /*end for*/ Sleep(dwDelay); } break;
case 'x': // done
bDone = TRUE; break;
default: printf ("Huh? >%s<\n", sz); printf (INSTRUCTIONS); break; } } // end of while
pWalk= HidDevices; for(uiLoop=0;uiLoop<ulCount;uiLoop++,pWalk++) CloseHandle(pWalk->HidDevice); return 0; }
void PrintDeviceinfo( PHID_DEVICE HidDevices, LONG ulCount ) { PHID_DEVICE pWalk; LONG uiLoop, i, num; PHIDP_VALUE_CAPS pValue; PHIDP_BUTTON_CAPS pButton;
pWalk=HidDevices; for(uiLoop=0;uiLoop<ulCount;uiLoop++, pWalk++) { if(pWalk->Caps.UsagePage == HID_USAGE_PAGE_GENERIC) { switch(pWalk->Caps.Usage){ case HID_USAGE_GENERIC_POINTER: printf("Device (%d) Pointer", uiLoop);break; case HID_USAGE_GENERIC_MOUSE: printf("Device (%d) Mouse", uiLoop);break; case HID_USAGE_GENERIC_PEN: printf("Device (%d) PEN", uiLoop);break; case HID_USAGE_GENERIC_JOYSTICK: printf("Device (%d) Joystick", uiLoop);break; case HID_USAGE_GENERIC_GAMEPAD: printf("Device (%d) GamePad", uiLoop);break; case HID_USAGE_GENERIC_KEYBOARD : printf("Device (%d) Keyboard", uiLoop);break; case HID_USAGE_GENERIC_KEYPAD : printf("Device (%d) Keypad", uiLoop);break; case HID_USAGE_GENERIC_STYLUS2: printf("Device (%d) Stylus2", uiLoop);break; case HID_USAGE_GENERIC_PUCK : printf("Device (%d) Pointer", uiLoop);break; case HID_USAGE_GENERIC_SYSTEM_CTL : printf("Device (%d) System Control", uiLoop);break; default: goto PRN; }// end of switch
} else { PRN: printf("Device (%d) UsagePage:0%x Usage:0%x", uiLoop,pWalk->Caps.UsagePage,pWalk->Caps.Usage); } //pValue = pWalk->InputValueCaps;
if(pWalk->Caps.NumberInputButtonCaps){ pButton = pWalk->InputButtonCaps; for(num=0,i=0;i<pWalk->Caps.NumberInputButtonCaps;i++,pButton++) { num += (pButton->Range.UsageMax - pButton->Range.UsageMin + 1); } printf("\tNumInpBut(%d):%d",pWalk->Caps.NumberInputButtonCaps, num); } if(pWalk->Caps.NumberInputValueCaps){ printf("\tInpValCaps:%d",pWalk->Caps.NumberInputValueCaps); }
if(pWalk->Caps.NumberOutputButtonCaps){ pButton = pWalk->OutputButtonCaps; for(num=0,i=0;i<pWalk->Caps.NumberOutputButtonCaps;i++,pButton++) { num += (pButton->Range.UsageMax - pButton->Range.UsageMin + 1); } printf("\tNumOutBut(%d):%d",pWalk->Caps.NumberOutputButtonCaps, num); } if(pWalk->Caps.NumberOutputValueCaps){ printf("\tOutButCaps:%d\n",pWalk->Caps.NumberOutputValueCaps); }
if(pWalk->Caps.NumberFeatureButtonCaps){ pButton = pWalk->FeatureButtonCaps; for(num=0,i=0;i<pWalk->Caps.NumberFeatureButtonCaps;i++,pButton++) { num += (pButton->Range.UsageMax - pButton->Range.UsageMin + 1); } printf("\tNumFeatBut(%d):%d",pWalk->Caps.NumberFeatureButtonCaps, num); } if(pWalk->Caps.NumberFeatureValueCaps){ printf("\tFeatButCaps:%d\n",pWalk->Caps.NumberFeatureValueCaps); } printf("\n"); } /*end for*/
}
BOOLEAN FindKnownHidDevices ( OUT PHID_DEVICE * HidDevices, // A array of struct _HID_DEVICE
OUT PULONG NumberDevices // the length of this array.
) /*++
Routine Description: Do the required PnP things in order to find, the all the HID devices in the system at this time. --*/ { HDEVINFO hardwareDeviceInfo; SP_DEVICE_INTERFACE_DATA deviceInfoData; ULONG i; BOOL done; PHID_DEVICE hidDeviceInst; GUID hidGuid;
HidD_GetHidGuid (&hidGuid);
*HidDevices = NULL; *NumberDevices = 0;
//
// Open a handle to the plug and play dev node.
//
hardwareDeviceInfo = SetupDiGetClassDevs ( &hidGuid, NULL, // Define no enumerator (global)
NULL, // Define no
(DIGCF_PRESENT | // Only Devices present
DIGCF_DEVICEINTERFACE)); // Function class devices.
//
// Take a wild guess to start
//
*NumberDevices = 4; done = FALSE; deviceInfoData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);
i=0; while (!done) { *NumberDevices *= 2;
if (*HidDevices) { *HidDevices = realloc (*HidDevices, (*NumberDevices * sizeof (HID_DEVICE))); } else { *HidDevices = calloc (*NumberDevices, sizeof (HID_DEVICE)); }
if (NULL == *HidDevices) { SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); return FALSE; }
hidDeviceInst = *HidDevices + i;
for (; i < *NumberDevices; i++, hidDeviceInst++) { if (SetupDiEnumDeviceInterfaces (hardwareDeviceInfo, 0, // No care about specific PDOs
&hidGuid, i, &deviceInfoData)) {
OpenHidDevice (hardwareDeviceInfo, &deviceInfoData, hidDeviceInst);
} else { if (ERROR_NO_MORE_ITEMS == GetLastError()) { done = TRUE; break; } } } }
*NumberDevices = i;
SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); return TRUE; }
VOID ReportToString( PHID_DATA pData ) { PUSAGE pUsage; ULONG i;
if (pData->IsButtonData && pData->UsagePage == HID_USAGE_PAGE_BUTTON ) { printf (" Buttons :"); for (i=0, pUsage = pData->ButtonData.Usages; i < pData->ButtonData.MaxUsageLength; i++, pUsage++) { if (0 == *pUsage) { break; // A usage of zero is a non button.
} printf (" 0x%x", *pUsage); } printf("\n"); } else { switch(pData->UsagePage) { case HID_USAGE_PAGE_GENERIC : case HID_USAGE_PAGE_VEHICLE : switch(pData->ValueData.Usage) { case HID_USAGE_VEHICLE_THROTTLE: printf(" THROTTLE(%4d) :%4d\n", pData->ValueData.ScaledValue, pData->ValueData.Value); break; case HID_USAGE_VEHICLE_RUDDER: printf(" RUDDER(%4d) :%4d\n", pData->ValueData.ScaledValue, pData->ValueData.Value); break; case HID_USAGE_GENERIC_X: printf(" X(%4d) :%4d\n", pData->ValueData.ScaledValue, pData->ValueData.Value); break; case HID_USAGE_GENERIC_Y: printf(" Y(%4d) :%4d\n", pData->ValueData.ScaledValue, pData->ValueData.Value); break; case HID_USAGE_GENERIC_Z: printf(" Z(%4d) :%4d\n", pData->ValueData.ScaledValue, pData->ValueData.Value); break; case HID_USAGE_GENERIC_RX: printf(" RX(%4d) :%4d\n", pData->ValueData.ScaledValue, pData->ValueData.Value); break; case HID_USAGE_GENERIC_RY: printf(" RY(%4d) :%4d\n", pData->ValueData.ScaledValue, pData->ValueData.Value); break; case HID_USAGE_GENERIC_RZ: printf(" RZ(%4d) :%4d\n", pData->ValueData.ScaledValue, pData->ValueData.Value); break; case HID_USAGE_GENERIC_SLIDER: printf(" SLIDDER(%4d) :%4d\n", pData->ValueData.ScaledValue, pData->ValueData.Value); break; case HID_USAGE_GENERIC_DIAL: printf(" DIAL(%4d) :%4d\n", pData->ValueData.ScaledValue, pData->ValueData.Value); break; case HID_USAGE_GENERIC_WHEEL: printf(" WHEEL(%4d) :%4d\n", pData->ValueData.ScaledValue, pData->ValueData.Value); break;
case HID_USAGE_GENERIC_HATSWITCH: printf(" HATSWITCH(%4d):%4d\n", pData->ValueData.ScaledValue, pData->ValueData.Value); break; default: goto END; break; }// end of switch
break; case HID_USAGE_PAGE_KEYBOARD: switch(pData->ValueData.Usage) { case HID_USAGE_GENERIC_KEYBOARD: printf(" KEYBOARD(%4d) :%4d\n", pData->ValueData.ScaledValue, pData->ValueData.Value); break; case HID_USAGE_GENERIC_KEYPAD: printf(" KEYPAD(%4d) :%4d\n", pData->ValueData.ScaledValue, pData->ValueData.Value); break; default: goto END; break; }// end of switch
default: END: printf ("Usage Page: 0x%x, Usage: 0x%x, Scaled: %d Value:%d\n", pData->UsagePage, pData->ValueData.Usage, pData->ValueData.ScaledValue, pData->ValueData.Value); }//end of switch
} }
BOOLEAN Read ( PHID_DEVICE HidDevice ) /*++
RoutineDescription: Given a struct _HID_DEVICE, obtain a read report and unpack the values into to InputData array. --*/ { DWORD bytesRead;
if (!ReadFile (HidDevice->HidDevice, HidDevice->InputReportBuffer, HidDevice->Caps.InputReportByteLength, &bytesRead, NULL)) { // No overlapped structure. HidClass buffers for us.
return FALSE; }
ASSERT (bytesRead == hidDevice->Caps.InputReportByteLength);
return UnpackReport (HidDevice->InputReportBuffer, HidDevice->Caps.InputReportByteLength, HidP_Input, HidDevice->InputData, HidDevice->InputDataLength, HidDevice->Ppd); }
BOOL UnpackReport ( IN PCHAR ReportBuffer, IN USHORT ReportBufferLength, IN HIDP_REPORT_TYPE ReportType, IN OUT PHID_DATA Data, IN ULONG DataLength, IN PHIDP_PREPARSED_DATA Ppd ) /*++
Routine Description:
--*/ { ULONG numUsages; // Number of usages returned from GetUsages.
ULONG i;
for (i = 0; i < DataLength; i++, Data++) { if (Data->IsButtonData) { numUsages = Data->ButtonData.MaxUsageLength; Data->Status = HidP_GetUsages ( ReportType, Data->UsagePage, 0, // All collections
Data->ButtonData.Usages, &numUsages, Ppd, ReportBuffer, ReportBufferLength); //
// Get usages writes the list of usages into the buffer
// Data->ButtonData.Usages newUsage is set to the number of usages
// written into this array.
// We assume that there will not be a usage of zero.
// (None have been defined to date.)
// So lets assume that a zero indicates an end of the list of usages.
//
if (numUsages < Data->ButtonData.MaxUsageLength) { Data->ButtonData.Usages[numUsages] = 0; }
} else { Data->Status = HidP_GetUsageValue ( ReportType, Data->UsagePage, 0, // All Collections.
Data->ValueData.Usage, &Data->ValueData.Value, Ppd, ReportBuffer, ReportBufferLength);
Data->Status = HidP_GetScaledUsageValue ( ReportType, Data->UsagePage, 0, // All Collections.
Data->ValueData.Usage, &Data->ValueData.ScaledValue, Ppd, ReportBuffer, ReportBufferLength); } } return (HIDP_STATUS_SUCCESS == Data->Status); }
BOOLEAN OpenHidDevice ( IN HDEVINFO HardwareDeviceInfo, IN PSP_DEVICE_INTERFACE_DATA DeviceInfoData, IN OUT PHID_DEVICE HidDevice ) /*++
RoutineDescription: Given the HardwareDeviceInfo, representing a handle to the plug and play information, and deviceInfoData, representing a specific hid device, open that device and fill in all the relivant information in the given HID_DEVICE structure.
return if the open and initialization was successfull or not.
--*/ { PSP_DEVICE_INTERFACE_DETAIL_DATA functionClassDeviceData = NULL; ULONG predictedLength = 0; ULONG requiredLength = 0; ULONG i; ULONG numValues; USHORT numCaps; PHIDP_BUTTON_CAPS buttonCaps; PHIDP_VALUE_CAPS valueCaps; PHID_DATA data; USAGE usage; static ULONG NumberDevices = 0;
//
// allocate a function class device data structure to receive the
// goods about this particular device.
//
SetupDiGetDeviceInterfaceDetail ( HardwareDeviceInfo, DeviceInfoData, NULL, // probing so no output buffer yet
0, // probing so output buffer length of zero
&requiredLength, NULL); // not interested in the specific dev-node
predictedLength = requiredLength;
functionClassDeviceData = malloc (predictedLength); functionClassDeviceData->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);
//
// Retrieve the information from Plug and Play.
//
if (! SetupDiGetDeviceInterfaceDetail ( HardwareDeviceInfo, DeviceInfoData, functionClassDeviceData, predictedLength, &requiredLength, NULL)) { return FALSE; } //printf("\nDevicePath of %d HID device: %s\n", NumberDevices,
// functionClassDeviceData->DevicePath);
HidDevice->HidDevice = CreateFile ( functionClassDeviceData->DevicePath, GENERIC_READ | GENERIC_WRITE, 0, // FILE_SHARE_READ | FILE_SHARE_WRITE
NULL, // no SECURITY_ATTRIBUTES structure
OPEN_EXISTING, // No special create flags
0, // No special attributes
NULL); // No template file
if (INVALID_HANDLE_VALUE == HidDevice->HidDevice) { return FALSE; } if (!HidD_GetPreparsedData (HidDevice->HidDevice, &HidDevice->Ppd)) { return FALSE; }
if (!HidP_GetCaps (HidDevice->Ppd, &HidDevice->Caps)) { HidD_FreePreparsedData (HidDevice->Ppd); return FALSE; }
NumberDevices++; //
// At this point the client has a choise. It may chose to look at the
// Usage and Page of the top level collection found in the HIDP_CAPS
// structure. In this way it could just use the usages it knows about.
// If either HidP_GetUsages or HidP_GetUsageValue return an error then
// that particular usage does not exist in the report.
// This is most likely the preferred method as the application can only
// use usages of which it already knows.
// In this case the app need not even call GetButtonCaps or GetValueCaps.
//
// In this example, however, we look for all of the usages in the device.
//
//
// setup Input Data buffers.
//
//
// Allocate memory to hold on input report
//
HidDevice->InputReportBuffer = (PCHAR) calloc (HidDevice->Caps.InputReportByteLength, sizeof (CHAR));
//
// Allocate memory to hold the button and value capabilities.
// NumberXXCaps is in terms of array elements.
//
HidDevice->InputButtonCaps = buttonCaps = (PHIDP_BUTTON_CAPS) calloc (HidDevice->Caps.NumberInputButtonCaps, sizeof (HIDP_BUTTON_CAPS)); HidDevice->InputValueCaps = valueCaps = (PHIDP_VALUE_CAPS) calloc (HidDevice->Caps.NumberInputValueCaps, sizeof (HIDP_VALUE_CAPS));
//
// Have the HidP_X functions fill in the capability structure arrays.
//
numCaps = HidDevice->Caps.NumberInputButtonCaps; HidP_GetButtonCaps (HidP_Input, buttonCaps, &numCaps, HidDevice->Ppd);
numCaps = HidDevice->Caps.NumberInputValueCaps; HidP_GetValueCaps (HidP_Input, valueCaps, &numCaps, HidDevice->Ppd);
//
// Depending on the device, some value caps structures may represent more
// than one value. (A range). In the interest of being verbose, over
// efficient we will expand these so that we have one and only one
// struct _HID_DATA for each value.
//
// To do this we need to count up the total number of values are listed
// in the value caps structure. For each element in the array we test
// for range if it is a range then UsageMax and UsageMin describe the
// usages for this range INCLUSIVE.
//
numValues = 0; for (i = 0; i < HidDevice->Caps.NumberInputValueCaps; i++, valueCaps++) { if (valueCaps->IsRange) { numValues += valueCaps->Range.UsageMax - valueCaps->Range.UsageMin + 1; } else { numValues++; } } valueCaps = HidDevice->InputValueCaps;
//
// Allocate a buffer to hold the struct _HID_DATA structures.
// One element for each set of buttons, and one element for each value
// found.
//
HidDevice->InputDataLength = HidDevice->Caps.NumberInputButtonCaps + numValues; HidDevice->InputData = data = (PHID_DATA) calloc (HidDevice->InputDataLength, sizeof (HID_DATA));
//
// Fill in the button data
//
for (i = 0; i < HidDevice->Caps.NumberInputButtonCaps; i++, data++, buttonCaps++) {
data->IsButtonData = TRUE; data->Status = HIDP_STATUS_SUCCESS; data->UsagePage = buttonCaps->UsagePage; data->ButtonData.MaxUsageLength = HidP_MaxUsageListLength ( HidP_Input, buttonCaps->UsagePage, HidDevice->Ppd); data->ButtonData.Usages = (PUSAGE) calloc (data->ButtonData.MaxUsageLength, sizeof (USAGE)); }
//
// Fill in the value data
//
for (i = 0; i < numValues; 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++; } } else { data->IsButtonData = FALSE; data->Status = HIDP_STATUS_SUCCESS; data->UsagePage = valueCaps->UsagePage; data->ValueData.Usage = valueCaps->NotRange.Usage; data++; } } //return TRUE; // no need to get other info
//
// setup Output Data buffers.
//
HidDevice->OutputReportBuffer = (PCHAR) calloc (HidDevice->Caps.OutputReportByteLength, sizeof (CHAR));
HidDevice->OutputButtonCaps = buttonCaps = (PHIDP_BUTTON_CAPS) calloc (HidDevice->Caps.NumberOutputButtonCaps, sizeof (HIDP_BUTTON_CAPS)); HidDevice->OutputValueCaps = valueCaps = (PHIDP_VALUE_CAPS) calloc (HidDevice->Caps.NumberOutputValueCaps, sizeof (HIDP_VALUE_CAPS));
numCaps = HidDevice->Caps.NumberOutputButtonCaps; HidP_GetButtonCaps (HidP_Output, buttonCaps, &numCaps, HidDevice->Ppd);
numCaps = HidDevice->Caps.NumberOutputValueCaps; HidP_GetValueCaps (HidP_Output, valueCaps, &numCaps, HidDevice->Ppd);
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));
for (i = 0; i < HidDevice->Caps.NumberOutputButtonCaps; i++, data++, buttonCaps++) {
data->IsButtonData = TRUE; data->Status = HIDP_STATUS_SUCCESS; data->UsagePage = buttonCaps->UsagePage; data->ButtonData.MaxUsageLength = HidP_MaxUsageListLength ( HidP_Output, buttonCaps->UsagePage, HidDevice->Ppd); data->ButtonData.Usages = (PUSAGE) calloc (data->ButtonData.MaxUsageLength, sizeof (USAGE)); }
for (i = 0; i < numValues; 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++; } } else { data->IsButtonData = FALSE; data->Status = HIDP_STATUS_SUCCESS; data->UsagePage = valueCaps->UsagePage; data->ValueData.Usage = valueCaps->NotRange.Usage; data++; } }
//
// setup Feature Data buffers.
//
HidDevice->FeatureReportBuffer = (PCHAR) calloc (HidDevice->Caps.FeatureReportByteLength, sizeof (CHAR));
HidDevice->FeatureButtonCaps = buttonCaps = (PHIDP_BUTTON_CAPS) calloc (HidDevice->Caps.NumberFeatureButtonCaps, sizeof (HIDP_BUTTON_CAPS)); HidDevice->FeatureValueCaps = valueCaps = (PHIDP_VALUE_CAPS) calloc (HidDevice->Caps.NumberFeatureValueCaps, sizeof (HIDP_VALUE_CAPS));
numCaps = HidDevice->Caps.NumberFeatureButtonCaps; HidP_GetButtonCaps (HidP_Feature, buttonCaps, &numCaps, HidDevice->Ppd);
numCaps = HidDevice->Caps.NumberFeatureValueCaps; HidP_GetValueCaps (HidP_Feature, valueCaps, &numCaps, HidDevice->Ppd);
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;
HidDevice->FeatureDataLength = HidDevice->Caps.NumberFeatureButtonCaps + numValues; HidDevice->FeatureData = data = (PHID_DATA) calloc (HidDevice->FeatureDataLength, sizeof (HID_DATA));
for (i = 0; i < HidDevice->Caps.NumberFeatureButtonCaps; i++, data++, buttonCaps++) {
data->IsButtonData = TRUE; data->Status = HIDP_STATUS_SUCCESS; data->UsagePage = buttonCaps->UsagePage; data->ButtonData.MaxUsageLength = HidP_MaxUsageListLength ( HidP_Feature, buttonCaps->UsagePage, HidDevice->Ppd); data->ButtonData.Usages = (PUSAGE) calloc (data->ButtonData.MaxUsageLength, sizeof (USAGE)); }
for (i = 0; i < numValues; 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++; } } else { data->IsButtonData = FALSE; data->Status = HIDP_STATUS_SUCCESS; data->UsagePage = valueCaps->UsagePage; data->ValueData.Usage = valueCaps->NotRange.Usage; data++; } }
return TRUE; }
|