#include "stdafx.h" #include "TuonoLib.h" #include #include #include #include #include using namespace std; #define MAX_LOADSTRING 256 extern "C" { // This file is in the Windows DDK available from Microsoft. #include "hidsdi.h" #include #include } #pragma once static const int WIIMOTE_VENDOR_ID = 0x057E; static const int WIIMOTE_PRODUCT_ID = 0x0306; class TUONOLIB_API HIDDevice { protected: int m_controller_id; HIDP_CAPS m_capabilities; HANDLE m_device_handle, m_read_handle, m_write_handle; HANDLE m_event_object; OVERLAPPED m_hid_overlapped; LPOVERLAPPED m_lp_overlap; wstring m_device_path_name; public: HIDDevice(void); ~HIDDevice(void); //static RegisterForDeviceNotifications(Wiimote & device); static void PrepareForOverlappedTransfer(HIDDevice & device, PSP_DEVICE_INTERFACE_DETAIL_DATA & detailData); static void GetDeviceCapabilities(HIDDevice & device); bool WriteOutputReport(char out_bytes[]); /* This function is templated in order to support instantiation of subclassed versions of Wiimote */ template static vector ConnectToHIDDevices() { vector devices; HANDLE WriteHandle = 0, DeviceHandle = 0; HANDLE hDevInfo; HIDD_ATTRIBUTES Attributes; SP_DEVICE_INTERFACE_DATA devInfoData; int MemberIndex = 0; LONG Result; GUID HidGuid; PSP_DEVICE_INTERFACE_DETAIL_DATA detailData; ULONG Required = 0; ULONG Length = 0; detailData = NULL; DeviceHandle = NULL; HidD_GetHidGuid(&HidGuid); hDevInfo = SetupDiGetClassDevs(&HidGuid, NULL, NULL, DIGCF_PRESENT|DIGCF_INTERFACEDEVICE); devInfoData.cbSize = sizeof(devInfoData); MemberIndex = 0; do { // Got any more devices? Result = SetupDiEnumDeviceInterfaces (hDevInfo, 0, &HidGuid, MemberIndex, &devInfoData); if (Result == 0) break; // Call once to get the needed buffer length Result = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, NULL, 0, &Length, NULL); detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length); detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); // After allocating, call again to get data Result = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, detailData, Length, &Required, NULL); DeviceHandle = CreateFile(detailData->DevicePath, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, 0, NULL); Attributes.Size = sizeof(Attributes); Result = HidD_GetAttributes(DeviceHandle, &Attributes); if (Attributes.VendorID == WIIMOTE_VENDOR_ID && Attributes.ProductID == WIIMOTE_PRODUCT_ID) { // If the vendor and product IDs match, we've found a wiimote T device; device.m_device_path_name = detailData->DevicePath; device.m_device_handle = DeviceHandle; // Register to receive device notifications. // RegisterForDeviceNotifications(); GetDeviceCapabilities(device); device.m_write_handle = CreateFile(detailData->DevicePath, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, 0, NULL); PrepareForOverlappedTransfer(device, detailData); device.m_controller_id = int(devices.size()) + 1; devices.push_back(device); } else { CloseHandle(DeviceHandle); } free(detailData); MemberIndex = MemberIndex + 1; } while (true); SetupDiDestroyDeviceInfoList(hDevInfo); return devices; } };