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"
35 #include "wine/unicode.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
40 IPropertyBag IPropertyBag_iface
;
41 IPropertyBag2 IPropertyBag2_iface
;
54 static void free_prop(param_prop_t
*prop
)
56 list_remove(&prop
->entry
);
58 heap_free(prop
->name
);
59 heap_free(prop
->value
);
63 static param_prop_t
*find_prop(PropertyBag
*prop_bag
, const WCHAR
*name
)
67 LIST_FOR_EACH_ENTRY(iter
, &prop_bag
->props
, param_prop_t
, entry
) {
68 if(!strcmpiW(iter
->name
, name
))
75 static HRESULT
add_prop(PropertyBag
*prop_bag
, const WCHAR
*name
, const WCHAR
*value
)
82 TRACE("%p %s %s\n", prop_bag
, debugstr_w(name
), debugstr_w(value
));
84 prop
= heap_alloc(sizeof(*prop
));
88 prop
->name
= heap_strdupW(name
);
89 prop
->value
= heap_strdupW(value
);
90 if(!prop
->name
|| !prop
->value
) {
91 list_init(&prop
->entry
);
96 list_add_tail(&prop_bag
->props
, &prop
->entry
);
100 static inline PropertyBag
*impl_from_IPropertyBag(IPropertyBag
*iface
)
102 return CONTAINING_RECORD(iface
, PropertyBag
, IPropertyBag_iface
);
105 static HRESULT WINAPI
PropertyBag_QueryInterface(IPropertyBag
*iface
, REFIID riid
, void **ppv
)
107 PropertyBag
*This
= impl_from_IPropertyBag(iface
);
109 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
110 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
111 *ppv
= &This
->IPropertyBag_iface
;
112 }else if(IsEqualGUID(&IID_IPropertyBag
, riid
)) {
113 TRACE("(%p)->(IID_IPropertyBag %p)\n", This
, ppv
);
114 *ppv
= &This
->IPropertyBag_iface
;
115 }else if(IsEqualGUID(&IID_IPropertyBag2
, riid
)) {
116 TRACE("(%p)->(IID_IPropertyBag2 %p)\n", This
, ppv
);
117 *ppv
= &This
->IPropertyBag2_iface
;
119 WARN("Unsopported interface %s\n", debugstr_guid(riid
));
121 return E_NOINTERFACE
;
124 IUnknown_AddRef((IUnknown
*)*ppv
);
128 static ULONG WINAPI
PropertyBag_AddRef(IPropertyBag
*iface
)
130 PropertyBag
*This
= impl_from_IPropertyBag(iface
);
131 LONG ref
= InterlockedIncrement(&This
->ref
);
133 TRACE("(%p) ref=%d\n", This
, ref
);
138 static ULONG WINAPI
PropertyBag_Release(IPropertyBag
*iface
)
140 PropertyBag
*This
= impl_from_IPropertyBag(iface
);
141 LONG ref
= InterlockedDecrement(&This
->ref
);
143 TRACE("(%p) ref=%d\n", This
, ref
);
146 while(!list_empty(&This
->props
))
147 free_prop(LIST_ENTRY(This
->props
.next
, param_prop_t
, entry
));
154 static HRESULT WINAPI
PropertyBag_Read(IPropertyBag
*iface
, LPCOLESTR pszPropName
, VARIANT
*pVar
, IErrorLog
*pErrorLog
)
156 PropertyBag
*This
= impl_from_IPropertyBag(iface
);
160 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(pszPropName
), pVar
, pErrorLog
);
162 prop
= find_prop(This
, pszPropName
);
164 TRACE("Not found\n");
168 V_BSTR(&v
) = SysAllocString(prop
->value
);
170 return E_OUTOFMEMORY
;
172 if(V_VT(pVar
) != VT_BSTR
) {
176 hres
= VariantChangeType(pVar
, &v
, 0, V_VT(pVar
));
177 SysFreeString(V_BSTR(&v
));
181 V_BSTR(pVar
) = V_BSTR(&v
);
185 static HRESULT WINAPI
PropertyBag_Write(IPropertyBag
*iface
, LPCOLESTR pszPropName
, VARIANT
*pVar
)
187 PropertyBag
*This
= impl_from_IPropertyBag(iface
);
188 FIXME("(%p)->(%s %s)\n", This
, debugstr_w(pszPropName
), debugstr_variant(pVar
));
192 static const IPropertyBagVtbl PropertyBagVtbl
= {
193 PropertyBag_QueryInterface
,
200 static inline PropertyBag
*impl_from_IPropertyBag2(IPropertyBag2
*iface
)
202 return CONTAINING_RECORD(iface
, PropertyBag
, IPropertyBag2_iface
);
205 static HRESULT WINAPI
PropertyBag2_QueryInterface(IPropertyBag2
*iface
, REFIID riid
, void **ppv
)
207 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
208 return IPropertyBag_QueryInterface(&This
->IPropertyBag_iface
, riid
, ppv
);
211 static ULONG WINAPI
PropertyBag2_AddRef(IPropertyBag2
*iface
)
213 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
214 return IPropertyBag_AddRef(&This
->IPropertyBag_iface
);
217 static ULONG WINAPI
PropertyBag2_Release(IPropertyBag2
*iface
)
219 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
220 return IPropertyBag_Release(&This
->IPropertyBag_iface
);
223 static HRESULT WINAPI
PropertyBag2_Read(IPropertyBag2
*iface
, ULONG cProperties
, PROPBAG2
*pPropBag
,
224 IErrorLog
*pErrLog
, VARIANT
*pvarValue
, HRESULT
*phrError
)
226 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
227 FIXME("(%p)->(%d %p %p %p %p)\n", This
, cProperties
, pPropBag
, pErrLog
, pvarValue
, phrError
);
231 static HRESULT WINAPI
PropertyBag2_Write(IPropertyBag2
*iface
, ULONG cProperties
, PROPBAG2
*pPropBag
, VARIANT
*pvarValue
)
233 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
234 FIXME("(%p)->(%d %p %s)\n", This
, cProperties
, pPropBag
, debugstr_variant(pvarValue
));
238 static HRESULT WINAPI
PropertyBag2_CountProperties(IPropertyBag2
*iface
, ULONG
*pcProperties
)
240 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
241 FIXME("(%p)->(%p)\n", This
, pcProperties
);
245 static HRESULT WINAPI
PropertyBag2_GetPropertyInfo(IPropertyBag2
*iface
, ULONG iProperty
, ULONG cProperties
,
246 PROPBAG2
*pPropBag
, ULONG
*pcProperties
)
248 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
249 FIXME("(%p)->(%u %u %p %p)\n", This
, iProperty
, cProperties
, pPropBag
, pcProperties
);
253 static HRESULT WINAPI
PropertyBag2_LoadObject(IPropertyBag2
*iface
, LPCOLESTR pstrName
, DWORD dwHint
,
254 IUnknown
*pUnkObject
, IErrorLog
*pErrLog
)
256 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
257 FIXME("(%p)->(%s %x %p %p)\n", This
, debugstr_w(pstrName
), dwHint
, pUnkObject
, pErrLog
);
261 static const IPropertyBag2Vtbl PropertyBag2Vtbl
= {
262 PropertyBag2_QueryInterface
,
264 PropertyBag2_Release
,
267 PropertyBag2_CountProperties
,
268 PropertyBag2_GetPropertyInfo
,
269 PropertyBag2_LoadObject
272 static HRESULT
fill_props(nsIDOMHTMLElement
*nselem
, PropertyBag
*prop_bag
)
274 nsIDOMHTMLParamElement
*nsparam
;
275 nsAString name_str
, value_str
;
276 nsIDOMNodeList
*params
;
282 static const PRUnichar paramW
[] = {'p','a','r','a','m',0};
284 nsAString_InitDepend(&name_str
, paramW
);
285 nsres
= nsIDOMHTMLElement_GetElementsByTagName(nselem
, &name_str
, ¶ms
);
286 nsAString_Finish(&name_str
);
290 nsres
= nsIDOMNodeList_GetLength(params
, &length
);
294 for(i
=0; i
< length
; i
++) {
295 nsres
= nsIDOMNodeList_Item(params
, i
, &nsnode
);
296 if(NS_FAILED(nsres
)) {
301 nsres
= nsIDOMNode_QueryInterface(nsnode
, &IID_nsIDOMHTMLParamElement
, (void**)&nsparam
);
302 nsIDOMNode_Release(nsnode
);
303 if(NS_FAILED(nsres
)) {
308 nsAString_Init(&name_str
, NULL
);
309 nsres
= nsIDOMHTMLParamElement_GetName(nsparam
, &name_str
);
310 if(NS_SUCCEEDED(nsres
)) {
311 nsAString_Init(&value_str
, NULL
);
312 nsres
= nsIDOMHTMLParamElement_GetValue(nsparam
, &value_str
);
313 if(NS_SUCCEEDED(nsres
)) {
314 const PRUnichar
*name
, *value
;
316 nsAString_GetData(&name_str
, &name
);
317 nsAString_GetData(&value_str
, &value
);
319 hres
= add_prop(prop_bag
, name
, value
);
321 nsAString_Finish(&value_str
);
324 nsAString_Finish(&name_str
);
325 nsIDOMHTMLParamElement_Release(nsparam
);
328 if(NS_FAILED(nsres
)) {
337 HRESULT
create_param_prop_bag(nsIDOMHTMLElement
*nselem
, IPropertyBag
**ret
)
339 PropertyBag
*prop_bag
;
342 prop_bag
= heap_alloc(sizeof(*prop_bag
));
344 return E_OUTOFMEMORY
;
346 prop_bag
->IPropertyBag_iface
.lpVtbl
= &PropertyBagVtbl
;
347 prop_bag
->IPropertyBag2_iface
.lpVtbl
= &PropertyBag2Vtbl
;
350 list_init(&prop_bag
->props
);
351 hres
= fill_props(nselem
, prop_bag
);
352 if(FAILED(hres
) || list_empty(&prop_bag
->props
)) {
353 IPropertyBag_Release(&prop_bag
->IPropertyBag_iface
);
358 *ret
= &prop_bag
->IPropertyBag_iface
;