1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
class Device {
public:
....
private:
....
HANDLE hdl_device;
HIDD_ATTRIBUTES hid_dev_attributes;
PSP_DEVICE_INTERFACE_DETAIL_DATA ptr_detail_data;
HDEVINFO hdl_dev_info;
GUID hid_guid;
HANDLE hdl_io_event;
OVERLAPPED overlap_io;
};
void Hid::Device::connect()
throw(DeviceExc::NotAttached, DeviceExc::ApiCallFail)
{
hdl_dev_info = SetupDiGetClassDevs(
&hid_guid,
NULL,
NULL,
DIGCF_PRESENT | DIGCF_INTERFACEDEVICE );
if (!hdl_dev_info)
throw DeviceExc::ApiCallFail(GetLastError());
hdl_io_event = CreateEvent(
NULL,
TRUE,
TRUE,
"");
if (!hdl_io_event)
{
DWORD last_err = GetLastError();
SetupDiDestroyDeviceInfoList(hdl_dev_info);
hdl_dev_info = 0;
throw DeviceExc::ApiCallFail(last_err);
}
overlap_io.hEvent = hdl_io_event;
overlap_io.Offset = 0;
overlap_io.OffsetHigh = 0;
unsigned int interf_indexer = 0;
unsigned char more_available;
do {
SP_DEVICE_INTERFACE_DATA dev_info_data;
dev_info_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
more_available = SetupDiEnumDeviceInterfaces(
hdl_dev_info,
0,
&hid_guid,
interf_indexer,
&dev_info_data);
DWORD length;
SetupDiGetDeviceInterfaceDetail(
hdl_dev_info,
&dev_info_data,
NULL,
0,
&length,
0 );
ptr_detail_data = reinterpret_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA>
(new unsigned char[length]);
ptr_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
BOOL result = SetupDiGetDeviceInterfaceDetail(
hdl_dev_info,
&dev_info_data,
ptr_detail_data,
length,
NULL,
NULL );
if (!result)
{
DWORD last_err = GetLastError();
delete[] ptr_detail_data;
ptr_detail_data = 0;
SetupDiDestroyDeviceInfoList(hdl_dev_info);
hdl_dev_info = 0;
CloseHandle(hdl_io_event);
hdl_io_event = 0;
throw DeviceExc::ApiCallFail(last_err);
}
hdl_device = CreateFile(
ptr_detail_data->DevicePath,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
if (hdl_device != INVALID_HANDLE_VALUE)
{
hid_dev_attributes.Size = sizeof(hid_dev_attributes);
result = HidD_GetAttributes(
hdl_device,
&hid_dev_attributes);
if ( hid_dev_attributes.VendorID == this->vendor_id &&
hid_dev_attributes.ProductID == this->product_id)
return;
CloseHandle(hdl_device);
hdl_device = INVALID_HANDLE_VALUE;
}
delete[] ptr_detail_data;
ptr_detail_data = 0;
interf_indexer++;
} while(more_available);
SetupDiDestroyDeviceInfoList(hdl_dev_info);
hdl_dev_info = 0;
CloseHandle(hdl_io_event);
hdl_io_event = 0;
throw DeviceExc::NotAttached();
}
|