mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
Bug 600280. Use Setup API instead of the registry directly to get device information. r=jrmuizel,a=joe
This fixes driver version and date being empty or null for some graphic cards under Windows 2000/XP
This commit is contained in:
parent
29b9aa6f92
commit
14c9aac484
@ -37,6 +37,7 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <windows.h>
|
||||
#include <setupapi.h>
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#include "GfxInfo.h"
|
||||
#include "GfxInfoWebGL.h"
|
||||
@ -180,6 +181,31 @@ static void normalizeDriverId(nsString& driverid) {
|
||||
}
|
||||
}
|
||||
|
||||
// Setup API functions
|
||||
typedef HDEVINFO (WINAPI*SetupDiGetClassDevsWFunc)(
|
||||
CONST GUID *ClassGuid,
|
||||
PCWSTR Enumerator,
|
||||
HWND hwndParent,
|
||||
DWORD Flags
|
||||
);
|
||||
typedef BOOL (WINAPI*SetupDiEnumDeviceInfoFunc)(
|
||||
HDEVINFO DeviceInfoSet,
|
||||
DWORD MemberIndex,
|
||||
PSP_DEVINFO_DATA DeviceInfoData
|
||||
);
|
||||
typedef BOOL (WINAPI*SetupDiGetDeviceRegistryPropertyWFunc)(
|
||||
HDEVINFO DeviceInfoSet,
|
||||
PSP_DEVINFO_DATA DeviceInfoData,
|
||||
DWORD Property,
|
||||
PDWORD PropertyRegDataType,
|
||||
PBYTE PropertyBuffer,
|
||||
DWORD PropertyBufferSize,
|
||||
PDWORD RequiredSize
|
||||
);
|
||||
typedef BOOL (WINAPI*SetupDiDestroyDeviceInfoListFunc)(
|
||||
HDEVINFO DeviceInfoSet
|
||||
);
|
||||
|
||||
|
||||
|
||||
/* Other interesting places for info:
|
||||
@ -232,50 +258,73 @@ GfxInfo::Init()
|
||||
mDeviceString = displayDevice.DeviceString;
|
||||
|
||||
|
||||
HKEY key, subkey;
|
||||
LONG result, enumresult;
|
||||
DWORD index = 0;
|
||||
WCHAR subkeyname[64];
|
||||
WCHAR value[128];
|
||||
DWORD dwcbData = sizeof(subkeyname);
|
||||
HMODULE setupapi = LoadLibraryW(L"setupapi.dll");
|
||||
|
||||
// "{4D36E968-E325-11CE-BFC1-08002BE10318}" is the display class
|
||||
result = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
L"System\\CurrentControlSet\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}",
|
||||
0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &key);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
return rv;
|
||||
}
|
||||
if (setupapi) {
|
||||
SetupDiGetClassDevsWFunc setupGetClassDevs = (SetupDiGetClassDevsWFunc)
|
||||
GetProcAddress(setupapi, "SetupDiGetClassDevsW");
|
||||
SetupDiEnumDeviceInfoFunc setupEnumDeviceInfo = (SetupDiEnumDeviceInfoFunc)
|
||||
GetProcAddress(setupapi, "SetupDiEnumDeviceInfo");
|
||||
SetupDiGetDeviceRegistryPropertyWFunc setupGetDeviceRegistryProperty = (SetupDiGetDeviceRegistryPropertyWFunc)
|
||||
GetProcAddress(setupapi, "SetupDiGetDeviceRegistryPropertyW");
|
||||
SetupDiDestroyDeviceInfoListFunc setupDestroyDeviceInfoList = (SetupDiDestroyDeviceInfoListFunc)
|
||||
GetProcAddress(setupapi, "SetupDiDestroyDeviceInfoList");
|
||||
|
||||
nsAutoString wantedDriverId(mDeviceID);
|
||||
normalizeDriverId(wantedDriverId);
|
||||
if (setupGetClassDevs &&
|
||||
setupEnumDeviceInfo &&
|
||||
setupGetDeviceRegistryProperty &&
|
||||
setupDestroyDeviceInfoList) {
|
||||
/* create a device information set composed of the current display device */
|
||||
HDEVINFO devinfo = setupGetClassDevs(NULL,
|
||||
PromiseFlatString(mDeviceID).get(),
|
||||
NULL,
|
||||
DIGCF_PRESENT | DIGCF_PROFILE | DIGCF_ALLCLASSES);
|
||||
|
||||
while ((enumresult = RegEnumKeyExW(key, index, subkeyname, &dwcbData, NULL, NULL, NULL, NULL)) != ERROR_NO_MORE_ITEMS) {
|
||||
result = RegOpenKeyExW(key, subkeyname, 0, KEY_QUERY_VALUE, &subkey);
|
||||
if (result == ERROR_SUCCESS) {
|
||||
dwcbData = sizeof(value);
|
||||
result = RegQueryValueExW(subkey, L"MatchingDeviceId", NULL, NULL, (LPBYTE)value, &dwcbData);
|
||||
if (result == ERROR_SUCCESS) {
|
||||
nsAutoString matchingDeviceId(value);
|
||||
normalizeDriverId(matchingDeviceId);
|
||||
if (wantedDriverId.Find(matchingDeviceId) > -1) {
|
||||
/* we've found the driver we're looking for */
|
||||
result = RegQueryValueExW(subkey, L"DriverVersion", NULL, NULL, (LPBYTE)value, &dwcbData);
|
||||
if (result == ERROR_SUCCESS)
|
||||
mDriverVersion = value;
|
||||
result = RegQueryValueExW(subkey, L"DriverDate", NULL, NULL, (LPBYTE)value, &dwcbData);
|
||||
if (result == ERROR_SUCCESS)
|
||||
mDriverDate = value;
|
||||
break;
|
||||
if (devinfo != INVALID_HANDLE_VALUE) {
|
||||
HKEY key;
|
||||
LONG result;
|
||||
WCHAR value[255];
|
||||
DWORD dwcbData;
|
||||
SP_DEVINFO_DATA devinfoData;
|
||||
DWORD memberIndex = 0;
|
||||
|
||||
devinfoData.cbSize = sizeof(devinfoData);
|
||||
NS_NAMED_LITERAL_STRING(driverKeyPre, "System\\CurrentControlSet\\Control\\Class\\");
|
||||
/* enumerate device information elements in the device information set */
|
||||
while (setupEnumDeviceInfo(devinfo, memberIndex++, &devinfoData)) {
|
||||
/* get a string that identifies the device's driver key */
|
||||
if (setupGetDeviceRegistryProperty(devinfo,
|
||||
&devinfoData,
|
||||
SPDRP_DRIVER,
|
||||
NULL,
|
||||
(PBYTE)value,
|
||||
sizeof(value),
|
||||
NULL)) {
|
||||
nsAutoString driverKey(driverKeyPre);
|
||||
driverKey += value;
|
||||
result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, driverKey.BeginReading(), 0, KEY_QUERY_VALUE, &key);
|
||||
if (result == ERROR_SUCCESS) {
|
||||
/* we've found the driver we're looking for */
|
||||
dwcbData = sizeof(value);
|
||||
result = RegQueryValueExW(key, L"DriverVersion", NULL, NULL, (LPBYTE)value, &dwcbData);
|
||||
if (result == ERROR_SUCCESS)
|
||||
mDriverVersion = value;
|
||||
dwcbData = sizeof(value);
|
||||
result = RegQueryValueExW(key, L"DriverDate", NULL, NULL, (LPBYTE)value, &dwcbData);
|
||||
if (result == ERROR_SUCCESS)
|
||||
mDriverDate = value;
|
||||
RegCloseKey(key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RegCloseKey(subkey);
|
||||
}
|
||||
index++;
|
||||
dwcbData = sizeof(subkeyname);
|
||||
}
|
||||
|
||||
RegCloseKey(key);
|
||||
setupDestroyDeviceInfoList(devinfo);
|
||||
}
|
||||
}
|
||||
|
||||
FreeLibrary(setupapi);
|
||||
}
|
||||
|
||||
const char *spoofedDriverVersionString = PR_GetEnv("MOZ_GFX_SPOOF_DRIVER_VERSION");
|
||||
if (spoofedDriverVersionString) {
|
||||
|
Loading…
Reference in New Issue
Block a user