Как найти номер com-порта модема, обнаруженного с помощью CM_Get_Device_Interface_List - PullRequest
0 голосов
/ 06 апреля 2019

Я написал код для поиска установленных модемов на компьютере. Это может найти имя устройства, которое полезно для отображения, но пока не может найти COM-порт модема. Мне нужно это, чтобы использовать устройство. Как я могу получить эту информацию, учитывая то, что я могу обнаружить с помощью API установки Microsoft Device and Drive?

Вот код:

/*
use CM_Get_Device_Interface_ListW and CM_Get_Device_Interface_List_SizeW for get
list of interfaces for GUID_DEVINTERFACE_COMPORT. query CM_Get_Device_Interface_PropertyW 
with DEVPKEY_Device_InstanceId for get device id, than CM_Locate_DevNodeW and finally 
you can query devnode for many properties - like DEVPKEY_NAME, etc.
*/
#include <Windows.h>
#include <cfgmgr32.h>  // Device and Driver Installation header

#include <initguid.h>  // Put this in to get rid of linker errors - unresolved external symbol _DEVPKEY_Device_DeviceDesc
#include <devpkey.h>  // Property keys defined here are now defined inline.  DEVPKEY_Device_DeviceDesc

// Microsoft Device and Driver Installation library
#pragma comment(lib, "Cfgmgr32.lib")


#include <Ntddmodm.h>

#include <iostream>
#include <string>

using namespace std;

