2 * Copyright 2010 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
31 #include "mshtml_private.h"
32 #include "pluginhost.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
39 IPropertyBag IPropertyBag_iface
;
40 IPropertyBag2 IPropertyBag2_iface
;
53 static void free_prop(param_prop_t
*prop
)
55 list_remove(&prop
->entry
);
57 heap_free(prop
->name
);
58 heap_free(prop
->value
);
62 static param_prop_t
*find_prop(PropertyBag
*prop_bag
, const WCHAR
*name
)
66 LIST_FOR_EACH_ENTRY(iter
, &prop_bag
->props
, param_prop_t
, entry
) {
67 if(!strcmpiW(iter
->name
, name
))
74 static HRESULT
add_prop(PropertyBag
*prop_bag
, const WCHAR
*name
, const WCHAR
*value
)
81 TRACE("%p %s %s\n", prop_bag
, debugstr_w(name
), debugstr_w(value
));
83 prop
= heap_alloc(sizeof(*prop
));
87 prop
->name
= heap_strdupW(name
);
88 prop
->value
= heap_strdupW(value
);
89 if(!prop
->name
|| !prop
->value
) {
90 list_init(&prop
->entry
);
95 list_add_tail(&prop_bag
->props
, &prop
->entry
);
99 static inline PropertyBag
*impl_from_IPropertyBag(IPropertyBag
*iface
)
101 return CONTAINING_RECORD(iface
, PropertyBag
, IPropertyBag_iface
);
104 static HRESULT WINAPI
PropertyBag_QueryInterface(IPropertyBag
*iface
, REFIID riid
, void **ppv
)
106 PropertyBag
*This
= impl_from_IPropertyBag(iface
);
108 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
109 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
110 *ppv
= &This
->IPropertyBag_iface
;
111 }else if(IsEqualGUID(&IID_IPropertyBag
, riid
)) {
112 TRACE("(%p)->(IID_IPropertyBag %p)\n", This
, ppv
);
113 *ppv
= &This
->IPropertyBag_iface
;
114 }else if(IsEqualGUID(&IID_IPropertyBag2
, riid
)) {
115 TRACE("(%p)->(IID_IPropertyBag2 %p)\n", This
, ppv
);
116 *ppv
= &This
->IPropertyBag2_iface
;
118 WARN("Unsopported interface %s\n", debugstr_guid(riid
));
120 return E_NOINTERFACE
;
123 IUnknown_AddRef((IUnknown
*)*ppv
);
127 static ULONG WINAPI
PropertyBag_AddRef(IPropertyBag
*iface
)
129 PropertyBag
*This
= impl_from_IPropertyBag(iface
);
130 LONG ref
= InterlockedIncrement(&This
->ref
);
132 TRACE("(%p) ref=%d\n", This
, ref
);
137 static ULONG WINAPI
PropertyBag_Release(IPropertyBag
*iface
)
139 PropertyBag
*This
= impl_from_IPropertyBag(iface
);
140 LONG ref
= InterlockedDecrement(&This
->ref
);
142 TRACE("(%p) ref=%d\n", This
, ref
);
145 while(!list_empty(&This
->props
))
146 free_prop(LIST_ENTRY(This
->props
.next
, param_prop_t
, entry
));
153 static HRESULT WINAPI
PropertyBag_Read(IPropertyBag
*iface
, LPCOLESTR pszPropName
, VARIANT
*pVar
, IErrorLog
*pErrorLog
)
155 PropertyBag
*This
= impl_from_IPropertyBag(iface
);
159 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(pszPropName
), pVar
, pErrorLog
);
161 prop
= find_prop(This
, pszPropName
);
163 TRACE("Not found\n");
167 V_BSTR(&v
) = SysAllocString(prop
->value
);
169 return E_OUTOFMEMORY
;
171 if(V_VT(pVar
) != VT_BSTR
) {
175 hres
= VariantChangeType(pVar
, &v
, 0, V_VT(pVar
));
176 SysFreeString(V_BSTR(&v
));
180 V_BSTR(pVar
) = V_BSTR(&v
);
184 static HRESULT WINAPI
PropertyBag_Write(IPropertyBag
*iface
, LPCOLESTR pszPropName
, VARIANT
*pVar
)
186 PropertyBag
*This
= impl_from_IPropertyBag(iface
);
187 FIXME("(%p)->(%s %s)\n", This
, debugstr_w(pszPropName
), debugstr_variant(pVar
));
191 static const IPropertyBagVtbl PropertyBagVtbl
= {
192 PropertyBag_QueryInterface
,
199 static inline PropertyBag
*impl_from_IPropertyBag2(IPropertyBag2
*iface
)
201 return CONTAINING_RECORD(iface
, PropertyBag
, IPropertyBag2_iface
);
204 static HRESULT WINAPI
PropertyBag2_QueryInterface(IPropertyBag2
*iface
, REFIID riid
, void **ppv
)
206 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
207 return IPropertyBag_QueryInterface(&This
->IPropertyBag_iface
, riid
, ppv
);
210 static ULONG WINAPI
PropertyBag2_AddRef(IPropertyBag2
*iface
)
212 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
213 return IPropertyBag_AddRef(&This
->IPropertyBag_iface
);
216 static ULONG WINAPI
PropertyBag2_Release(IPropertyBag2
*iface
)
218 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
219 return IPropertyBag_Release(&This
->IPropertyBag_iface
);
222 static HRESULT WINAPI
PropertyBag2_Read(IPropertyBag2
*iface
, ULONG cProperties
, PROPBAG2
*pPropBag
,
223 IErrorLog
*pErrLog
, VARIANT
*pvarValue
, HRESULT
*phrError
)
225 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
226 FIXME("(%p)->(%d %p %p %p %p)\n", This
, cProperties
, pPropBag
, pErrLog
, pvarValue
, phrError
);
230 static HRESULT WINAPI
PropertyBag2_Write(IPropertyBag2
*iface
, ULONG cProperties
, PROPBAG2
*pPropBag
, VARIANT
*pvarValue
)
232 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
233 FIXME("(%p)->(%d %p %s)\n", This
, cProperties
, pPropBag
, debugstr_variant(pvarValue
));
237 static HRESULT WINAPI
PropertyBag2_CountProperties(IPropertyBag2
*iface
, ULONG
*pcProperties
)
239 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
240 FIXME("(%p)->(%p)\n", This
, pcProperties
);
244 static HRESULT WINAPI
PropertyBag2_GetPropertyInfo(IPropertyBag2
*iface
, ULONG iProperty
, ULONG cProperties
,
245 PROPBAG2
*pPropBag
, ULONG
*pcProperties
)
247 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
248 FIXME("(%p)->(%u %u %p %p)\n", This
, iProperty
, cProperties
, pPropBag
, pcProperties
);
252 static HRESULT WINAPI
PropertyBag2_LoadObject(IPropertyBag2
*iface
, LPCOLESTR pstrName
, DWORD dwHint
,
253 IUnknown
*pUnkObject
, IErrorLog
*pErrLog
)
255 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
256 FIXME("(%p)->(%s %x %p %p)\n", This
, debugstr_w(pstrName
), dwHint
, pUnkObject
, pErrLog
);
260 static const IPropertyBag2Vtbl PropertyBag2Vtbl
= {
261 PropertyBag2_QueryInterface
,
263 PropertyBag2_Release
,
266 PropertyBag2_CountProperties
,
267 PropertyBag2_GetPropertyInfo
,
268 PropertyBag2_LoadObject
271 static HRESULT
fill_props(nsIDOMHTMLElement
*nselem
, PropertyBag
*prop_bag
)
273 nsIDOMHTMLParamElement
*nsparam
;
274 nsAString name_str
, value_str
;
275 nsIDOMNodeList
*params
;
281 static const PRUnichar paramW
[] = {'p','a','r','a','m',0};
283 nsAString_InitDepend(&name_str
, paramW
);
284 nsres
= nsIDOMHTMLElement_GetElementsByTagName(nselem
, &name_str
, ¶ms
);
285 nsAString_Finish(&name_str
);
289 nsres
= nsIDOMNodeList_GetLength(params
, &length
);
293 for(i
=0; i
< length
; i
++) {
294 nsres
= nsIDOMNodeList_Item(params
, i
, &nsnode
);
295 if(NS_FAILED(nsres
)) {
300 nsres
= nsIDOMNode_QueryInterface(nsnode
, &IID_nsIDOMHTMLParamElement
, (void**)&nsparam
);
301 nsIDOMNode_Release(nsnode
);
302 if(NS_FAILED(nsres
)) {
307 nsAString_Init(&name_str
, NULL
);
308 nsres
= nsIDOMHTMLParamElement_GetName(nsparam
, &name_str
);
309 if(NS_SUCCEEDED(nsres
)) {
310 nsAString_Init(&value_str
, NULL
);
311 nsres
= nsIDOMHTMLParamElement_GetValue(nsparam
, &value_str
);
312 if(NS_SUCCEEDED(nsres
)) {
313 const PRUnichar
*name
, *value
;
315 nsAString_GetData(&name_str
, &name
);
316 nsAString_GetData(&value_str
, &value
);
318 hres
= add_prop(prop_bag
, name
, value
);
320 nsAString_Finish(&value_str
);
323 nsAString_Finish(&name_str
);
324 nsIDOMHTMLParamElement_Release(nsparam
);
327 if(NS_FAILED(nsres
)) {
336 HRESULT
create_param_prop_bag(nsIDOMHTMLElement
*nselem
, IPropertyBag
**ret
)
338 PropertyBag
*prop_bag
;
341 prop_bag
= heap_alloc(sizeof(*prop_bag
));
343 return E_OUTOFMEMORY
;
345 prop_bag
->IPropertyBag_iface
.lpVtbl
= &PropertyBagVtbl
;
346 prop_bag
->IPropertyBag2_iface
.lpVtbl
= &PropertyBag2Vtbl
;
349 list_init(&prop_bag
->props
);
350 hres
= fill_props(nselem
, prop_bag
);
351 if(FAILED(hres
) || list_empty(&prop_bag
->props
)) {
352 IPropertyBag_Release(&prop_bag
->IPropertyBag_iface
);
357 *ret
= &prop_bag
->IPropertyBag_iface
;