Cool Thanks!
I need to use HidD_GetInputReport(). So by device support you mean from the host side or BLE device? I'm pretty sure my BLE device sends Input reports using control transfers. When InputReportBuffer[0] = 0, I received an error code of 87 (which is I guess ERROR_INVALID_PARAMETER). When InputReportBuffer[0] = 1, I received an error code of 122 (which is I guess ERROR_INSUFFICIENT_BUFFER).
If I use ReadFile(), I received an error code of 997 (ERROR_IO_PENDING).
I have pasted my new code & output. What is NumberInputValueCaps? Is it the number of endpoints? How do I use Get Report control transfer? Is there anything I'm missing out in my code? I also tried setting last 2 parameters in CreateFile() to NULL but did not work.
#include <iostream>
#include <windows.h>
#include <hidclass.h>
#include <hidsdi.h>
#include <setupapi.h>
#include <devguid.h>
#include <regstr.h>
#pragma comment(lib,"hid")
int main()
{
GUID HidGuid;
HidD_GetHidGuid(&HidGuid);
//HANDLE DeviceInfoSet;
HDEVINFO DeviceInfoSet;
DeviceInfoSet = SetupDiGetClassDevs(&HidGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if(DeviceInfoSet== INVALID_HANDLE_VALUE)
return NULL;
SP_DEVICE_INTERFACE_DATA MyDeviceInterfaceData;
MyDeviceInterfaceData.cbSize = sizeof(MyDeviceInterfaceData);
SP_DEVINFO_DATA dd;
dd.cbSize = sizeof(SP_DEVINFO_DATA);
HANDLE DeviceHandle=NULL;
for (DWORD MemberIndex = 0; SetupDiEnumDeviceInterfaces(DeviceInfoSet, 0, &HidGuid, MemberIndex, &MyDeviceInterfaceData); MemberIndex++)
{
SP_DEVICE_INTERFACE_DETAIL_DATA DetailData;
DetailData.cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
DWORD Length = 0;
if (!SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, &MyDeviceInterfaceData, NULL, 0, &Length, NULL))
{
int err = GetLastError();
if (err == ERROR_NO_MORE_ITEMS)
break;
PSP_DEVICE_INTERFACE_DETAIL_DATA pInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)GlobalAlloc(GPTR, Length);
pInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (!SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, &MyDeviceInterfaceData, pInterfaceDetailData, Length, &Length, &dd))
break;
DeviceHandle = CreateFile(pInterfaceDetailData->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, 0, NULL);
HIDD_ATTRIBUTES Attributes;
Attributes.Size = sizeof(Attributes);
HidD_GetAttributes(DeviceHandle, &Attributes);
const unsigned int VendorID = 0x1F38;
const unsigned int ProductID = 0x0100;
if (Attributes.VendorID == VendorID)
{
if (Attributes.ProductID == ProductID)
{
std::cout << "The Vendor ID and Product ID match.";
std::cout << "\nDeviceHandle: " << DeviceHandle;
std::cout << "\nVendor ID: " << Attributes.VendorID;
std::cout << "\nProduct ID: " << Attributes.ProductID;
std::cout << "\nVersionNumber: " << Attributes.VersionNumber;
std::cout << "\nSize: " << Attributes.Size;
PHIDP_PREPARSED_DATA PreparsedData;
HidD_GetPreparsedData(DeviceHandle, &PreparsedData);
HIDP_CAPS Capabilities;
HidP_GetCaps(PreparsedData, &Capabilities);
std::cout << "\nUsage: " << Capabilities.Usage;
std::cout << "\nUsagePage: " << Capabilities.UsagePage;
std::cout << "\nInputReportByteLength: " << Capabilities.InputReportByteLength;
std::cout << "\nOutputReportByteLength: " << Capabilities.OutputReportByteLength;
std::cout << "\nNumberLinkCollectionNodes: " << Capabilities.NumberLinkCollectionNodes;
std::cout << "\nNumberInputButtonCaps: " << Capabilities.NumberInputButtonCaps;
std::cout << "\nNumberInputValueCaps: " << Capabilities.NumberInputValueCaps;
std::cout << "\nNumberInputDataIndices: " << Capabilities.NumberInputDataIndices;
std::cout << "\nNumberOutputButtonCaps: " << Capabilities.NumberOutputButtonCaps;
std::cout << "\nNumberOutputValueCaps: " << Capabilities.NumberOutputValueCaps;
std::cout << "\nNumberOutputDataIndices: " << Capabilities.NumberOutputDataIndices;
CHAR InputReportBuffer[3];
DWORD BytesRead;
DWORD Result;
HANDLE hEventObject;
OVERLAPPED HIDOverlapped;
hEventObject = CreateEvent((LPSECURITY_ATTRIBUTES)NULL, FALSE, TRUE, NULL);
HIDOverlapped.hEvent = hEventObject;
HIDOverlapped.Offset = 0;
HIDOverlapped.OffsetHigh = 0;
InputReportBuffer[0] = 0; // Report Id
HANDLE ReadHandle = CreateFile(pInterfaceDetailData->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); //NULL, NULL);
if (ReadHandle == INVALID_HANDLE_VALUE)
std::cout << "\ncould not open"; //printf("Warning: CreateFile failed: %d\n", GetLastError());
else
std::cout << "\nopened";
Result = HidD_GetInputReport(ReadHandle, InputReportBuffer, Capabilities.InputReportByteLength);
DWORD err = GetLastError();
std::cout << "\nerr: " << err;
if (Result)
{
std::cout << "\nSuccess";
for (int i = 0; i < Capabilities.InputReportByteLength; i++)
{
std::cout << "\nInput Report Data: " << InputReportBuffer[i];
}
}
else
std::cout << "\nFailed to get report";
}
}
GlobalFree(pInterfaceDetailData);
}
}
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
}