/*
 * system property interfaces
 *
 * Copyright 2009 Maarten Lankhorst
 *
 * 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
 *
 */


import "objidl.idl";
import "oleidl.idl";
import "ocidl.idl";
import "shtypes.idl";
import "structuredquerycondition.idl";

cpp_quote("#ifndef PSSTDAPI")
cpp_quote("#define PSSTDAPI EXTERN_C DECLSPEC_IMPORT HRESULT STDAPICALLTYPE")
cpp_quote("#endif")

cpp_quote("#if 0")
typedef PROPERTYKEY *REFPROPERTYKEY;
cpp_quote("#endif")
cpp_quote("#include <propkeydef.h>")

[
    uuid(b7d14566-0509-4cce-a71f-0a554233bd9b),
    object,
    pointer_default(unique)
]
interface IInitializeWithFile : IUnknown
{
    HRESULT Initialize(
        [in,string] LPCWSTR pszFilePath,
        [in] DWORD grfMode
    );
}

[
    uuid(b824b49d-22ac-4161-ac8a-9916e8fa3f7f),
    object,
    pointer_default(unique)
]
interface IInitializeWithStream : IUnknown
{
    [local] HRESULT Initialize(
        [in] IStream *pstream,
        [in] DWORD grfMode
    );
}

[
    uuid(886d8eeb-8cf2-4446-8d02-cdba1dbdcf99),
    object,
    pointer_default(unique)
]
interface IPropertyStore : IUnknown
{
    HRESULT GetCount(
        [out] DWORD *cProps
    );
    HRESULT GetAt(
        [in] DWORD iProp,
        [out] PROPERTYKEY *pkey
    );
    HRESULT GetValue(
        [in] REFPROPERTYKEY key,
        [out] PROPVARIANT *pv
    );
    HRESULT SetValue(
        [in] REFPROPERTYKEY key,
        [in] REFPROPVARIANT propvar
    );
    HRESULT Commit(void);
}

typedef IPropertyStore *LPPROPERTYSTORE;

[
    uuid(71604b0f-97b0-4764-8577-2f13e98a1422),
    object,
    pointer_default(unique)
]
interface INamedPropertyStore : IUnknown
{
    HRESULT GetNamedValue(
        [in,string] LPCWSTR pszName,
        [out] PROPVARIANT *ppropvar
    );
    HRESULT SetNamedValue(
        [in,string] LPCWSTR pszName,
        [in] REFPROPVARIANT propvar
    );
    HRESULT GetNameCount(
        [out] DWORD *pdwCount
    );
    HRESULT GetNameAt(
        [in] DWORD iProp,
        [out] BSTR *pbstrName
    );
}

typedef [v1_enum] enum GETPROPERTYSTOREFLAGS
{
    GPS_DEFAULT = 0x00,
    GPS_HANDLERPROPERTIESONLY = 0x01,
    GPS_READWRITE = 0x02,
    GPS_TEMPORARY = 0x04,
    GPS_FASTPROPERTIESONLY = 0x08,
    GPS_OPENSLOWITEM = 0x10,
    GPS_DELAYCREATION = 0x20,
    GPS_BESTEFFORT = 0x40,
    GPS_NO_OPLOCK = 0x80,
    GPS_MASK_VALID = 0xff
} GETPROPERTYSTOREFLAGS;

cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(GETPROPERTYSTOREFLAGS)")

[
    uuid(fc0ca0a7-c316-4fd2-9031-3e628e6d4f23),
    object
]
interface IObjectWithPropertyKey : IUnknown
{
    HRESULT SetPropertyKey(
        [in] REFPROPERTYKEY key
    );
    HRESULT GetPropertyKey(
        [out] PROPERTYKEY *key
    );
}

typedef [v1_enum] enum PKA_FLAGS
{
    PKA_SET,
    PKA_APPEND,
    PKA_DELETE
} PKA_FLAGS;

