显卡驱动在哪里

发布时间: 2023-07-18 16:55 阅读: 文章来源:转载

上篇讲到英伟达在github上提供其显卡DLSS功能的SDK,因分析问题,就对其提供的库大概看了下,发现它内置了两种查询显卡驱动存储路径的方法,第一种是在Windows 10 1803以上使用gdi32.dll中提供的函数来查询,第二种是在Windows 10 1607到vista之间用常见的setupAPI来查询,由此可见有些知识需要更新了,用这么多年setupAPI,也许在未来真的不管用了呢。

我们来看下gdi32.dll方式,它主要是使用gdi32.dll中的导出函数D3DKMTEnumAdapters2和D3DKMTQueryAdapterInfo实现的,它需要d3dkmthk.h头文件(19041 SDK),如果没有可能就要自行声明许多用的到结构了:

std::wstring GetDriverStorePathFromQAI(int device_id){	std::wstring driver_store_path;	HMODULE gdi_h = NULL;	PFN_D3DKMTENUMADAPTERS2 pfnD3DKMTEnumAdapters2;	PFN_D3DKMTQUERYADAPTERINFO pfnD3DKMTQueryAdapterInfo;	gdi_h = LoadLibrary(_T("gdi32.dll"));	if (gdi_h) {		pfnD3DKMTEnumAdapters2 = (PFN_D3DKMTENUMADAPTERS2)GetProcAddress(gdi_h, "D3DKMTEnumAdapters2");		pfnD3DKMTQueryAdapterInfo = (PFN_D3DKMTQUERYADAPTERINFO)GetProcAddress(gdi_h, "D3DKMTQueryAdapterInfo");		if (!pfnD3DKMTEnumAdapters2 || !pfnD3DKMTQueryAdapterInfo)			return driver_store_path;		D3DKMT_ENUMADAPTERS2 enum_adapters = { 0 };		enum_adapters.NumAdapters = 0;		enum_adapters.pAdapters = NULL;		if (pfnD3DKMTEnumAdapters2(&enum_adapters) != 0)			return driver_store_path;		enum_adapters.pAdapters = new D3DKMT_ADAPTERINFO[enum_adapters.NumAdapters];		if (!enum_adapters.pAdapters)			return driver_store_path;		memset(enum_adapters.pAdapters, 0, sizeof(D3DKMT_ADAPTERINFO) * enum_adapters.NumAdapters);		if (pfnD3DKMTEnumAdapters2(&enum_adapters) == 0) {			for (ULONG i = 0; i < enum_adapters.NumAdapters; i++) {				D3DKMT_ADAPTERINFO* adapter_info_ptr = (D3DKMT_ADAPTERINFO*)&enum_adapters.pAdapters[i];				D3DKMT_QUERYADAPTERINFO	query_info = { 0 };				char					private_data[28] = { 0 };				query_info.hAdapter = adapter_info_ptr->hAdapter;				query_info.Type = KMTQAITYPE_PHYSICALADAPTERDEVICEIDS;				query_info.PrivateDriverDataSize = 28;				query_info.pPrivateDriverData = private_data;				if (pfnD3DKMTQueryAdapterInfo(&query_info) == 0) {					//nvidia = 0x10de, amd = 0x1002					if (*((DWORD*)private_data + 1) == device_id) {						D3DDDI_QUERYREGISTRY_INFO* reg_info_ptr;						//the size 0x432 is from nvidia's dll						reg_info_ptr = (D3DDDI_QUERYREGISTRY_INFO*)new char[0x432];						memset(reg_info_ptr, 0, 0x432);						reg_info_ptr->QueryType = D3DDDI_QUERYREGISTRY_DRIVERSTOREPATH;						query_info.hAdapter = adapter_info_ptr->hAdapter;						query_info.Type = KMTQAITYPE_QUERYREGISTRY;						query_info.pPrivateDriverData = reg_info_ptr;						query_info.PrivateDriverDataSize = 0x432;						NTSTATUS status = pfnD3DKMTQueryAdapterInfo(&query_info);						if (status == 0) {							driver_store_path = ReplaceSystemroot(reg_info_ptr->OutputString);							delete[]reg_info_ptr;							break;						}						delete[]reg_info_ptr;					}				}			}		}		if (enum_adapters.pAdapters)			delete[]enum_adapters.pAdapters;	}	return driver_store_path;}

再有就是setupAPI的方式,这个大家应该相当熟悉了:

std::wstring GetDriverStorePath(const std::wstring& device_id){	std::wstring infPath;	HDEVINFO deviceInfoSet = SetupDiGetClassDevs(&GUID_DEVCLASS_DISPLAY, NULL, NULL, DIGCF_PRESENT);	if (deviceInfoSet == INVALID_HANDLE_VALUE)		return infPath;	SP_DEVINFO_DATA deviceInfoData;	deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);	for (DWORD index = 0; SetupDiEnumDeviceInfo(deviceInfoSet, index, &deviceInfoData); ++index)	{		DWORD propertyType;		WCHAR buffer[1024];		deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);		if (SetupDiGetDeviceRegistryProperty(deviceInfoSet, &deviceInfoData, SPDRP_HARDWAREID, &propertyType,			reinterpret_cast(buffer), sizeof(buffer), NULL))		{			if (wcsstr(buffer, device_id.c_str()) != NULL) // NVIDIA vendor ID			{				DWORD req_size = 0;				if (SetupDiGetDeviceProperty(deviceInfoSet, &deviceInfoData, &DEVPKEY_Device_DriverInfPath, &propertyType,					reinterpret_cast(buffer), sizeof(buffer), &req_size, 0))				{					infPath = buffer;										if (SetupGetInfDriverStoreLocation(infPath.c_str(), NULL, NULL, buffer, sizeof(buffer), &req_size)) {						PathRemoveFileSpecW(buffer);						infPath = buffer;					}					else {						infPath.clear();					}				}			}		}	}	SetupDiDestroyDeviceInfoList(deviceInfoSet);	return infPath;}
•••展开全文