UpdateDriverForPlugAndPlayDevices 错误告诉我我*不*做我正在做的事情

问题描述:

我正在研究一种安装驱动程序的方法.由于这必须在多个平台上运行,因此我正在向 devcon 和 dpinst 发出请求,以便在需要时完成驱动程序安装/更新/删除的工作.在测试时,我在向 devcon 进行炮击时遇到了问题.为了隔离,我编写了一个小应用程序来执行 devcon 在更新 参见此处,使用来自 WinDDK 的 devcon 源作为参考.我在 Setup API(实际上是 Newdev.dll 的一部分)的 UpdateDriverForPlugAndPlayDevices() 中遇到了一些问题 见这里.源代码在这里:

I'm working on a means of installing a driver. Because of the multiple platforms on which this must work, I'm shelling-out to both devcon and dpinst to do the work of driver install/update/removal when needed. While testing, I'm having problems with the shelling out to devcon. To isolate, I wrote a small app to do what devcon does in update see here, using the devcon source from the WinDDK for reference. I'm having some problems with UpdateDriverForPlugAndPlayDevices() from Setup API (actually part of Newdev.dll) see here. The source code is here:

#include <iostream>
#include <Windows.h>
#include <newdev.h>

int main(int argc, char** argv) {
    // Go through the same steps as does dev con for this update crap
    char infFile[MAX_PATH];

    if(3 > argc) {
        std::cerr << "an INF and HW ID must be specified" << std::endl;
        return 1;
    }

    DWORD result(GetFullPathName(argv[1], MAX_PATH, infFile, NULL));
    if((result >= MAX_PATH) || (0 == result)) {
        std::cerr << "path is too long for buffer" << std::endl;
        return 1;
    }

    if(GetFileAttributes(infFile) == -1) {
        std::cerr << "file doesn't exist" << std::endl;
        return 1;
}

    BOOL reboot(FALSE);
    if(!UpdateDriverForPlugAndPlayDevices(NULL, argv[2], infFile, INSTALLFLAG_FORCE, &reboot)) {
        std::cerr << "Failed to install the driver.  Code: "
                  << GetLastError()
                  << std::endl;
        return 2;
}

    if(reboot) {
        std::cout << "A reboot is needed to complete driver install"
                  << std::endl;
    }

    return 0;
}

当 UpdateDriverForPlugAndPlayDevices() 返回 false 时程序失败.然后打印 GetLastError() 返回的错误代码,这样我就知道出了什么问题.返回的错误代码:259.根据 this 资源表示这是 ERROR_NO_MORE_ITEMS.根据 UpdateDriverForPlugAndPlayDevices() 的链接,该函数在以下情况下返回此错误代码:该函数找到了 HardwareId 值的匹配项,但指定的驱动程序并不比当前驱动程序更好的匹配,并且调用者做了not 指定 INSTALLFLAG_FORCE 标志."您会从我的代码中注意到我确实指定了这个标志.

The program fails when UpdateDriverForPlugAndPlayDevices() returns false. This then prints the error code, returned by GetLastError(), so I'd know what went wrong. The error code returned: 259. According to this resource says this is ERROR_NO_MORE_ITEMS. According to the link for UpdateDriverForPlugAndPlayDevices(), this function returns this error code when, "The function found a match for the HardwareId value, but the specified driver was not a better match than the current driver and the caller did not specify the INSTALLFLAG_FORCE flag." You'll notice from my code that I did specify this flag.

我不知道从哪里开始.有人可以从这段代码中找出我遗漏了什么吗?这只是简单的感觉",但我完全想念它.

I do not know where to go from here. Can someone please identify from this code what it is I'm missing? This just has the "feel" of something simple, but I'm totally missing it.

谢谢,安迪

问题似乎不在于代码,而在于 INF 文件.有趣的是,该函数的文档说使用该标志将强制安装,但当 INF 文件没有列出"时不会强制安装.模型部分中的任何设备类.这就是我最终能够安装的方式.我在 INF 的模型部分添加了正确的设备类.

The problem appeared to be not with the code but with the INF file. Interesting that the documentation for the function said that using that flag will force the install but didn't when the INF file didn't "list" any device classes in the models section. This is how I was able to install eventually. I added the correct device class to the models section in the INF.

编辑 2020 年 9 月 17 日就在今天(编辑的)有人要求添加来自 INF 的示例.我遇到这个问题已经 8 年了,我不再为这个团队工作了.但是,据我所知,并大量借鉴 INF 模型部分INF 制造商部分,希望对您有所帮助.

EDIT Sep. 17, 2020 It was requested by someone just today (of the edit) to add an example from the INF. It's been 8 years since I had this issue and I no longer work for this team. However, as best as I can recall, and drawing heavily upon the docs for INF Models Section and INF Manufacturers Section, I hope this helps.

本质上,类由模型部分指定,模型由制造商部分指定.

Essentially, the class is specified by the Models Section and the model is specified by the Manufacturer Section.

[Manufacturer]
%MfgName%=Standard,NTamd64

[Standard.NTamd64]
%DeviceString%=<class path or GUID>\<device>

[Strings]
MfgName=ACME
DeviceString="Device Type"