[
    uuid(f917bc8a-1bba-4478-a245-1bde03eb9431),
    object,
    pointer_default(unique)
]
interface IPropertyChange : IObjectWithPropertyKey
{
    HRESULT ApplyToPropVariant([in] REFPROPVARIANT propvarin, [out] PROPVARIANT *propvarout);
}

[
    uuid(380f5cad-1b5e-42f2-805d-637fd392d31e),
    object,
    pointer_default(unique)
]
interface IPropertyChangeArray : IUnknown
{
    HRESULT GetCount(
        [out] UINT *pcOperations
    );
    HRESULT GetAt(
        [in] UINT iIndex,
        [in] REFIID riid,
        [out, iid_is(riid)] void **ppv
    );
    HRESULT InsertAt(
        [in] UINT iIndex,
        [in] IPropertyChange *ppropChange
    );
    HRESULT Append(
        [in] IPropertyChange *ppropChange
    );
    HRESULT AppendOrReplace(
        [in] IPropertyChange *ppropChange
    );
    HRESULT RemoveAt(
        [in] UINT iIndex
    );
    HRESULT IsKeyInArray(
        [in] REFPROPERTYKEY key
    );
}

[
    uuid(c8e2d566-186e-4d49-bf41-6909ead56acc),
    object,
    pointer_default(unique)
]
interface IPropertyStoreCapabilities : IUnknown
{
    HRESULT IsPropertyWritable(
        [in] REFPROPERTYKEY key
    );
}

[
    uuid(3017056d-9a91-4e90-937d-746c72abbf4f),
    object,
    pointer_default(unique)
]
interface IPropertyStoreCache : IPropertyStore
{
    typedef [v1_enum] enum PSC_STATE
    {
        PSC_NORMAL = 0,
        PSC_NOTINSOURCE,
        PSC_DIRTY,
        PSC_READONLY
    } PSC_STATE;

    HRESULT GetState(
        [in] REFPROPERTYKEY key,
        [out] PSC_STATE *pstate
    );
    HRESULT GetValueAndState(
        [in] REFPROPERTYKEY key,
        [out] PROPVARIANT *ppropvar,
        [out] PSC_STATE *pstate
    );
    HRESULT SetState(
        [in] REFPROPERTYKEY key,
        [in] PSC_STATE pstate
    );
    HRESULT SetValueAndState(
        [in] REFPROPERTYKEY key,
        [in, unique] const PROPVARIANT *ppropvar,
        [in] PSC_STATE state
    );
}

[
    uuid(11e1fbf9-2d56-4a6b-8db3-7cd193a471f2),
    object,
    pointer_default(unique)
]
interface IPropertyEnumType : IUnknown
{
    typedef [v1_enum] enum PROPENUMTYPE
    {
        PET_DISCRETEVALUE = 0,
        PET_RANGEDVALUE,
        PET_DEFAULTVALUE,
        PET_ENDRANGE
    } PROPENUMTYPE;

    HRESULT GetEnumType(
        [out] PROPENUMTYPE *penumtype
    );
    HRESULT GetValue(
        [out] PROPVARIANT *ppropvar
    );
    HRESULT GetRangeMinValue(
        [out] PROPVARIANT *ppropvar
    );
    HRESULT GetRangeSetValue(
        [out] PROPVARIANT *ppropvar
    );
    HRESULT GetDisplayText(
        [out] LPWSTR *ppszDisplay
    );
}

[
    uuid(9b6e051c-5ddd-4321-9070-fe2acb55e974),
    object,
    pointer_default(unique)
]
interface IPropertyEnumType2 : IPropertyEnumType
{
    HRESULT GetImageReference(
        [out] LPWSTR *ppszImageRes
    );
}

[
    uuid(a99400f4-3d84-4557-94ba-1242fb2cc9a6),
    object,
    pointer_default(unique)
]
interface IPropertyEnumTypeList : IUnknown
{
    HRESULT GetCount(
        [out] UINT *pctypes
    );
    HRESULT GetAt(
        [in] UINT itype,
        [in] REFIID riid,
        [out, iid_is(riid)] void **ppv
    );
    HRESULT GetConditionAt(
        [in] UINT nIndex,
        [in] REFIID riid,
        [out, iid_is(riid)] void **ppv
    );
    HRESULT FindMatchingIndex(
        [in] REFPROPVARIANT propvarCmp,
        [out] UINT *pnIndex
    );
}

