From: Paul Gofman pgofman@codeweavers.com
--- dlls/cfgmgr32/main.c | 47 +++++++++++++++++++++++++++++++--- dlls/cfgmgr32/tests/cfgmgr32.c | 46 +++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 3 deletions(-)
diff --git a/dlls/cfgmgr32/main.c b/dlls/cfgmgr32/main.c index fbe39365975..fbff2c2fbf9 100644 --- a/dlls/cfgmgr32/main.c +++ b/dlls/cfgmgr32/main.c @@ -23,6 +23,10 @@ #include "winuser.h" #include "dbt.h" #include "wine/plugplay.h" +#include "setupapi.h" + +#include "initguid.h" +#include "devpkey.h"
WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
@@ -250,8 +254,45 @@ CONFIGRET WINAPI CM_Get_Device_Interface_PropertyW( LPCWSTR device_interface, co DEVPROPTYPE *property_type, BYTE *property_buffer, ULONG *property_buffer_size, ULONG flags ) { - FIXME("%s %p %p %p %p %ld stub!\n", debugstr_w(device_interface), property_key, property_type, - property_buffer, property_buffer_size, flags); + SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)}; + SP_DEVINFO_DATA device = { sizeof(device) }; + HDEVINFO set; + DWORD err; + BOOL ret; + + TRACE( "%s %p %p %p %p %ld.\n", debugstr_w(device_interface), property_key, property_type, property_buffer, + property_buffer_size, flags); + + if (!property_key) return CR_FAILURE; + if (!device_interface || !property_type || !property_buffer_size) return CR_INVALID_POINTER; + if (*property_buffer_size && !property_buffer) return CR_INVALID_POINTER; + if (flags) return CR_INVALID_FLAG; + + if (memcmp( property_key, &DEVPKEY_Device_InstanceId, sizeof(*property_key) )) + { + FIXME( "property %s\%lx.\n", debugstr_guid( &property_key->fmtid ), property_key->pid ); + return CR_NO_SUCH_VALUE; + }
- return CR_CALL_NOT_IMPLEMENTED; + set = SetupDiCreateDeviceInfoListExW( NULL, NULL, NULL, NULL ); + if (set == INVALID_HANDLE_VALUE) return CR_OUT_OF_MEMORY; + if (!SetupDiOpenDeviceInterfaceW( set, device_interface, 0, &iface )) + { + SetupDiDestroyDeviceInfoList( set ); + TRACE( "No interface %s, err %lu.\n", debugstr_w( device_interface ), GetLastError()); + return CR_NO_SUCH_DEVICE_INTERFACE; + } + if (!SetupDiEnumDeviceInfo( set, 0, &device )) + { + SetupDiDestroyDeviceInfoList( set ); + return CR_FAILURE; + } + ret = SetupDiGetDeviceInstanceIdW( set, &device, (WCHAR *)property_buffer, *property_buffer_size / sizeof(WCHAR), + property_buffer_size ); + err = ret ? 0 : GetLastError(); + SetupDiDestroyDeviceInfoList( set ); + *property_type = DEVPROP_TYPE_STRING; + *property_buffer_size *= sizeof(WCHAR); + if (!err) return CR_SUCCESS; + return err == ERROR_INSUFFICIENT_BUFFER ? CR_BUFFER_SMALL : CR_FAILURE; } diff --git a/dlls/cfgmgr32/tests/cfgmgr32.c b/dlls/cfgmgr32/tests/cfgmgr32.c index 165d262e29e..2af35d90fdd 100644 --- a/dlls/cfgmgr32/tests/cfgmgr32.c +++ b/dlls/cfgmgr32/tests/cfgmgr32.c @@ -369,10 +369,12 @@ static void test_CM_Get_Device_Interface_List(void) SP_DEVICE_INTERFACE_DATA iface = {sizeof(iface)}; SP_DEVICE_INTERFACE_DETAIL_DATA_W *iface_data; SP_DEVINFO_DATA device = { sizeof(device) }; + WCHAR instance_id[256], expected_id[256]; unsigned int count, count2; char *buffera, *pa; WCHAR *buffer, *p; ULONG size, size2; + DEVPROPTYPE type; CONFIGRET ret; HDEVINFO set; GUID guid; @@ -420,7 +422,48 @@ static void test_CM_Get_Device_Interface_List(void) bret = SetupDiGetDeviceInterfaceDetailW(set, &iface, iface_data, sizeof(iface_detail_buffer), NULL, &device); ok(bret, "got error %lu.\n", GetLastError()); ok(!wcsicmp(iface_data->DevicePath, p), "got %s, expected %s.\n", debugstr_w(p), debugstr_w(iface_data->DevicePath)); + bret = SetupDiGetDeviceInstanceIdW(set, &device, expected_id, ARRAY_SIZE(expected_id), NULL); + ok(bret, "got error %lu.\n", GetLastError()); SetupDiDestroyDeviceInfoList(set); + + size = 0xdeadbeef; + type = 0xdeadbeef; + ret = CM_Get_Device_Interface_PropertyW(p, &DEVPKEY_Device_InstanceId, &type, NULL, &size, 0); + ok(ret == CR_INVALID_POINTER, "got %#lx.\n", ret); + ok(type == 0xdeadbeef, "got type %#lx.\n", type); + ok(size == 0xdeadbeef, "got %#lx.\n", size); + + size = 0; + type = 0xdeadbeef; + ret = CM_Get_Device_Interface_PropertyW(p, &DEVPKEY_Device_InstanceId, &type, NULL, &size, 0); + ok(ret == CR_BUFFER_SMALL, "got %#lx.\n", ret); + ok(type == DEVPROP_TYPE_STRING, "got type %#lx.\n", type); + ok(size && size != 0xdeadbeef, "got %#lx.\n", size); + + ret = CM_Get_Device_Interface_PropertyW(p, NULL, &type, (BYTE *)instance_id, &size, 0); + ok(ret == CR_FAILURE, "got %#lx.\n", ret); + ret = CM_Get_Device_Interface_PropertyW(p, &DEVPKEY_Device_InstanceId, NULL, (BYTE *)instance_id, &size, 0); + ok(ret == CR_INVALID_POINTER, "got %#lx.\n", ret); + ret = CM_Get_Device_Interface_PropertyW(NULL, &DEVPKEY_Device_InstanceId, &type, (BYTE *)instance_id, &size, 0); + ok(ret == CR_INVALID_POINTER, "got %#lx.\n", ret); + ret = CM_Get_Device_Interface_PropertyW(p, &DEVPKEY_Device_InstanceId, &type, (BYTE *)instance_id, NULL, 0); + ok(ret == CR_INVALID_POINTER, "got %#lx.\n", ret); + ret = CM_Get_Device_Interface_PropertyW(p, &DEVPKEY_Device_InstanceId, &type, (BYTE *)instance_id, &size, 1); + ok(ret == CR_INVALID_FLAG, "got %#lx.\n", ret); + + size = 0; + ret = CM_Get_Device_Interface_PropertyW(p, &DEVPKEY_Device_InstanceId, &type, NULL, &size, 0); + ok(ret == CR_BUFFER_SMALL, "got %#lx.\n", ret); + + --size; + ret = CM_Get_Device_Interface_PropertyW(p, &DEVPKEY_Device_InstanceId, &type, (BYTE *)instance_id, &size, 0); + ok(ret == CR_BUFFER_SMALL, "got %#lx.\n", ret); + + type = 0xdeadbeef; + ret = CM_Get_Device_Interface_PropertyW(p, &DEVPKEY_Device_InstanceId, &type, (BYTE *)instance_id, &size, 0); + ok(!ret, "got %#lx.\n", ret); + ok(type == DEVPROP_TYPE_STRING, "got type %#lx.\n", type); + ok(!wcsicmp(instance_id, expected_id), "got %s, expected %s.\n", debugstr_w(instance_id), debugstr_w(expected_id)); p += wcslen(p) + 1; ++count; } @@ -433,6 +476,9 @@ static void test_CM_Get_Device_Interface_List(void) ; SetupDiDestroyDeviceInfoList(set); ok(count == count2, "got %u, expected %u.\n", count, count2); + + ret = CM_Get_Device_Interface_PropertyW(L"qqq", &DEVPKEY_Device_InstanceId, &type, (BYTE *)instance_id, &size, 0); + ok(ret == CR_NO_SUCH_DEVICE_INTERFACE, "got %#lx.\n", ret); }
START_TEST(cfgmgr32)