[PATCH v2 06/15] propsys: Implement named properties on the in-memory property store

Nikolay Sivov bunglehead at gmail.com
Sat Jul 18 12:06:07 CDT 2015


On 18.07.2015 19:26, Jonas Kümmerlin wrote:
> The in-memory property store now supports INamedPropertyStore.
> ---
>   dlls/propsys/propstore.c         | 275 ++++++++++++++++++++++++++++++++++++---
>   dlls/propsys/propsys_classes.idl |   5 +-
>   dlls/propsys/tests/propstore.c   |  72 ++++++++++
>   3 files changed, 336 insertions(+), 16 deletions(-)
>
> diff --git a/dlls/propsys/propstore.c b/dlls/propsys/propstore.c
> index 9c848fc..3f028e9 100644
> --- a/dlls/propsys/propstore.c
> +++ b/dlls/propsys/propstore.c
> @@ -28,6 +28,7 @@
>   #include "objbase.h"
>   #include "rpcproxy.h"
>   #include "propsys.h"
> +#include "propvarutil.h"
>   #include "wine/debug.h"
>   #include "wine/unicode.h"
>   #include "wine/list.h"
> @@ -53,11 +54,20 @@ typedef struct {
>       DWORD count;
>   } propstore_format;
>
> +/* FIXME: We should really do something clever, like using a hashtable */
> +typedef struct {
> +    struct list entry;
> +    PROPVARIANT propvar;
> +    WCHAR name[1];
> +} propstore_named_value;
> +
>   typedef struct {
>       IPropertyStoreCache IPropertyStoreCache_iface;
> +    INamedPropertyStore INamedPropertyStore_iface;
>       LONG ref;
>       CRITICAL_SECTION lock;
>       struct list formats; /* list of struct propstore_format */
> +    struct list named; /* list of struct propstore_named_value */
>   } PropertyStore;
>
>   static inline PropertyStore *impl_from_IPropertyStoreCache(IPropertyStoreCache *iface)
> @@ -65,12 +75,13 @@ static inline PropertyStore *impl_from_IPropertyStoreCache(IPropertyStoreCache *
>       return CONTAINING_RECORD(iface, PropertyStore, IPropertyStoreCache_iface);
>   }
>
> -static HRESULT WINAPI PropertyStore_QueryInterface(IPropertyStoreCache *iface, REFIID iid,
> -    void **ppv)
> +static inline PropertyStore *impl_from_INamedPropertyStore(INamedPropertyStore *iface)
>   {
> -    PropertyStore *This = impl_from_IPropertyStoreCache(iface);
> -    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
> +    return CONTAINING_RECORD(iface, PropertyStore, INamedPropertyStore_iface);
> +}
>
> +static HRESULT query_interface(PropertyStore *This, REFIID iid, void **ppv)
> +{
>       if (!ppv) return E_INVALIDARG;
>
>       if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IPropertyStore, iid) ||
> @@ -78,6 +89,10 @@ static HRESULT WINAPI PropertyStore_QueryInterface(IPropertyStoreCache *iface, R
>       {
>           *ppv = &This->IPropertyStoreCache_iface;
>       }
> +    else if (IsEqualIID(&IID_INamedPropertyStore, iid))
> +    {
> +        *ppv = &This->INamedPropertyStore_iface;
> +    }
>       else
>       {
>           FIXME("No interface for %s\n", debugstr_guid(iid));
> @@ -89,10 +104,45 @@ static HRESULT WINAPI PropertyStore_QueryInterface(IPropertyStoreCache *iface, R
>       return S_OK;
>   }
>
> -static ULONG WINAPI PropertyStore_AddRef(IPropertyStoreCache *iface)
> +static HRESULT WINAPI PropertyStore_IPropertyStoreCache_QueryInterface(
> +    IPropertyStoreCache *iface, REFIID iid, void **ppv)
> +{
> +    PropertyStore *This = impl_from_IPropertyStoreCache(iface);
> +
> +    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
> +
> +    return query_interface(This, iid, ppv);
> +}
> +

We usually do it differently, keeping IUnknown methods implementations 
in one of interfaces object implements. After that the rest of 
interfaces use proper impl_from_* and forward to that "main" interface 
using "*_QueryInterface(&This->IPropertyStoreCache_iface, iid, ppv);" way.

I also suggest to change function naming, for existing 
IPropertyStoreCache methods to PropertyStoreCache_*, for new one to 
NamedPropertyStore_*.


>
> -static const IPropertyStoreCacheVtbl PropertyStore_Vtbl = {
> -    PropertyStore_QueryInterface,
> -    PropertyStore_AddRef,
> -    PropertyStore_Release,
> +static const IPropertyStoreCacheVtbl PropertyStore_IPropertyStoreCache_Vtbl = {
> +    PropertyStore_IPropertyStoreCache_QueryInterface,
> +    PropertyStore_IPropertyStoreCache_AddRef,
> +    PropertyStore_IPropertyStoreCache_Release,
>       PropertyStore_GetCount,
>       PropertyStore_GetAt,
>       PropertyStore_GetValue,
> @@ -450,6 +683,16 @@ static const IPropertyStoreCacheVtbl PropertyStore_Vtbl = {
>       PropertyStore_SetValueAndState
>   };
>
> +static const INamedPropertyStoreVtbl PropertyStore_INamedPropertyStore_Vtbl = {
> +    PropertyStore_INamedPropertyStore_QueryInterface,
> +    PropertyStore_INamedPropertyStore_AddRef,
> +    PropertyStore_INamedPropertyStore_Release,
> +    PropertyStore_GetNamedValue,
> +    PropertyStore_SetNamedValue,
> +    PropertyStore_GetNameCount,
> +    PropertyStore_GetNameAt
> +};

This name change will also make vtables look nicer.

> +

>
> +static void test_namedpropertystore(void)
> +{
> +    IPropertyStore *propstore;
> +    INamedPropertyStore *named;
> +    HRESULT hr;
> +    PROPVARIANT propvar;
> +    const WCHAR wcsJava[] = { 'J', 'a', 'v', 'a', 0 };
> +    const WCHAR wcsBlub[] = { 'B', 'l', 'u', 'b', 0 };
> +    DWORD count;
> +    BSTR name;
> +
> +    hr = CoCreateInstance(&CLSID_InMemoryPropertyStore, NULL, CLSCTX_INPROC_SERVER,
> +        &IID_IPropertyStore, (void**)&propstore);
> +    ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr);
> +
> +    hr = IPropertyStore_QueryInterface(propstore, &IID_INamedPropertyStore,
> +        (void**)&named);
> +    ok(hr == S_OK, "QueryInterface failed, hr=%x\n", hr);
> +
> +    if (FAILED(hr))
> +    {
> +        skip("IPersistSerializedPropStorage not supported\n");
> +        return;
> +    }

If it works in win2000 you don't need to skip, if it's a newer addition 
you should use win_skip().





More information about the wine-devel mailing list