GetRawInputDeviceInfo возвращает неверный синтаксис имени устройства HID USB в Windows 10 - PullRequest
0 голосов
/ 05 декабря 2018

У меня есть код, который я нашел в интернете и который использует функцию GetRawInputDeviceInfo, но он не дает правильное имя устройства.иногда это не получает имя вообще.Я искал ответ и обнаружил, что люди имели эту проблему на Windows XP и Windows 7, чтобы.Я использую Windows 10, так что это мне не очень помогает.

C ++ - WinAPI получает список всех подключенных USB-устройств (нужно ли размещать сам код? Я новичок в стекепереполнение)

В конце дня я пытаюсь получить имена всех устройств, подключенных к моему ПК, и распечатать их, но эта функция также не возвращает имя мыши, поэтомуесли у кого-то есть предложение, как это исправить, или лучший способ получить имена, которые я бы хотел услышать от вас.заранее спасибо, -shon:)

EDIT2!полный код:

#include <windows.h>
#include <iostream>
#include <vector>
#include <string>
#include <set>

// Namespace
using namespace std;

// Main
int main()
{
    // Program
    cout << "USB Device Lister." << endl;

    // Get Number Of Devices
    UINT nDevices = 0;
    GetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVICELIST));

    // Got Any?
    if (nDevices < 1)
    {
        // Exit
        cout << "ERR: 0 Devices?";
        cin.get();
        return 0;
    }

    // Allocate Memory For Device List
    PRAWINPUTDEVICELIST pRawInputDeviceList;
    pRawInputDeviceList = new RAWINPUTDEVICELIST[sizeof(RAWINPUTDEVICELIST) * nDevices];

    // Got Memory?
    if (pRawInputDeviceList == NULL)
    {
        // Error
        cout << "ERR: Could not allocate memory for Device List.";
        cin.get();
        return 0;
    }

    // Fill Device List Buffer
    int nResult;
    nResult = GetRawInputDeviceList(pRawInputDeviceList, &nDevices, sizeof(RAWINPUTDEVICELIST));

    // Got Device List?
    if (nResult < 0)
    {
        // Clean Up
        delete[] pRawInputDeviceList;

        // Error
        cout << "ERR: Could not get device list.";
        cin.get();
        return 0;
    }

    std::set<std::string> DeviceList;
    // Loop Through Device List
    for (UINT i = 0; i < nDevices; i++)
    {
        // Get Character Count For Device Name
        UINT nBufferSize = 0;
        nResult = GetRawInputDeviceInfo(pRawInputDeviceList[i].hDevice, // Device
            RIDI_DEVICENAME,                // Get Device Name
            NULL,                           // NO Buff, Want Count!
            &nBufferSize);                 // Char Count Here!

                                           // Got Device Name?
        if (nResult < 0)
        {
            // Error
            cout << "ERR: Unable to get Device Name character count.. Moving to next device." << endl << endl;

            // Next
            continue;
        }

        // Allocate Memory For Device Name
        WCHAR* wcDeviceName = new WCHAR[nBufferSize + 1];

        // Got Memory
        if (wcDeviceName == NULL)
        {
            // Error
            cout << "ERR: Unable to allocate memory for Device Name.. Moving to next device." << endl << endl;

            // Next
            continue;
        }

        // Get Name
        nResult = GetRawInputDeviceInfo(pRawInputDeviceList[i].hDevice, // Device
            RIDI_DEVICENAME,                // Get Device Name
            wcDeviceName,                   // Get Name!
            &nBufferSize);                 // Char Count

                                           // Got Device Name?
        if (nResult < 0)
        {
            // Error
            cout << "ERR: Unable to get Device Name.. Moving to next device." << endl << endl;

            // Clean Up
            delete[] wcDeviceName;

            // Next
            continue;
        }

        // Set Device Info & Buffer Size
        RID_DEVICE_INFO rdiDeviceInfo;
        rdiDeviceInfo.cbSize = sizeof(RID_DEVICE_INFO);
        nBufferSize = rdiDeviceInfo.cbSize;

        // Get Device Info
        nResult = GetRawInputDeviceInfo(pRawInputDeviceList[i].hDevice,
            RIDI_DEVICEINFO,
            &rdiDeviceInfo,
            &nBufferSize);

        // Got All Buffer?
        if (nResult < 0)
        {
            // Error
            cout << "ERR: Unable to read Device Info.. Moving to next device." << endl << endl;

            // Next
            continue;
        }

        // Mouse
        if (rdiDeviceInfo.dwType == RIM_TYPEMOUSE)
        {
            // Current Device
            int id = rdiDeviceInfo.mouse.dwId; //device id
            string s = "ID: " + std::to_string(id) + ", Type : MOUSE"; //device type is mouse
            DeviceList.insert(s);
        }

        // Keyboard
        else if (rdiDeviceInfo.dwType == RIM_TYPEKEYBOARD)
        {
        // Current Device
        cout << endl << "Displaying device " << i + 1 << " information. (KEYBOARD)" << endl;
        wcout << L"Name " << wcDeviceName << endl; //*Problem is here!* //
        cout << "Keyboard mode: " << rdiDeviceInfo.keyboard.dwKeyboardMode << endl;
        cout << "Number of function keys: " << rdiDeviceInfo.keyboard.dwNumberOfFunctionKeys << endl;
        cout << "Number of indicators: " << rdiDeviceInfo.keyboard.dwNumberOfIndicators << endl;
        cout << "Number of keys total: " << rdiDeviceInfo.keyboard.dwNumberOfKeysTotal << endl;
        cout << "Type of the keyboard: " << rdiDeviceInfo.keyboard.dwType << endl;
        cout << "Subtype of the keyboard: " << rdiDeviceInfo.keyboard.dwSubType << endl;
        }

        // Some HID
        else // (rdi.dwType == RIM_TYPEHID)
        {
        // Current Device
        cout << endl << "Displaying device " << i + 1 << " information. (HID)" << endl;
        wcout << L"Device Name: " << wcDeviceName << endl;
        cout << "Vendor Id:" << rdiDeviceInfo.hid.dwVendorId << endl;
        cout << "Product Id:" << rdiDeviceInfo.hid.dwProductId << endl;
        cout << "Version No:" << rdiDeviceInfo.hid.dwVersionNumber << endl;
        cout << "Usage for the device: " << rdiDeviceInfo.hid.usUsage << endl;
        cout << "Usage Page for the device: " << rdiDeviceInfo.hid.usUsagePage << endl;
        } 

        // Delete Name Memory!
        delete[] wcDeviceName;
    }

    // Clean Up - Free Memory
    delete[] pRawInputDeviceList;

    for (std::set<string>::iterator i = DeviceList.begin(); i != DeviceList.end(); ++i)
        std::cout << *i << '\n';
    // Exit
    cout << endl << "Finnished.";
    cin.get();
    return 0;
}

