50万做网站,网易企业邮箱登录登录入口,建材 团购 网站怎么做,天汇大厦网站建设公司参考腾讯电脑管家-软件市场中的驱动备份专家写的一个驱动备份软件案例#xff0c;学习Setupapi.h库中的函数使用.通过Setupapi.h库读取设备管理器中安装的设备获取安装的驱动列表#xff0c;通过bit7z库备份驱动目录下的所有文件. 目录导读 实现效果相关内容示例获取SP_DRVIN… 参考腾讯电脑管家-软件市场中的驱动备份专家写的一个驱动备份软件案例学习Setupapi.h库中的函数使用.通过Setupapi.h库读取设备管理器中安装的设备获取安装的驱动列表通过bit7z库备份驱动目录下的所有文件. 目录导读 实现效果相关内容示例获取SP_DRVINFO_DETAIL_DATA结构数据相关函数SetupDiBuildDriverInfoList 函数SetupDiEnumDriverInfo函数SetupDiGetDriverInfoDetail 函数 相关实现获取所有驱动列表获取驱动SP_DRVINFO_DETAIL_DATA结构数据qDebug打印输出 SP_DRVINFO_DETAIL_DATA 结构数据 实现效果
参考腾讯电脑管家-软件市场中的驱动备份专家软件 实现对设备管理器中的驱动信息的读取和备份 其中的驱动名称版本信息和驱动目录都是通过设备管理器的属性获取 详情参考以下文章内容 Qt案例 调用WINDOWS API中的SETUPAPI.H库获取设备管理器中设备的详细信息中的属性值(一) Qt案例 调用WINDOWS API中的SETUPAPI.H库获取设备管理器中设备的详细信息中的属性值(二) 驱动备份使用bit7z调用7z.exe实现相关功能,参考 Qt 编译使用Bit7z库接口调用7z.dll、7-Zip.dll解压压缩常用Zip、ISO9660、Wim、Esd、7z等格式文件一
相关内容示例
遍历设备管理器中驱动程序的相关信息 获取SP_DRVINFO_DETAIL_DATA结构数据
SP_DRVINFO_DETAIL_DATA结构包含有关特定驱动程序信息结构的详细信息。 语法
typedef struct _SP_DRVINFO_DETAIL_DATA_W {DWORD cbSize; //SP_DRVINFO_DETAIL_DATA结构的大小以字节为单位。FILETIME InfDate; //此驱动程序的 INF 文件的日期。DWORD CompatIDsOffset; //此值还可用于确定 CompatID 列表之前是否有 硬件 ID 。 如果此值大于 1则 HardwareID 缓冲区中的第一个字符串是硬件 ID。 如果此值小于或等于 1则没有硬件 ID。DWORD CompatIDsLength; //CompatID 列表的长度以字符为单位从 HardwareID 缓冲区的开头偏移 CompatIDsOffset 开始。ULONG_PTR Reserved; //保留。 仅限内部使用。WCHAR SectionName[LINE_LEN]; //一个以 NULL 结尾的字符串包含此驱动程序的 INF DDInstall 节 的名称。 这必须是基本 DDInstall 节名称如 InstallSec没有任何特定于 OS/体系结构的扩展。WCHAR InfFileName[MAX_PATH]; //一个以 NULL 结尾的字符串其中包含此驱动程序的 INF 文件的完整限定名称。WCHAR DrvDescription[LINE_LEN]; //一个以 NULL 结尾的字符串用于描述驱动程序。WCHAR HardwareID[ANYSIZE_ARRAY]; //包含 ID 列表的缓冲区 (单个 硬件 ID 后跟 兼容 ID 列表) 。 这些 ID 对应于 INF 模型部分中的硬件 ID 和兼容 ID。列表中的每个 ID 都是以 NULL 结尾的字符串。
} SP_DRVINFO_DETAIL_DATA_W, *PSP_DRVINFO_DETAIL_DATA_W;相关函数 SetupDiBuildDriverInfoList 函数
SetupDiBuildDriverInfoList 函数生成与特定设备关联的驱动程序列表或与设备信息集的全局类驱动程序列表相关联。 语法
//! 如果成功该函数将返回 TRUE 。 否则它将返回 FALSE 并且可以通过调用 GetLastError 来检索记录的错误。
WINSETUPAPI BOOL SetupDiBuildDriverInfoList([in] HDEVINFO DeviceInfoSet, //设备信息设置为包含驱动程序列表的设备信息的句柄可以是全局所有设备信息元素也可以是专用于单个设备信息元素。 设备信息集不得包含远程设备信息元素[in, out] PSP_DEVINFO_DATA DeviceInfoData,//指向 DeviceInfoSet 中设备信息元素的SP_DEVINFO_DATA结构的指针该元素表示要为其生成驱动程序列表的设备。 此参数是可选的可以为 NULL。 如果指定此参数则列表与指定的设备相关联。 如果此参数为 NULL则列表与 DeviceInfoSet 的全局类驱动程序列表相关联。[in] DWORD DriverType //要生成的驱动程序列表的类型
);SetupDiEnumDriverInfo函数
SetupDiEnumDriverInfo 函数枚举驱动程序列表的成员。 语法
//! 如果成功该函数将返回 TRUE 。 否则它将返回 FALSE 并且可以通过调用 GetLastError 来检索记录的错误。
WINSETUPAPI BOOL SetupDiEnumDriverInfoA([in] HDEVINFO DeviceInfoSet, //包含要枚举的驱动程序列表 的设备信息集 的句柄。[in, optional] PSP_DEVINFO_DATA DeviceInfoData, //指向 SP_DEVINFO_DATA 结构的指针该结构指定 DeviceInfoSet 中的设备信息元素。 此参数是可选的可以为 NULL。 如果指定此参数 SetupDiEnumDriverInfo 将枚举指定设备的驱动程序列表。 如果此参数为 NULL 则 SetupDiEnumDriverInfo 枚举与 DeviceInfoSet 关联的全局类驱动程序列表 (此列表的类型为 SPDIT_CLASSDRIVER) 。[in] DWORD DriverType, //要枚举的驱动程序列表的类型[in] DWORD MemberIndex, //要检索的驱动程序信息成员的从零开始的索引。[out] PSP_DRVINFO_DATA_A DriverInfoData //指向调用方初始化 的SP_DRVINFO_DATA 结构的指针该结构接收有关枚举驱动程序的信息。 调用方必须设置 DriverInfoData。在调用 SetupDiEnumDriverInfo 之前cbSize 为 sizeof ( SP_DRVINFO_DATA) 。 如果未正确设置 cbSize 成员 则 SetupDiEnumDriverInfo 将返回 FALSE。
);SetupDiGetDriverInfoDetail 函数
SetupDiGetDriverInfoDetail 函数检索设备信息集或设备信息集中特定设备信息元素的驱动程序信息详细信息。 语法
//! 如果成功该函数将返回 TRUE 。 否则它将返回 FALSE
WINSETUPAPI BOOL SetupDiGetDriverInfoDetailW([in] HDEVINFO DeviceInfoSet, //包含要为其检索驱动程序信息的驱动程序信息元素 的设备信息集 的句柄。[in, optional] PSP_DEVINFO_DATA DeviceInfoData, //指向 SP_DEVINFO_DATA 结构的指针该结构指定表示要为其检索驱动程序信息的设备的设备信息元素。 此参数是可选的可以为 NULL。 如果指定此参数 SetupDiGetDriverInfoDetail 将检索指定设备的驱动程序列表中有关驱动程序的信息。 如果此参数为 NULL 则 SetupDiGetDriverInfoDetail 将检索有关作为 DeviceInfoSet 全局类驱动程序列表成员的驱动程序的信息。[in] PSP_DRVINFO_DATA_W DriverInfoData, //指向 SP_DRVINFO_DATA 结构的指针该结构指定要为其检索详细信息的驱动程序信息元素。 如果指定 了 DeviceInfoData 则驱动程序必须是 DeviceInfoData 指定的设备的驱动程序列表的成员。 否则驱动程序必须是 DeviceInfoSet 的全局类驱动程序列表的成员。[in, out] PSP_DRVINFO_DETAIL_DATA_W DriverInfoDetailData, //指向 SP_DRVINFO_DETAIL_DATA 结构的指针该结构接收有关指定驱动程序的详细信息。 如果未指定此参数 DriverInfoDetailDataSize 必须为零。 如果指定此参数则 DriverInfoDetailData。在调用 SetupDiGetDriverInfoDetail 之前cbSize 必须设置为 size of ( SP_DRVINFO_DETAIL_DATA) 的值。[in] DWORD DriverInfoDetailDataSize, //DriverInfoDetailData 缓冲区的大小以字节为单位。[out, optional] PDWORD RequiredSize //向变量的指针该变量接收存储详细驱动程序信息所需的字节数。 此值包括结构的大小以及包含硬件 ID 列表和兼容 ID 列表的末尾的可变长度字符缓冲区所需的其他字节。
);相关实现
获取所有驱动列表
//! QListCONST GUID* GUID_DEVCLASS_LIST 设备标识
for(int t0;tGUID_DEVCLASS_LIST.count();t){QString IconPathLib_ExtrationDrives::getInstance().GeticonPath(GUID_DEVCLASS_LIST[t]);HDEVINFO deviceInfoSet SetupDiGetClassDevs(GUID_DEVCLASS_LIST[t], NULL, NULL, DIGCF_PRESENT);if (deviceInfoSet INVALID_HANDLE_VALUE) {printf(Failed to get device information set. Error code: %d\n, GetLastError());return ;}SP_DEVINFO_DATA deviceInfoData;deviceInfoData.cbSize sizeof(SP_DEVINFO_DATA);for (DWORD i 0; SetupDiEnumDeviceInfo(deviceInfoSet, i, deviceInfoData); i) {//SetupDiBuildDriverInfoList 函数生成与特定设备关联的驱动程序列表或与设备信息集的全局类驱动程序列表相关联。bool ret SetupDiBuildDriverInfoList(deviceInfoSet, deviceInfoData, SPDIT_CLASSDRIVER);if(!ret){qDebug(Error enumerating driver info. Error code: %d\n, GetLastError());continue ;}SP_DRVINFO_DATA rDriverInfoData;rDriverInfoData.cbSize sizeof(SP_DRVINFO_DATA);//SetupDiEnumDriverInfo 函数枚举驱动程序列表的成员for(int j0;SetupDiEnumDriverInfo(deviceInfoSet, deviceInfoData, SPDIT_CLASSDRIVER, j, rDriverInfoData);j){PSP_DRVINFO_DETAIL_DATA rDriverInfoDetailnew SP_DRVINFO_DETAIL_DATA() ;rDriverInfoDetail-cbSizesizeof(SP_DRVINFO_DETAIL_DATA);if(Lib_ExtrationDrives::getInstance().GetSetupDiGetDriverInfoDetail(deviceInfoSet,deviceInfoData, rDriverInfoData,rDriverInfoDetail)){qDebug()-----i - j;
// Print_DriverInfoDetail(rDriverInfoDetail);qDebug()[cbSize] :rDriverInfoDetail-cbSize;qDebug()[SectionName] :QString::fromWCharArray(rDriverInfoDetail-SectionName);//! SetupOpenInfFile 函数打开一个 INF 文件并返回它的句柄。qDebug()[InfFileName] :QString::fromWCharArray(rDriverInfoDetail-InfFileName);qDebug()[DrvDescription] :QString::fromWCharArray(rDriverInfoDetail-DrvDescription);qDebug()[CompatIDsOffset] :rDriverInfoDetail-CompatIDsOffset;qDebug()[CompatIDsLength] :rDriverInfoDetail-CompatIDsLength;}free(rDriverInfoDetail);}}SetupDiDestroyDeviceInfoList(deviceInfoSet);}获取驱动SP_DRVINFO_DETAIL_DATA结构数据
通过SetupDiGetDriverInfoDetail函数检索SP_DRVINFO_DETAIL_DATA包含有关特定驱动程序信息结构的详细信息预防ERROR_INSUFFICIENT_BUFFER异常
bool Lib_ExtrationDrives::GetSetupDiGetDriverInfoDetail(HDEVINFO infoset,PSP_DEVINFO_DATA device,PSP_DRVINFO_DATA rDriver,PSP_DRVINFO_DETAIL_DATA rDriverInfoDetail) const
{bool isSuccesstrue;DWORD needSize0;if(!SetupDiGetDriverInfoDetail(infoset,device,rDriver,rDriverInfoDetail,sizeof(SP_DRVINFO_DETAIL_DATA),needSize)){if((GetLastError() ERROR_INSUFFICIENT_BUFFER)){// qDebug()cbSize : rDriverInfoDetail-cbSize needSize : needSize;rDriverInfoDetail(SP_DRVINFO_DETAIL_DATA*)malloc(needSize);rDriverInfoDetail-cbSize sizeof(SP_DRVINFO_DETAIL_DATA) ;if (!SetupDiGetDriverInfoDetail(infoset, device, rDriver, rDriverInfoDetail, needSize, NULL)){isSuccessfalse;qDebug()Error getting detailed driver info . because needSize:needSize;}}else{isSuccessfalse;qDebug()Error getting detailed driver info !;}}return isSuccess;
}
qDebug打印输出 SP_DRVINFO_DETAIL_DATA 结构数据 注根据硬件 ID 和 兼容 ID 列表在 INF 模型部分中的指定方式 HardwareID 缓冲区可以类似于以下任何一种 \0HWID\0HWID\0COMPATID_1\0…COMPATID_N\0\0\0COMPATID_1\0…COMPATID_N\0\0 void Print_DriverInfoDetail(PSP_DRVINFO_DETAIL_DATA rDriverInfoDetail)
{qDebug()[cbSize] :rDriverInfoDetail-cbSize;qDebug()[SectionName] :QString::fromWCharArray(rDriverInfoDetail-SectionName);//! SetupOpenInfFile 函数打开一个 INF 文件并返回它的句柄。qDebug()[InfFileName] :QString::fromWCharArray(rDriverInfoDetail-InfFileName);qDebug()[DrvDescription] :QString::fromWCharArray(rDriverInfoDetail-DrvDescription);qDebug()[CompatIDsOffset] :rDriverInfoDetail-CompatIDsOffset;qDebug()[CompatIDsLength] :rDriverInfoDetail-CompatIDsLength;// parse the hardware ID, if it existsif (rDriverInfoDetail-CompatIDsOffset 1){// Parse for hardware ID from index 0.// This is a single NULL-terminated stringqDebug()设备的硬件 id:;// qDebug()QString::fromWCharArray(rDriverInfoDetail-HardwareID);wchar_t* hardwareidnew wchar_t[MAX_PATH];int col0;for(int i0;irDriverInfoDetail-CompatIDsOffset;i){if(rDriverInfoDetail-HardwareID[i]!\0){hardwareid[col]rDriverInfoDetail-HardwareID[i];col;}else{hardwareid[col]\0;qDebug()QString::fromWCharArray(hardwareid);free(hardwareid);hardwareidnew wchar_t[MAX_PATH];col0;}}}// Parse the compatible IDs, if they existif (rDriverInfoDetail-CompatIDsLength 0){qDebug()设备的兼容 id:;// Parse for list of compatible IDs from CompatIDsOffset.// This is a double NULL-terminated list of strings (i.e. MULTI-SZ)wchar_t* compatibleidnew wchar_t[MAX_PATH];int col0;int lengthsrDriverInfoDetail-CompatIDsOffsetrDriverInfoDetail-CompatIDsLength;for(int irDriverInfoDetail-CompatIDsOffset;ilengths;i){if(rDriverInfoDetail-HardwareID[i]!\0){compatibleid[col]rDriverInfoDetail-HardwareID[i];col;}else{compatibleid[col]\0;qDebug()QString::fromWCharArray(compatibleid);free(compatibleid);if(i1lengths (rDriverInfoDetail-HardwareID[i1]\0)) //结束break;compatibleidnew wchar_t[MAX_PATH];col0;}}}qDebug()endl;}