setupapi: Correctly implement SetupDiCreateDeviceInterfaceRegKey().
This family of functions manipulates the "Device Parameters" subkey, not its parent. Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
86d26dded5
commit
1d17352ce2
|
@ -76,6 +76,7 @@ static const WCHAR Enum[] = {'S','y','s','t','e','m','\\',
|
|||
'E','n','u','m',0};
|
||||
static const WCHAR DeviceDesc[] = {'D','e','v','i','c','e','D','e','s','c',0};
|
||||
static const WCHAR DeviceInstance[] = {'D','e','v','i','c','e','I','n','s','t','a','n','c','e',0};
|
||||
static const WCHAR DeviceParameters[] = {'D','e','v','i','c','e',' ','P','a','r','a','m','e','t','e','r','s',0};
|
||||
static const WCHAR HardwareId[] = {'H','a','r','d','w','a','r','e','I','D',0};
|
||||
static const WCHAR CompatibleIDs[] = {'C','o','m','p','a','t','i','b','l','e','I','d','s',0};
|
||||
static const WCHAR Service[] = {'S','e','r','v','i','c','e',0};
|
||||
|
@ -2559,111 +2560,63 @@ static PWSTR SETUPDI_GetInstancePath(struct device_iface *iface)
|
|||
/***********************************************************************
|
||||
* SetupDiCreateDeviceInterfaceRegKeyW (SETUPAPI.@)
|
||||
*/
|
||||
HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW(
|
||||
HDEVINFO DeviceInfoSet,
|
||||
PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
|
||||
DWORD Reserved,
|
||||
REGSAM samDesired,
|
||||
HINF InfHandle,
|
||||
PCWSTR InfSectionName)
|
||||
HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW(HDEVINFO devinfo,
|
||||
SP_DEVICE_INTERFACE_DATA *iface_data, DWORD reserved, REGSAM access,
|
||||
HINF hinf, const WCHAR *section)
|
||||
{
|
||||
struct DeviceInfoSet *set = DeviceInfoSet;
|
||||
HKEY key = INVALID_HANDLE_VALUE, interfacesKey;
|
||||
LONG l;
|
||||
struct DeviceInfoSet *set = devinfo;
|
||||
struct device_iface *iface;
|
||||
HKEY refstr_key, params_key;
|
||||
WCHAR *path;
|
||||
LONG ret;
|
||||
|
||||
TRACE("%p %p %d %08x %p %p\n", DeviceInfoSet, DeviceInterfaceData, Reserved,
|
||||
samDesired, InfHandle, InfSectionName);
|
||||
TRACE("%p %p %d %#x %p %s\n", devinfo, iface_data, reserved, access, hinf,
|
||||
debugstr_w(section));
|
||||
|
||||
if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE ||
|
||||
if (!devinfo || devinfo == INVALID_HANDLE_VALUE ||
|
||||
set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
if (!DeviceInterfaceData ||
|
||||
DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) ||
|
||||
!DeviceInterfaceData->Reserved)
|
||||
if (!iface_data || iface_data->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) ||
|
||||
!iface_data->Reserved)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
if (InfHandle && !InfSectionName)
|
||||
if (hinf && !section)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
if (!(l = RegCreateKeyExW(HKEY_LOCAL_MACHINE, DeviceClasses, 0, NULL, 0,
|
||||
samDesired, NULL, &interfacesKey, NULL)))
|
||||
|
||||
iface = (struct device_iface *)iface_data->Reserved;
|
||||
if (!(path = get_refstr_key_path(iface)))
|
||||
{
|
||||
HKEY parent;
|
||||
WCHAR bracedGuidString[39];
|
||||
|
||||
SETUPDI_GuidToString(&DeviceInterfaceData->InterfaceClassGuid,
|
||||
bracedGuidString);
|
||||
if (!(l = RegCreateKeyExW(interfacesKey, bracedGuidString, 0, NULL, 0,
|
||||
samDesired, NULL, &parent, NULL)))
|
||||
{
|
||||
struct device_iface *ifaceInfo =
|
||||
(struct device_iface *)DeviceInterfaceData->Reserved;
|
||||
PWSTR instancePath = SETUPDI_GetInstancePath(ifaceInfo);
|
||||
PWSTR interfKeyName = HeapAlloc(GetProcessHeap(), 0,
|
||||
(lstrlenW(ifaceInfo->symlink) + 1) * sizeof(WCHAR));
|
||||
HKEY interfKey;
|
||||
WCHAR *ptr;
|
||||
|
||||
lstrcpyW(interfKeyName, ifaceInfo->symlink);
|
||||
if (lstrlenW(ifaceInfo->symlink) > 3)
|
||||
{
|
||||
interfKeyName[0] = '#';
|
||||
interfKeyName[1] = '#';
|
||||
interfKeyName[3] = '#';
|
||||
}
|
||||
ptr = strchrW(interfKeyName, '\\');
|
||||
if (ptr)
|
||||
*ptr = 0;
|
||||
l = RegCreateKeyExW(parent, interfKeyName, 0, NULL, 0,
|
||||
samDesired, NULL, &interfKey, NULL);
|
||||
if (!l)
|
||||
{
|
||||
struct device *device = ifaceInfo->device;
|
||||
|
||||
l = RegSetValueExW(interfKey, DeviceInstance, 0, REG_SZ,
|
||||
(BYTE *)device->instanceId,
|
||||
(lstrlenW(device->instanceId) + 1) * sizeof(WCHAR));
|
||||
if (!l)
|
||||
{
|
||||
if (instancePath)
|
||||
{
|
||||
LONG l;
|
||||
|
||||
l = RegCreateKeyExW(interfKey, instancePath, 0, NULL, 0,
|
||||
samDesired, NULL, &key, NULL);
|
||||
if (l)
|
||||
{
|
||||
SetLastError(l);
|
||||
key = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
else if (InfHandle)
|
||||
FIXME("INF section installation unsupported\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
SetLastError(l);
|
||||
RegCloseKey(interfKey);
|
||||
}
|
||||
else
|
||||
SetLastError(l);
|
||||
HeapFree(GetProcessHeap(), 0, interfKeyName);
|
||||
HeapFree(GetProcessHeap(), 0, instancePath);
|
||||
RegCloseKey(parent);
|
||||
}
|
||||
else
|
||||
SetLastError(l);
|
||||
RegCloseKey(interfacesKey);
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
else
|
||||
SetLastError(l);
|
||||
return key;
|
||||
|
||||
ret = RegCreateKeyExW(HKEY_LOCAL_MACHINE, path, 0, NULL, 0, 0, NULL,
|
||||
&refstr_key, NULL);
|
||||
heap_free(path);
|
||||
if (ret)
|
||||
{
|
||||
SetLastError(ret);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
ret = RegCreateKeyExW(refstr_key, DeviceParameters, 0, NULL, 0, access,
|
||||
NULL, ¶ms_key, NULL);
|
||||
RegCloseKey(refstr_key);
|
||||
if (ret)
|
||||
{
|
||||
SetLastError(ret);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
return params_key;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -1376,6 +1376,62 @@ static void test_devnode(void)
|
|||
SetupDiDestroyDeviceInfoList(set);
|
||||
}
|
||||
|
||||
static void test_device_interface_key(void)
|
||||
{
|
||||
const char keypath[] = "System\\CurrentControlSet\\Control\\DeviceClasses\\"
|
||||
"{6a55b5a4-3f65-11db-b704-0011955c2bdb}\\"
|
||||
"##?#ROOT#LEGACY_BOGUS#0001#{6a55b5a4-3f65-11db-b704-0011955c2bdb}";
|
||||
SP_DEVICE_INTERFACE_DATA iface = { sizeof(iface) };
|
||||
SP_DEVINFO_DATA devinfo = { sizeof(devinfo) };
|
||||
HKEY parent, key, dikey;
|
||||
char buffer[5];
|
||||
HDEVINFO set;
|
||||
LONG sz, ret;
|
||||
|
||||
set = SetupDiGetClassDevsA(NULL, NULL, 0, DIGCF_ALLCLASSES);
|
||||
ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevs failed: %#x\n", GetLastError());
|
||||
|
||||
ret = SetupDiCreateDeviceInfoA(set, "ROOT\\LEGACY_BOGUS\\0001", &guid, NULL, NULL, 0, &devinfo);
|
||||
ok(ret, "SetupDiCreateDeviceInfo failed: %#x\n", GetLastError());
|
||||
|
||||
ret = SetupDiCreateDeviceInterfaceA(set, &devinfo, &guid, NULL, 0, &iface);
|
||||
ok(ret, "SetupDiCreateDeviceInterface failed: %#x\n", GetLastError());
|
||||
|
||||
ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &parent);
|
||||
ok(!ret, "failed to open device parent key: %u\n", ret);
|
||||
|
||||
ret = RegOpenKeyA(parent, "#\\Device Parameters", &key);
|
||||
ok(ret == ERROR_FILE_NOT_FOUND, "key shouldn't exist\n");
|
||||
|
||||
dikey = SetupDiCreateDeviceInterfaceRegKeyA(set, &iface, 0, KEY_ALL_ACCESS, NULL, NULL);
|
||||
ok(dikey != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
|
||||
|
||||
ret = RegOpenKeyA(parent, "#\\Device Parameters", &key);
|
||||
ok(!ret, "key should exist: %u\n", ret);
|
||||
|
||||
ret = RegSetValueA(key, NULL, REG_SZ, "test", 5);
|
||||
sz = sizeof(buffer);
|
||||
ret = RegQueryValueA(dikey, NULL, buffer, &sz);
|
||||
ok(!ret, "RegQueryValue failed: %u\n", ret);
|
||||
ok(!strcmp(buffer, "test"), "got wrong data %s\n", buffer);
|
||||
|
||||
RegCloseKey(dikey);
|
||||
RegCloseKey(key);
|
||||
|
||||
ret = SetupDiDeleteDeviceInterfaceRegKey(set, &iface, 0);
|
||||
todo_wine
|
||||
ok(ret, "got error %u\n", GetLastError());
|
||||
|
||||
ret = RegOpenKeyA(parent, "#\\Device Parameters", &key);
|
||||
todo_wine
|
||||
ok(ret == ERROR_FILE_NOT_FOUND, "key shouldn't exist\n");
|
||||
|
||||
RegCloseKey(parent);
|
||||
SetupDiRemoveDeviceInterface(set, &iface);
|
||||
SetupDiRemoveDevice(set, &devinfo);
|
||||
SetupDiDestroyDeviceInfoList(set);
|
||||
}
|
||||
|
||||
START_TEST(devinst)
|
||||
{
|
||||
HKEY hkey;
|
||||
|
@ -1414,4 +1470,5 @@ START_TEST(devinst)
|
|||
testDeviceRegistryPropertyW();
|
||||
testSetupDiGetINFClassA();
|
||||
test_devnode();
|
||||
test_device_interface_key();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue