简体   繁体   English

获取USB设备C ++的父信息

[英]Get parent information of a USB device C++

I'm working on an MFC tool that check some driver information's of connected USB device such as location info, parent, hardware id, etc. I have got all other information i want but i'm stuck in getting device parent information. 我正在研究一个MFC工具,它检查连接的USB设备的一些驱动程序信息,如位置信息,父级,硬件ID等。我有我想要的所有其他信息,但我一直在获取设备父信息。

I have used Setupapi.dll to get device information in my code. 我使用Setupapi.dll在我的代码中获取设备信息。 Got USB device information handle using SetupDiGetClassDevs function. 使用SetupDiGetClassDevs函数获得USB设备信息句柄。 Got specific device info data using SetupDiEnumDeviceInfo function. 使用SetupDiEnumDeviceInfo函数获取特定的设备信息数据。 Got device description and hardware id using SetupDiGetDeviceRegistryProperty function. 使用SetupDiGetDeviceRegistryProperty函数获得设备描述和硬件ID。

// 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);
}

It is very useful for me to get the parent information of USB device. 获取USB设备的父信息对我非常有用。 Please help with some clues. 请帮忙解决一些线索。

please look into image 请看图像

CM_Locate_DevNode opens a device handle given a device ID; CM_Locate_DevNode在给定设备ID的CM_Locate_DevNode打开设备句柄;

CM_Get_Parent finds the parent device; CM_Get_Parent找到父设备;

CM_Get_Device_ID_Size and CM_Get_Device_ID take the device handle and return the device ID. CM_Get_Device_ID_SizeCM_Get_Device_ID获取设备句柄并返回设备ID。

Sample: 样品:

#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;
}

Debug result: 调试结果:

1

2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM