From: Vibhav Pant vibhavp@gmail.com
--- dlls/cfgmgr32/cfgmgr32.spec | 3 + dlls/cfgmgr32/main.c | 22 +++++ dlls/cfgmgr32/tests/cfgmgr32.c | 158 +++++++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+)
diff --git a/dlls/cfgmgr32/cfgmgr32.spec b/dlls/cfgmgr32/cfgmgr32.spec index a437eb72afc..2d4d6b23bec 100644 --- a/dlls/cfgmgr32/cfgmgr32.spec +++ b/dlls/cfgmgr32/cfgmgr32.spec @@ -191,6 +191,9 @@ @ stdcall DevCloseObjectQuery(ptr) @ stdcall DevCreateObjectQuery(long long long ptr long ptr ptr ptr ptr) @ stdcall DevCreateObjectQueryEx(long long long ptr long ptr long ptr ptr ptr ptr) +@ stdcall DevFreeObjectProperties(long ptr) @ stdcall DevFreeObjects(long ptr) +@ stdcall DevGetObjectProperties(long ptr long long ptr ptr ptr) +@ stdcall DevGetObjectPropertiesEx(long ptr long long ptr long ptr ptr ptr) @ stdcall DevGetObjects(long long long ptr long ptr ptr ptr) @ stdcall DevGetObjectsEx(long long long ptr long ptr long ptr ptr ptr) diff --git a/dlls/cfgmgr32/main.c b/dlls/cfgmgr32/main.c index 4ba2aee672d..89302a282b5 100644 --- a/dlls/cfgmgr32/main.c +++ b/dlls/cfgmgr32/main.c @@ -829,3 +829,25 @@ void WINAPI DevCloseObjectQuery( HDEVQUERY query ) device_query_context_release( ctx ); return; } + +HRESULT WINAPI DevGetObjectProperties( DEV_OBJECT_TYPE type, const WCHAR *id, ULONG flags, ULONG props_len, + const DEVPROPCOMPKEY *props, ULONG *buf_len, const DEVPROPERTY **buf ) +{ + TRACE( "(%d, %s, %#lx, %lu, %p, %p, %p)\n", type, debugstr_w( id ), flags, props_len, props, buf_len, buf ); + return DevGetObjectPropertiesEx( type, id, flags, props_len, props, 0, NULL, buf_len, buf ); +} + +HRESULT WINAPI DevGetObjectPropertiesEx( DEV_OBJECT_TYPE type, const WCHAR *id, ULONG flags, ULONG props_len, + const DEVPROPCOMPKEY *props, ULONG params_len, + const DEV_QUERY_PARAMETER *params, ULONG *buf_len, const DEVPROPERTY **buf ) +{ + FIXME( "(%d, %s, %#lx, %lu, %p, %lu, %p, %p, %p): stub!\n", type, debugstr_w( id ), flags, props_len, props, + params_len, params, buf_len, buf ); + return E_NOTIMPL; +} + +void WINAPI DevFreeObjectProperties( ULONG len, const DEVPROPERTY *props ) +{ + FIXME( "(%lu, %p): stub!\n", len, props ); + return; +} diff --git a/dlls/cfgmgr32/tests/cfgmgr32.c b/dlls/cfgmgr32/tests/cfgmgr32.c index fbbd504d23e..ab3bec676ff 100644 --- a/dlls/cfgmgr32/tests/cfgmgr32.c +++ b/dlls/cfgmgr32/tests/cfgmgr32.c @@ -549,6 +549,125 @@ struct test_property
DEFINE_DEVPROPKEY(DEVPKEY_dummy, 0xdeadbeef, 0xdead, 0xbeef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 1);
+static BOOL dev_property_val_equal( const DEVPROPERTY *p1, const DEVPROPERTY *p2 ) +{ + if (!(p1->Type == p2->Type && p1->BufferSize == p2->BufferSize)) + return FALSE; + switch (p1->Type) + { + case DEVPROP_TYPE_STRING: + return !wcsicmp( (WCHAR *)p1->Buffer, (WCHAR *)p2->Buffer ); + default: + return !memcmp( p1->Buffer, p2->Buffer, p1->BufferSize ); + } +} + +static const char *debugstr_DEVPROP_val( const DEVPROPERTY *prop ) +{ + switch (prop->Type) + { + case DEVPROP_TYPE_STRING: + return wine_dbg_sprintf( "{type=%#lx buf=%s buf_len=%lu}", prop->Type, debugstr_w( prop->Buffer ), prop->BufferSize ); + default: + return wine_dbg_sprintf( "{type=%#lx buf=%p buf_len=%lu}", prop->Type, prop->Buffer, prop->BufferSize ); + } +} + +static void test_DevGetObjectProperties( DEV_OBJECT_TYPE type, const WCHAR *id, const DEVPROPERTY *exp_props, ULONG props_len ) +{ + static const DEVPROPKEY dummy_propkey = { { 0xdeadbeef, 0xdead, 0xbeef, { 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef } }, 0x1 }; + static const DEVPROPCOMPKEY dummy_propcompkey = { dummy_propkey, DEVPROP_STORE_SYSTEM, NULL }; + ULONG buf_len, rem_props = props_len, i; + const DEVPROPERTY *buf; + DEVPROPCOMPKEY *keys; + HRESULT hr; + + hr = DevGetObjectProperties( type, id, DevQueryFlagUpdateResults, 0, NULL, NULL, NULL ); + todo_wine ok( hr == E_INVALIDARG, "got hr %#lx\n", hr ); + + hr = DevGetObjectProperties( type, id, DevQueryFlagAsyncClose, 0, NULL, &buf_len, &buf ); + todo_wine ok( hr == E_INVALIDARG, "got hr %#lx\n", hr ); + + hr = DevGetObjectProperties( type, id, DevQueryFlagAsyncClose, 0, NULL, &buf_len, &buf ); + todo_wine ok( hr == E_INVALIDARG, "got hr %#lx\n", hr ); + + hr = DevGetObjectProperties( type, id, DevQueryFlagNone, 1, NULL, &buf_len, &buf ); + todo_wine ok( hr == E_INVALIDARG, "got hr %#lx\n", hr ); + + hr = DevGetObjectProperties( type, id, DevQueryFlagNone, 0, (DEVPROPCOMPKEY *)0xdeadbeef, &buf_len, &buf ); + todo_wine ok( hr == E_INVALIDARG, "got hr %#lx\n", hr ); + + buf = NULL; + buf_len = 0; + hr = DevGetObjectProperties( type, id, DevQueryFlagAllProperties, 0, NULL, &buf_len, &buf ); + todo_wine ok( hr == S_OK, "got hr %#lx\n", hr ); + todo_wine ok( buf_len == props_len, "%lu != %lu\n", buf_len, props_len ); + for (i = 0; i < props_len; i++) + { + ULONG j; + for (j = 0; j < buf_len; j++) + { + if (IsEqualDevPropKey( exp_props[i].CompKey.Key, buf[j].CompKey.Key )) + { + winetest_push_context( "{%s,%#lx}", debugstr_guid( &exp_props[i].CompKey.Key.fmtid ), + exp_props[i].CompKey.Key.pid ); + ok( dev_property_val_equal( &exp_props[i], &buf[j] ), "%s != %s\n", debugstr_DEVPROP_val( &buf[j] ), + debugstr_DEVPROP_val( &exp_props[i] ) ); + winetest_pop_context(); + rem_props--; + } + } + } + todo_wine ok( rem_props == 0, "got rem_props %lu\n", rem_props ); + DevFreeObjectProperties( buf_len, buf ); + + buf = (DEVPROPERTY *)0xdeadbeef; + buf_len = 0xdeadbeef; + rem_props = props_len; + hr = DevGetObjectProperties( type, id, DevQueryFlagNone, 0, NULL, &buf_len, &buf ); + todo_wine ok( hr == S_OK, "got hr %#lx\n", hr ); + todo_wine ok( buf_len == 0, "got buf_len %lu\n", buf_len ); + todo_wine ok( !buf, "got buf %p\n", buf ); + + buf = NULL; + buf_len = 0; + keys = calloc( props_len, sizeof( *keys ) ); + for (i = 0; i < props_len; i++) + keys[i] = exp_props[i].CompKey; + hr = DevGetObjectProperties( type, id, DevQueryFlagNone, props_len, keys, &buf_len, &buf ); + todo_wine ok( hr == S_OK, "got hr %#lx\n", hr ); + todo_wine ok( buf_len == props_len, "%lu != %lu\n", buf_len, props_len ); + for (i = 0; i < props_len; i++) + { + ULONG j; + for (j = 0; j < buf_len; j++) + { + if (IsEqualDevPropKey( exp_props[i].CompKey.Key, buf[j].CompKey.Key )) + { + rem_props--; + break; + } + } + } + todo_wine ok( rem_props == 0, "got rem_props %lu\n", rem_props ); + DevFreeObjectProperties( buf_len, buf ); + + buf_len = 0; + buf = NULL; + hr = DevGetObjectProperties( type, id, DevQueryFlagNone, 1, &dummy_propcompkey, &buf_len, &buf ); + todo_wine ok( hr == S_OK, "got hr %#lx\n", hr ); + todo_wine ok( !!buf, "got buf %p", buf ); + todo_wine ok( buf_len == 1, "got buf_len %lu\n", buf_len ); + if (buf) + { + ok( IsEqualDevPropKey( buf[0].CompKey.Key, dummy_propkey ), "got propkey {%s, %#lx}\n", + debugstr_guid( &buf[0].CompKey.Key.fmtid ), buf[0].CompKey.Key.pid ); + ok( buf[0].Type == DEVPROP_TYPE_EMPTY, "got Type %#lx\n", buf[0].Type ); + DevFreeObjectProperties( buf_len, buf ); + } + free( keys ); +} + static void test_dev_object_iface_props( int line, const DEV_OBJECT *obj, const struct test_property *exp_props, DWORD props_len ) { @@ -713,6 +832,9 @@ static void test_DevGetObjects( void ) winetest_push_context( "device %s", debugstr_w( obj->pszObjectId ) ); ok( obj->ObjectType == test_cases[i].object_type, "got ObjectType %d\n", obj->ObjectType ); test_dev_object_iface_props( __LINE__, obj, test_cases[i].exp_props, test_cases[i].props_len ); + winetest_push_context( "%d", __LINE__ ); + test_DevGetObjectProperties( obj->ObjectType, obj->pszObjectId, obj->pProperties, obj->cPropertyCount ); + winetest_pop_context(); winetest_pop_context(); } DevFreeObjects( len, objects ); @@ -920,6 +1042,41 @@ static void test_DevCreateObjectQuery( void ) CloseHandle( data.closed ); }
+static void test_DevGetObjectProperties_invalid( void ) +{ + HRESULT hr; + + hr = DevGetObjectProperties( DevObjectTypeUnknown, NULL, 0, 0, NULL, NULL, NULL ); + todo_wine ok( hr == HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ), "got hr %#lx\n", hr ); + + hr = DevGetObjectProperties( DevObjectTypeUnknown, L"", 0, 0, NULL, NULL, NULL ); + todo_wine ok( hr == HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ), "got hr %#lx\n", hr ); + + hr = DevGetObjectProperties( DevObjectTypeUnknown, NULL, DevQueryFlagAsyncClose, 0, NULL, NULL, NULL ); + todo_wine ok( hr == E_INVALIDARG, "got hr %#lx\n", hr ); + + hr = DevGetObjectProperties( DevObjectTypeDeviceInterface, L"foobar", DevQueryFlagUpdateResults, 0, NULL, NULL, NULL ); + todo_wine ok( hr == E_INVALIDARG, "got hr %#lx\n", hr ); + + hr = DevGetObjectProperties( DevObjectTypeDeviceInterface, L"foobar", 0xdeadbeef, 0, NULL, NULL, NULL ); + todo_wine ok( hr == E_INVALIDARG, "got hr %#lx\n", hr ); + + hr = DevGetObjectProperties( DevObjectTypeUnknown, NULL, 0, 1, NULL, NULL, NULL ); + todo_wine ok( hr == HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ), "got hr %#lx\n", hr ); + + hr = DevGetObjectProperties( DevObjectTypeUnknown, NULL, 0, 0, (DEVPROPCOMPKEY *)0xdeadbeef, NULL, NULL ); + todo_wine ok( hr == HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ), "got hr %#lx\n", hr ); + + hr = DevGetObjectProperties( DevObjectTypeDeviceInterface, L"foobar", 0, 0, NULL, NULL, NULL ); + todo_wine ok( hr == HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ), "got hr %#lx\n", hr ); + + hr = DevGetObjectProperties( DevObjectTypeDeviceInterfaceDisplay, L"foobar", 0, 0, NULL, NULL, NULL ); + todo_wine ok( hr == HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ), "got hr %#lx\n", hr ); + + hr = DevGetObjectProperties( DevObjectTypeDeviceInterface, NULL, 0, 0, NULL, NULL, NULL ); + todo_wine ok( hr == E_INVALIDARG, "got hr %#lx\n", hr ); +} + START_TEST(cfgmgr32) { test_CM_MapCrToWin32Err(); @@ -928,4 +1085,5 @@ START_TEST(cfgmgr32) test_CM_Get_Device_Interface_List(); test_DevGetObjects(); test_DevCreateObjectQuery(); + test_DevGetObjectProperties_invalid(); }