msdn CM_GET_Parent Пример не работает - PullRequest
4 голосов
/ 06 августа 2010

Я работаю над получением идентификатора устройства из USB-устройства, которое я подключаю ...

Вышеуказанное приложение работает на 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 );
}

1 Ответ

2 голосов
/ 10 августа 2010

следующий маленький модифицированный код

#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

ОБНОВЛЕНО на основе комментария: На моей Windows XP в VMware эта же утилита выдает следующий вывод

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 (идентификатор продукта и идентификатор продавца). Я описал в Получение информации о результате на дисках в windows7 - 32-битной системе , но для любых букв дисков и не для устройств громкости . Можно легко изменить код, чтобы показать больше информации, такой как имя тома, имя шины и другую информацию. Но это уже другой вопрос.

ОБНОВЛЕНО: Я разместил расширенную версию программы с Получите информацию о результате с дисководами на Windows7 - 32-битной системе в http://www.ok -soft-gmbh.com /ForStackOverflow/EnumMassStorage.c из-за ограничения размером сообщения в stackoverflow.com. Результаты теста выглядят как http://www.ok -soft-gmbh.com / ForStackOverflow / EnumMassStorage.txt

...