SetupApi函数
+ -

SetupAPI根据硬件ID获取驱动INF文件和驱动日期版本信息

2022-01-25 252 0

SetupAPI根据硬件ID获取驱动INF文件和驱动日期版本信息。

注释掉的代码是获取该硬件的所有可用驱动信息。

代码是逐渐完善的,没想到可以直接从注册表信息中获取到。

SetupDiOpenDevRegKey打开的注册表路径示例为:

计算机\HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class\{36fc9e60-c465-11cf-8056-444553540000}\0002

完整的SetupAPI根据硬件ID获取驱动INF文件和驱动日期版本信息代码如下


BOOL CDriver::GetDeviDriverInfo(TCHAR* hwid, std::wstring& info)
{
    HDEVINFO devs = INVALID_HANDLE_VALUE;

    do
    {
        //获取某类设备集合
        devs = SetupDiGetClassDevsEx(NULL,
            NULL,
            NULL,
            DIGCF_ALLCLASSES | DIGCF_PRESENT,
            NULL,
            NULL,
            NULL);
        if (devs == INVALID_HANDLE_VALUE)
        {
            break;
        }


        SP_DEVINFO_LIST_DETAIL_DATA devInfoListDetail;
        devInfoListDetail.cbSize = sizeof(devInfoListDetail);
        if (!SetupDiGetDeviceInfoListDetail(devs, &devInfoListDetail))
        {
            break;
        }

        SP_DEVINFO_DATA devInfo;
        devInfo.cbSize = sizeof(devInfo);
        for (DWORD devIndex = 0; SetupDiEnumDeviceInfo(devs, devIndex, &devInfo); devIndex++)
        {
            //获取硬件ID
            std::wstring HardId = GetDevcieProperty(devs, &devInfo, SPDRP_HARDWAREID);
            TCHAR* pHardId = NULL;
            if (HardId.size())
            {
                pHardId = (TCHAR*)&HardId.at(0);
            }

            //printf("%d %ws\n", devIndex, pHardId);
            if (pHardId != NULL
                && _tcsicmp(hwid, pHardId) == 0)
            {
                SP_DEVINSTALL_PARAMS deviceInstallParams;
                {
                    HKEY hKey = SetupDiOpenDevRegKey(devs, &devInfo,
                        DICS_FLAG_GLOBAL,
                        0,
                        DIREG_DRV,
                        KEY_READ);
                    if (hKey == INVALID_HANDLE_VALUE)
                    {
                        RegCloseKey(hKey);
                        return FALSE;
                    }

                    TCHAR buff[512] = { 0 };
                    DWORD RegDataType;
                    DWORD RegDataLength = sizeof(buff); // bytes!!!
                    long regerr = RegQueryValueEx(hKey,
                        TEXT("InfPath"),
                        NULL,
                        &RegDataType,
                        (PBYTE)buff,
                        &RegDataLength
                    );
                    if ((regerr != ERROR_SUCCESS) || (RegDataType != REG_SZ))
                    {
                        RegCloseKey(hKey);
                        return FALSE;
                    }
                    printf("InfPath:%S\n", buff);

                    RegDataLength = sizeof(buff);
                    regerr = RegQueryValueEx(hKey,
                        TEXT("DriverDesc"),
                        NULL,
                        &RegDataType,
                        (PBYTE)buff,
                        &RegDataLength
                    );
                    if ((regerr != ERROR_SUCCESS) || (RegDataType != REG_SZ))
                    {
                        RegCloseKey(hKey);
                        return FALSE;
                    }
                    printf("DriverDesc:%S\n", buff);

                    RegDataLength = sizeof(buff);
                    regerr = RegQueryValueEx(hKey,
                        TEXT("DriverDate"),
                        NULL,
                        &RegDataType,
                        (PBYTE)buff,
                        &RegDataLength
                    );
                    if ((regerr != ERROR_SUCCESS) || (RegDataType != REG_SZ))
                    {
                        RegCloseKey(hKey);
                        return FALSE;
                    }
                    printf("DriverDate:%S\n", buff);

                    RegDataLength = sizeof(buff);
                    regerr = RegQueryValueEx(hKey,
                        TEXT("DriverVersion"),
                        NULL,
                        &RegDataType,
                        (PBYTE)buff,
                        &RegDataLength
                    );
                    if ((regerr != ERROR_SUCCESS) || (RegDataType != REG_SZ))
                    {
                        RegCloseKey(hKey);
                        return FALSE;
                    }
                    printf("DriverVersion:%S\n", buff);
                    RegCloseKey(hKey);
                }


                //ZeroMemory(&deviceInstallParams, sizeof(deviceInstallParams));
                //deviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
                //if (!SetupDiGetDeviceInstallParams(devs, &devInfo, &deviceInstallParams))
                //{
                //    break;
                //}
                //deviceInstallParams.FlagsEx |= DI_FLAGSEX_ALLOWEXCLUDEDDRVS;
                //if (!SetupDiSetDeviceInstallParams(devs, &devInfo, &deviceInstallParams))
                //{
                //    break;
                //}

                //if (SetupDiBuildDriverInfoList(devs, &devInfo, SPDIT_COMPATDRIVER))
                //{
                //    ULONG index = 0;
                //    SP_DRVINFO_DATA driverInfoData;
                //    ZeroMemory(&driverInfoData, sizeof(driverInfoData));
                //    driverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
                //    while (SetupDiEnumDriverInfo(devs, &devInfo, SPDIT_COMPATDRIVER, index, &driverInfoData))
                //    {
                //        SP_DRVINFO_DETAIL_DATA driverInfoDetail;
                //        driverInfoDetail.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
                //        if (SetupDiGetDriverInfoDetail(devs, &devInfo, &driverInfoData, &driverInfoDetail, sizeof(SP_DRVINFO_DETAIL_DATA), NULL))
                //        {
                //            index = index;
                //        }
                //        printf("driverInfoData.ProviderName:%S\n", driverInfoData.ProviderName);
                //        printf("driverInfoData.MfgName:%S\n", driverInfoData.MfgName);
                //        printf("driverInfoDetail.InfFileName:%S\n", driverInfoDetail.InfFileName);

                //        SYSTEMTIME SystemTime;
                //        if (FileTimeToSystemTime(&driverInfoData.DriverDate, &SystemTime)) 
                //        {
                //            TCHAR Buffer[MAX_PATH];
                //            if (GetDateFormat(LOCALE_USER_DEFAULT,
                //                DATE_SHORTDATE,
                //                &SystemTime,
                //                NULL,
                //                Buffer,
                //                sizeof(Buffer) / sizeof(TCHAR)
                //            ) != 0) 
                //            {
                //                printf("driverInfoData.DriverDate:%S\n", Buffer);
                //            }
                //        }
                //        ULARGE_INTEGER Version;
                //        Version.QuadPart = driverInfoData.DriverVersion;
                //        printf("Version:%d.%d.%d.%d\n",
                //            HIWORD(Version.HighPart),
                //            LOWORD(Version.HighPart),
                //            HIWORD(Version.LowPart),
                //            LOWORD(Version.LowPart)
                //        );
                //        DWORD e = GetLastError();
                //        e = e;
                //        index++;
                //    }
                //}


            }
        }

    } while (0);

    if (devs != INVALID_HANDLE_VALUE)
    {
        SetupDiDestroyDeviceInfoList(devs);
    }

    return TRUE;
}

PS:
另一种方法是通过实现,详情见devcon的FindCurrentDriver源代码

 deviceInstallParams.FlagsEx |= (DI_FLAGSEX_INSTALLEDDRIVER | DI_FLAGSEX_ALLOWEXCLUDEDDRVS);

0 篇笔记 写笔记

Windows驱动注册表写数据
实际上注册表的写入比读取要简单。因为这省略了一个尝试数据的大小的过程。直接将数据写入即可。写入值一般使用函数ZwSetValueKey 。这个函数的原型如下:NTSTATUS ZwSetValueKey( IN HANDLE KeyHandle, IN PUNICODE_STRI......
Windows驱动读注册表数据
一般使用ZwQueryValueKey来读取注册表中键的值。要注意的是注册表中的值可能有多种数据类型。而且长度也是没有定数的。为此,在读取过程中,就可能要面对很多种可能的情况。ZwQueryValueKey这个函数的原型如下:NTSTATUS ZwQueryValueKey( IN HAN......
Windows修改注册表使应用程序开机自动运行
先向大家介绍能让WINDOWS自动启动的2个文件和8个注册键1: 当前用户专用的启动文件夹 将快捷方式放入WINDOWS的用户启动文件夹中.在开始菜单的启动文件夹上,右键选中“打开”菜单如在本机win7 x64下为:C:/Users/Administrator/AppData/Roaming/M......
Windows内核打开注册表
和在应用程序中编程的方式类似,注册表是一个巨大的树形结构。操作一般都是打开某个子键。子键下有若干个值可以获得。每一个值有一个名字。值有不同的类型。一般需要查询才能获得其类型。子键一般用一个路径来表示。和应用程序编程的一点重大不同是这个路径的写法不一样。一般应用编程中需要提供一个根子键的句柄。而驱动......
SetupApi关于INF文件处理的函数
INF文件处理功能提供安装功能,包括以下内容:打开和关闭INF文件。检索有关INF文件的信息。检索有关复制操作的源文件和目标目录的信息。执行INF文件节中指定的安装操作。FunctionDescriptionInstallHinfSectionExecutes a spec......
SetupApi磁盘提示和错误处理函数大全
可以使用setup函数提示用户插入新介质,或处理复制、重命名或删除文件时出现的错误。下表列出了为请求安装介质和报告错误提供对话框的功能。FunctionDescriptionSetupCopyErrorGenerates a dialog box that informs th......
SetupApi文件队列函数大全
使用setup函数,可以为各种操作对文件进行排队。可以为复制、重命名和删除文件建立文件队列。通常,应用程序将整个安装所需的所有文件操作排队,然后“提交”队列,以便在单个批中执行操作。FunctionDescriptionSetupCloseFileQueueDestroys a......
SetupApi默认队列回调例程函数
如果将回调例程与文件队列相关联,则每次系统执行一个排队的文件操作时都会调用回调例程。通常,您可以使用默认队列回调例程SetupDefaultQueueCallback来处理这些通知。FunctionDescriptionSetupDefaultQueueCallbackHand......
SetupApi CAB文件函数
CAB文件是单个文件,通常扩展名为.CAB,包含多个压缩文件作为文件库。CAB文件用于组织将复制到用户系统的安装文件。压缩文件可以分布在多个CAB文件上。FunctionDescription SetupIterateCabinetSends a notification to......
SetupApi 磁盘空间列表函数
磁盘空间列表函数用于创建和修改磁盘空间列表。这些列表可用于计算处理将在安装过程中复制或删除的文件所需的总磁盘空间。FunctionDescriptionSetupAddInstallSectionToDiskSpaceListSearches for CopyFile and ......
SetupApi MRB文件列表
Most recently used (MRU) source lists 最近使用的(MRU)源列表驻留在用户的计算机上,包含有关以前安装中使用的源路径的信息。提示用户输入源路径时,可以使用此信息。安装应用程序可以访问特定于用户的源列表,如果应用程序具有管理员权限,还可以访问系统范围的源列表。......
SetupApi 文件日志函数
可以使用日志文件记录安装期间复制到系统的文件的相关信息。日志文件可以是系统日志,也可以是您自己的安装日志文件。FunctionDescriptionSetupInitializeFileLogInitializes a log file for use.SetupLogE......
SetupApi用户接口函数
可以在类安装程序和联合安装程序中使用以下设置函数来确定当前进程是否可以与用户交互。FunctionDescription SetupGetNonInteractiveModeReturns the value of a SetupAPI non-interactive flag......
SetupApi 日志函数
从Windows Vista开始,即插即用(PnP)设备安装应用程序、类安装程序和协同安装程序可以使用以下函数将日志条目写入SetupAPI文本日志。FunctionDescriptionSetupGetThreadLogTokenRetrieves the log token......
Windows设备树及设备信息管理接口
Windows下的所有设备都会挂接在其设备树上,设备树由PNP管理器来维护。如一个设备树如下图所示:设备树上每个节点代表一个设备,凡是有子节点的节点是一个总线设备,其负责枚举下子节点设备,这样进行层层枚举,形成一棵设备树。其中根节点由PNP管理器创建,其用于挂载ACPI子节点。ACPI是一个抽象的......
作者信息
我爱内核
Windows驱动开发,网站开发
好好学习,天天向上。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!