[
    uuid(6f79d558-3e96-4549-a1d1-7d75d2288814),
    object,
    pointer_default(unique)
]
interface IPropertyDescription : IUnknown
{
    typedef [v1_enum] enum PROPDESC_TYPE_FLAGS
    {
        PDTF_DEFAULT = 0,
        PDTF_MULTIPLEVALUES = 0x001,
        PDTF_ISINNATE = 0x002,
        PDTF_ISGROUP = 0x004,
        PDTF_CANGROUPBY = 0x008,
        PDTF_CANSTACKBY = 0x010,
        PDTF_ISTREEPROPERTY = 0x020,
        PDTF_INCLUDEINFULLTEXTQUERY = 0x040,
        PDTF_ISVIEWABLE = 0x080,
        PDTF_ISQUERYABLE = 0x100,
        PDTF_CANBEPURGED = 0x200,
        PDTF_SEARCHRAWVALUE = 0x400,
        PDTF_ISSYSTEMPROPERTY = 0x80000000,
        PDTF_MASK_ALL = 0x800007ff
    } PROPDESC_TYPE_FLAGS;
    cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(PROPDESC_TYPE_FLAGS)")

    typedef [v1_enum] enum PROPDESC_VIEW_FLAGS
    {
        PDVF_DEFAULT = 0x0000,
        PDVF_CENTERALIGN = 0x0001,
        PDVF_RIGHTALIGN = 0x0002,
        PDVF_BEGINNEWGROUP = 0x0004,
        PDVF_FILLAREA = 0x0008,
        PDVF_SORTDESCENDING = 0x0010,
        PDVF_SHOWONLYIFPRESENT = 0x0020,
        PDVF_SHOWBYDEFAULT = 0x0040,
        PDVF_SHOWINPRIMARYLIST = 0x0080,
        PDVF_SHOWINSECONDARYLIST = 0x0100,
        PDVF_HIDELABEL = 0x0200,
        PDVF_HIDDEN = 0x0800,
        PDVF_CANWRAP = 0x1000,
        PDVF_MASK_ALL = 0x1bff
    } PROPDESC_VIEW_FLAGS;
    cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(PROPDESC_VIEW_FLAGS)")

    typedef [v1_enum] enum PROPDESC_DISPLAYTYPE
    {
        PDDT_STRING = 0,
        PDDT_NUMBER,
        PDDT_BOOLEAN,
        PDDT_DATETIME,
        PDDT_ENUMERATED
    } PROPDESC_DISPLAYTYPE;

    typedef [v1_enum] enum PROPDESC_GROUPING_RANGE
    {
        PDGR_DISCRETE = 0,
        PDGR_ALPHANUMERIC,
        PDGR_SIZE,
        PDGR_DYNAMIC,
        PDGR_DATE,
        PDGR_PERCENT,
        PDGR_ENUMERATED
    } PROPDESC_GROUPING_RANGE;

    typedef [v1_enum] enum PROPDESC_FORMAT_FLAGS
    {
        PDFF_DEFAULT = 0x0000,
        PDFF_PREFIXNAME = 0x0001,
        PDFF_FILENAME = 0x0002,
        PDFF_ALWAYSKB = 0x0004,
        PDFF_RESERVED_RIGHTTOLEFT = 0x0008,
        PDFF_SHORTTIME = 0x0010,
        PDFF_LONGTIME = 0x0020,
        PDFF_HIDETIME = 0x0040,
        PDFF_SHORTDATE = 0x0080,
        PDFF_LONGDATE = 0x0100,
        PDFF_HIDEDATE = 0x0200,
        PDFF_RELATIVEDATE = 0x0400,
        PDFF_USEEDITINVITATION = 0x0800,
        PDFF_READONLY = 0x1000,
        PDFF_NOAUTOREADINGORDER = 0x2000
    } PROPDESC_FORMAT_FLAGS;
    cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(PROPDESC_FORMAT_FLAGS)")