const char* error2string(int err) {
    switch (err) {
    case CR_SUCCESS:  return "CR_OK";
    case CR_DEFAULT: return "CR_DEFAULT";
    case CR_OUT_OF_MEMORY: return "CR_OUT_OF_MEMORY";
    case CR_INVALID_POINTER: return "CR_INVALID_POINTER";
    case CR_INVALID_FLAG: return "CR_INVALID_FLAG";
    case CR_INVALID_DEVNODE: return "CR_INVALID_DEVNODE";
    case CR_INVALID_RES_DES: return "CR_INVALID_RES_DES";
    case CR_INVALID_LOG_CONF: return "CR_INVALID_LOG_CONF";
    case CR_INVALID_ARBITRATOR: return "CR_INVALID_ARBITRATOR";
    case CR_INVALID_NODELIST: return "CR_INVALID_NODELIST";
    case CR_DEVNODE_HAS_REQS: return "CR_DEVNODE_HAS_REQS";
    case CR_INVALID_RESOURCEID: return "CR_INVALID_RESOURCEID";
    case CR_DLVXD_NOT_FOUND: return "CR_DLVXD_NOT_FOUND";
    case CR_NO_SUCH_DEVNODE: return "CR_NO_SUCH_DEVNODE";
    case CR_NO_MORE_LOG_CONF: return "CR_NO_MORE_LOG_CONF";
    case CR_NO_MORE_RES_DES: return "CR_NO_MORE_RES_DES";
    case CR_ALREADY_SUCH_DEVNODE: return "CR_ALREADY_SUCH_DEVNODE";
    case CR_INVALID_RANGE_LIST: return "CR_INVALID_RANGE_LIST";
    case CR_INVALID_RANGE: return "CR_INVALID_RANGE";
    case CR_FAILURE: return "CR_FAILURE";
    case CR_NO_SUCH_LOGICAL_DEV: return "CR_NO_SUCH_LOGICAL_DEV";
    case CR_CREATE_BLOCKED: return "CR_CREATE_BLOCKED";
    case CR_NOT_SYSTEM_VM: return "CR_NOT_SYSTEM_VM";
    case CR_REMOVE_VETOED: return "CR_REMOVE_VETOED";
    case CR_APM_VETOED: return "CR_APM_VETOED";
    case CR_INVALID_LOAD_TYPE: return "CR_INVALID_LOAD_TYPE";
    case CR_BUFFER_SMALL: return "CR_BUFFER_SMALL";
    case CR_NO_ARBITRATOR: return "CR_NO_ARBITRATOR";
    case CR_NO_REGISTRY_HANDLE: return "CR_NO_REGISTRY_HANDLE";
    case CR_REGISTRY_ERROR: return "CR_REGISTRY_ERROR";
    case CR_INVALID_DEVICE_ID: return "CR_INVALID_DEVICE_ID";
    case CR_INVALID_DATA: return "CR_INVALID_DATA";
    case CR_INVALID_API: return "CR_INVALID_API";
    case CR_DEVLOADER_NOT_READY: return "CR_DEVLOADER_NOT_READY";
    case CR_NEED_RESTART: return "CR_NEED_RESTART";
    case CR_NO_MORE_HW_PROFILES: return "CR_NO_MORE_HW_PROFILES";
    case CR_DEVICE_NOT_THERE: return "CR_DEVICE_NOT_THERE";
    case CR_NO_SUCH_VALUE: return "CR_NO_SUCH_VALUE";
    case CR_WRONG_TYPE: return "CR_WRONG_TYPE";
    case CR_INVALID_PRIORITY: return "CR_INVALID_PRIORITY";
    case CR_NOT_DISABLEABLE: return "CR_NOT_DISABLEABLE";
    case CR_FREE_RESOURCES: return "CR_FREE_RESOURCES";
    case CR_QUERY_VETOED: return "CR_QUERY_VETOED";
    case CR_CANT_SHARE_IRQ: return "CR_CANT_SHARE_IRQ";
    case CR_NO_DEPENDENT: return "CR_NO_DEPENDENT";
    case CR_SAME_RESOURCES: return "CR_SAME_RESOURCES";
    case CR_NO_SUCH_REGISTRY_KEY: return "CR_NO_SUCH_REGISTRY_KEY";
    case CR_INVALID_MACHINENAME: return "CR_INVALID_MACHINENAME";
    case CR_REMOTE_COMM_FAILURE: return "CR_REMOTE_COMM_FAILURE";
    case CR_MACHINE_UNAVAILABLE: return "CR_MACHINE_UNAVAILABLE";
    case CR_NO_CM_SERVICES: return "CR_NO_CM_SERVICES";
    case CR_ACCESS_DENIED: return "CR_ACCESS_DENIED";
    case CR_CALL_NOT_IMPLEMENTED: return "CR_CALL_NOT_IMPLEMENTED";
    case CR_INVALID_PROPERTY: return "CR_INVALID_PROPERTY";
    case CR_DEVICE_INTERFACE_ACTIVE: return "CR_DEVICE_INTERFACE_ACTIVE";
    case CR_NO_SUCH_DEVICE_INTERFACE: return "CR_NO_SUCH_DEVICE_INTERFACE";
    case CR_INVALID_REFERENCE_STRING: return "CR_INVALID_REFERENCE_STRING";
    case CR_INVALID_CONFLICT_LIST: return "CR_INVALID_CONFLICT_LIST";
    case CR_INVALID_INDEX: return "CR_INVALID_INDEX";
    case CR_INVALID_STRUCTURE_SIZE: return "CR_INVALID_STRUCTURE_SIZE";
    case NUM_CR_RESULTS: return "NUM_CR_RESULTS";
    default: return "unknown";
    }
}

void printerror(int line, int code) {
    cout << "error: " << error2string(code) << " on line " << line << endl;
}


