Получить родительскую информацию о USB-устройстве C ++ - PullRequest
3 голосов
/ 19 июня 2019

Я работаю над инструментом MFC, который проверяет некоторую информацию о драйвере подключенного USB-устройства, такую ​​как информация о местоположении, родительский, идентификатор оборудования и т. Д. У меня есть вся другая информация, которую я хочу, но я застрял в получении информации о родителе устройства .

Я использовал Setupapi.dll , чтобы получить информацию об устройстве в моем коде. Получил информацию об устройстве USB с помощью функции SetupDiGetClassDevs . Получил информацию о конкретном устройстве с помощью функции SetupDiEnumDeviceInfo . Получил описание устройства и идентификатор оборудования с помощью функции SetupDiGetDeviceRegistryProperty .

// List all connected USB devices
hDevInfo = SetupDiGetClassDevs(pClassGuid, pszEnumerator, 
    NULL, pClassGuid != NULL ? DIGCF_PRESENT : DIGCF_ALLCLASSES | 
    DIGCF_PRESENT);

// Get device info data
SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData);

// Get device instance id
CM_Get_Device_ID(DeviceInfoData.DevInst, szDeviceInstanceID, MAX_PATH, 
    0);

// Get device description
SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, 
    SPDRP_DEVICEDESC,
    &dwPropertyRegDataType, (BYTE*)szDesc, sizeof(szDesc), &dwSize);

#define DEFINE_DEVPROPKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, 
    b8, pid) EXTERN_C const DEVPROPKEY DECLSPEC_SELECTANY 
    name = { { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6, b7,  b8 } }, pid 
}

// DEVPROP_TYPE_STRING 
DEFINE_DEVPROPKEY(DEVPKEY_Device_Manufacturer, 0xa45c254e, 0xdf1c, 
    0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 13);        
// DEVPROP_TYPE_GUID
DEFINE_DEVPROPKEY(DEVPKEY_Device_ContainerId, 0x8c7ed206, 0x3f8a, 0x4827, 
    0xb3, 0xab, 0xae, 0x9e, 0x1f, 0xae, 0xfc, 0x6c, 2);     

typedef BOOL(WINAPI *FN_SetupDiGetDevicePropertyW)(
    __in       HDEVINFO DeviceInfoSet,
    __in       PSP_DEVINFO_DATA DeviceInfoData,
    __in       const DEVPROPKEY *PropertyKey,
    __out      DEVPROPTYPE *PropertyType,
    __out_opt  PBYTE PropertyBuffer,
    __in       DWORD PropertyBufferSize,
    __out_opt  PDWORD RequiredSize,
    __in       DWORD Flags
);

FN_SetupDiGetDevicePropertyW fn_SetupDiGetDevicePropertyW = 
    (FN_SetupDiGetDevicePropertyW) 
    GetProcAddress(GetModuleHandle(TEXT("Setupapi.dll")), 
    "SetupDiGetDevicePropertyW");

if (fn_SetupDiGetDevicePropertyW(hDevInfo, &DeviceInfoData, 
    &DEVPKEY_Device_Manufacturer, &ulPropertyType, (BYTE*)szBuffer, 
    sizeof(szBuffer), &dwSize, 0)) 
{
    _tprintf(TEXT("    Device Manufacturer: \"%ls\"\n"), szBuffer);
}

if (fn_SetupDiGetDevicePropertyW(hDevInfo, &DeviceInfoData, 
    &DEVPKEY_Device_ContainerId, &ulPropertyType, (BYTE*)szDesc, 
    sizeof(szDesc), &dwSize, 0)) 
{
    StringFromGUID2((REFGUID)szDesc, szBuffer, ARRAY_SIZE(szBuffer));
    _tprintf(TEXT("    ContainerId: \"%ls\"\n"), szBuffer);
}

Мне очень полезно получить информацию о родительском устройстве USB. Пожалуйста, помогите с некоторыми подсказками.

пожалуйста, посмотрите на изображение

1 Ответ

2 голосов
/ 19 июня 2019

CM_Locate_DevNode открывает дескриптор устройства с указанным идентификатором устройства;

CM_Get_Parent находит родительское устройство;

CM_Get_Device_ID_Size и CM_Get_Device_ID берут дескриптор устройства и возвращают устройствоID.

Пример:

#include <Windows.h>
#include <setupapi.h>
#include <cfgmgr32.h>
#include <tchar.h>
#include <stdio.h>
#define ARRAY_SIZE(arr)     (sizeof(arr)/sizeof(arr[0]))

#pragma comment (lib, "setupapi.lib")

int main()
{
    HDEVINFO hDevInfo;
    GUID guid;
    BYTE buffer[1024];
    DWORD dwRequiredSize;
    DEVINST devInstParent;
    SP_DEVICE_INTERFACE_DATA devInterfaceData;
    SP_DEVINFO_DATA devInfoData;
    PSP_DEVICE_INTERFACE_DETAIL_DATA pDevDetail;
    CONFIGRET status;
    TCHAR szDeviceInstanceID[MAX_DEVICE_ID_LEN];
    BOOL bSuccess;

    guid = GUID_DEVINTERFACE_VOLUME;
    hDevInfo = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
    if (hDevInfo == INVALID_HANDLE_VALUE) {
        return 1;
    }

    for (DWORD dwIndex = 0;; dwIndex++)
    {
        ZeroMemory(&devInterfaceData, sizeof(devInterfaceData));
        devInterfaceData.cbSize = sizeof(devInterfaceData);

        if (!SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &guid, dwIndex, &devInterfaceData)) {
            DWORD dwErrorCode = GetLastError();
            if (dwErrorCode == ERROR_NO_MORE_ITEMS)
                break;
            else
                return 1;  
        }

        ZeroMemory(&devInfoData, sizeof(devInfoData));
        devInfoData.cbSize = sizeof(devInfoData);
        pDevDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)buffer;
        pDevDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

        // Get device interface detail data to get Device Instance from
        // SP_DEVINFO_DATA and Device Path from SP_DEVICE_INTERFACE_DETAIL_DATA
        bSuccess = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInterfaceData,
            pDevDetail,// SP_DEVICE_INTERFACE_DETAIL_DATA
            sizeof(buffer), &dwRequiredSize, &devInfoData); // SP_DEVINFO_DATA

        status = CM_Get_Parent(&devInstParent, devInfoData.DevInst, 0);
        if (status == CR_SUCCESS) 
        {
            status = CM_Get_Device_ID(devInstParent, szDeviceInstanceID, ARRAY_SIZE(szDeviceInstanceID), 0);
            if (status == CR_SUCCESS)
                _tprintf(TEXT("    %s\n"), szDeviceInstanceID);
        }
        else 
        {
            continue;
        }
    }

    return 0;
}

Результат отладки:

1

2

...