1 Ответ

0 голосов
/ 05 декабря 2018

В Windows существует два вида вызовов API: Unicode и ANSI.Первый принимает и возвращает строки Unicode в кодировке UTF-16;последний принимает и возвращает 8-битные кодированные строки (точное кодирование зависит от локализации ОС).

Вы выбираете, какой вариант вы хотите использовать, #defining (или не #defining) макрос UNICODE.В зависимости от этого функция меняет имя с суффиксом W или A.

#ifdef UNICODE
#define GetRawInputDeviceInfo GetRawInputDeviceInfoW
#else
#define GetRawInputDeviceInfo GetRawInputDeviceInfoA
#endif

Все структуры, которые могут содержать текстовые данные, также дублируются с суффиксами W или A.

Теперь ваша проблема: вы не определяете UNICODE, поэтому вы на самом деле вызываете GetRawInputDeviceInfoA(), вариант ANSI, который ожидает char*, но вы передаете WCHAR*, то есть UNICODEstring!

Решение простое:

char* wcDeviceName = new char[nBufferSize + 1];

К сожалению, аргументы этой функции GetRawInputDeviceInfo() перегружены, поэтому она объявлена ​​как принимающая void*, поэтому компиляторне могу поймать ошибку.Если бы вы вызывали более простую функцию, скажем, SetWindowText(), то вы бы получили ошибку компилятора из-за несовместимого типа указателя.

Если вы действительно хотите полное имя UNICODE устройства, вы можете оставить WCHAR string и затем вызвать функцию UNICODE, в частности:

WCHAR* wcDeviceName = new WCHAR[nBufferSize + 1];
...
GetRawInputDeviceInfoW(..., RIDI_DEVICENAME, wcDeviceName, ...);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...