    typedef [v1_enum] enum PROPDESC_SORTDESCRIPTION
    {
        PDSD_GENERAL = 0,
        PDSD_A_Z,
        PDSD_LOWEST_HIGHEST,
        PDSD_SMALLEST_BIGGEST,
        PDSD_OLDEST_NEWEST
    } PROPDESC_SORTDESCRIPTION;

    typedef [v1_enum] enum PROPDESC_RELATIVEDESCRIPTION_TYPE
    {
        PDRDT_GENERAL = 0,
        PDRDT_DATE,
        PDRDT_SIZE,
        PDRDT_COUNT,
        PDRDT_REVISION,
        PDRDT_LENGTH,
        PDRDT_DURATION,
        PDRDT_SPEED,
        PDRDT_RATE,
        PDRDT_RATING,
        PDRDT_PRIORITY
    } PROPDESC_RELATIVEDESCRIPTION_TYPE;

    typedef [v1_enum] enum PROPDESC_AGGREGATION_TYPE
    {
        PDAT_DEFAULT = 0,
        PDAT_FIRST,
        PDAT_SUM,
        PDAT_AVERAGE,
        PDAT_DATERANGE,
        PDAT_UNION,
        PDAT_MAX,
        PDAT_MIN
    } PROPDESC_AGGREGATION_TYPE;

    typedef [v1_enum] enum PROPDESC_CONDITION_TYPE
    {
        PDCOT_NONE = 0,
        PDCOT_STRING,
        PDCOT_SIZE,
        PDCOT_DATETIME,
        PDCOT_BOOLEAN,
        PDCOT_NUMBER
    } PROPDESC_CONDITION_TYPE;

    HRESULT GetPropertyKey(
        [out] PROPERTYKEY *pkey
    );
    HRESULT GetCanonicalName(
        [out, string] LPWSTR *ppszName
    );
    HRESULT GetPropertyType(
        [out] VARTYPE *pvartype
    );
    HRESULT GetDisplayName(
        [out, string] LPWSTR *ppszName
    );
    HRESULT GetEditInvitation(
        [out, string] LPWSTR *ppszName
    );
    HRESULT GetTypeFlags(
        [in] PROPDESC_TYPE_FLAGS mask,
        [out] PROPDESC_TYPE_FLAGS *ppdtFlags
    );
    HRESULT GetViewFlags(
        [out] PROPDESC_VIEW_FLAGS *ppdvFlags
    );
    HRESULT GetDefaultColumnWidth(
        [out] UINT *pcxChars
    );
    HRESULT GetDisplayType(
        [out] PROPDESC_DISPLAYTYPE *pdisplaytype
    );
    HRESULT GetColumnState(
        [out] SHCOLSTATEF *pcsFlags
    );
    HRESULT GetGroupingRange(
        [out] PROPDESC_GROUPING_RANGE *psd
    );
    HRESULT GetRelativeDescriptionType(
        [out] PROPDESC_RELATIVEDESCRIPTION_TYPE *prdt
    );
    HRESULT GetRelativeDescription(
        [in] REFPROPVARIANT propvar1,
        [in] REFPROPVARIANT propvar2,
        [out,string] LPWSTR *ppszDesc1,
        [out,string] LPWSTR *ppszDesc2
    );
    HRESULT GetSortDescription(
        [out] PROPDESC_SORTDESCRIPTION *psd
    );
    HRESULT GetSortDescriptionLabel(
        [in] BOOL fDescending,
        [out,string] LPWSTR *ppszDescription
    );
    HRESULT GetAggregationType(
        [out] PROPDESC_AGGREGATION_TYPE *paggtype
    );
    HRESULT GetConditionType(
        [out] PROPDESC_CONDITION_TYPE *pcontype,
        [out] CONDITION_OPERATION *popDefault
    );
    HRESULT GetEnumTypeList(
        [in] REFIID riid,
        [out,iid_is(riid)] void **ppv
    );
    [local] HRESULT CoerceToCanonicalValue(
        [in,out] PROPVARIANT *propvar
    );
    [call_as(CoerceToCanonicalValue)] HRESULT RemoteCoerceToCanonicalValue(
        [in] REFPROPVARIANT propvar,
        [out] PROPVARIANT *ppropvar
    );
    HRESULT FormatForDisplay(
        [in] REFPROPVARIANT propvar,
        [in] PROPDESC_FORMAT_FLAGS flags,
        [out,string] LPWSTR *ppszDisplay
    );
    HRESULT IsValueCanonical(
        [in] REFPROPVARIANT propvar
    );
}

[
    uuid(57d2eded-5062-400e-b107-5dae79fe57a6),
    object,
    pointer_default(unique)
]
interface IPropertyDescription2 : IPropertyDescription
{
    HRESULT GetImageReferenceForValue(
        [in] REFPROPVARIANT propvar,
        [out,string] LPWSTR *ppszImageRes
    );
}

[
    uuid(f67104fc-2af9-46fd-b32d-243c1404f3d1),
    object,
    pointer_default(unique)
]
interface IPropertyDescriptionAliasInfo : IPropertyDescription
{
    HRESULT GetSortByAlias(
        [in] REFIID riid,
        [out,iid_is(riid)] void **ppv
    );
    HRESULT GetAdditionalSortByAliases(
        [in] REFIID riid,
        [out,iid_is(riid)] void **ppv
    );
}

[
    uuid(078f91bd-29a2-440f-924e-46a291524520),
    object,
    pointer_default(unique)
]
interface IPropertyDescriptionSearchInfo : IPropertyDescription
{
    typedef [v1_enum] enum PROPDESC_SEARCHINFO_FLAGS
    {
        PDSIF_DEFAULT = 0x0,
        PDSIF_ININVERTEDINDEX = 0x1,
        PDSIF_ISCOLUMN = 0x2,
        PDSIF_ISCOLUMNSPARSE = 0x4,
        PDSIF_ALWAYSINCLUDE = 0x8,
    } PROPDESC_SEARCHINFO_FLAGS;
    cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(PROPDESC_SEARCHINFO_FLAGS)")

    typedef [v1_enum] enum PROPDESC_COLUMNINDEX_TYPE
    {
        PDCIT_NONE = 0,
        PDCIT_ONDISK,
        PDCIT_INMEMORY,
        PDCIT_ONDEMAND,
        PDCIT_ONDISKALL,
        PDCIT_ONDISKVECTOR
    } PROPDESC_COLUMNINDEX_TYPE;

    HRESULT GetSearchInfoFlags(
        [out] PROPDESC_SEARCHINFO_FLAGS *ppdsiFlags
    );
    HRESULT GetColumnIndexType(
        [out] PROPDESC_COLUMNINDEX_TYPE *ppdciType
    );
    HRESULT GetProjectionString(
        [out] LPWSTR *ppszProjection
    );
    HRESULT GetMaxSize(
        [out] UINT *pcbMaxSize
    );
}

[
    uuid(507393f4-2a3d-4a60-b59e-d9c75716c2dd),
    object,
    pointer_default(unique)
]
interface IPropertyDescriptionRelatedPropertyInfo : IPropertyDescription
{
    HRESULT GetRelatedProperty(
        [in] LPCWSTR ppszRelationshipName,
        [in] REFIID riid,
        [out,iid_is(riid)] void **ppv
    );
}

typedef [v1_enum] enum PROPDESC_ENUMFILTER
{
    PDEF_ALL = 0,
    PDEF_SYSTEM,
    PDEF_NONSYSTEM,
    PDEF_VIEWABLE,
    PDEF_QUERYABLE,
    PDEF_INFULLTEXTQUERY,
    PDEF_COLUMN
} PROPDESC_ENUMFILTER;

[
    uuid(ca724e8a-c3e6-442b-88a4-6fb0db8035a3),
    object,
    pointer_default(unique)
]
interface IPropertySystem : IUnknown
{
    HRESULT GetPropertyDescription(
        [in] REFPROPERTYKEY propkey,
        [in] REFIID riid,
        [out,iid_is(riid)] void **ppv
    );
    HRESULT GetPropertyDescriptionByName(
        [in,string] LPCWSTR pszCanonicalName,
        [in] REFIID riid,
        [out,iid_is(riid)] void **ppv
    );
    HRESULT GetPropertyDescriptionListFromString(
        [in,string] LPCWSTR pszPropList,
        [in] REFIID riid,
        [out,iid_is(riid)] void **ppv
    );
    HRESULT EnumeratePropertyDescriptions(
        [in] PROPDESC_ENUMFILTER filterOn,
        [in] REFIID riid,
        [out,iid_is(riid)] void **ppv
    );
    HRESULT FormatForDisplay(
        [in] REFPROPERTYKEY key,
        [in] REFPROPVARIANT propvar,
        [in] PROPDESC_FORMAT_FLAGS pdff,
        [out,string,size_is(cchText)] LPWSTR pszText,
        [in] DWORD cchText
    );
    HRESULT FormatForDisplayAlloc(
        [in] REFPROPERTYKEY key,
        [in] REFPROPVARIANT propvar,
        [in] PROPDESC_FORMAT_FLAGS pdff,
        [out,string] LPWSTR *pszText
    );
    HRESULT RegisterPropertySchema(
        [in,string] LPCWSTR pszPath
    );
    HRESULT UnregisterPropertySchema(
        [in,string] LPCWSTR pszPath
    );
    HRESULT RefreshPropertySchema(void);
}

[
    uuid(1f9fc1d0-c39b-4b26-817f-011967d3440e),
    object,
    pointer_default(unique)
]
interface IPropertyDescriptionList : IUnknown
{
    HRESULT GetCount(
        [out] UINT *pcelem
    );
    HRESULT GetAt(
        [in] UINT iElem,
        [in] REFIID riid,
        [out,iid_is(riid)] void **ppv
    );
}

[
    uuid(bc110b6d-57e8-4148-a9c6-91015ab2f3a5),
    object,
    pointer_default(unique)
]
interface IPropertyStoreFactory : IUnknown
{
    HRESULT GetPropertyStore(
        [in] GETPROPERTYSTOREFLAGS flags,
        [in,unique] IUnknown *pUnkFactory,
        [in] REFIID riid,
        [out,iid_is(riid)] void **ppv
    );
    HRESULT GetPropertyStoreForKeys(
        [in,unique] const PROPERTYKEY *rgKeys,
        [in] UINT cKeys,
        [in] GETPROPERTYSTOREFLAGS flags,
        [in] REFIID riid,
        [out,iid_is(riid)] void **ppv
    );
}

[
    uuid(40d4577f-e237-4bdb-bd69-58f089431b6a),
    object,
    pointer_default(unique)
]
interface IDelayedPropertyStoreFactory : IPropertyStoreFactory
{
    HRESULT GetDelayedPropertyStore(
        [in] GETPROPERTYSTOREFLAGS flags,
        [in] DWORD dwStoreId,
        [in] REFIID riid,
        [out,iid_is(riid)] void **ppv
    );
}

[v1_enum] enum _PERSIST_SPROPSTORE_FLAGS
{
    FPSPS_DEFAULT = 0,
    FPSPS_READONLY = 1
};
typedef int PERSIST_SPROPSTORE_FLAGS;

typedef struct tagSERIALIZEDROPSTORAGE SERIALIZEDPROPSTORAGE;

