From 4a3cd01bd150c27d7fd40d04fc92b173f2f988af Mon Sep 17 00:00:00 2001 From: Zhiyi Zhang Date: Tue, 4 Feb 2020 15:52:54 +0800 Subject: [PATCH] setupapi: Implement SetupDiOpenDeviceInterfaceRegKey(). Signed-off-by: Zhiyi Zhang Signed-off-by: Alexandre Julliard --- dlls/setupapi/devinst.c | 25 +++++++++++++++ dlls/setupapi/setupapi.spec | 2 +- dlls/setupapi/tests/devinst.c | 60 +++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 0840341b7d7..268965f0fed 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -3525,6 +3525,31 @@ BOOL WINAPI SetupDiOpenDeviceInterfaceA( return FALSE; } +/*********************************************************************** + * SetupDiOpenDeviceInterfaceRegKey (SETUPAPI.@) + */ +HKEY WINAPI SetupDiOpenDeviceInterfaceRegKey(HDEVINFO devinfo, PSP_DEVICE_INTERFACE_DATA iface_data, + DWORD reserved, REGSAM access) +{ + struct device_iface *iface; + LSTATUS lr; + HKEY key; + + TRACE("devinfo %p, iface_data %p, reserved %d, access %#x.\n", devinfo, iface_data, reserved, access); + + if (!(iface = get_device_iface(devinfo, iface_data))) + return INVALID_HANDLE_VALUE; + + lr = RegOpenKeyExW(iface->refstr_key, DeviceParameters, 0, access, &key); + if (lr) + { + SetLastError(lr); + return INVALID_HANDLE_VALUE; + } + + return key; +} + /*********************************************************************** * SetupDiSetClassInstallParamsA (SETUPAPI.@) */ diff --git a/dlls/setupapi/setupapi.spec b/dlls/setupapi/setupapi.spec index 74c252c6fd5..33ccc480974 100644 --- a/dlls/setupapi/setupapi.spec +++ b/dlls/setupapi/setupapi.spec @@ -380,7 +380,7 @@ @ stdcall SetupDiOpenDeviceInfoA(ptr str ptr long ptr) @ stdcall SetupDiOpenDeviceInfoW(ptr wstr ptr long ptr) @ stdcall SetupDiOpenDeviceInterfaceA(ptr str long ptr) -@ stub SetupDiOpenDeviceInterfaceRegKey +@ stdcall SetupDiOpenDeviceInterfaceRegKey(ptr ptr long long) @ stdcall SetupDiOpenDeviceInterfaceW(ptr wstr long ptr) @ stdcall SetupDiRegisterCoDeviceInstallers(ptr ptr) @ stdcall SetupDiRegisterDeviceInfo(ptr ptr long ptr ptr ptr) diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c index b887bd8977e..dcfe5cd231e 100644 --- a/dlls/setupapi/tests/devinst.c +++ b/dlls/setupapi/tests/devinst.c @@ -2011,6 +2011,7 @@ static void test_device_interface_key(void) ok(!ret, "key should exist: %u\n", ret); ret = RegSetValueA(key, NULL, REG_SZ, "test", 5); + ok(!ret, "RegSetValue failed: %u\n", ret); sz = sizeof(buffer); ret = RegQueryValueA(dikey, NULL, buffer, &sz); ok(!ret, "RegQueryValue failed: %u\n", ret); @@ -2031,6 +2032,64 @@ static void test_device_interface_key(void) SetupDiDestroyDeviceInfoList(set); } +static void test_open_device_interface_key(void) +{ + SP_DEVICE_INTERFACE_DATA iface; + SP_DEVINFO_DATA device; + CHAR buffer[5]; + HDEVINFO set; + LSTATUS lr; + LONG size; + HKEY key; + BOOL ret; + + set = SetupDiCreateDeviceInfoList(&guid, NULL); + ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x\n", GetLastError()); + + device.cbSize = sizeof(device); + ret = SetupDiCreateDeviceInfoA(set, "ROOT\\LEGACY_BOGUS\\0000", &guid, NULL, NULL, 0, &device); + ok(ret, "Failed to create device, error %#x.\n", GetLastError()); + + iface.cbSize = sizeof(iface); + ret = SetupDiCreateDeviceInterfaceA(set, &device, &guid, NULL, 0, &iface); + ok(ret, "Failed to create interface, error %#x.\n", GetLastError()); + + /* Test open before creation */ + key = SetupDiOpenDeviceInterfaceRegKey(set, &iface, 0, KEY_ALL_ACCESS); + ok(key == INVALID_HANDLE_VALUE, "Expect open interface registry key failure\n"); + + /* Test opened key is from SetupDiCreateDeviceInterfaceRegKey */ + key = SetupDiCreateDeviceInterfaceRegKeyW(set, &iface, 0, KEY_ALL_ACCESS, NULL, NULL); + ok(key != INVALID_HANDLE_VALUE, "Failed to create interface registry key, error %#x\n", GetLastError()); + + lr = RegSetValueA(key, NULL, REG_SZ, "test", 5); + ok(!lr, "RegSetValue failed, error %#x\n", lr); + + RegCloseKey(key); + + key = SetupDiOpenDeviceInterfaceRegKey(set, &iface, 0, KEY_ALL_ACCESS); + ok(key != INVALID_HANDLE_VALUE, "Failed to open interface registry key, error %#x\n", GetLastError()); + + size = sizeof(buffer); + lr = RegQueryValueA(key, NULL, buffer, &size); + ok(!lr, "RegQueryValue failed, error %#x\n", lr); + ok(!strcmp(buffer, "test"), "got wrong data %s\n", buffer); + + RegCloseKey(key); + + /* Test open after removal */ + ret = SetupDiRemoveDeviceInterface(set, &iface); + ok(ret, "Failed to remove device interface, error %#x.\n", GetLastError()); + + key = SetupDiOpenDeviceInterfaceRegKey(set, &iface, 0, KEY_ALL_ACCESS); + ok(key == INVALID_HANDLE_VALUE, "Expect open interface registry key failure\n"); + + ret = SetupDiRemoveDevice(set, &device); + ok(ret, "Failed to remove device, error %#x.\n", GetLastError()); + ret = SetupDiDestroyDeviceInfoList(set); + ok(ret, "Failed to destroy device list, error %#x.\n", GetLastError()); +} + static void test_device_install_params(void) { SP_DEVINFO_DATA device = {sizeof(device)}; @@ -3142,6 +3201,7 @@ START_TEST(devinst) test_get_inf_class(); test_devnode(); test_device_interface_key(); + test_open_device_interface_key(); test_device_install_params(); test_driver_list(); test_call_class_installer();