diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..1a91911 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,120 @@ +cmake_minimum_required (VERSION 2.8.1) + +############################################################ +# Project +############################################################ +project (libhid) +set (name hid) + +############################################################ +# Sources +############################################################ +set (file_inc_common + include/device.h + include/element.h + include/enumerator.h + include/filter.h + include/hid.h + ) +set (file_src_win + win32/device.cc + win32/enumerator.cc + win32/hid.cc + ) +set (file_inc_win + win32/auto_free.h + win32/button.h + win32/collection.h + win32/common.h + win32/device.h + win32/element.h + win32/enumerator.h + win32/value.h + ) +set (file_src_macos + macos/device.cc + macos/element.cc + macos/enumerator.cc + macos/hid.cc + macos/util.cc + ) +set (file_inc_macos + macos/common.h + macos/device.h + macos/element.h + macos/enumerator.h + macos/util.h + ) +set (file_src_linux + ) +set (file_inc_linux + ) + +set (file_inc ${file_inc_common}) +if (WIN32) + set (file_src ${file_src} ${file_src_win}) + set (file_inc ${file_inc} ${file_inc_win}) +elseif (APPLE) + set (file_src ${file_src} ${file_src_macos}) + set (file_inc ${file_inc} ${file_inc_macos}) +elseif (UNIX) + set (file_src ${file_src} ${file_src_linux}) + set (file_inc ${file_inc} ${file_inc_linux}) +endif () + +if (WIN32) + source_group ("common" FILES ${file_inc_common}) +endif () + +############################################################ +# Build +############################################################ +set (dir_inc + include) +set (dir_lib + ) + +include_directories (${dir_inc}) + +link_directories (${dir_lib}) + +add_definitions (-DUNICODE) +set (CMAKE_MODULE_LINKER_FLAGS "-static-libstdc++") + +############################################################ +# Target +############################################################ +set (target_static lib${name}-static) + +add_library (${target_static} STATIC ${file_src} ${file_inc}) + +if (WIN32) + set (file_name_static lib${name}) +else () + set (file_name_static ${name}) +endif () + +set_target_properties (${target_static} PROPERTIES + OUTPUT_NAME ${file_name_static} + OUTPUT_NAME_DEBUG ${file_name_static}d + ) + +#target_link_libraries (${target_shared} ) + +############################################################ +# Install +############################################################ +if (WIN32) + set (CMAKE_INSTALL_LIBDIR lib) + set (CMAKE_INSTALL_INCLUDEDIR include) +else (WIN32) + #include (GNUInstallDirs) + if (NOT DEFINED CMAKE_INSTALL_LIBDIR) + set (CMAKE_INSTALL_LIBDIR ${CMAKE_INSTALL_PREFIX}/lib) + endif () + if (NOT DEFINED CMAKE_INSTALL_INCLUDEDIR) + set (CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX}/include) + endif () +endif (WIN32) + +install (TARGETS ${target_static} DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/include/element.h b/include/element.h index d09de16..78b7042 100644 --- a/include/element.h +++ b/include/element.h @@ -7,6 +7,17 @@ #include #include +// workaround for no 'stdint.h' support before msvc 10 +#if defined(_MSC_VER) && _MSC_VER < 1600 +# include "stdint.h" +#else +# include +#endif + +#if defined(_MSC_VER) + typedef int ssize_t; +#endif + namespace HID { class device_type; diff --git a/include/filter.h b/include/filter.h index b8163ce..f8a636d 100644 --- a/include/filter.h +++ b/include/filter.h @@ -47,7 +47,7 @@ class HID::filter_set : public filter_type void push_back(filter_type* f) { children.push_back(f); } }; -struct HID::filter::And : public filter_set +class HID::filter::And : public filter_set { bool accept(device_type& device) { @@ -74,7 +74,7 @@ class HID::filter::Not : public filter_type } }; -struct HID::filter::Or : public filter_set +class HID::filter::Or : public filter_set { bool accept(device_type& device) { diff --git a/include/stdint.h b/include/stdint.h new file mode 100644 index 0000000..6423fc8 --- /dev/null +++ b/include/stdint.h @@ -0,0 +1,199 @@ +/* stdint.h standard header */ +#pragma once +#ifndef _STDINT +#define _STDINT +#ifndef RC_INVOKED +#include + +/* NB: assumes + byte has 8 bits + long is 32 bits + pointer can convert to and from long long + long long is longest type + */ + +_C_STD_BEGIN + /* TYPE DEFINITIONS */ +typedef signed char int8_t; +typedef short int16_t; +typedef int int32_t; + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; + +typedef signed char int_least8_t; +typedef short int_least16_t; +typedef int int_least32_t; + +typedef unsigned char uint_least8_t; +typedef unsigned short uint_least16_t; +typedef unsigned int uint_least32_t; + +typedef char int_fast8_t; +typedef int int_fast16_t; +typedef int int_fast32_t; + +typedef unsigned char uint_fast8_t; +typedef unsigned int uint_fast16_t; +typedef unsigned int uint_fast32_t; + +#ifndef _INTPTR_T_DEFINED + #define _INTPTR_T_DEFINED + #ifdef _WIN64 +typedef __int64 intptr_t; + #else /* _WIN64 */ +typedef _W64 int intptr_t; + #endif /* _WIN64 */ +#endif /* _INTPTR_T_DEFINED */ + +#ifndef _UINTPTR_T_DEFINED + #define _UINTPTR_T_DEFINED + #ifdef _WIN64 +typedef unsigned __int64 uintptr_t; + #else /* _WIN64 */ +typedef _W64 unsigned int uintptr_t; + #endif /* _WIN64 */ +#endif /* _UINTPTR_T_DEFINED */ + +typedef _Longlong int64_t; +typedef _ULonglong uint64_t; + +typedef _Longlong int_least64_t; +typedef _ULonglong uint_least64_t; + +typedef _Longlong int_fast64_t; +typedef _ULonglong uint_fast64_t; + +typedef _Longlong intmax_t; +typedef _ULonglong uintmax_t; + + /* LIMIT MACROS */ +#define INT8_MIN (-0x7f - _C2) +#define INT16_MIN (-0x7fff - _C2) +#define INT32_MIN (-0x7fffffff - _C2) + +#define INT8_MAX 0x7f +#define INT16_MAX 0x7fff +#define INT32_MAX 0x7fffffff +#define UINT8_MAX 0xff +#define UINT16_MAX 0xffff +#define UINT32_MAX 0xffffffff + +#define INT_LEAST8_MIN (-0x7f - _C2) +#define INT_LEAST16_MIN (-0x7fff - _C2) +#define INT_LEAST32_MIN (-0x7fffffff - _C2) + +#define INT_LEAST8_MAX 0x7f +#define INT_LEAST16_MAX 0x7fff +#define INT_LEAST32_MAX 0x7fffffff +#define UINT_LEAST8_MAX 0xff +#define UINT_LEAST16_MAX 0xffff +#define UINT_LEAST32_MAX 0xffffffff + +#define INT_FAST8_MIN (-0x7f - _C2) +#define INT_FAST16_MIN (-0x7fff - _C2) +#define INT_FAST32_MIN (-0x7fffffff - _C2) + +#define INT_FAST8_MAX 0x7f +#define INT_FAST16_MAX 0x7fff +#define INT_FAST32_MAX 0x7fffffff +#define UINT_FAST8_MAX 0xff +#define UINT_FAST16_MAX 0xffff +#define UINT_FAST32_MAX 0xffffffff + + #if _INTPTR == 0 || _INTPTR == 1 +#define INTPTR_MAX 0x7fffffff +#define INTPTR_MIN (-INTPTR_MAX - _C2) +#define UINTPTR_MAX 0xffffffff + + #else /* _INTPTR == 2 */ +#define INTPTR_MIN (-_LLONG_MAX - _C2) +#define INTPTR_MAX _LLONG_MAX +#define UINTPTR_MAX _ULLONG_MAX +#endif /* _INTPTR */ + +#define INT8_C(x) (x) +#define INT16_C(x) (x) +#define INT32_C(x) ((x) + (INT32_MAX - INT32_MAX)) + +#define UINT8_C(x) (x) +#define UINT16_C(x) (x) +#define UINT32_C(x) ((x) + (UINT32_MAX - UINT32_MAX)) + +#ifdef _WIN64 + #define PTRDIFF_MIN INT64_MIN + #define PTRDIFF_MAX INT64_MAX +#else /* _WIN64 */ + #define PTRDIFF_MIN INT32_MIN + #define PTRDIFF_MAX INT32_MAX +#endif /* _WIN64 */ + +#define SIG_ATOMIC_MIN INT32_MIN +#define SIG_ATOMIC_MAX INT32_MAX + +#ifndef SIZE_MAX + #ifdef _WIN64 + #define SIZE_MAX UINT64_MAX + #else /* _WIN64 */ + #define SIZE_MAX UINT32_MAX + #endif /* _WIN64 */ +#endif /* SIZE_MAX */ + +#define WCHAR_MIN 0x0000 +#define WCHAR_MAX 0xffff + +#define WINT_MIN 0x0000 +#define WINT_MAX 0xffff + + #define INT64_MIN (-0x7fffffffffffffff - _C2) + #define INT64_MAX 0x7fffffffffffffff + #define UINT64_MAX 0xffffffffffffffffU + + #define INT_LEAST64_MIN (-0x7fffffffffffffff - _C2) + #define INT_LEAST64_MAX 0x7fffffffffffffff + #define UINT_LEAST64_MAX 0xffffffffffffffffU + + #define INT_FAST64_MIN (-0x7fffffffffffffff - _C2) + #define INT_FAST64_MAX 0x7fffffffffffffff + #define UINT_FAST64_MAX 0xffffffffffffffffU + + #define INTMAX_MIN (-0x7fffffffffffffff - _C2) + #define INTMAX_MAX 0x7fffffffffffffff + #define UINTMAX_MAX 0xffffffffffffffffU + +#define INT64_C(x) ((x) + (INT64_MAX - INT64_MAX)) +#define UINT64_C(x) ((x) + (UINT64_MAX - UINT64_MAX)) +#define INTMAX_C(x) INT64_C(x) +#define UINTMAX_C(x) UINT64_C(x) +_C_STD_END +#endif /* RC_INVOKED */ +#endif /* _STDINT */ + + #if defined(_STD_USING) +using _CSTD int8_t; using _CSTD int16_t; +using _CSTD int32_t; using _CSTD int64_t; + +using _CSTD uint8_t; using _CSTD uint16_t; +using _CSTD uint32_t; using _CSTD uint64_t; + +using _CSTD int_least8_t; using _CSTD int_least16_t; +using _CSTD int_least32_t; using _CSTD int_least64_t; +using _CSTD uint_least8_t; using _CSTD uint_least16_t; +using _CSTD uint_least32_t; using _CSTD uint_least64_t; + +using _CSTD intmax_t; using _CSTD uintmax_t; + +using _CSTD uintptr_t; +using _CSTD intptr_t; + +using _CSTD int_fast8_t; using _CSTD int_fast16_t; +using _CSTD int_fast32_t; using _CSTD int_fast64_t; +using _CSTD uint_fast8_t; using _CSTD uint_fast16_t; +using _CSTD uint_fast32_t; using _CSTD uint_fast64_t; + #endif /* defined(_STD_USING) */ + +/* + * Copyright (c) 1992-2009 by P.J. Plauger. ALL RIGHTS RESERVED. + * Consult your license regarding permissions and restrictions. +V5.20:0009 */ diff --git a/win32/common.h b/win32/common.h index 76833a4..739c6d5 100644 --- a/win32/common.h +++ b/win32/common.h @@ -13,6 +13,7 @@ extern "C" #include #include #include +#include #include #include #endif diff --git a/win32/device.cc b/win32/device.cc index 6ebf87d..3a29bd4 100644 --- a/win32/device.cc +++ b/win32/device.cc @@ -1,6 +1,7 @@ #include #include +#include "common.h" #include "device.h" #include "button.h" #include "value.h" @@ -18,7 +19,7 @@ WINHIDSDI BOOL WINAPI HidD_SetOutputReport(HANDLE, void*, ULONG); std::string stringFromTCHAR(const TCHAR* c) { std::string s; - const uint8_t num = lstrlen((LPCTSTR)c) * sizeof(TCHAR); + const uint8_t num = lstrlen((LPCTSTR)c); for(unsigned k = 0; k < num; ++c, ++k) s.push_back(wctob(*c)); return s; @@ -135,6 +136,10 @@ bool HID::win32::device_type::open(OpenMode mode) overlapped.Offset = 0; overlapped.OffsetHigh = 0; + _write_overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + _write_overlapped.Offset = 0; + _write_overlapped.OffsetHigh = 0; + handle = CreateFile(_tpath.c_str(), m, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if( INVALID_HANDLE_VALUE == handle ) @@ -159,6 +164,8 @@ bool HID::win32::device_type::read(buffer_type& buffer) bool run = true; while(run) { + if( INVALID_HANDLE_VALUE == handle ) + return false; ReadFile(handle, b, length, NULL, &overlapped); switch( WaitForSingleObject(overlapped.hEvent, time) ) { @@ -190,21 +197,45 @@ bool HID::win32::device_type::read(buffer_type& buffer) bool HID::win32::device_type::write(const buffer_type& buffer) { - DWORD num; - if( INVALID_HANDLE_VALUE == handle ) return false; if( buffer.size() > capabilities()->OutputReportByteLength ) return false; - uint8_t* b = bufferInputReport(); + uint8_t* b = bufferOutputReport(); std::copy(buffer.begin(), buffer.end(), b); - return WriteFile(handle, b, capabilities()->OutputReportByteLength, &num, NULL); + DWORD num = 0; + const size_t time = 100; + bool run = true; + while(run) + { + if( INVALID_HANDLE_VALUE == handle ) + return false; + WriteFile(handle, b, capabilities()->OutputReportByteLength, NULL, &_write_overlapped); + switch( WaitForSingleObject(_write_overlapped.hEvent, time) ) + { + case WAIT_OBJECT_0: + GetOverlappedResult(handle, &_write_overlapped, &num, 0); + run = false; + break; + case WAIT_TIMEOUT: + CancelIo(handle); + break; + default: + run = false; + CancelIo(handle); + break; + } + } + + return num == capabilities()->OutputReportByteLength; } +#if !defined(_MSC_VER) #pragma mark - #pragma mark Report elements +#endif // Fetch the button capabilities and generate element_type objects for each void HID::win32::device_type::button_elements(elements_type& _buttons) @@ -212,14 +243,17 @@ void HID::win32::device_type::button_elements(elements_type& _buttons) capabilities(); // Ensure that the HIDP_CAPS structure is populated // Get the array lengths from _capabilities - long unsigned numFeature = _capabilities->NumberFeatureButtonCaps; - long unsigned numInput = _capabilities->NumberInputButtonCaps; - long unsigned numOutput = _capabilities->NumberOutputButtonCaps; + USHORT numFeature = _capabilities->NumberFeatureButtonCaps; + USHORT numInput = _capabilities->NumberInputButtonCaps; + USHORT numOutput = _capabilities->NumberOutputButtonCaps; size_t numberOfCaps = numFeature + numInput + numOutput; - HIDP_BUTTON_CAPS buffer[numberOfCaps]; + if (numberOfCaps <= 0) + return; + + std::vector buffer(numberOfCaps); - HidP_GetButtonCaps(HidP_Feature, buffer, &numFeature, _preparsedData); + HidP_GetButtonCaps(HidP_Feature, &buffer[0], &numFeature, _preparsedData); HIDP_BUTTON_CAPS *const _inputButtons = &buffer[numFeature]; HidP_GetButtonCaps(HidP_Input, _inputButtons, &numInput, _preparsedData); @@ -237,7 +271,7 @@ void HID::win32::device_type::button_elements(elements_type& _buttons) if( buffer[i].IsRange ) { unsigned k = 0; - for(unsigned j=buffer[i].Range.DataIndexMin; j < buffer[i].Range.DataIndexMax; ++j, ++k) + for(unsigned j=buffer[i].Range.DataIndexMin; j <= buffer[i].Range.DataIndexMax; ++j, ++k) { element_type *const element = new button_type(buffer[i], k, this); if( element ) @@ -259,20 +293,27 @@ void HID::win32::device_type::value_elements(elements_type& _values) capabilities(); // Ensure that the HIDP_CAPS structure is populated // Get the array lengths from _capabilities - long unsigned numFeature = _capabilities->NumberFeatureValueCaps; - long unsigned numInput = _capabilities->NumberInputValueCaps; - long unsigned numOutput = _capabilities->NumberOutputValueCaps; + USHORT numFeature = _capabilities->NumberFeatureValueCaps; + USHORT numInput = _capabilities->NumberInputValueCaps; + USHORT numOutput = _capabilities->NumberOutputValueCaps; size_t numberOfCaps = numFeature + numInput + numOutput; - HIDP_VALUE_CAPS buffer[numberOfCaps]; + if (numberOfCaps <= 0) + return; - HidP_GetValueCaps(HidP_Feature, buffer, &numFeature, _preparsedData); + std::vector buffer(numberOfCaps); - HIDP_VALUE_CAPS *const _inputButtons = &buffer[numFeature]; - HidP_GetValueCaps(HidP_Input, _inputButtons, &numInput, _preparsedData); + if (numFeature > 0) { + HidP_GetValueCaps(HidP_Feature, &buffer[0], &numFeature, _preparsedData); + } - HIDP_VALUE_CAPS *const _outputButtons = &_inputButtons[numInput]; - HidP_GetValueCaps(HidP_Output, _outputButtons, &numOutput, _preparsedData); + if (numInput > 0) { + HidP_GetValueCaps(HidP_Input, &buffer[numFeature], &numInput, _preparsedData); + } + + if (numOutput > 0) { + HidP_GetValueCaps(HidP_Output, &buffer[numFeature + numInput], &numOutput, _preparsedData); + } // Update the array length in case HidP_GetButtonCaps() returned different lengths numberOfCaps = numFeature + numInput + numOutput; @@ -283,7 +324,7 @@ void HID::win32::device_type::value_elements(elements_type& _values) // If the item is a range, generate elements for each member if( buffer[i].IsRange ) { - for(unsigned j=buffer[i].Range.DataIndexMin; j < buffer[i].Range.DataIndexMax; ++j) + for(unsigned j=buffer[i].Range.DataIndexMin; j <= buffer[i].Range.DataIndexMax; ++j) { element_type *const element = new HID::win32::value_type(buffer[i], j, this); if( element ) @@ -316,18 +357,22 @@ HID::elements_type& HID::win32::device_type::elements() the link collections be at the beginning of the temp container and in the same order returned by HidP_GetLinkCollectionNodes() */ unsigned long length = _capabilities->NumberLinkCollectionNodes; - HIDP_LINK_COLLECTION_NODE nodes[length]; - HidP_GetLinkCollectionNodes(nodes, &length, _preparsedData); + std::vector nodes(length); + HidP_GetLinkCollectionNodes(&nodes[0], &length, _preparsedData); for(size_t i=0; i < length; ++i) { element_type *const collection = new collection_type(nodes[i], this); // Everything goes into the temporary container temp.push_back(collection); - - // Add top-level nodes to the _elements container - if( 0 == nodes[i].Parent ) - _elements.push_back(collection); + } + if (length > 0) + { + /* The top-level collections were divided into different physical device object (PDO) in Windows + (see: http://msdn.microsoft.com/en-us/library/windows/hardware/ff543475(v=vs.85).aspx). + Therefore, there is only one top-level collection, others are sub-collections. */ + _elements.push_back(temp[0]); + link_subcollections(temp, nodes); } // Get the button elements @@ -336,16 +381,12 @@ HID::elements_type& HID::win32::device_type::elements() // Get the value elements value_elements(temp); - // Walk the temporary container and reparent anything that has a parent - elements_type::iterator i = temp.begin(); - for(; i != temp.end(); ++i) - { - const unsigned parent = static_cast(*i)->parentCollectionIndex(); - if( (parent < length) && (parent || !(*i)->isCollection()) ) - temp[parent]->children().push_back(*i); - - if( (((*i)->isCollection() && parent) || parent) && (parent < length) ) - temp[parent]->children().push_back(*i); + // Walk the temporary container and reparent anything that has a parent (skip collections) + elements_type::iterator it = temp.begin() + length; + for(; it != temp.end(); ++it) { + const unsigned parent = static_cast(*it)->parentCollectionIndex(); + if (parent < length) + temp[parent]->children().push_back(*it); } return _elements; @@ -363,7 +404,7 @@ bool HID::win32::device_type::feature(unsigned reportID, buffer_type& report) HidP_InitializeReportForID(HidP_Feature, reportID, preparsedData(), (char*)b, length); std::copy(report.begin(), report.end(), b+1); - return HidD_SetFeature(handle, b, report.size()+1); + return HidD_SetFeature(handle, b, report.size()+1) != FALSE; } HID::buffer_type HID::win32::device_type::feature(unsigned reportID) @@ -399,7 +440,7 @@ bool HID::win32::device_type::output(unsigned reportID, buffer_type& report) HidP_InitializeReportForID(HidP_Output, reportID, preparsedData(), (char*)b, length); std::copy(report.begin(), report.end(), b+1); - return HidD_SetOutputReport(handle, b, length); + return HidD_SetOutputReport(handle, b, length) != FALSE; } const std::string& HID::win32::device_type::manufacturer() @@ -461,3 +502,24 @@ uint16_t HID::win32::device_type::usagePage() return 0; return capabilities()->UsagePage; } + +void HID::win32::device_type::link_subcollections(elements_type& elements, std::vector& nodes, size_t index) +{ + /* refer: http://msdn.microsoft.com/en-us/library/windows/hardware/ff542355(v=vs.85).aspx#ddk_link_collection_array_kg. */ + const size_t firstChild = nodes[index].FirstChild; + if (firstChild <= 0) + return; + + if (nodes[firstChild].FirstChild > 0) + link_subcollections(elements, nodes, firstChild); + elements[index]->children().push_back(elements[firstChild]); + for (HIDP_LINK_COLLECTION_NODE* node = &nodes[nodes[index].FirstChild]; + node->NextSibling > 0; + node = &nodes[node->NextSibling]) + { + const size_t nextSibling = node->NextSibling; + if (nodes[nextSibling].FirstChild > 0) + link_subcollections(elements, nodes, nextSibling); + elements[index]->children().push_back(elements[nextSibling]); + } +} diff --git a/win32/device.h b/win32/device.h index 1811057..8810a8d 100644 --- a/win32/device.h +++ b/win32/device.h @@ -44,6 +44,7 @@ class HID::win32::device_type : public HID::device_type HANDLE handle; HIDD_ATTRIBUTES _attributes; OVERLAPPED overlapped; + OVERLAPPED _write_overlapped; PHIDP_PREPARSED_DATA _preparsedData; HIDP_CAPS* _capabilities; @@ -60,6 +61,7 @@ class HID::win32::device_type : public HID::device_type PHIDP_PREPARSED_DATA preparsedData(); void button_elements(elements_type&); void value_elements(elements_type&); + void link_subcollections(elements_type&, std::vector&, size_t index = 0); public: device_type(const TCHAR*); diff --git a/win32/enumerator.cc b/win32/enumerator.cc index b1aa70f..d0fa38d 100644 --- a/win32/enumerator.cc +++ b/win32/enumerator.cc @@ -133,8 +133,9 @@ void HID::win32::enumerator_type::removed(DEV_BROADCAST_DEVICEINTERFACE& d) _removalCallback(this, *i, _removalContext); // Destroy the device object and remove it from the device list + HID::device_type* tmp = *i; _devices.remove(*i); - delete *i; + delete tmp; break; } diff --git a/win32/hid.cc b/win32/hid.cc index 92874b2..da05b6f 100644 --- a/win32/hid.cc +++ b/win32/hid.cc @@ -33,7 +33,7 @@ HID::device_list HID::find(filter_type* f) unsigned i = 0; while(1) { - SP_DEVICE_INTERFACE_DATA devInterface = { cbSize : sizeof(SP_DEVICE_INTERFACE_DATA) }; + SP_DEVICE_INTERFACE_DATA devInterface = { sizeof(SP_DEVICE_INTERFACE_DATA) }; if( !SetupDiEnumDeviceInterfaces(info, NULL, &guid, i, &devInterface) ) break; ++i; diff --git a/win32/value.h b/win32/value.h index 8a16bd7..4614207 100644 --- a/win32/value.h +++ b/win32/value.h @@ -32,7 +32,7 @@ class HID::win32::value_type : public HID::win32::element_type virtual ~value_type() {}; // Properties - virtual bool hasNullState() const { return _value.HasNull; } + virtual bool hasNullState() const { return _value.HasNull != FALSE; } virtual bool hasPreferredState() const { return false; } virtual bool isArray() const { return false; } virtual bool isCollection() const { return false; } @@ -54,8 +54,8 @@ class HID::win32::value_type : public HID::win32::element_type virtual range_type physicalRange() const { return std::make_pair(_value.PhysicalMin, _value.PhysicalMax);} virtual range_type reportedRange() { return std::make_pair(_value.LogicalMin, _value.LogicalMax); } virtual uint32_t reportID() const { return _value.ReportID; } - virtual uint32_t reportSize() const { return 0; } - virtual uint32_t reportCount() const{ return 0; } + virtual uint32_t reportSize() const { return _value.BitSize; } + virtual uint32_t reportCount() const{ return _value.ReportCount; } virtual const char* typeName() const{ return "Value"; } virtual uint32_t unit() const { return _value.Units; } virtual uint32_t unitExponent() const { return _value.UnitsExp; }