mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-30 05:31:39 +00:00
setupapi: Use INF parser to read class GUID and class name.
Previously, SetupDiGetINFClassW read INF files with GetPrivateProfileString, which does not substitute %strkey% tokens. This caused device installation to fail for devices which had driver INF files using %strkey% tokens in Version section. An example of such device is Vernier LabQuest Mini (08f7:0008) for which Vernier's LoggerPro application includes a driver. The INF file in question adds a new device setup class and has following entries in Version section: Class = %ClassName% ClassGuid = %DeviceClassGUID% Strings section includes following entries: DeviceClassGUID = "{6B8429BF-10AD-4b66-9FBA-2FE72B891721}" ClassName = "VST_WinUSB" Previously, when LoggerPro was installed and LabQuest Mini was hotplugged, device installation failed with the following error: fixme:setupapi:SetupDiGetINFClassW failed to convert "L"%DeviceClassGUID"" into a guid This caused GUID_NULL to be used and Class was not set to the registry for the device. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56579
This commit is contained in:
parent
d8bbf6d0ae
commit
987695a427
|
@ -4280,8 +4280,11 @@ BOOL WINAPI SetupDiGetINFClassW(PCWSTR inf, LPGUID class_guid, PWSTR class_name,
|
|||
DWORD size, PDWORD required_size)
|
||||
{
|
||||
BOOL have_guid, have_name;
|
||||
DWORD dret;
|
||||
DWORD class_name_len;
|
||||
WCHAR buffer[MAX_PATH];
|
||||
INFCONTEXT inf_ctx;
|
||||
HINF hinf;
|
||||
BOOL retval = FALSE;
|
||||
|
||||
if (!inf)
|
||||
{
|
||||
|
@ -4302,30 +4305,63 @@ BOOL WINAPI SetupDiGetINFClassW(PCWSTR inf, LPGUID class_guid, PWSTR class_name,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (!GetPrivateProfileStringW(Version, Signature, NULL, buffer, MAX_PATH, inf))
|
||||
if ((hinf = SetupOpenInfFileW(inf, NULL, INF_STYLE_WIN4, NULL)) == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
ERR("failed to open INF file %s\n", debugstr_w(inf));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!SetupFindFirstLineW(hinf, Version, Signature, &inf_ctx))
|
||||
{
|
||||
ERR("INF file %s does not have mandatory [Version].Signature\n", debugstr_w(inf));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!SetupGetStringFieldW(&inf_ctx, 1, buffer, ARRAY_SIZE(buffer), NULL))
|
||||
{
|
||||
ERR("failed to get [Version].Signature string from %s\n", debugstr_w(inf));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (lstrcmpiW(buffer, Chicago) && lstrcmpiW(buffer, WindowsNT))
|
||||
return FALSE;
|
||||
{
|
||||
ERR("INF file %s has invalid [Version].Signature: %s\n", debugstr_w(inf), debugstr_w(buffer));
|
||||
goto out;
|
||||
}
|
||||
|
||||
have_guid = SetupFindFirstLineW(hinf, Version, ClassGUID, &inf_ctx);
|
||||
|
||||
buffer[0] = '\0';
|
||||
have_guid = 0 < GetPrivateProfileStringW(Version, ClassGUID, NULL, buffer, MAX_PATH, inf);
|
||||
if (have_guid)
|
||||
{
|
||||
if (!SetupGetStringFieldW(&inf_ctx, 1, buffer, ARRAY_SIZE(buffer), NULL))
|
||||
{
|
||||
ERR("failed to get [Version].ClassGUID as a string from '%s'\n", debugstr_w(inf));
|
||||
goto out;
|
||||
}
|
||||
|
||||
buffer[lstrlenW(buffer)-1] = 0;
|
||||
if (RPC_S_OK != UuidFromStringW(buffer + 1, class_guid))
|
||||
{
|
||||
FIXME("failed to convert \"%s\" into a guid\n", debugstr_w(buffer));
|
||||
ERR("INF file %s has invalid [Version].ClassGUID: %s\n", debugstr_w(inf), debugstr_w(buffer));
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
buffer[0] = '\0';
|
||||
dret = GetPrivateProfileStringW(Version, Class, NULL, buffer, MAX_PATH, inf);
|
||||
have_name = 0 < dret;
|
||||
have_name = SetupFindFirstLineW(hinf, Version, Class, &inf_ctx);
|
||||
|
||||
class_name_len = 0;
|
||||
if (have_name)
|
||||
{
|
||||
if (!SetupGetStringFieldW(&inf_ctx, 1, buffer, ARRAY_SIZE(buffer), NULL))
|
||||
{
|
||||
ERR("failed to get [Version].Class as a string from '%s'\n", debugstr_w(inf));
|
||||
goto out;
|
||||
}
|
||||
|
||||
class_name_len = lstrlenW(buffer);
|
||||
}
|
||||
|
||||
if (dret >= MAX_PATH -1) FIXME("buffer might be too small\n");
|
||||
if (have_guid && !have_name)
|
||||
{
|
||||
class_name[0] = '\0';
|
||||
|
@ -4334,7 +4370,7 @@ BOOL WINAPI SetupDiGetINFClassW(PCWSTR inf, LPGUID class_guid, PWSTR class_name,
|
|||
|
||||
if (have_name)
|
||||
{
|
||||
if (dret < size) lstrcpyW(class_name, buffer);
|
||||
if (class_name_len < size) lstrcpyW(class_name, buffer);
|
||||
else
|
||||
{
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
|
@ -4342,9 +4378,12 @@ BOOL WINAPI SetupDiGetINFClassW(PCWSTR inf, LPGUID class_guid, PWSTR class_name,
|
|||
}
|
||||
}
|
||||
|
||||
if (required_size) *required_size = dret + ((dret) ? 1 : 0);
|
||||
if (required_size) *required_size = class_name_len + ((class_name_len) ? 1 : 0);
|
||||
|
||||
return (have_guid || have_name);
|
||||
retval = (have_guid || have_name);
|
||||
out:
|
||||
SetupCloseInfFile(hinf);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static LSTATUS get_device_property(struct device *device, const DEVPROPKEY *prop_key, DEVPROPTYPE *prop_type,
|
||||
|
|
|
@ -2031,12 +2031,11 @@ static void test_get_inf_class(void)
|
|||
WritePrivateProfileStringA("Strings", "ClassGuid", "{deadbeef-dead-beef-dead-beefdeadbeef}", filename);
|
||||
count = 0xdeadbeef;
|
||||
retval = SetupDiGetINFClassA(filename, &guid, cn, MAX_PATH, &count);
|
||||
todo_wine {
|
||||
ok(retval, "expected SetupDiGetINFClassA to succeed! error %lu\n", GetLastError());
|
||||
ok(count == lstrlenA(deadbeef_class_name) + 1, "expected count=%d, got %lu\n", lstrlenA(deadbeef_class_name) + 1, count);
|
||||
ok(!lstrcmpA(deadbeef_class_name, cn), "expected class_name='%s', got '%s'\n", deadbeef_class_name, cn);
|
||||
ok(IsEqualGUID(&deadbeef_class_guid, &guid), "expected ClassGUID to be deadbeef-dead-beef-dead-beefdeadbeef\n");
|
||||
}
|
||||
|
||||
DeleteFileA(filename);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue