12bde8e466a4451c7319e3a072d118917957d6554Steve Block/*
22bde8e466a4451c7319e3a072d118917957d6554Steve Block * Copyright (C) 2008 Apple Inc. All Rights Reserved.
32bde8e466a4451c7319e3a072d118917957d6554Steve Block *
42bde8e466a4451c7319e3a072d118917957d6554Steve Block * Redistribution and use in source and binary forms, with or without
52bde8e466a4451c7319e3a072d118917957d6554Steve Block * modification, are permitted provided that the following conditions
62bde8e466a4451c7319e3a072d118917957d6554Steve Block * are met:
72bde8e466a4451c7319e3a072d118917957d6554Steve Block * 1. Redistributions of source code must retain the above copyright
82bde8e466a4451c7319e3a072d118917957d6554Steve Block *    notice, this list of conditions and the following disclaimer.
92bde8e466a4451c7319e3a072d118917957d6554Steve Block * 2. Redistributions in binary form must reproduce the above copyright
102bde8e466a4451c7319e3a072d118917957d6554Steve Block *    notice, this list of conditions and the following disclaimer in the
112bde8e466a4451c7319e3a072d118917957d6554Steve Block *    documentation and/or other materials provided with the distribution.
122bde8e466a4451c7319e3a072d118917957d6554Steve Block *
132bde8e466a4451c7319e3a072d118917957d6554Steve Block * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
142bde8e466a4451c7319e3a072d118917957d6554Steve Block * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
152bde8e466a4451c7319e3a072d118917957d6554Steve Block * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
162bde8e466a4451c7319e3a072d118917957d6554Steve Block * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
172bde8e466a4451c7319e3a072d118917957d6554Steve Block * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
182bde8e466a4451c7319e3a072d118917957d6554Steve Block * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
192bde8e466a4451c7319e3a072d118917957d6554Steve Block * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
202bde8e466a4451c7319e3a072d118917957d6554Steve Block * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
212bde8e466a4451c7319e3a072d118917957d6554Steve Block * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
222bde8e466a4451c7319e3a072d118917957d6554Steve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
232bde8e466a4451c7319e3a072d118917957d6554Steve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
242bde8e466a4451c7319e3a072d118917957d6554Steve Block */
252bde8e466a4451c7319e3a072d118917957d6554Steve Block
262bde8e466a4451c7319e3a072d118917957d6554Steve Block#ifndef COMPropertyBag_h
272bde8e466a4451c7319e3a072d118917957d6554Steve Block#define COMPropertyBag_h
282bde8e466a4451c7319e3a072d118917957d6554Steve Block
292bde8e466a4451c7319e3a072d118917957d6554Steve Block#define NOMINMAX
302bde8e466a4451c7319e3a072d118917957d6554Steve Block#include <ocidl.h>
312bde8e466a4451c7319e3a072d118917957d6554Steve Block#include <unknwn.h>
322bde8e466a4451c7319e3a072d118917957d6554Steve Block
332bde8e466a4451c7319e3a072d118917957d6554Steve Block#include <wtf/Noncopyable.h>
342bde8e466a4451c7319e3a072d118917957d6554Steve Block#include <wtf/HashMap.h>
352bde8e466a4451c7319e3a072d118917957d6554Steve Block
362bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "COMVariantSetter.h"
372bde8e466a4451c7319e3a072d118917957d6554Steve Block
382bde8e466a4451c7319e3a072d118917957d6554Steve Blocktemplate<typename ValueType, typename KeyType = typename WTF::String, typename HashType = typename WTF::StringHash>
392bde8e466a4451c7319e3a072d118917957d6554Steve Blockclass COMPropertyBag : public IPropertyBag, public IPropertyBag2 {
402bde8e466a4451c7319e3a072d118917957d6554Steve Block    WTF_MAKE_NONCOPYABLE(COMPropertyBag);
412bde8e466a4451c7319e3a072d118917957d6554Steve Blockpublic:
422bde8e466a4451c7319e3a072d118917957d6554Steve Block    typedef HashMap<KeyType, ValueType, HashType> HashMapType;
432bde8e466a4451c7319e3a072d118917957d6554Steve Block
442bde8e466a4451c7319e3a072d118917957d6554Steve Block    static COMPropertyBag* createInstance(const HashMapType&);
452bde8e466a4451c7319e3a072d118917957d6554Steve Block    static COMPropertyBag* adopt(HashMapType&);
462bde8e466a4451c7319e3a072d118917957d6554Steve Block
472bde8e466a4451c7319e3a072d118917957d6554Steve Block    // IUnknown
482bde8e466a4451c7319e3a072d118917957d6554Steve Block    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
492bde8e466a4451c7319e3a072d118917957d6554Steve Block    virtual ULONG STDMETHODCALLTYPE AddRef();
502bde8e466a4451c7319e3a072d118917957d6554Steve Block    virtual ULONG STDMETHODCALLTYPE Release();
512bde8e466a4451c7319e3a072d118917957d6554Steve Block
522bde8e466a4451c7319e3a072d118917957d6554Steve Block    // IPropertyBag
532bde8e466a4451c7319e3a072d118917957d6554Steve Block    virtual HRESULT STDMETHODCALLTYPE Read(LPCOLESTR pszPropName, VARIANT*, IErrorLog*);
542bde8e466a4451c7319e3a072d118917957d6554Steve Block    virtual HRESULT STDMETHODCALLTYPE Write(LPCOLESTR pszPropName, VARIANT*);
552bde8e466a4451c7319e3a072d118917957d6554Steve Block
562bde8e466a4451c7319e3a072d118917957d6554Steve Block    // IPropertyBag2
572bde8e466a4451c7319e3a072d118917957d6554Steve Block    virtual HRESULT STDMETHODCALLTYPE Read(ULONG cProperties, PROPBAG2*, IErrorLog*, VARIANT* pvarValue, HRESULT* phrError);
582bde8e466a4451c7319e3a072d118917957d6554Steve Block    virtual HRESULT STDMETHODCALLTYPE Write(ULONG cProperties, PROPBAG2*, VARIANT*);
592bde8e466a4451c7319e3a072d118917957d6554Steve Block    virtual HRESULT STDMETHODCALLTYPE CountProperties(ULONG* pcProperties);
602bde8e466a4451c7319e3a072d118917957d6554Steve Block    virtual HRESULT STDMETHODCALLTYPE GetPropertyInfo(ULONG iProperty, ULONG cProperties, PROPBAG2* pPropBag, ULONG* pcProperties);
612bde8e466a4451c7319e3a072d118917957d6554Steve Block    virtual HRESULT STDMETHODCALLTYPE LoadObject(LPCOLESTR pstrName, DWORD dwHint, IUnknown*, IErrorLog*);
622bde8e466a4451c7319e3a072d118917957d6554Steve Block
632bde8e466a4451c7319e3a072d118917957d6554Steve Blockprivate:
642bde8e466a4451c7319e3a072d118917957d6554Steve Block    COMPropertyBag()
652bde8e466a4451c7319e3a072d118917957d6554Steve Block        : m_refCount(0)
662bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
672bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
682bde8e466a4451c7319e3a072d118917957d6554Steve Block
692bde8e466a4451c7319e3a072d118917957d6554Steve Block    COMPropertyBag(const HashMapType& hashMap)
702bde8e466a4451c7319e3a072d118917957d6554Steve Block        : m_refCount(0)
712bde8e466a4451c7319e3a072d118917957d6554Steve Block        , m_hashMap(hashMap)
722bde8e466a4451c7319e3a072d118917957d6554Steve Block    {
732bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
742bde8e466a4451c7319e3a072d118917957d6554Steve Block
752bde8e466a4451c7319e3a072d118917957d6554Steve Block    ~COMPropertyBag() {}
762bde8e466a4451c7319e3a072d118917957d6554Steve Block
772bde8e466a4451c7319e3a072d118917957d6554Steve Block    ULONG m_refCount;
782bde8e466a4451c7319e3a072d118917957d6554Steve Block    HashMapType m_hashMap;
792bde8e466a4451c7319e3a072d118917957d6554Steve Block};
802bde8e466a4451c7319e3a072d118917957d6554Steve Block
812bde8e466a4451c7319e3a072d118917957d6554Steve Block// COMPropertyBag ------------------------------------------------------------------
822bde8e466a4451c7319e3a072d118917957d6554Steve Blocktemplate<typename ValueType, typename KeyType, typename HashType>
832bde8e466a4451c7319e3a072d118917957d6554Steve BlockCOMPropertyBag<ValueType, KeyType, HashType>* COMPropertyBag<typename ValueType, typename KeyType, HashType>::createInstance(const HashMapType& hashMap)
842bde8e466a4451c7319e3a072d118917957d6554Steve Block{
852bde8e466a4451c7319e3a072d118917957d6554Steve Block    COMPropertyBag* instance = new COMPropertyBag(hashMap);
862bde8e466a4451c7319e3a072d118917957d6554Steve Block    instance->AddRef();
872bde8e466a4451c7319e3a072d118917957d6554Steve Block    return instance;
882bde8e466a4451c7319e3a072d118917957d6554Steve Block}
892bde8e466a4451c7319e3a072d118917957d6554Steve Block
902bde8e466a4451c7319e3a072d118917957d6554Steve Blocktemplate<typename ValueType, typename KeyType, typename HashType>
912bde8e466a4451c7319e3a072d118917957d6554Steve BlockCOMPropertyBag<ValueType, KeyType, HashType>* COMPropertyBag<typename ValueType, typename KeyType, HashType>::adopt(HashMapType& hashMap)
922bde8e466a4451c7319e3a072d118917957d6554Steve Block{
932bde8e466a4451c7319e3a072d118917957d6554Steve Block    COMPropertyBag* instance = new COMPropertyBag;
942bde8e466a4451c7319e3a072d118917957d6554Steve Block    instance->m_hashMap.swap(hashMap);
952bde8e466a4451c7319e3a072d118917957d6554Steve Block    instance->AddRef();
962bde8e466a4451c7319e3a072d118917957d6554Steve Block    return instance;
972bde8e466a4451c7319e3a072d118917957d6554Steve Block}
982bde8e466a4451c7319e3a072d118917957d6554Steve Block
992bde8e466a4451c7319e3a072d118917957d6554Steve Block// IUnknown ------------------------------------------------------------------------
1002bde8e466a4451c7319e3a072d118917957d6554Steve Blocktemplate<typename ValueType, typename KeyType, typename HashType>
1012bde8e466a4451c7319e3a072d118917957d6554Steve BlockHRESULT STDMETHODCALLTYPE COMPropertyBag<ValueType, KeyType, HashType>::QueryInterface(REFIID riid, void** ppvObject)
1022bde8e466a4451c7319e3a072d118917957d6554Steve Block{
1032bde8e466a4451c7319e3a072d118917957d6554Steve Block    *ppvObject = 0;
1042bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (IsEqualGUID(riid, IID_IUnknown))
1052bde8e466a4451c7319e3a072d118917957d6554Steve Block        *ppvObject = static_cast<IPropertyBag*>(this);
1062bde8e466a4451c7319e3a072d118917957d6554Steve Block    else if (IsEqualGUID(riid, IID_IPropertyBag))
1072bde8e466a4451c7319e3a072d118917957d6554Steve Block        *ppvObject = static_cast<IPropertyBag*>(this);
1082bde8e466a4451c7319e3a072d118917957d6554Steve Block    else if (IsEqualGUID(riid, IID_IPropertyBag2))
1092bde8e466a4451c7319e3a072d118917957d6554Steve Block        *ppvObject = static_cast<IPropertyBag2*>(this);
1102bde8e466a4451c7319e3a072d118917957d6554Steve Block    else
1112bde8e466a4451c7319e3a072d118917957d6554Steve Block        return E_NOINTERFACE;
1122bde8e466a4451c7319e3a072d118917957d6554Steve Block
1132bde8e466a4451c7319e3a072d118917957d6554Steve Block    AddRef();
1142bde8e466a4451c7319e3a072d118917957d6554Steve Block    return S_OK;
1152bde8e466a4451c7319e3a072d118917957d6554Steve Block}
1162bde8e466a4451c7319e3a072d118917957d6554Steve Block
1172bde8e466a4451c7319e3a072d118917957d6554Steve Blocktemplate<typename ValueType, typename KeyType, typename HashType>
1182bde8e466a4451c7319e3a072d118917957d6554Steve BlockULONG STDMETHODCALLTYPE COMPropertyBag<ValueType, KeyType, HashType>::AddRef()
1192bde8e466a4451c7319e3a072d118917957d6554Steve Block{
1202bde8e466a4451c7319e3a072d118917957d6554Steve Block    return ++m_refCount;
1212bde8e466a4451c7319e3a072d118917957d6554Steve Block}
1222bde8e466a4451c7319e3a072d118917957d6554Steve Block
1232bde8e466a4451c7319e3a072d118917957d6554Steve Blocktemplate<typename ValueType, typename KeyType, typename HashType>
1242bde8e466a4451c7319e3a072d118917957d6554Steve BlockULONG STDMETHODCALLTYPE COMPropertyBag<ValueType, KeyType, HashType>::Release()
1252bde8e466a4451c7319e3a072d118917957d6554Steve Block{
1262bde8e466a4451c7319e3a072d118917957d6554Steve Block    ULONG newRef = --m_refCount;
1272bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!newRef)
1282bde8e466a4451c7319e3a072d118917957d6554Steve Block        delete this;
1292bde8e466a4451c7319e3a072d118917957d6554Steve Block
1302bde8e466a4451c7319e3a072d118917957d6554Steve Block    return newRef;
1312bde8e466a4451c7319e3a072d118917957d6554Steve Block}
1322bde8e466a4451c7319e3a072d118917957d6554Steve Block
1332bde8e466a4451c7319e3a072d118917957d6554Steve Block// IPropertyBag --------------------------------------------------------------------
1342bde8e466a4451c7319e3a072d118917957d6554Steve Block
1352bde8e466a4451c7319e3a072d118917957d6554Steve Blocktemplate<typename ValueType, typename KeyType, typename HashType>
1362bde8e466a4451c7319e3a072d118917957d6554Steve BlockHRESULT STDMETHODCALLTYPE COMPropertyBag<ValueType, KeyType, HashType>::Read(LPCOLESTR pszPropName, VARIANT* pVar, IErrorLog* pErrorLog)
1372bde8e466a4451c7319e3a072d118917957d6554Steve Block{
1382bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!pszPropName)
1392bde8e466a4451c7319e3a072d118917957d6554Steve Block        return E_POINTER;
1402bde8e466a4451c7319e3a072d118917957d6554Steve Block
1412bde8e466a4451c7319e3a072d118917957d6554Steve Block    HashMapType::const_iterator it = m_hashMap.find(String(pszPropName));
1422bde8e466a4451c7319e3a072d118917957d6554Steve Block    HashMapType::const_iterator end = m_hashMap.end();
1432bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (it == end)
1442bde8e466a4451c7319e3a072d118917957d6554Steve Block        return E_INVALIDARG;
1452bde8e466a4451c7319e3a072d118917957d6554Steve Block
1462bde8e466a4451c7319e3a072d118917957d6554Steve Block    VARTYPE requestedType = V_VT(pVar);
1472bde8e466a4451c7319e3a072d118917957d6554Steve Block    V_VT(pVar) = VT_EMPTY;
1482bde8e466a4451c7319e3a072d118917957d6554Steve Block    COMVariantSetter<ValueType>::setVariant(pVar, it->second);
1492bde8e466a4451c7319e3a072d118917957d6554Steve Block
1502bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (requestedType != COMVariantSetter<ValueType>::variantType(it->second) && requestedType != VT_EMPTY)
1512bde8e466a4451c7319e3a072d118917957d6554Steve Block        return ::VariantChangeType(pVar, pVar, VARIANT_NOUSEROVERRIDE | VARIANT_ALPHABOOL, requestedType);
1522bde8e466a4451c7319e3a072d118917957d6554Steve Block
1532bde8e466a4451c7319e3a072d118917957d6554Steve Block    return S_OK;
1542bde8e466a4451c7319e3a072d118917957d6554Steve Block}
1552bde8e466a4451c7319e3a072d118917957d6554Steve Block
1562bde8e466a4451c7319e3a072d118917957d6554Steve Blocktemplate<typename ValueType, typename KeyType, typename HashType>
1572bde8e466a4451c7319e3a072d118917957d6554Steve BlockHRESULT STDMETHODCALLTYPE COMPropertyBag<ValueType, KeyType, HashType>::Write(LPCOLESTR pszPropName, VARIANT* pVar)
1582bde8e466a4451c7319e3a072d118917957d6554Steve Block{
1592bde8e466a4451c7319e3a072d118917957d6554Steve Block    return E_FAIL;
1602bde8e466a4451c7319e3a072d118917957d6554Steve Block}
1612bde8e466a4451c7319e3a072d118917957d6554Steve Block
1622bde8e466a4451c7319e3a072d118917957d6554Steve Blocktemplate<typename ValueType, typename KeyType, typename HashType>
1632bde8e466a4451c7319e3a072d118917957d6554Steve BlockHRESULT STDMETHODCALLTYPE COMPropertyBag<ValueType, KeyType, HashType>::Read(ULONG cProperties, PROPBAG2* pPropBag, IErrorLog* pErrorLog, VARIANT* pvarValue, HRESULT* phrError)
1642bde8e466a4451c7319e3a072d118917957d6554Steve Block{
1652bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!pPropBag || !pvarValue || !phrError)
1662bde8e466a4451c7319e3a072d118917957d6554Steve Block        return E_POINTER;
1672bde8e466a4451c7319e3a072d118917957d6554Steve Block
1682bde8e466a4451c7319e3a072d118917957d6554Steve Block    HRESULT hr = S_OK;
1692bde8e466a4451c7319e3a072d118917957d6554Steve Block
1702bde8e466a4451c7319e3a072d118917957d6554Steve Block    for (ULONG i = 0; i < cProperties; ++i) {
1712bde8e466a4451c7319e3a072d118917957d6554Steve Block        VariantInit(&pvarValue[i]);
1722bde8e466a4451c7319e3a072d118917957d6554Steve Block        pvarValue[i].vt = pPropBag[i].vt;
1732bde8e466a4451c7319e3a072d118917957d6554Steve Block        phrError[i] = Read(pPropBag[i].pstrName, &pvarValue[i], pErrorLog);
1742bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (FAILED(phrError[i]))
1752bde8e466a4451c7319e3a072d118917957d6554Steve Block            hr = E_FAIL;
1762bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
1772bde8e466a4451c7319e3a072d118917957d6554Steve Block
1782bde8e466a4451c7319e3a072d118917957d6554Steve Block    return hr;
1792bde8e466a4451c7319e3a072d118917957d6554Steve Block}
1802bde8e466a4451c7319e3a072d118917957d6554Steve Block
1812bde8e466a4451c7319e3a072d118917957d6554Steve Blocktemplate<typename ValueType, typename KeyType, typename HashType>
1822bde8e466a4451c7319e3a072d118917957d6554Steve BlockHRESULT STDMETHODCALLTYPE COMPropertyBag<ValueType, KeyType, HashType>::Write(ULONG cProperties, PROPBAG2*, VARIANT*)
1832bde8e466a4451c7319e3a072d118917957d6554Steve Block{
1842bde8e466a4451c7319e3a072d118917957d6554Steve Block    return E_NOTIMPL;
1852bde8e466a4451c7319e3a072d118917957d6554Steve Block}
1862bde8e466a4451c7319e3a072d118917957d6554Steve Block
1872bde8e466a4451c7319e3a072d118917957d6554Steve Blocktemplate<typename ValueType, typename KeyType, typename HashType>
1882bde8e466a4451c7319e3a072d118917957d6554Steve BlockHRESULT STDMETHODCALLTYPE COMPropertyBag<ValueType, KeyType, HashType>::CountProperties(ULONG* pcProperties)
1892bde8e466a4451c7319e3a072d118917957d6554Steve Block{
1902bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!pcProperties)
1912bde8e466a4451c7319e3a072d118917957d6554Steve Block        return E_POINTER;
1922bde8e466a4451c7319e3a072d118917957d6554Steve Block
1932bde8e466a4451c7319e3a072d118917957d6554Steve Block    *pcProperties = m_hashMap.size();
1942bde8e466a4451c7319e3a072d118917957d6554Steve Block    return S_OK;
1952bde8e466a4451c7319e3a072d118917957d6554Steve Block}
1962bde8e466a4451c7319e3a072d118917957d6554Steve Block
1972bde8e466a4451c7319e3a072d118917957d6554Steve Blocktemplate<typename ValueType, typename KeyType, typename HashType>
1982bde8e466a4451c7319e3a072d118917957d6554Steve BlockHRESULT STDMETHODCALLTYPE COMPropertyBag<ValueType, KeyType, HashType>::GetPropertyInfo(ULONG iProperty, ULONG cProperties, PROPBAG2* pPropBag, ULONG* pcProperties)
1992bde8e466a4451c7319e3a072d118917957d6554Steve Block{
2002bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!pPropBag || !pcProperties)
2012bde8e466a4451c7319e3a072d118917957d6554Steve Block        return E_POINTER;
2022bde8e466a4451c7319e3a072d118917957d6554Steve Block
2032bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (m_hashMap.size() <= iProperty)
2042bde8e466a4451c7319e3a072d118917957d6554Steve Block        return E_INVALIDARG;
2052bde8e466a4451c7319e3a072d118917957d6554Steve Block
2062bde8e466a4451c7319e3a072d118917957d6554Steve Block    *pcProperties = 0;
2072bde8e466a4451c7319e3a072d118917957d6554Steve Block    typedef HashMapType::const_iterator Iterator;
2082bde8e466a4451c7319e3a072d118917957d6554Steve Block    Iterator current = m_hashMap.begin();
2092bde8e466a4451c7319e3a072d118917957d6554Steve Block    Iterator end = m_hashMap.end();
2102bde8e466a4451c7319e3a072d118917957d6554Steve Block    for (ULONG i = 0; i < iProperty; ++i, ++current)
2112bde8e466a4451c7319e3a072d118917957d6554Steve Block        ;
2122bde8e466a4451c7319e3a072d118917957d6554Steve Block    for (ULONG j = 0; j < cProperties && current != end; ++j, ++current) {
2132bde8e466a4451c7319e3a072d118917957d6554Steve Block        // FIXME: the following fields aren't filled in
2142bde8e466a4451c7319e3a072d118917957d6554Steve Block        //pPropBag[j].cfType;   // (CLIPFORMAT) Clipboard format or MIME type of the property.
2152bde8e466a4451c7319e3a072d118917957d6554Steve Block        //pPropBag[j].clsid;    // (CLSID) CLSID of the object. This member is valid only if dwType is PROPBAG2_TYPE_OBJECT.
2162bde8e466a4451c7319e3a072d118917957d6554Steve Block
2172bde8e466a4451c7319e3a072d118917957d6554Steve Block        pPropBag[j].dwType = PROPBAG2_TYPE_DATA;
2182bde8e466a4451c7319e3a072d118917957d6554Steve Block        pPropBag[j].vt = COMVariantSetter<ValueType>::variantType(current->second);
2192bde8e466a4451c7319e3a072d118917957d6554Steve Block        pPropBag[j].dwHint = iProperty + j;
2202bde8e466a4451c7319e3a072d118917957d6554Steve Block        pPropBag[j].pstrName = (LPOLESTR)CoTaskMemAlloc(sizeof(wchar_t)*(current->first.length()+1));
2212bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!pPropBag[j].pstrName)
2222bde8e466a4451c7319e3a072d118917957d6554Steve Block            return E_OUTOFMEMORY;
2232bde8e466a4451c7319e3a072d118917957d6554Steve Block        wcscpy_s(pPropBag[j].pstrName, current->first.length()+1, static_cast<String>(current->first).charactersWithNullTermination());
2242bde8e466a4451c7319e3a072d118917957d6554Steve Block        ++*pcProperties;
2252bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2262bde8e466a4451c7319e3a072d118917957d6554Steve Block    return S_OK;
2272bde8e466a4451c7319e3a072d118917957d6554Steve Block}
2282bde8e466a4451c7319e3a072d118917957d6554Steve Block
2292bde8e466a4451c7319e3a072d118917957d6554Steve Blocktemplate<typename ValueType, typename KeyType, typename HashType>
2302bde8e466a4451c7319e3a072d118917957d6554Steve BlockHRESULT STDMETHODCALLTYPE COMPropertyBag<ValueType, KeyType, HashType>::LoadObject(LPCOLESTR pstrName, DWORD dwHint, IUnknown*, IErrorLog*)
2312bde8e466a4451c7319e3a072d118917957d6554Steve Block{
2322bde8e466a4451c7319e3a072d118917957d6554Steve Block    return E_NOTIMPL;
2332bde8e466a4451c7319e3a072d118917957d6554Steve Block}
2342bde8e466a4451c7319e3a072d118917957d6554Steve Block
2352bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif // COMPropertyBag_h
236