Beispiel #1
0
  void System::onRawArrival( HANDLE handle )
  {
    UINT pathLength = 0;

    if ( GetRawInputDeviceInfoW( handle, RIDI_DEVICENAME, NULL, &pathLength ) )
      NIL_EXCEPT_WINAPI( "GetRawInputDeviceInfoW failed" );

    wideString rawPath( pathLength, '\0' );

    GetRawInputDeviceInfoW( handle, RIDI_DEVICENAME, &rawPath[0], &pathLength );
    rawPath.resize( rawPath.length() - 1 );

    for ( auto device : mDevices )
    {
      if ( device->getHandler() != Device::Handler_RawInput )
        continue;

      auto rawDevice = static_cast<RawInputDevice*>( device );

      if ( !_wcsicmp( rawDevice->getRawPath().c_str(), rawPath.c_str() ) )
      {
        deviceConnect( rawDevice );
        return;
      }
    }

    auto device = new RawInputDevice( this, getNextID(), handle, rawPath );

    if ( isInitializing() )
      device->setStatus( Device::Status_Connected );
    else
      deviceConnect( device );

    mDevices.push_back( device );
  }
Beispiel #2
0
std::unique_ptr<std::wstring> rawinput_device_name(HANDLE hDevice){
	UINT _data_size;
    UINT _result;
	if(0 != GetRawInputDeviceInfoW(hDevice, RIDI_DEVICENAME, 0, &_data_size)){
		std::cerr << "rawinput_device_name: 0 != GetRawInputDeviceInfoW(hDevice, RIDI_DEVICENAME, 0, &data_size)" << std::endl;
		return std::unique_ptr<std::wstring>(nullptr);
	}

    std::unique_ptr<std::wstring> device_name (new std::wstring(_data_size, '\0'));
    _result = GetRawInputDeviceInfoW(hDevice, RIDI_DEVICENAME, &(*device_name)[0], &_data_size);
    if(-1 == _result){
		std::cerr << "rawinput_device_name: -1 == GetRawInputDeviceInfoW(hDevice, RIDI_DEVICENAME, &(*device_name)[0], &data_size)" << std::endl;
		return std::unique_ptr<std::wstring>(nullptr);
	}

    device_name->resize(_result);
	return device_name;
}
Beispiel #3
0
int _tmain(int argc, _TCHAR* argv[])
{
	BOOL b;
	UINT size = 0, i;
	RAWINPUTDEVICELIST *pRawInputDeviceList;

	b = GetRawInputDeviceList(NULL, &size, sizeof(RAWINPUTDEVICELIST));
	printf("b ==> %d, size ==> %d\n", b, size);

	pRawInputDeviceList = (RAWINPUTDEVICELIST *)malloc(sizeof(RAWINPUTDEVICELIST)* size);
	b = GetRawInputDeviceList(pRawInputDeviceList, &size, sizeof(RAWINPUTDEVICELIST));
	printf("b ==> %d, size ==> %d\n", b, size);
	for (i = 0; i < size; ++i)
	{
		WCHAR buffer[MAX_PATH + 1];

		printf("device.type ==> 0x%x\n", pRawInputDeviceList[i].dwType);
		printf("device.handle ==> 0x%p\n", pRawInputDeviceList[i].hDevice);

		UINT BufferSize = ARRAYSIZE(buffer);
		UINT retval = GetRawInputDeviceInfoW(pRawInputDeviceList[i].hDevice, RIDI_DEVICENAME, &buffer[0], &BufferSize);
		printf("retval ==> %d\n", retval);
		printf("buffer ==> %ws\n", buffer);

		RID_DEVICE_INFO DeviceInfo = { 0 };
		BufferSize = sizeof(DeviceInfo);
		retval = GetRawInputDeviceInfoW(pRawInputDeviceList[i].hDevice, RIDI_DEVICEINFO, &DeviceInfo, &BufferSize);
		printf("Device info.dwType ==> 0x%x\n", DeviceInfo.dwType);
		if (DeviceInfo.dwType == RIM_TYPEHID)
		{
			printf("usage page ==> 0x%x, usage ==> 0x%x\n", DeviceInfo.hid.usUsagePage, DeviceInfo.hid.usUsage);
		}
	}

	return 0;
}
bool nxRawInputDevice::GetInformation(void)
{
    HKEY hKey = NULL;
    try
    {
        /// Retrieve the encoded device name
        UINT uSize = 0;
        // Retrieve the number of characters needed to store the device name (including the null)
        // Calling the unicode version, that way we get the number of characters properly.
        // All the characters used, in practice, are representable in ANSI.
        if (GetRawInputDeviceInfoW(hDevice,RIDI_DEVICENAME,NULL,&uSize) < 0)
            nxThrow("Couldn't retrieve length of device name string.");

        // Allocate the space
        strDeviceName.resize(uSize-1);
        // Retrieve the device name.  Example: "\\??\\ACPI#PNP0303#3&13c0b0c5&0#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}"
        if (GetRawInputDeviceInfoA(hDevice,RIDI_DEVICENAME,const_cast<char*>(strDeviceName.c_str()),&uSize) < 0)
            nxThrow("Couldn't retrieve the encoded device name.");

        /// Multiply Occurring Error.  Placing here so we can include the device name.
        const std::string strFormatError = std::string("Device name is encoded in an unsupported format. \"") + strDeviceName + std::string("\"");
        // Validate the device name is nonempty.
        if (strDeviceName.empty())
                nxThrow(strFormatError);

        /// Split the device name into parts
        // Delimiter offsets
        std::string::size_type uCurrent, uNext;
        // First # position
        uNext = strDeviceName.find_first_of('#');
        // Position of the trailing slash of the beginning "\\??\\" part.
        uCurrent = strDeviceName.find_last_of('\\',uNext);

        /// Loop through the fields
        std::string strField;
        for (UINT uField = 0;uField < 4;++uField)
        {
            // Validate field offsets
            if (uCurrent == std::string::npos)
                nxThrow(strFormatError);
            // Pull out the field data
            if (uNext != std::string::npos)
                strField = strDeviceName.substr(uCurrent+1,uNext-uCurrent-1);
            else
                strField = strDeviceName.substr(uCurrent+1);

            // Ensure some value was retrieved
            if (strField.empty())
                nxThrow(strFormatError);

            /// Set the appropriate field
            switch (uField)
            {
                case 0:	strClassCode = strField; break;
                case 1:	strSubClassCode = strField; break;
                case 2:	strProtocolCode = strField; break;
                case 3:	strGUID = strField; break;
                default:
                    nxThrow("Unhandled token index, notify the developer of his silly mistake.");
            }
            // Advance to the next token.
            uCurrent = uNext;
            if (uCurrent != std::string::npos)
                uNext = strDeviceName.find_first_of('#',uCurrent+1);
            else
                uNext = std::string::npos;
        }

        /// Retrieve the device description and class from the registry
        DWORD dwKeyType;
        DWORD dwKeySize;
        std::string strRegKey = std::string("SYSTEM\\CurrentControlSet\\Enum\\")+strClassCode+"\\"+strSubClassCode+"\\"+strProtocolCode;
        if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,strRegKey.c_str(),0,KEY_QUERY_VALUE,&hKey) != ERROR_SUCCESS)
        {
            hKey = NULL;
            nxThrow(std::string("Couldn't open the device's registry key - ") + strRegKey);
        }
        // Retrieve data type and size (including null)
        if (RegQueryValueEx(hKey,"DeviceDesc",NULL,&dwKeyType,NULL,&dwKeySize) != ERROR_SUCCESS)
            nxThrow(std::string("Couldn't retrieve size of \"DeviceDesc\" value for registry key - ") + strRegKey);
        // Size the buffer accordingly
        strDeviceDesc.resize(dwKeySize-1);
        // Added the const_cast for clarity, though it isn't necessary.
        if (RegQueryValueEx(hKey,"DeviceDesc",NULL,&dwKeyType,(BYTE*)const_cast<char*>(strDeviceDesc.c_str()),&dwKeySize) != ERROR_SUCCESS)
            nxThrow(std::string("Couldn't retrieve value of \"DeviceDesc\" for registry key - ") + strRegKey);

        // Retrieve data type and size (including null)
        if (RegQueryValueEx(hKey,"Class",NULL,&dwKeyType,NULL,&dwKeySize) != ERROR_SUCCESS)
            nxThrow(std::string("Couldn't retrieve size of \"Class\" value for registry key - ") + strRegKey);
        // Size the buffer accordingly
        strDeviceClass.resize(dwKeySize-1);
        // Added the const_cast for clarity, though it isn't necessary.
        if (RegQueryValueEx(hKey,"Class",NULL,&dwKeyType,(BYTE*)const_cast<char*>(strDeviceClass.c_str()),&dwKeySize) != ERROR_SUCCESS)
            nxThrow(std::string("Couldn't retrieve value of \"Class\" for registry key - ") + strRegKey);

        /// Use registry information to verify our keyboards/mice are in fact keyboards and mice.
        // This will also turn the terminal services "system" devices to HID
        if (stricmp(strClassCode.c_str(),"root")==0)
            dwType = RIM_TYPEHID;
        else if (IsKeyboard())
        {
            if (stricmp(strDeviceClass.c_str(),"keyboard")!=0)
                dwType = RIM_TYPEHID;
        }
        else if (IsMouse())
        {
            if (stricmp(strDeviceClass.c_str(),"mouse")!=0)
                dwType = RIM_TYPEHID;
        }
        else //HID
        {
            if (stricmp(strDeviceClass.c_str(),"keyboard")==0)
                dwType = RIM_TYPEKEYBOARD;
            else if (stricmp(strDeviceClass.c_str(),"mouse")==0)
                dwType = RIM_TYPEMOUSE;
        }

        // Make sure this isn't vmware's keyboard driver (rather than a physical keyboard)
        if (IsKeyboard())
        {
            HKEY hKeyVM = NULL;
            // If this fails, then something is amiss (there should be a control key), but, it isn't really a bail-out situation
            if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,(strRegKey+"\\Control").c_str(),0,KEY_QUERY_VALUE,&hKeyVM) == ERROR_SUCCESS)
            {
                // Retrieve data type and size (including null)
                if (RegQueryValueEx(hKeyVM,"ActiveService",NULL,&dwKeyType,NULL,&dwKeySize) == ERROR_SUCCESS)
                {
                    std::string strActiveService;
                    // Size the buffer accordingly
                    strActiveService.resize(dwKeySize-1);
                    // Added the const_cast for clarity, though it isn't necessary.
                    if (RegQueryValueEx(hKeyVM,"ActiveService",NULL,&dwKeyType,(BYTE*)const_cast<char*>(strActiveService.c_str()),&dwKeySize) == ERROR_SUCCESS)
                    {
                        if (stricmp(strActiveService.c_str(),"vmkbd") == 0)
                        {
                            // It's the vmware keyboard, not a physical keyboard.
                            dwType = RIM_TYPEHID;
                        }
                    }
                }
                RegCloseKey(hKeyVM);
            }
        }

        // Clean up
        RegCloseKey(hKey);
        hKey=NULL;

        // Return false if it isn't a supported keyboard and mouse
        if (!IsMouse() && !IsKeyboard())
            return false;

    } catch (const std::exception&e)
    {
        nxLog << e.what() << std::endl;
        Clear();
        if (hKey)
            RegCloseKey(hKey);
        return false;
    }
    return true;
}