cpp_quote("#if 0") /* Wine doesn't have __unaligned builtin, hack */
typedef SERIALIZEDPROPSTORAGE *PUSERIALIZEDPROPSTORAGE;
typedef const SERIALIZEDPROPSTORAGE *PCUSERIALIZEDPROPSTORAGE;
cpp_quote("#endif")
cpp_quote("typedef SERIALIZEDPROPSTORAGE UNALIGNED *PUSERIALIZEDPROPSTORAGE;")
cpp_quote("typedef const SERIALIZEDPROPSTORAGE UNALIGNED *PCUSERIALIZEDPROPSTORAGE;")

[
    uuid(e318ad57-0aa0-450f-aca5-6fab7103d917),
    pointer_default(unique),
    local
]
interface IPersistSerializedPropStorage : IUnknown
{
    HRESULT SetFlags(
        [in] PERSIST_SPROPSTORE_FLAGS flags
    );
    HRESULT SetPropertyStorage(
        [in] PCUSERIALIZEDPROPSTORAGE psps,
        [in] DWORD cb
    );
    HRESULT GetPropertyStorage(
        [out] SERIALIZEDPROPSTORAGE **psps,
        [out] DWORD *pcb
    );
}

[
    uuid(77effa68-4f98-4366-ba72-573b3d880571),
    pointer_default(unique),
    local
]
interface IPersistSerializedPropStorage2 : IPersistSerializedPropStorage
{
    HRESULT GetpropertyStorageSize(
        [out] DWORD *pcb
    );
    HRESULT GetPropertyStorageBuffer(
        [out] SERIALIZEDPROPSTORAGE *psps,
        [in] DWORD cb,
        [out] DWORD *pcbWritten
    );
}

[
    uuid(fa955fd9-38be-4879-a6ce-824cf52d609f),
    object,
    pointer_default(unique)
]
interface IPropertySystemChangeNotify : IUnknown
{
    HRESULT SchemaRefreshed(void);
}

/* Interface for CoCreateInstance? */
[
    uuid(75121952-e0d0-43e5-9380-1d80483acf72),
    pointer_default(unique)
]
interface ICreateObject : IUnknown
{
    HRESULT CreateObject(
        [in] REFCLSID clsid,
        [in,unique] IUnknown *pUnkOuter,
        [in] REFIID riid,
        [out,iid_is(riid)] void **ppv
    );
}

cpp_quote("#define PKEY_PIDSTR_MAX 10")
cpp_quote("#define GUIDSTRING_MAX 39")
cpp_quote("#define PKEYSTR_MAX (GUIDSTRING_MAX + 1 + PKEY_PIDSTR_MAX)")

cpp_quote("HRESULT WINAPI PSCreateMemoryPropertyStore(REFIID,void **);")
cpp_quote("HRESULT WINAPI PSCreatePropertyStoreFromObject(IUnknown*,DWORD,REFIID,void **);")
cpp_quote("HRESULT WINAPI PSStringFromPropertyKey(REFPROPERTYKEY,LPWSTR,UINT);")
cpp_quote("HRESULT WINAPI PSPropertyKeyFromString(LPCWSTR,PROPERTYKEY*);")
cpp_quote("HRESULT WINAPI PSGetPropertyDescription(REFPROPERTYKEY,REFIID,void **);")
cpp_quote("HRESULT WINAPI PSGetPropertyDescriptionListFromString(LPCWSTR,REFIID,void **);")
cpp_quote("HRESULT WINAPI PSRefreshPropertySchema(void);")
cpp_quote("HRESULT WINAPI PSRegisterPropertySchema(LPCWSTR);")
cpp_quote("HRESULT WINAPI PSUnregisterPropertySchema(LPCWSTR);")

/* TODO: Add remainder of the C api here */

[
    uuid(2cda3294-6c4f-4020-b161-27c530c81fa6),
    lcid(0x0000),
    version(1.0)
]
library PropSysObjects
{
    [uuid(9a02e012-6303-4e1e-b9a1-630f802592c5)] coclass InMemoryPropertyStore
    {
        interface IPropertyStore;
    }
    [uuid(b8967f86-58ae-4f96-9fb2-5d7904798f4b)] coclass PropertySystem
    {
        interface IPropertySystem;
    }
}