From: Vibhav Pant vibhavp@gmail.com
--- dlls/propsys/propsys_classes.idl | 6 ++ dlls/propsys/propsys_main.c | 107 +++++++++++++++++++++++++++---- dlls/propsys/propsys_private.h | 7 ++ dlls/propsys/tests/propsys.c | 5 +- 4 files changed, 110 insertions(+), 15 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..407fde90482 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,24 +171,33 @@ 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; }
@@ -199,11 +260,9 @@ 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) @@ -216,14 +275,22 @@ HRESULT WINAPI PSRegisterPropertySchema(PCWSTR path) HRESULT WINAPI PSUnregisterPropertySchema(PCWSTR path) { FIXME("%s stub\n", debugstr_w(path)); - return E_NOTIMPL; }
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) @@ -234,8 +301,24 @@ HRESULT WINAPI PSGetPropertyDescriptionListFromString(LPCWSTR proplist, REFIID r
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) 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 8224249d6df..25d7c984281 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);
@@ -3003,11 +3002,11 @@ static void test_PropertySystem(void) SIZE_T i;
hr = PSGetPropertySystem(&IID_IPropertySystem, (void **)&system); - todo_wine ok(hr == CO_E_NOTINITIALIZED, "got %#lx != %#lx", hr, CO_E_NOTINITIALIZED); + ok(hr == CO_E_NOTINITIALIZED, "got %#lx != %#lx", hr, CO_E_NOTINITIALIZED);
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");