0

我有一个相当有趣的问题,我无法找到解决方案。我正在使用 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 专家,我可能会遗漏系统配置或权限方面的某些内容(尽管错误并未暗示)。

我希望很清楚,我已经在一台笔记本电脑上运行了这段代码,我可以同时以具有管理员权限的用户和管理员用户的身份对其进行测试:两者都具有相同的结果。笔记本电脑是运行 Windows 7 64 位 Service Pack 1 的 HP EliteBook 8460p。以 32 位或 64 位编译此代码没有区别。

4

1 回答 1

1

我将发布我从 MSDN 支持论坛上的一位同事那里得到的答案,以帮助可能对同一问题感到困惑的人。显然,这是 Windows 7 的预期行为。如果系统从未见过具有为 SetupDiGetClassDevs() 指定的枚举器的硬件,则发生故障并且预期会出现此错误代码。

作为参考,我问这个问题的线程在这里链接。

于 2013-01-30T18:56:32.910 回答