【问题标题】:msdn CM_GET_Parent Example Doesn't Workmsdn CM_GET_Parent 示例不起作用
【发布时间】:2010-08-06 10:32:11
【问题描述】:

我正在努力从我插入的 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 );
}

【问题讨论】:

  • 前段时间我在stackoverflow.com/questions/3098696/… 中向您发布了一个使用CM_Get_Parent 的代码示例,并且我在Windows 7 下进行了测试。因此,如果您有一个CM_Get_Parent () 函数不起作用的示例,您应该发布可用于重现问题的相应代码示例。

标签: winapi windows-7 msdn


【解决方案1】:

以下是一点修改的代码

#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 计算机上正常工作?

如何获取我在Get information about disk drives result on windows7 - 32 bit system 中描述的 pid 和 vid(产品 id 和 ventor id),但适用于任何 驱动器号,而不适用于 卷设备。可以轻松更改代码以显示更多信息,例如卷名称、总线名称和其他信息。但这一切已经是另一个问题了。

更新:由于 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

【讨论】:

  • @barbgal:代码是否在您的 Windows 7 和 Windows XP 计算机上运行?你对CM_Get_Parent()还有问题吗?
猜你喜欢
  • 2011-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多