SetupDiGetClassDevs для вывода списка дисков SCSI завершается с ошибкой с кодом ошибки 13 (ERROR_INVALID_DATA)

У меня довольно интересная проблема, для которой я не могу найти решение. Я использую Setup API для вывода списка дисков в системе. У меня нет проблем с использованием приведенного ниже кода при установке перечислителя в "IDE". Мой страх возникает, когда значение перечислителя установлено на "SCSI". Код, который воспроизводит эту проблему ниже:

#include <iostream>
#include <Windows.h>
#include <SetupAPI.h>
#include <cfgmgr32.h>
#include <devguid.h>

int main() {
    std::cout << "Looking for only SCSI disks" << std::endl;
    HDEVINFO hDevs(SetupDiGetClassDevs(&GUID_DEVCLASS_DISKDRIVE, "SCSI", NULL, DIGCF_PRESENT));
    if(INVALID_HANDLE_VALUE == hDevs) {
        DWORD error(GetLastError());
        std::cout << "Handle returned is invalid. Error code: " << error << std::endl;
        return 1;
    }

    SP_DEVINFO_DATA sp = {sizeof(SP_DEVINFO_DATA)};
    char buff[256];
    memset(buff, 0, 256);
    DWORD index(0);

    std::cout << "The handle is valid, listing drives now" << std::endl;
    while(SetupDiEnumDeviceInfo(hDevs, index++, &sp)) {
        CM_Get_Device_ID(sp.DevInst, buff, 256, 0);
        std::cout << buff << std::endl;
        memset(buff, 0, 256);
    }

    SetupDiDestroyDeviceInfoList(hDevs);
    return 0;
}

Как видите, в этом коде нет ничего примечательного. Проблема заключается в том, что на некоторых ноутбуках этот код вызывает ошибки в SetupDiGetClassDevs(). Проверка GetLastError() показывает, что он завершился ошибкой для ERROR_INVALID_DATA (0xd). Чего я не понимаю, так это почему. Эта точно такая же программа, запускаемая на моем компьютере разработчика как и для моего пользователя (с правами администратора), так и для непривилегированного пользователя, прекрасно работает независимо от того, присутствуют или нет диски SCSI.

Я знаю, что используемый GUID верен. Это определено в devguid.h. "SCSI" является действительным перечислителем PnP, на который ссылается эта страница MSDN, а также из проверки свойства "Перечислитель" в диспетчере устройств. Третий аргумент может быть NULL, а четвертый является допустимым определенным флагом для этой функции. Я знаю это, потому что, за исключением этих ноутбуков, это работает на всех системах, на которых я когда-либо пробовал (которых в моей организации довольно много). Я надеюсь, что кто-то здесь может знать о том, что может вызвать сбой SetupDiGetClassDevs () для этой ошибки с этими условиями, или, по крайней мере, может указывать мне в правильном направлении. Я не эксперт по Windows, и я мог что-то упустить из-за конфигурации системы или прав доступа (хотя это не подразумевается из-за ошибки).

Как я надеюсь, ясно, я запустил этот код на одном ноутбуке, на котором я могу его протестировать как пользователь с правами администратора и как пользователь администратора: оба с одинаковым результатом. Это ноутбук HP EliteBook 8460p с 64-разрядным пакетом обновления 1 (SP1) для Windows 7. Компиляция этого кода в 32 или 64 бита не имеет значения.

1 ответ

Решение

Я собираюсь опубликовать ответ, полученный мною на форумах поддержки MSDN, чтобы помочь кому-то, кто может быть смущен этой же проблемой. Очевидно, это ожидаемое поведение для Windows 7. Если система никогда не видела аппаратное обеспечение с перечислителем, указанным в SetupDiGetClassDevs(), то происходит сбой, и ожидается наличие этого кода ошибки.

Для справки, нить, где я задавал этот вопрос, связана здесь.

Другие вопросы по тегам