Как получить информацию об устройстве (идентификаторы оборудования) при отключении в обратном вызове процесса Windows? - PullRequest
0 голосов
/ 13 июня 2019

Используя обратный вызов процесса Windows для изменений устройства, я могу настроить дескриптор, когда устройство прибывает, что позволяет мне просто взглянуть на его атрибуты устройства, такие как идентификаторы оборудования, без необходимости перечисления каких-либо устройств.

Однако при «отключении устройства» полученная ручка недействительна, что кажется правильным, поскольку устройство больше не подключено, но я не могу посмотреть атрибуты устройства. Есть ли способ, которым ручку все еще можно использовать?

DEV_BROADCAST_HDR* devHDR = reinterpret_cast<DEV_BROADCAST_HDR*>(lParam);
if (devHDR->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
{
    DEV_BROADCAST_DEVICEINTERFACE* devInterface = reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(lParam);
    DeviceHandle = CreateFile(devInterface->dbcc_name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
    if(DeviceHandle ==  != INVALID_HANDLE_VALUE){
        // arrive gets here
    } else {
        // disconnect gets here
    }
}

По сути, поскольку я не могу получить действительный дескриптор при отключении, я не могу получить идентификаторы оборудования и другие данные из структуры DEV_BROADCAST_DEVICEINTERFACE. Есть ли другой способ получить аппаратные идентификаторы устройства при отключении?

Ответы [ 2 ]

1 голос
/ 13 июня 2019

Когда устройство подключается, сохраняйте информацию, которая вам понадобится при отключении, на карте, где вы используете в качестве ключа что-то уникальное для устройства.

Когда устройство отключается, используйте ключ, полученный в событии отключения.чтобы найти информацию на карте, а затем удалить запись.

Пример:

using String = std::basic_string<TCHAR>;

// a struct with all the properties you'd like to use on disconnect
struct device_info {
    CHANGER_PRODUCT_DATA cpd; // just an example
    String something;
};

int main() {
    // a map where the device_name is the key and device_info the value
    std::unordered_map<String, device_info> devices;

    {   // on connect, create a device_info struct and fill it with the info you need on
        // disconnect
        DEV_BROADCAST_DEVICEINTERFACE* devInterface =
            reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(lParam);
        String new_dev_name { devInterface->dbcc_name };

        device_info di{}; // store what you need from the opened device here
                          // and put it in the map
        devices.emplace(new_dev_name, di);
    }

    {   // on disconnect, find the entry in the map using the disconnected device_name
        DEV_BROADCAST_DEVICEINTERFACE* devInterface =
            reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(lParam);
        String disc_dev_name{ devInterface->dbcc_name };

        auto fit = devices.find(disc_dev_name);

        if (fit != devices.end()) {
            // we found the device, extract it
            device_info disc_di = fit->second;
            // and erase it from the map
            devices.erase(fit);
            std::wcout << "\"" << disc_di.something << "\" disconnected\n";
        }
    }
}
0 голосов
/ 13 июня 2019

Ваш метод неверен.

Сначала необходимо проверить wParam и проверить, если == DBT_DEVICEARRIVAL и == DBT_DEVICEREMOVECOMPLETE

В DBT_DEVICEREMOVECOMPLETE тесте вы получите lParam заполненный, чтобы получить DEV_BROADCAST_HANDLE

...