void print_filtered_devices() {

    /* find properties for GUID_DEVINTERFACE_COMPORT and GUID_DEVINTERFACE_MODEM */
    LPGUID InterfaceClassGuid = (LPGUID)&GUID_DEVINTERFACE_MODEM;
    PWSTR DeviceList = NULL;
    ULONG DeviceListLength = 0;
    CONFIGRET cr = CM_Get_Device_Interface_List_SizeW(&DeviceListLength, InterfaceClassGuid, 0, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
    if (cr == CR_SUCCESS) {
        DeviceList = (PWSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, DeviceListLength * sizeof(WCHAR));

        cr = CM_Get_Device_Interface_ListW(InterfaceClassGuid, NULL, DeviceList, DeviceListLength, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
        if (cr == CR_SUCCESS) {
            for (PWSTR CurrentDevice = DeviceList; *CurrentDevice; CurrentDevice += wcslen(CurrentDevice) + 1) {

                wcout << L"interface = " << CurrentDevice << endl;
                DEVPROPTYPE PropertyType;
                WCHAR buf[1024];
                ULONG BufferSize = sizeof(buf);
                cr = CM_Get_Device_Interface_PropertyW(CurrentDevice, &DEVPKEY_Device_InstanceId, &PropertyType, (PBYTE)buf, &BufferSize, 0);
                cout << "CM_Get_Device_Interface_PropertyW returned: " << error2string(cr) << endl;

                DEVINST Devinst;
                cr = CM_Locate_DevNodeW(&Devinst, buf, CM_LOCATE_DEVNODE_NORMAL);

                cout << "CM_Locate_DevNodeW returned: " << error2string(cr) << endl;

                if (cr == CR_SUCCESS) {
                    // Query a property on the device.  For example, the device description.
                    WCHAR DeviceDesc[2048];
                    ULONG PropertySize = sizeof(DeviceDesc);
                    cr = CM_Get_DevNode_PropertyW(Devinst,
                        &DEVPKEY_Device_DeviceDesc,
                        &PropertyType,
                        (PBYTE)DeviceDesc,
                        &PropertySize,
                        0);

                    cout << "CM_Get_DevNode_PropertyW returned: " << error2string(cr) << endl;
                    if (cr == CR_SUCCESS && PropertyType == DEVPROP_TYPE_STRING) {
                        // print device
                        wcout << "DEVPKEY_Device_DeviceDesc=" << DeviceDesc << endl;
                        wcout << "";
                    }
                    else {
                        printerror(__LINE__, cr);
                    }
                    //WCHAR DeviceDesc[2048];
                     PropertySize = sizeof(DeviceDesc);
                    cr = CM_Get_DevNode_PropertyW(Devinst,
                        &DEVPKEY_NAME,
                        &PropertyType,
                        (PBYTE)DeviceDesc,
                        &PropertySize,
                        0);
                    cout << "CM_Get_DevNode_PropertyW returned: " << error2string(cr) << endl;
                    if (cr == CR_SUCCESS && PropertyType == DEVPROP_TYPE_STRING) {
                        // print device
                        wcout << "DEVPKEY_NAME=" << DeviceDesc << endl;
                        wcout << "";
                    }
                    else {
                        printerror(__LINE__, cr);
                    }

                    //Need a port property???                   
                }
                else {
                    printerror(__LINE__, cr);
                }
            }
        }
        else {
            printerror(__LINE__, cr);
        }
    }
    else {
        printerror(__LINE__, cr);
    }

    if (DeviceList != NULL) {
        HeapFree(GetProcessHeap(), 0, DeviceList);
    }
}

int main() {

    // This call fails to retrieve any devices of class GUID_DEVINTERFACE_COMPORT
    print_filtered_devices();
}

И на моем компьютере я получаю этот вывод:

interface = \\?\USB#VID_0572&PID_1340#12345678#{2c7089aa-2e0e-11d1-b114-00c04fc2aae4}
CM_Get_Device_Interface_PropertyW returned: CR_OK
CM_Locate_DevNodeW returned: CR_OK
CM_Get_DevNode_PropertyW returned: CR_OK
DEVPKEY_Device_DeviceDesc=Conexant USB CX93010 ACF Modem
CM_Get_DevNode_PropertyW returned: CR_OK
DEVPKEY_NAME=Conexant USB CX93010 ACF Modem
...