Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
268 views
in Technique[技术] by (71.8m points)

c++ - Check if a Windows driver exists for a given Device ID

I'm writing a Windows library using C++. This library should be able to check if the device driver of a specific device is installed on the system. So I am searching for a way to check if a driver is installed for a known Device ID.

So far, I found this information:

SetupDiBuildDriverInfoList lists available drivers for given devices. However, I have to supply more than just a Device ID.

SetupDiGetClassDevs seems to return exactly what I need for calling SetupDiBuildDriverInfoList, but it still doesn't take a Device ID as input. It may take a GUID of a device setup/interface class, but if I understand it correctly, a vendor-specific driver does not have such a GUID. It can also take a PnP enumerator, which I don't know enough about to tell whether I can use that somehow. Or finally, it may take a Device Instance ID - but not a Device ID.

Obviously, I want to check for any device of the same kind, so querying by Device Instance ID is not feasible. So, the question is: How do I check whether the driver for a given Device ID (or any other information that can identify the device; I assume Device ID is the right thing here) is installed, using the API functions I have listed (or any other way)?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Harry Johnston's answer brought me close, but I had to add a bit more to make it work. The magic bit that was missing was that I had to call both SetupDiEnumDeviceInfo and SetupDiBuildDriverInfoList before SetupDiEnumDriverInfoW actually did something useful.

Here is a complete (modulo cleanup) example, replace the string passed to SetupDiGetClassDevsW to match your own device. For my specific device it prints

Driver found: description: USBXpress Device, MfgName: Silicon Labs, ProviderName: Silicon Laboratories Inc.

on a PC with the driver installed and

No driver found

on a PC (actually VM) with no driver installed.

#include <Windows.h>
#include <SetupAPI.h>
#include <stdio.h>
#include <stdlib.h>

#pragma comment(lib, "setupapi.lib")

int main(int argc, char ** argv)
{
    HDEVINFO hdevinfo = SetupDiGetClassDevsW(NULL, LR"(USBVID_10C4&PID_EA61)",
                                             NULL, DIGCF_ALLCLASSES);
    if (hdevinfo == INVALID_HANDLE_VALUE)
    {
        DWORD err = GetLastError();
        printf("SetupDiGetClassDevs: %u
", err);
        return 1;
    }

    SP_DEVINFO_DATA devinfo;
    devinfo.cbSize = sizeof(devinfo);
    if (!SetupDiEnumDeviceInfo(hdevinfo, 0, &devinfo))
    {
        DWORD err = GetLastError();
        printf("SetupDiEnumDeviceInfo: %u %d
", err, 0);
        return 1;
    }

    if (!SetupDiBuildDriverInfoList(hdevinfo, &devinfo, SPDIT_COMPATDRIVER)) {
        printf("error %d
", GetLastError());
        return 1;
    }

    SP_DRVINFO_DATA_W drvdata;
    drvdata.cbSize = sizeof(SP_DRVINFO_DATA_W);
    BOOL worked = SetupDiEnumDriverInfoW(hdevinfo, &devinfo, SPDIT_COMPATDRIVER,
                                         0, &drvdata);
    if (worked) {
        printf("Driver found: description: %ws, MfgName: %ws, ProviderName: %ws
",
               drvdata.Description, drvdata.MfgName, drvdata.ProviderName);
    }
    else {
        DWORD err = GetLastError();
        if (err == ERROR_NO_MORE_ITEMS)
            printf("No driver found
");
        else {
            printf("SetupDiEnumDriverInfoW: %d", err);
            return 1;
        }
    }
    return 0;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...