winapi – msdn CM_GET_Parent示例不起作用

我正在努力从USB插件中获取设备ID …

上面的应用程序适用于win-Xp,但不适用于Windows 7

当我试图弄清楚时,我发现CM_Get_Parent()不起作用……

任何人都可以指导我为什么它不工作…并有任何兼容的功能,可以在Windows 7上工作

源代码:

HDEVINFO hDevInfo;
GUID guid;
BYTE buffer[ 1024 ];
DWORD dwRequiredSize ;
WCHAR buf[ 1024 ];
DEVINST devInstParent;
WCHAR volume[1024];
int aLength, anIndex;
SP_DEVICE_INTERFACE_DATA devInterfaceData;
SP_DEVINFO_DATA devInfoData;
PSP_DEVICE_INTERFACE_DETAIL_DATA pDevDetail;

guid = GUID_DEVINTERFACE_VOLUME;
hDevInfo = SetupDiGetClassDevs( &guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT );

if( hDevInfo == INVALID_HANDLE_VALUE )
{
    qDebug() << "Error - SetupDiGetClassDevs failed\n";
}

for( DWORD dwIndex = 0;; dwIndex ++ )
{
    ZeroMemory( &devInterfaceData, sizeof( devInterfaceData ) );
    devInterfaceData.cbSize = sizeof(devInterfaceData );
    if( !SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &guid,dwIndex, &devInterfaceData ) )
    {
        break;
    }

    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   
    SetupDiGetDeviceInterfaceDetail(
      hDevInfo,&devInterfaceData,
      pDevDetail, // SP_DEVICE_INTERFACE_DETAIL_DATA
      1024,&dwRequiredSize,&devInfoData ); // SP_DEVINFO_DATA

    CM_Get_Parent( &devInstParent,devInfoData.DevInst, 0 );
    CM_Get_Parent( &devInstParent,devInstParent, 0 );
    CM_Get_Device_ID(  devInstParent, buf, 1024,0 );
}

最佳答案 以下是litle修改后的代码

#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;  // ERROR!!!
        }

        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_Device_ID (devInfoData.DevInst, szDeviceInstanceID, ARRAY_SIZE(szDeviceInstanceID), 0);
        if (status == CR_SUCCESS) {
            _tprintf (TEXT("%s\n"), szDeviceInstanceID);
        }

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

            status = CM_Get_Parent( &devInstParent,devInstParent, 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;
            }
        }
        else {
            continue;
        }
    }
}

在我的Windows 7计算机上没有任何问题,并产生如下输出:

SCSI\CDROM&VEN_ELBY&PROD_CLONEDRIVE&REV_1.4\1&2AFD7D61&0&000000
    ROOT\SCSIADAPTER\0000
        HTREE\ROOT\0
STORAGE\VOLUME\{21C004DA-0EB2-11DF-8C02-806E6F6E6963}#0000000000100000
    ROOT\VOLMGR\0000
        HTREE\ROOT\0
STORAGE\VOLUME\{21C004DA-0EB2-11DF-8C02-806E6F6E6963}#000000004B100000
    ROOT\VOLMGR\0000
        HTREE\ROOT\0
STORAGE\VOLUME\{21C004DA-0EB2-11DF-8C02-806E6F6E6963}#00000037C7A00000
    ROOT\VOLMGR\0000
        HTREE\ROOT\0

根据评论更新:在VMware的Windows XP中,同一个实用程序产生以下输出

FDC\GENERIC_FLOPPY_DRIVE\6&1435B2E2&0&0
    ACPI\PNP0700\5&324D5432&0
        ACPI\PNP0A05\4&5289E18&0
IDE\CDROMNECVMWAR_VMWARE_IDE_CDR10_______________1.00____\3031303030303030303030303030303030303130
    PCIIDE\IDECHANNEL\4&23686003&0&1
        PCI\VEN_8086&DEV_7111&SUBSYS_197615AD&REV_01\3&61AAA01&0&39
STORAGE\VOLUME\1&30A96598&0&SIGNATURE91929192OFFSET7E00LENGTH1FFD5AA00
    ROOT\FTDISK\0000
        HTREE\ROOT\0

因为它是另一个操作系统上的另一台计算机(虚拟计算机),我们收到另一个设备列表.您当前的问题是使函数CM_Get_Parent()在Windows XP和Windows 7上都能正常工作.已发布的代码就像我们所看到的那样.或者它现在可以在Windows XP或Windows 7计算机上正常运行?

如何获取pid和vid(产品ID和发件人ID)我在Get information about disk drives result on windows7 – 32 bit system中描述过,但是对于任何驱动器号而不是卷设备.可以轻松更改代码以显示更多信息,如卷名,总线名称和其他信息.但这一切都是另一个问题.

更新:由于stackoverflow.com中的邮件大小限制,我将程序的扩展版本从Get information about disk drives result on windows7 – 32 bit system置于http://www.ok-soft-gmbh.com/ForStackOverflow/EnumMassStorage.c之下.测试输出看起来像http://www.ok-soft-gmbh.com/ForStackOverflow/EnumMassStorage.txt

点赞