This MR adds a very basic implementation of `IPropertyDescription` for system defined properties (i.e, the ones in <propkey.h>). This is needed to support the [`Properties`](https://learn.microsoft.com/en-us/uwp/api/windows.devices.enumeration.device...) method for `IDeviceInformation` in Windows.Devices.Enumeration (!6874).
-- v7: dlls/propsys: Implement IPropertyDescription for several known system properties. dlls/propsys: Add IPropertyDescription stub for system defined properties. dlls/propsys/tests: Add conformance tests for PSGetNameFromPropertyKey. dlls/propsys: Add stubs for PSGetNameFromPropertyKey. dlls/propsys: Add stubs for PropertySystem. dlls/propsys/tests: Add conformance tests for PSGetPropertyKeyFromName. dlls/propsys/tests: Add conformance tests for getting PropertyDescriptions from PropertySystem.
From: Vibhav Pant vibhavp@gmail.com
--- dlls/propsys/tests/propsys.c | 114 +++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+)
diff --git a/dlls/propsys/tests/propsys.c b/dlls/propsys/tests/propsys.c index 749704eb9c2..eb340790f4c 100644 --- a/dlls/propsys/tests/propsys.c +++ b/dlls/propsys/tests/propsys.c @@ -32,6 +32,7 @@ #include "propsys.h" #include "propvarutil.h" #include "strsafe.h" +#include "propkey.h" #include "wine/test.h"
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); @@ -56,6 +57,13 @@ static void _expect_ref(IUnknown *obj, ULONG ref, int line) ok_(__FILE__,line)(rc == ref, "expected refcount %ld, got %ld\n", ref, rc); }
+static inline const char *debugstr_propkey(const PROPERTYKEY *key) +{ + if (!key) + return "(null)"; + return wine_dbg_sprintf("{%s,%04lx}", wine_dbgstr_guid(&key->fmtid), key->pid); +} + static void test_PSStringFromPropertyKey(void) { static const WCHAR fillerW[] = {'X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X','X', @@ -2949,6 +2957,110 @@ void test_PropVariantGetStringElem(void) PropVariantClear(&propvar); }
+static void test_PropertyDescription_(int line, const PROPERTYKEY *expect_key, const WCHAR *expect_name, VARTYPE expect_type, + IPropertyDescription *desc) +{ + HRESULT hr; + PROPERTYKEY key; + VARTYPE type; + WCHAR *name; + + hr = IPropertyDescription_GetPropertyKey(desc, &key); + ok_(__FILE__, line)(SUCCEEDED(hr), "got %#lx\n", hr); + ok_(__FILE__, line)(!memcmp(&key, expect_key, sizeof(key)), "%s != %s\n", debugstr_propkey(&key), + debugstr_propkey(expect_key)); + hr = IPropertyDescription_GetCanonicalName(desc, &name); + ok_(__FILE__, line)(SUCCEEDED(hr), "got %#lx\n", hr); + if (SUCCEEDED(hr)) + { + ok_(__FILE__, line)(!wcscmp(name, expect_name), "%s != %s\n", debugstr_w(name), debugstr_w(expect_name)); + CoTaskMemFree(name); + } + hr = IPropertyDescription_GetPropertyType(desc, &type); + ok_(__FILE__, line)(SUCCEEDED(hr), "got %#lx\n", hr); + if (SUCCEEDED(hr)) + ok_(__FILE__, line)(type == expect_type, "%s != !%s\n", debugstr_vt(type), debugstr_vt(expect_type)); +} +#define test_PropertyDescription(k,n,t,d) test_PropertyDescription_(__LINE__, k, n, t, d) + +static void test_PropertySystem(void) +{ + const static struct + { + const PROPERTYKEY *key; + const WCHAR *name; + VARTYPE type; + } system_props[] = { + {&PKEY_ItemNameDisplay, L"System.ItemNameDisplay", VT_LPWSTR}, + {&PKEY_Devices_ContainerId, L"System.Devices.ContainerId", VT_CLSID}, + {&PKEY_Devices_InterfaceClassGuid, L"System.Devices.InterfaceClassGuid", VT_CLSID}, + {&PKEY_Devices_HardwareIds, L"System.Devices.HardwareIds", VT_VECTOR | VT_LPWSTR}, + {&PKEY_Devices_ClassGuid, L"System.Devices.ClassGuid", VT_CLSID} + }; + PROPERTYKEY empty = {0}; + IPropertySystem *system; + HRESULT hr; + IPropertyDescription *desc; + SIZE_T i; + + CoInitialize(NULL); + hr = CoCreateInstance(&CLSID_PropertySystem, NULL, CLSCTX_INPROC_SERVER, &IID_IPropertySystem, (void **)&system); + todo_wine ok(SUCCEEDED(hr), "got %#lx\n", hr); + if (FAILED(hr)) + { + skip("Could not create IPropertySystem instance.\n"); + CoUninitialize(); + return; + } + + for(i = 0; i < ARRAY_SIZE(system_props); i++) + { + IPropertyDescription *desc; + winetest_push_context("system_props %d", (int)i); + + hr = IPropertySystem_GetPropertyDescription(system, system_props[i].key, &IID_IPropertyDescription, (void **)&desc); + todo_wine ok(SUCCEEDED(hr), "got %#lx\n", hr); + if (SUCCEEDED(hr)) + { + test_PropertyDescription(system_props[i].key, system_props[i].name, system_props[i].type, desc); + IPropertyDescription_Release(desc); + } + hr = PSGetPropertyDescription(system_props[i].key, &IID_IPropertyDescription, (void **)&desc); + todo_wine ok(SUCCEEDED(hr), "got %#lx\n", hr); + if (SUCCEEDED(hr)) + { + test_PropertyDescription(system_props[i].key, system_props[i].name, system_props[i].type, desc); + IPropertyDescription_Release(desc); + } + + hr = IPropertySystem_GetPropertyDescriptionByName(system, system_props[i].name, &IID_IPropertyDescription, (void **)&desc); + todo_wine ok(SUCCEEDED(hr), "got %#lx\n", hr); + if (SUCCEEDED(hr)) + { + test_PropertyDescription(system_props[i].key, system_props[i].name, system_props[i].type, desc); + IPropertyDescription_Release(desc); + } + hr = PSGetPropertyDescription(system_props[i].key, &IID_IPropertyDescription, (void **)&desc); + todo_wine ok(SUCCEEDED(hr), "got %#lx\n", hr); + if (SUCCEEDED(hr)) + { + test_PropertyDescription(system_props[i].key, system_props[i].name, system_props[i].type, desc); + IPropertyDescription_Release(desc); + } + + winetest_pop_context(); + } + + hr = IPropertySystem_GetPropertyDescription(system, &empty, &IID_IPropertyDescription, (void **)&desc); + todo_wine ok(hr == TYPE_E_ELEMENTNOTFOUND, "%#lx != %#lx\n", hr, TYPE_E_ELEMENTNOTFOUND); + + hr = IPropertySystem_GetPropertyDescriptionByName(system, L"Non.Existent.Property.Name", &IID_IPropertyDescription, (void **)&desc); + todo_wine ok(hr == TYPE_E_ELEMENTNOTFOUND, "%#lx != %#lx\n", hr, TYPE_E_ELEMENTNOTFOUND); + + IPropertySystem_Release(system); + CoUninitialize(); +} + START_TEST(propsys) { test_InitPropVariantFromGUIDAsString(); @@ -2981,4 +3093,6 @@ START_TEST(propsys) test_VariantToPropVariant(); test_PropVariantToVariant(); test_PropVariantGetStringElem(); + + test_PropertySystem(); }
From: Vibhav Pant vibhavp@gmail.com
--- dlls/propsys/tests/propsys.c | 8 ++++++++ include/propsys.idl | 1 + 2 files changed, 9 insertions(+)
diff --git a/dlls/propsys/tests/propsys.c b/dlls/propsys/tests/propsys.c index eb340790f4c..943684ddb0b 100644 --- a/dlls/propsys/tests/propsys.c +++ b/dlls/propsys/tests/propsys.c @@ -3016,6 +3016,8 @@ static void test_PropertySystem(void) for(i = 0; i < ARRAY_SIZE(system_props); i++) { IPropertyDescription *desc; + PROPERTYKEY key; + winetest_push_context("system_props %d", (int)i);
hr = IPropertySystem_GetPropertyDescription(system, system_props[i].key, &IID_IPropertyDescription, (void **)&desc); @@ -3033,6 +3035,12 @@ static void test_PropertySystem(void) IPropertyDescription_Release(desc); }
+ hr = PSGetPropertyKeyFromName(system_props[i].name, &key); + todo_wine ok(SUCCEEDED(hr), "got %#lx\n", hr); + if (SUCCEEDED(hr)) + ok(!memcmp(&key, system_props[i].key, sizeof(key)), "%s != %s\n", debugstr_propkey(&key), + debugstr_propkey(system_props[i].key)); + hr = IPropertySystem_GetPropertyDescriptionByName(system, system_props[i].name, &IID_IPropertyDescription, (void **)&desc); todo_wine ok(SUCCEEDED(hr), "got %#lx\n", hr); if (SUCCEEDED(hr)) diff --git a/include/propsys.idl b/include/propsys.idl index 9dc93caf15d..5627b23dbcd 100644 --- a/include/propsys.idl +++ b/include/propsys.idl @@ -808,6 +808,7 @@ cpp_quote("#define PKEYSTR_MAX (GUIDSTRING_MAX + 1 + PKEY_PIDSTR_MAX)") cpp_quote("PSSTDAPI PSCreateMemoryPropertyStore(REFIID,void **);") cpp_quote("PSSTDAPI PSCreatePropertyStoreFromObject(IUnknown*,DWORD,REFIID,void **);") cpp_quote("PSSTDAPI PSStringFromPropertyKey(REFPROPERTYKEY,LPWSTR,UINT);") +cpp_quote("PSSTDAPI PSGetPropertyKeyFromName(PCWSTR,PROPERTYKEY *);") cpp_quote("PSSTDAPI PSPropertyKeyFromString(LPCWSTR,PROPERTYKEY*);") cpp_quote("PSSTDAPI PSGetPropertyDescription(REFPROPERTYKEY,REFIID,void **);") cpp_quote("PSSTDAPI PSGetPropertyDescriptionListFromString(LPCWSTR,REFIID,void **);")
From: Vibhav Pant vibhavp@gmail.com
--- dlls/propsys/propsys_classes.idl | 6 ++ dlls/propsys/propsys_main.c | 180 ++++++++++++++++++++++++++----- dlls/propsys/propsys_private.h | 7 ++ dlls/propsys/tests/propsys.c | 3 +- 4 files changed, 168 insertions(+), 28 deletions(-)
diff --git a/dlls/propsys/propsys_classes.idl b/dlls/propsys/propsys_classes.idl index 02555a37d26..c6e1821ecbc 100644 --- a/dlls/propsys/propsys_classes.idl +++ b/dlls/propsys/propsys_classes.idl @@ -26,3 +26,9 @@ uuid(9a02e012-6303-4e1e-b9a1-630f802592c5) ] coclass InMemoryPropertyStore { interface IPropertyStoreCache; } + +[ + threading(both), + uuid(b8967f85-58ae-4f46-9fb2-5d7904798f4b) +] +coclass PropertySystem { interface IPropertySystem; } diff --git a/dlls/propsys/propsys_main.c b/dlls/propsys/propsys_main.c index 6e87b3d3579..db79983e255 100644 --- a/dlls/propsys/propsys_main.c +++ b/dlls/propsys/propsys_main.c @@ -92,19 +92,71 @@ static const IClassFactoryVtbl InMemoryPropertyStoreFactoryVtbl = {
static IClassFactory InMemoryPropertyStoreFactory = { &InMemoryPropertyStoreFactoryVtbl };
+struct property_system +{ + IPropertySystem IPropertySystem_iface; + LONG ref; +}; + +static const IPropertySystemVtbl propsysvtbl; + +static HRESULT WINAPI propsys_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID iid, void **out) +{ + struct property_system *propsys_impl; + HRESULT hr; + + TRACE("%p, %p, %s, %p\n", iface, outer, debugstr_guid(iid), out); + + *out = NULL; + if (outer) + return CLASS_E_NOAGGREGATION; + + propsys_impl = calloc(1, sizeof(*propsys_impl)); + if (!propsys_impl) + return E_OUTOFMEMORY; + + propsys_impl->IPropertySystem_iface.lpVtbl = &propsysvtbl; + propsys_impl->ref = 1; + hr = IPropertySystem_QueryInterface(&propsys_impl->IPropertySystem_iface, iid, out); + IPropertySystem_Release(&propsys_impl->IPropertySystem_iface); + return hr; +} + +static const IClassFactoryVtbl PropertySystemFactoryVtbl = +{ + ClassFactory_QueryInterface, + ClassFactory_AddRef, + ClassFactory_Release, + propsys_factory_CreateInstance, + ClassFactory_LockServer +}; + +static IClassFactory PropertySystemFactory = { &PropertySystemFactoryVtbl }; + HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { if(IsEqualGUID(&CLSID_InMemoryPropertyStore, rclsid)) { TRACE("(CLSID_InMemoryPropertyStore %s %p)\n", debugstr_guid(riid), ppv); return IClassFactory_QueryInterface(&InMemoryPropertyStoreFactory, riid, ppv); } + if (IsEqualGUID(&CLSID_PropertySystem, rclsid)) + { + TRACE("(CLSID_PropertySystem %s %p)\n", debugstr_guid(riid), ppv); + return IClassFactory_QueryInterface(&PropertySystemFactory, riid, ppv); + }
FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); return CLASS_E_CLASSNOTAVAILABLE; }
+static inline struct property_system *impl_from_IPropertySystem( IPropertySystem *iface ) +{ + return CONTAINING_RECORD( iface, struct property_system, IPropertySystem_iface ); +} + static HRESULT WINAPI propsys_QueryInterface(IPropertySystem *iface, REFIID riid, void **obj) { + TRACE("(%p, %s, %p)\n", iface, debugstr_guid(riid), obj); *obj = NULL;
if (IsEqualIID(riid, &IID_IPropertySystem) || IsEqualIID(riid, &IID_IUnknown)) { @@ -119,37 +171,49 @@ static HRESULT WINAPI propsys_QueryInterface(IPropertySystem *iface, REFIID riid
static ULONG WINAPI propsys_AddRef(IPropertySystem *iface) { - return 2; + struct property_system *impl = impl_from_IPropertySystem(iface); + return InterlockedIncrement(&impl->ref); }
static ULONG WINAPI propsys_Release(IPropertySystem *iface) { - return 1; + struct property_system *impl; + ULONG ref; + + impl = impl_from_IPropertySystem(iface); + ref = InterlockedDecrement(&impl->ref); + if (!ref) + free(impl); + return ref; }
static HRESULT WINAPI propsys_GetPropertyDescription(IPropertySystem *iface, REFPROPERTYKEY propkey, REFIID riid, void **ppv) { - return PSGetPropertyDescription(propkey, riid, ppv); + FIXME("(%p, %s, %s, %p): stub\n", iface, debugstr_propkey(propkey), debugstr_guid(riid), ppv); + return E_NOTIMPL; }
static HRESULT WINAPI propsys_GetPropertyDescriptionByName(IPropertySystem *iface, LPCWSTR canonical_name, REFIID riid, void **ppv) { - FIXME("%s %s %p: stub\n", debugstr_w(canonical_name), debugstr_guid(riid), ppv); + FIXME("(%p, %s, %s, %p): stub\n", iface, debugstr_w(canonical_name), debugstr_guid(riid), ppv); return E_NOTIMPL; }
static HRESULT WINAPI propsys_GetPropertyDescriptionListFromString(IPropertySystem *iface, LPCWSTR proplist, REFIID riid, void **ppv) { - return PSGetPropertyDescriptionListFromString(proplist, riid, ppv); + FIXME("(%p, %s, %s, %p): stub\n", iface, debugstr_w(proplist), debugstr_guid(riid), ppv); + *ppv = NULL; + return E_NOTIMPL; }
static HRESULT WINAPI propsys_EnumeratePropertyDescriptions(IPropertySystem *iface, PROPDESC_ENUMFILTER filter, REFIID riid, void **ppv) { - FIXME("%d %s %p: stub\n", filter, debugstr_guid(riid), ppv); + FIXME("(%p, %d, %s, %p): stub\n", iface, filter, debugstr_guid(riid), ppv); + *ppv = NULL; return E_NOTIMPL; }
@@ -157,7 +221,7 @@ static HRESULT WINAPI propsys_FormatForDisplay(IPropertySystem *iface, REFPROPERTYKEY key, REFPROPVARIANT propvar, PROPDESC_FORMAT_FLAGS flags, LPWSTR dest, DWORD destlen) { - FIXME("%p %p %x %p %ld: stub\n", key, propvar, flags, dest, destlen); + FIXME("(%p, %s, %p, %x, %p, %ld): stub\n", iface, debugstr_propkey(key), propvar, flags, dest, destlen); return E_NOTIMPL; }
@@ -165,23 +229,26 @@ static HRESULT WINAPI propsys_FormatForDisplayAlloc(IPropertySystem *iface, REFPROPERTYKEY key, REFPROPVARIANT propvar, PROPDESC_FORMAT_FLAGS flags, LPWSTR *text) { - FIXME("%p %p %x %p: stub\n", key, propvar, flags, text); + FIXME("(%p, %s, %p, %x, %p): stub\n", iface, debugstr_propkey(key), propvar, flags, text); return E_NOTIMPL; }
static HRESULT WINAPI propsys_RegisterPropertySchema(IPropertySystem *iface, LPCWSTR path) { - return PSRegisterPropertySchema(path); + FIXME("(%p, %s): stub\n", iface, debugstr_w(path)); + return S_OK; }
static HRESULT WINAPI propsys_UnregisterPropertySchema(IPropertySystem *iface, LPCWSTR path) { - return PSUnregisterPropertySchema(path); + FIXME("(%p, %s): stub\n", iface, debugstr_w(path)); + return E_NOTIMPL; }
static HRESULT WINAPI propsys_RefreshPropertySchema(IPropertySystem *iface) { - return PSRefreshPropertySchema(); + FIXME("(%p): stub\n", iface); + return S_OK; }
static const IPropertySystemVtbl propsysvtbl = { @@ -199,49 +266,110 @@ static const IPropertySystemVtbl propsysvtbl = { propsys_RefreshPropertySchema };
-static IPropertySystem propsys = { &propsysvtbl }; - HRESULT WINAPI PSGetPropertySystem(REFIID riid, void **obj) { - return IPropertySystem_QueryInterface(&propsys, riid, obj); + return CoCreateInstance(&CLSID_PropertySystem, NULL, CLSCTX_INPROC_SERVER, riid, obj); }
HRESULT WINAPI PSRegisterPropertySchema(PCWSTR path) { - FIXME("%s stub\n", debugstr_w(path)); + HRESULT hr; + IPropertySystem *system;
- return S_OK; + TRACE("%s\n", debugstr_w(path)); + hr = PSGetPropertySystem(&IID_IPropertySystem, (void **)&system); + if (SUCCEEDED(hr)) + { + hr = IPropertySystem_RegisterPropertySchema(system, path); + IPropertySystem_Release(system); + } + + return hr; }
HRESULT WINAPI PSUnregisterPropertySchema(PCWSTR path) { - FIXME("%s stub\n", debugstr_w(path)); + HRESULT hr; + IPropertySystem *system;
- return E_NOTIMPL; + TRACE("%s\n", debugstr_w(path)); + hr = PSGetPropertySystem(&IID_IPropertySystem, (void **)&system); + if (SUCCEEDED(hr)) + { + hr = IPropertySystem_UnregisterPropertySchema(system, path); + IPropertySystem_Release(system); + } + + return hr; }
HRESULT WINAPI PSGetPropertyDescription(REFPROPERTYKEY propkey, REFIID riid, void **ppv) { - FIXME("%p, %p, %p\n", propkey, riid, ppv); - return E_NOTIMPL; + HRESULT hr; + IPropertySystem *system; + + TRACE("%p, %p, %p\n", propkey, riid, ppv); + hr = PSGetPropertySystem(&IID_IPropertySystem, (void **)&system); + if (SUCCEEDED(hr)) + { + hr = IPropertySystem_GetPropertyDescription(system, propkey, riid, ppv); + IPropertySystem_Release(system); + } + return hr; }
HRESULT WINAPI PSGetPropertyDescriptionListFromString(LPCWSTR proplist, REFIID riid, void **ppv) { - FIXME("%s, %p, %p\n", debugstr_w(proplist), riid, ppv); - return E_NOTIMPL; + HRESULT hr; + IPropertySystem *system; + + TRACE("%s, %p, %p\n", debugstr_w(proplist), riid, ppv); + hr = PSGetPropertySystem(&IID_IPropertySystem, (void **)&system); + if (SUCCEEDED(hr)) + { + hr = IPropertySystem_GetPropertyDescriptionListFromString(system, proplist, riid, ppv); + IPropertySystem_Release(system); + } + + return hr; }
HRESULT WINAPI PSGetPropertyKeyFromName(PCWSTR name, PROPERTYKEY *key) { - FIXME("%s, %p\n", debugstr_w(name), key); - return E_NOTIMPL; + HRESULT hr; + IPropertySystem *system; + + TRACE("%s, %p\n", debugstr_w(name), debugstr_propkey(key)); + hr = PSGetPropertySystem(&IID_IPropertySystem, (void **)&system); + if (SUCCEEDED(hr)) + { + IPropertyDescription *desc; + hr = IPropertySystem_GetPropertyDescriptionByName(system, name, &IID_IPropertyDescription, (void *)&desc); + if (SUCCEEDED(hr)) + { + hr = IPropertyDescription_GetPropertyKey(desc, key); + IPropertyDescription_Release(desc); + } + IPropertySystem_Release(system); + } + + return hr; }
HRESULT WINAPI PSRefreshPropertySchema(void) { - FIXME("\n"); - return S_OK; + HRESULT hr; + IPropertySystem *system; + + TRACE("\n"); + hr = PSGetPropertySystem(&IID_IPropertySystem, (void **)&system); + if (SUCCEEDED(hr)) + { + hr = IPropertySystem_RefreshPropertySchema(system); + IPropertySystem_Release(system); + } + + return hr; }
HRESULT WINAPI PSStringFromPropertyKey(REFPROPERTYKEY pkey, LPWSTR psz, UINT cch) diff --git a/dlls/propsys/propsys_private.h b/dlls/propsys/propsys_private.h index ab5b0fe255c..0d2d0fb4556 100644 --- a/dlls/propsys/propsys_private.h +++ b/dlls/propsys/propsys_private.h @@ -19,3 +19,10 @@ */
HRESULT PropertyStore_CreateInstance(IUnknown *outer, REFIID riid, void **ppv); + +static inline const char *debugstr_propkey(const PROPERTYKEY *key) +{ + if (!key) + return "(null)"; + return wine_dbg_sprintf("{%s,%04lx}", wine_dbgstr_guid(&key->fmtid), key->pid); +} diff --git a/dlls/propsys/tests/propsys.c b/dlls/propsys/tests/propsys.c index 943684ddb0b..c3e36b79779 100644 --- a/dlls/propsys/tests/propsys.c +++ b/dlls/propsys/tests/propsys.c @@ -457,7 +457,6 @@ static void test_PSRefreshPropertySchema(void) HRESULT ret;
ret = PSRefreshPropertySchema(); - todo_wine ok(ret == CO_E_NOTINITIALIZED, "Expected PSRefreshPropertySchema to return CO_E_NOTINITIALIZED, got 0x%08lx\n", ret);
@@ -3005,7 +3004,7 @@ static void test_PropertySystem(void)
CoInitialize(NULL); hr = CoCreateInstance(&CLSID_PropertySystem, NULL, CLSCTX_INPROC_SERVER, &IID_IPropertySystem, (void **)&system); - todo_wine ok(SUCCEEDED(hr), "got %#lx\n", hr); + ok(SUCCEEDED(hr), "got %#lx\n", hr); if (FAILED(hr)) { skip("Could not create IPropertySystem instance.\n");
From: Vibhav Pant vibhavp@gmail.com
--- dlls/propsys/propsys.spec | 2 +- dlls/propsys/propsys_main.c | 15 +++++++++++++++ include/propsys.idl | 1 + 3 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/dlls/propsys/propsys.spec b/dlls/propsys/propsys.spec index 6a1a313f93b..fbaf3b575e5 100644 --- a/dlls/propsys/propsys.spec +++ b/dlls/propsys/propsys.spec @@ -77,7 +77,7 @@ @ stub PSFormatPropertyValue @ stub PSGetItemPropertyHandler @ stub PSGetItemPropertyHandlerWithCreateObject -@ stub PSGetNameFromPropertyKey +@ stdcall PSGetNameFromPropertyKey(ptr ptr) @ stub PSGetNamedPropertyFromPropertyStorage @ stdcall PSGetPropertyDescription(ptr ptr ptr) @ stub PSGetPropertyDescriptionByName diff --git a/dlls/propsys/propsys_main.c b/dlls/propsys/propsys_main.c index db79983e255..5c9b2c3de3b 100644 --- a/dlls/propsys/propsys_main.c +++ b/dlls/propsys/propsys_main.c @@ -334,6 +334,21 @@ HRESULT WINAPI PSGetPropertyDescriptionListFromString(LPCWSTR proplist, REFIID r return hr; }
+HRESULT WINAPI PSGetNameFromPropertyKey(REFPROPERTYKEY key, LPWSTR *name) +{ + HRESULT hr; + IPropertyDescription *desc; + + TRACE("(%s, %p)\n", debugstr_propkey(key), name); + hr = PSGetPropertyDescription(key, &IID_IPropertyDescription, (void *)&desc); + if (SUCCEEDED(hr)) + { + hr = IPropertyDescription_GetCanonicalName(desc, name); + IPropertyDescription_Release(desc); + } + return hr; +} + HRESULT WINAPI PSGetPropertyKeyFromName(PCWSTR name, PROPERTYKEY *key) { HRESULT hr; diff --git a/include/propsys.idl b/include/propsys.idl index 5627b23dbcd..4baffc75826 100644 --- a/include/propsys.idl +++ b/include/propsys.idl @@ -809,6 +809,7 @@ cpp_quote("PSSTDAPI PSCreateMemoryPropertyStore(REFIID,void **);") cpp_quote("PSSTDAPI PSCreatePropertyStoreFromObject(IUnknown*,DWORD,REFIID,void **);") cpp_quote("PSSTDAPI PSStringFromPropertyKey(REFPROPERTYKEY,LPWSTR,UINT);") cpp_quote("PSSTDAPI PSGetPropertyKeyFromName(PCWSTR,PROPERTYKEY *);") +cpp_quote("PSSTDAPI PSGetNameFromPropertyKey(REFPROPERTYKEY,LPWSTR *);") cpp_quote("PSSTDAPI PSPropertyKeyFromString(LPCWSTR,PROPERTYKEY*);") cpp_quote("PSSTDAPI PSGetPropertyDescription(REFPROPERTYKEY,REFIID,void **);") cpp_quote("PSSTDAPI PSGetPropertyDescriptionListFromString(LPCWSTR,REFIID,void **);")
From: Vibhav Pant vibhavp@gmail.com
--- dlls/propsys/tests/propsys.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/dlls/propsys/tests/propsys.c b/dlls/propsys/tests/propsys.c index c3e36b79779..abf8936bbd5 100644 --- a/dlls/propsys/tests/propsys.c +++ b/dlls/propsys/tests/propsys.c @@ -3015,6 +3015,7 @@ static void test_PropertySystem(void) for(i = 0; i < ARRAY_SIZE(system_props); i++) { IPropertyDescription *desc; + LPWSTR name; PROPERTYKEY key;
winetest_push_context("system_props %d", (int)i); @@ -3040,6 +3041,14 @@ static void test_PropertySystem(void) ok(!memcmp(&key, system_props[i].key, sizeof(key)), "%s != %s\n", debugstr_propkey(&key), debugstr_propkey(system_props[i].key));
+ hr = PSGetNameFromPropertyKey(system_props[i].key, &name); + todo_wine ok(SUCCEEDED(hr), "got %#lx\n", hr); + if (SUCCEEDED(hr)) + { + ok(!wcscmp(name, system_props[i].name), "%s != %s\n", debugstr_w(name), debugstr_w(system_props[i].name)); + CoTaskMemFree(name); + } + hr = IPropertySystem_GetPropertyDescriptionByName(system, system_props[i].name, &IID_IPropertyDescription, (void **)&desc); todo_wine ok(SUCCEEDED(hr), "got %#lx\n", hr); if (SUCCEEDED(hr))
From: Vibhav Pant vibhavp@gmail.com
--- dlls/propsys/Makefile.in | 1 + dlls/propsys/propsys_desc.c | 269 +++++++++++++++++++++++++++++++++ dlls/propsys/propsys_main.c | 31 +++- dlls/propsys/propsys_private.h | 2 + 4 files changed, 300 insertions(+), 3 deletions(-) create mode 100644 dlls/propsys/propsys_desc.c
diff --git a/dlls/propsys/Makefile.in b/dlls/propsys/Makefile.in index a8661ca17e9..c8f4eb953a4 100644 --- a/dlls/propsys/Makefile.in +++ b/dlls/propsys/Makefile.in @@ -8,5 +8,6 @@ EXTRADLLFLAGS = -Wb,--prefer-native SOURCES = \ propstore.c \ propsys_classes.idl \ + propsys_desc.c \ propsys_main.c \ propvar.c diff --git a/dlls/propsys/propsys_desc.c b/dlls/propsys/propsys_desc.c new file mode 100644 index 00000000000..91622ebb4df --- /dev/null +++ b/dlls/propsys/propsys_desc.c @@ -0,0 +1,269 @@ +/* + * IPropertyDescription implementation + * + * Copyright 2024 Vibhav Pant + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include <propsys.h> +#include <propkey.h> + +#include <wine/debug.h> + +#include "propsys_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL( propsys ); + +struct property_description +{ + IPropertyDescription IPropertyDescription_iface; + LONG ref; +}; + +static inline struct property_description * +impl_from_IPropertyDescription( IPropertyDescription *iface ) +{ + return CONTAINING_RECORD( iface, struct property_description, IPropertyDescription_iface ); +} + +static HRESULT WINAPI propdesc_QueryInterface( IPropertyDescription *iface, REFIID iid, void **out ) +{ + TRACE( "(%p, %s, %p)\n", iface, debugstr_guid( iid ), out ); + *out = NULL; + + if (IsEqualGUID( &IID_IUnknown, iid ) || + IsEqualGUID( &IID_IPropertyDescription, iid )) + { + *out = iface; + IUnknown_AddRef( iface ); + return S_OK; + } + + FIXME( "%s not implemented\n", debugstr_guid( iid ) ); + return E_NOINTERFACE; +} + +static ULONG WINAPI propdesc_AddRef( IPropertyDescription *iface ) +{ + struct property_description *impl; + TRACE( "(%p)\n", iface ); + impl = impl_from_IPropertyDescription( iface ); + return InterlockedIncrement( &impl->ref ); +} + +static ULONG WINAPI propdesc_Release( IPropertyDescription *iface ) +{ + struct property_description *impl; + ULONG ref; + + TRACE( "(%p)\n", iface ); + + impl = impl_from_IPropertyDescription( iface ); + ref = InterlockedDecrement( &impl->ref ); + if (!ref) + free( impl ); + + return ref; +} + +static HRESULT WINAPI propdesc_GetPropertyKey( IPropertyDescription *iface, PROPERTYKEY *pkey ) +{ + FIXME( "(%p, %p) stub!\n", iface, pkey ); + return E_NOTIMPL; +} + +static HRESULT WINAPI propdesc_GetCanonicalName( IPropertyDescription *iface, LPWSTR *name ) +{ + TRACE( "(%p, %p) stub!\n", iface, name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI propdesc_GetPropertyType( IPropertyDescription *iface, VARTYPE *vt ) +{ + FIXME( "(%p, %p) stub!\n", iface, vt ); + return E_NOTIMPL; +} + +static HRESULT WINAPI propdesc_GetDisplayName( IPropertyDescription *iface, LPWSTR *name ) +{ + FIXME( "(%p, %p) semi-stub!\n", iface, name ); + return IPropertyDescription_GetCanonicalName( iface, name ); +} + +static HRESULT WINAPI propdesc_GetEditInvitation( IPropertyDescription *iface, LPWSTR *invite ) +{ + FIXME( "(%p, %p) stub!\n", iface, invite ); + return E_NOTIMPL; +} + +static HRESULT WINAPI propdesc_GetTypeFlags( IPropertyDescription *iface, PROPDESC_TYPE_FLAGS mask, + PROPDESC_TYPE_FLAGS *flags ) +{ + FIXME( "(%p, %#x, %p) stub!\n", iface, mask, flags ); + return E_NOTIMPL; +} + +static HRESULT WINAPI propdesc_GetViewFlags( IPropertyDescription *iface, PROPDESC_VIEW_FLAGS *flags ) +{ + FIXME( "(%p, %p) stub!\n", iface, flags ); + return E_NOTIMPL; +} + +static HRESULT WINAPI propdesc_GetDefaultColumnWidth( IPropertyDescription *iface, UINT *chars ) +{ + FIXME( "(%p, %p) stub!\n", iface, chars ); + return E_NOTIMPL; +} + +static HRESULT WINAPI propdesc_GetDisplayType( IPropertyDescription *iface, PROPDESC_DISPLAYTYPE *type ) +{ + FIXME( "(%p, %p) stub!\n", iface, type ); + return E_NOTIMPL; +} + +static HRESULT WINAPI propdesc_GetColumnState( IPropertyDescription *iface, SHCOLSTATEF *flags ) +{ + FIXME( "(%p, %p) stub!\n", iface, flags ); + return E_NOTIMPL; +} + +static HRESULT WINAPI propdesc_GetGroupingRange( IPropertyDescription *iface, PROPDESC_GROUPING_RANGE *range ) +{ + FIXME( "(%p, %p) stub!\n", iface, range ); + return E_NOTIMPL; +} + +static HRESULT WINAPI propdesc_GetRelativeDescriptionType( IPropertyDescription *iface, + PROPDESC_RELATIVEDESCRIPTION_TYPE *type ) +{ + FIXME( "(%p, %p) stub!\n", iface, type ); + return E_NOTIMPL; +} + +static HRESULT WINAPI propdesc_GetRelativeDescription( IPropertyDescription *iface, REFPROPVARIANT propvar1, + REFPROPVARIANT propvar2, LPWSTR *desc1, LPWSTR *desc2 ) +{ + FIXME( "(%p, %p, %p, %p, %p) stub!\n", iface, propvar1, propvar2, desc1, desc2 ); + return E_NOTIMPL; +} + +static HRESULT WINAPI propdesc_GetSortDescription( IPropertyDescription *iface, PROPDESC_SORTDESCRIPTION *psd ) +{ + FIXME( "(%p, %p) stub!\n", iface, psd ); + return E_NOTIMPL; +} + +static HRESULT WINAPI propdesc_GetSortDescriptionLabel( IPropertyDescription *iface, BOOL descending, LPWSTR *desc ) +{ + FIXME( "(%p, %d, %p) stub!\n", iface, descending, desc ); + return E_NOTIMPL; +} + +static HRESULT WINAPI propdesc_GetAggregationType( IPropertyDescription *iface, PROPDESC_AGGREGATION_TYPE *type ) +{ + FIXME( "(%p, %p) stub!\n", iface, type ); + return E_NOTIMPL; +} + +static HRESULT WINAPI propdesc_GetConditionType( IPropertyDescription *iface, PROPDESC_CONDITION_TYPE *cond_type, + CONDITION_OPERATION *op_default ) +{ + FIXME( "(%p, %p, %p) stub!\n", iface, cond_type, op_default ); + return E_NOTIMPL; +} + +static HRESULT WINAPI propdesc_GetEnumTypeList( IPropertyDescription *iface, REFIID riid, void **out ) +{ + FIXME( "(%p, %s, %p) stub!\n", iface, debugstr_guid( riid ), out ); + *out = NULL; + return E_NOTIMPL; +} + +static HRESULT WINAPI propdesc_CoerceToCanonicalValue( IPropertyDescription *iface, PROPVARIANT *propvar ) +{ + FIXME( "(%p, %p) stub!\n", iface, propvar ); + return E_NOTIMPL; +} + +static HRESULT WINAPI propdesc_FormatForDisplay( IPropertyDescription *iface, REFPROPVARIANT propvar, + PROPDESC_FORMAT_FLAGS flags, LPWSTR *display ) +{ + FIXME( "(%p, %p, %#x, %p) stub!\n", iface, propvar, flags, display ); + return E_NOTIMPL; +} + +static HRESULT WINAPI propdesc_IsValueCanonical( IPropertyDescription *iface, REFPROPVARIANT propvar ) +{ + FIXME( "(%p, %p) stub!\n", iface, propvar ); + return E_NOTIMPL; +} + +const static IPropertyDescriptionVtbl property_description_vtbl = +{ + /* IUnknown */ + propdesc_QueryInterface, + propdesc_AddRef, + propdesc_Release, + /* IPropertyDescription */ + propdesc_GetPropertyKey, + propdesc_GetCanonicalName, + propdesc_GetPropertyType, + propdesc_GetDisplayName, + propdesc_GetEditInvitation, + propdesc_GetTypeFlags, + propdesc_GetViewFlags, + propdesc_GetDefaultColumnWidth, + propdesc_GetDisplayType, + propdesc_GetColumnState, + propdesc_GetGroupingRange, + propdesc_GetRelativeDescriptionType, + propdesc_GetRelativeDescription, + propdesc_GetSortDescription, + propdesc_GetSortDescriptionLabel, + propdesc_GetAggregationType, + propdesc_GetConditionType, + propdesc_GetEnumTypeList, + propdesc_CoerceToCanonicalValue, + propdesc_FormatForDisplay, + propdesc_IsValueCanonical +}; + +static HRESULT propdesc_from_system_property( IPropertyDescription **out ) +{ + struct property_description *impl; + + impl = calloc(1, sizeof( *impl )); + if (!impl) + return E_OUTOFMEMORY; + + impl->IPropertyDescription_iface.lpVtbl = &property_description_vtbl; + impl->ref = 1; + + *out = &impl->IPropertyDescription_iface; + return S_OK; +} + +HRESULT propsys_get_system_propdesc_by_name( const WCHAR *name, IPropertyDescription **desc ) +{ + return propdesc_from_system_property( desc ); +} + +HRESULT propsys_get_system_propdesc_by_key( const PROPERTYKEY *key, IPropertyDescription **desc ) +{ + return propdesc_from_system_property( desc ); +} diff --git a/dlls/propsys/propsys_main.c b/dlls/propsys/propsys_main.c index 5c9b2c3de3b..9eae9cd8c99 100644 --- a/dlls/propsys/propsys_main.c +++ b/dlls/propsys/propsys_main.c @@ -190,15 +190,40 @@ static ULONG WINAPI propsys_Release(IPropertySystem *iface) static HRESULT WINAPI propsys_GetPropertyDescription(IPropertySystem *iface, REFPROPERTYKEY propkey, REFIID riid, void **ppv) { - FIXME("(%p, %s, %s, %p): stub\n", iface, debugstr_propkey(propkey), debugstr_guid(riid), ppv); - return E_NOTIMPL; + HRESULT hr; + IPropertyDescription *desc; + + FIXME("(%p, %s, %s, %p): semi-stub!\n", iface, debugstr_propkey(propkey), debugstr_guid(riid), ppv); + + if (!ppv) + return E_INVALIDARG; + *ppv = NULL; + hr = propsys_get_system_propdesc_by_key( propkey, &desc ); + if (FAILED( hr )) + return hr; + + hr = IPropertyDescription_QueryInterface( desc, riid, ppv ); + IPropertyDescription_Release( desc ); + return hr; }
static HRESULT WINAPI propsys_GetPropertyDescriptionByName(IPropertySystem *iface, LPCWSTR canonical_name, REFIID riid, void **ppv) { + HRESULT hr; + IPropertyDescription *desc; + FIXME("(%p, %s, %s, %p): stub\n", iface, debugstr_w(canonical_name), debugstr_guid(riid), ppv); - return E_NOTIMPL; + + if (!ppv) + return E_INVALIDARG; + *ppv = NULL; + hr = propsys_get_system_propdesc_by_name( canonical_name, &desc ); + if (FAILED( hr )) + return hr; + hr = IPropertyDescription_QueryInterface( desc, riid, ppv ); + IPropertyDescription_Release( desc ); + return hr; }
static HRESULT WINAPI propsys_GetPropertyDescriptionListFromString(IPropertySystem *iface, diff --git a/dlls/propsys/propsys_private.h b/dlls/propsys/propsys_private.h index 0d2d0fb4556..cd38692c499 100644 --- a/dlls/propsys/propsys_private.h +++ b/dlls/propsys/propsys_private.h @@ -20,6 +20,8 @@
HRESULT PropertyStore_CreateInstance(IUnknown *outer, REFIID riid, void **ppv);
+HRESULT propsys_get_system_propdesc_by_name(const WCHAR *name, IPropertyDescription **desc); +HRESULT propsys_get_system_propdesc_by_key(const PROPERTYKEY *key, IPropertyDescription **desc); static inline const char *debugstr_propkey(const PROPERTYKEY *key) { if (!key)
From: Vibhav Pant vibhavp@gmail.com
--- dlls/propsys/propsys_desc.c | 100 +++++++++++++++++++++++++++++++---- dlls/propsys/tests/propsys.c | 19 +++---- 2 files changed, 99 insertions(+), 20 deletions(-)
diff --git a/dlls/propsys/propsys_desc.c b/dlls/propsys/propsys_desc.c index 91622ebb4df..5ec0b36a24c 100644 --- a/dlls/propsys/propsys_desc.c +++ b/dlls/propsys/propsys_desc.c @@ -32,7 +32,13 @@ WINE_DEFAULT_DEBUG_CHANNEL( propsys ); struct property_description { IPropertyDescription IPropertyDescription_iface; + + PROPERTYKEY key; + VARTYPE type; + PROPDESC_TYPE_FLAGS type_flags; + LONG ref; + WCHAR canonical_name[1]; };
static inline struct property_description * @@ -83,20 +89,35 @@ static ULONG WINAPI propdesc_Release( IPropertyDescription *iface )
static HRESULT WINAPI propdesc_GetPropertyKey( IPropertyDescription *iface, PROPERTYKEY *pkey ) { - FIXME( "(%p, %p) stub!\n", iface, pkey ); - return E_NOTIMPL; + struct property_description *impl; + + TRACE( "(%p, %p)\n", iface, pkey ); + impl = impl_from_IPropertyDescription( iface ); + *pkey = impl->key; + return S_OK; }
static HRESULT WINAPI propdesc_GetCanonicalName( IPropertyDescription *iface, LPWSTR *name ) { - TRACE( "(%p, %p) stub!\n", iface, name ); - return E_NOTIMPL; + struct property_description *impl; + + TRACE( "(%p, %p)\n", iface, name ); + impl = impl_from_IPropertyDescription( iface ); + *name = CoTaskMemAlloc( wcslen( impl->canonical_name ) * sizeof( WCHAR ) ); + if (!*name) + return E_OUTOFMEMORY; + wcscpy( *name, impl->canonical_name ); + return S_OK; }
static HRESULT WINAPI propdesc_GetPropertyType( IPropertyDescription *iface, VARTYPE *vt ) { - FIXME( "(%p, %p) stub!\n", iface, vt ); - return E_NOTIMPL; + struct property_description *impl; + + TRACE( "(%p, %p)\n", iface, vt ); + impl = impl_from_IPropertyDescription( iface ); + *vt = impl->type; + return S_OK; }
static HRESULT WINAPI propdesc_GetDisplayName( IPropertyDescription *iface, LPWSTR *name ) @@ -114,7 +135,11 @@ static HRESULT WINAPI propdesc_GetEditInvitation( IPropertyDescription *iface, L static HRESULT WINAPI propdesc_GetTypeFlags( IPropertyDescription *iface, PROPDESC_TYPE_FLAGS mask, PROPDESC_TYPE_FLAGS *flags ) { - FIXME( "(%p, %#x, %p) stub!\n", iface, mask, flags ); + struct property_description *impl; + + TRACE( "(%p, %#x, %p)\n", iface, mask, flags ); + impl = impl_from_IPropertyDescription( iface ); + *flags = mask & impl->type_flags; return E_NOTIMPL; }
@@ -243,15 +268,52 @@ const static IPropertyDescriptionVtbl property_description_vtbl = propdesc_IsValueCanonical };
-static HRESULT propdesc_from_system_property( IPropertyDescription **out ) +struct system_property_description +{ + const WCHAR *canonical_name; + const PROPERTYKEY *key; + + VARTYPE type; +}; + +/* It may be ideal to construct rb_trees for looking up property descriptions by name and key if this array gets large + * enough. */ +static struct system_property_description system_properties[] = +{ + {L"System.Devices.ContainerId", &PKEY_Devices_ContainerId, VT_CLSID}, + {L"System.Devices.InterfaceClassGuid", &PKEY_Devices_InterfaceClassGuid, VT_CLSID}, + {L"System.Devices.DeviceInstanceId", &PKEY_Devices_DeviceInstanceId, VT_CLSID}, + {L"System.Devices.InterfaceEnabled", &PKEY_Devices_InterfaceEnabled, VT_BOOL}, + {L"System.Devices.ClassGuid", &PKEY_Devices_ClassGuid, VT_CLSID}, + {L"System.Devices.CompatibleIds", &PKEY_Devices_CompatibleIds, VT_VECTOR | VT_LPWSTR}, + {L"System.Devices.DeviceCapabilities", &PKEY_Devices_DeviceCapabilities, VT_UI2}, + {L"System.Devices.DeviceHasProblem", &PKEY_Devices_DeviceHasProblem, VT_BOOL}, + {L"System.Devices.DeviceManufacturer", &PKEY_Devices_DeviceManufacturer, VT_LPWSTR}, + {L"System.Devices.HardwareIds", &PKEY_Devices_HardwareIds, VT_VECTOR | VT_LPWSTR}, + {L"System.Devices.Parent", &PKEY_Devices_Parent, VT_LPWSTR}, + {L"System.ItemNameDisplay", &PKEY_ItemNameDisplay, VT_LPWSTR}, + {L"System.Devices.Category", &PKEY_Devices_Category, VT_VECTOR | VT_LPWSTR}, + {L"System.Devices.CategoryIds", &PKEY_Devices_CategoryIds, VT_VECTOR | VT_LPWSTR}, + {L"System.Devices.CategoryPlural", &PKEY_Devices_CategoryPlural, VT_VECTOR | VT_LPWSTR}, + {L"System.Devices.Connected", &PKEY_Devices_Connected, VT_BOOL}, + {L"System.Devices.GlyphIcon", &PKEY_Devices_GlyphIcon, VT_LPWSTR}, +}; + +static HRESULT propdesc_from_system_property( const struct system_property_description *desc, IPropertyDescription **out ) { struct property_description *impl;
- impl = calloc(1, sizeof( *impl )); + impl = calloc(1, offsetof( struct property_description, canonical_name[wcslen(desc->canonical_name)] )); if (!impl) return E_OUTOFMEMORY;
impl->IPropertyDescription_iface.lpVtbl = &property_description_vtbl; + impl->key = *desc->key; + wcscpy( impl->canonical_name, desc->canonical_name ); + impl->type = desc->type; + impl->type_flags = PDTF_ISINNATE; + if (impl->type & VT_VECTOR) + impl->type_flags |= PDTF_MULTIPLEVALUES; impl->ref = 1;
*out = &impl->IPropertyDescription_iface; @@ -260,10 +322,26 @@ static HRESULT propdesc_from_system_property( IPropertyDescription **out )
HRESULT propsys_get_system_propdesc_by_name( const WCHAR *name, IPropertyDescription **desc ) { - return propdesc_from_system_property( desc ); + SIZE_T i; + + for (i = 0; i < ARRAY_SIZE( system_properties ); i++) + { + if (!wcscmp( name, system_properties[i].canonical_name )) + return propdesc_from_system_property( &system_properties[i], desc ); + } + + return TYPE_E_ELEMENTNOTFOUND; }
HRESULT propsys_get_system_propdesc_by_key( const PROPERTYKEY *key, IPropertyDescription **desc ) { - return propdesc_from_system_property( desc ); + SIZE_T i; + + for (i = 0; i < ARRAY_SIZE( system_properties ); i++) + { + if (!memcmp( key, system_properties[i].key, sizeof( *key ) )) + return propdesc_from_system_property( &system_properties[i], desc ); + } + + return TYPE_E_ELEMENTNOTFOUND; } diff --git a/dlls/propsys/tests/propsys.c b/dlls/propsys/tests/propsys.c index abf8936bbd5..2334e815c6e 100644 --- a/dlls/propsys/tests/propsys.c +++ b/dlls/propsys/tests/propsys.c @@ -2996,7 +2996,8 @@ static void test_PropertySystem(void) {&PKEY_Devices_HardwareIds, L"System.Devices.HardwareIds", VT_VECTOR | VT_LPWSTR}, {&PKEY_Devices_ClassGuid, L"System.Devices.ClassGuid", VT_CLSID} }; - PROPERTYKEY empty = {0}; + GUID dummy = {0xdeadbeef, 0xdead, 0xdead, {0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef}}; + PROPERTYKEY empty = {dummy, 0xdeadbeef}; IPropertySystem *system; HRESULT hr; IPropertyDescription *desc; @@ -3021,14 +3022,14 @@ static void test_PropertySystem(void) winetest_push_context("system_props %d", (int)i);
hr = IPropertySystem_GetPropertyDescription(system, system_props[i].key, &IID_IPropertyDescription, (void **)&desc); - todo_wine ok(SUCCEEDED(hr), "got %#lx\n", hr); + ok(SUCCEEDED(hr), "got %#lx\n", hr); if (SUCCEEDED(hr)) { test_PropertyDescription(system_props[i].key, system_props[i].name, system_props[i].type, desc); IPropertyDescription_Release(desc); } hr = PSGetPropertyDescription(system_props[i].key, &IID_IPropertyDescription, (void **)&desc); - todo_wine ok(SUCCEEDED(hr), "got %#lx\n", hr); + ok(SUCCEEDED(hr), "got %#lx\n", hr); if (SUCCEEDED(hr)) { test_PropertyDescription(system_props[i].key, system_props[i].name, system_props[i].type, desc); @@ -3036,13 +3037,13 @@ static void test_PropertySystem(void) }
hr = PSGetPropertyKeyFromName(system_props[i].name, &key); - todo_wine ok(SUCCEEDED(hr), "got %#lx\n", hr); + ok(SUCCEEDED(hr), "got %#lx\n", hr); if (SUCCEEDED(hr)) ok(!memcmp(&key, system_props[i].key, sizeof(key)), "%s != %s\n", debugstr_propkey(&key), debugstr_propkey(system_props[i].key));
hr = PSGetNameFromPropertyKey(system_props[i].key, &name); - todo_wine ok(SUCCEEDED(hr), "got %#lx\n", hr); + ok(SUCCEEDED(hr), "got %#lx\n", hr); if (SUCCEEDED(hr)) { ok(!wcscmp(name, system_props[i].name), "%s != %s\n", debugstr_w(name), debugstr_w(system_props[i].name)); @@ -3050,14 +3051,14 @@ static void test_PropertySystem(void) }
hr = IPropertySystem_GetPropertyDescriptionByName(system, system_props[i].name, &IID_IPropertyDescription, (void **)&desc); - todo_wine ok(SUCCEEDED(hr), "got %#lx\n", hr); + ok(SUCCEEDED(hr), "got %#lx\n", hr); if (SUCCEEDED(hr)) { test_PropertyDescription(system_props[i].key, system_props[i].name, system_props[i].type, desc); IPropertyDescription_Release(desc); } hr = PSGetPropertyDescription(system_props[i].key, &IID_IPropertyDescription, (void **)&desc); - todo_wine ok(SUCCEEDED(hr), "got %#lx\n", hr); + ok(SUCCEEDED(hr), "got %#lx\n", hr); if (SUCCEEDED(hr)) { test_PropertyDescription(system_props[i].key, system_props[i].name, system_props[i].type, desc); @@ -3068,10 +3069,10 @@ static void test_PropertySystem(void) }
hr = IPropertySystem_GetPropertyDescription(system, &empty, &IID_IPropertyDescription, (void **)&desc); - todo_wine ok(hr == TYPE_E_ELEMENTNOTFOUND, "%#lx != %#lx\n", hr, TYPE_E_ELEMENTNOTFOUND); + ok(hr == TYPE_E_ELEMENTNOTFOUND, "%#lx != %#lx\n", hr, TYPE_E_ELEMENTNOTFOUND);
hr = IPropertySystem_GetPropertyDescriptionByName(system, L"Non.Existent.Property.Name", &IID_IPropertyDescription, (void **)&desc); - todo_wine ok(hr == TYPE_E_ELEMENTNOTFOUND, "%#lx != %#lx\n", hr, TYPE_E_ELEMENTNOTFOUND); + ok(hr == TYPE_E_ELEMENTNOTFOUND, "%#lx != %#lx\n", hr, TYPE_E_ELEMENTNOTFOUND);
IPropertySystem_Release(system); CoUninitialize();