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
23 #define WIN32_NO_STATUS
30 //#include "winuser.h"
34 #include "mshtml_private.h"
35 #include "pluginhost.h"
37 #include <wine/debug.h>
39 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
42 IPropertyBag IPropertyBag_iface
;
43 IPropertyBag2 IPropertyBag2_iface
;
56 static void free_prop(param_prop_t
*prop
)
58 list_remove(&prop
->entry
);
60 heap_free(prop
->name
);
61 heap_free(prop
->value
);
65 static param_prop_t
*find_prop(PropertyBag
*prop_bag
, const WCHAR
*name
)
69 LIST_FOR_EACH_ENTRY(iter
, &prop_bag
->props
, param_prop_t
, entry
) {
70 if(!strcmpiW(iter
->name
, name
))
77 static HRESULT
add_prop(PropertyBag
*prop_bag
, const WCHAR
*name
, const WCHAR
*value
)
84 TRACE("%p %s %s\n", prop_bag
, debugstr_w(name
), debugstr_w(value
));
86 prop
= heap_alloc(sizeof(*prop
));
90 prop
->name
= heap_strdupW(name
);
91 prop
->value
= heap_strdupW(value
);
92 if(!prop
->name
|| !prop
->value
) {
93 list_init(&prop
->entry
);
98 list_add_tail(&prop_bag
->props
, &prop
->entry
);
102 static inline PropertyBag
*impl_from_IPropertyBag(IPropertyBag
*iface
)
104 return CONTAINING_RECORD(iface
, PropertyBag
, IPropertyBag_iface
);
107 static HRESULT WINAPI
PropertyBag_QueryInterface(IPropertyBag
*iface
, REFIID riid
, void **ppv
)
109 PropertyBag
*This
= impl_from_IPropertyBag(iface
);
111 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
112 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
113 *ppv
= &This
->IPropertyBag_iface
;
114 }else if(IsEqualGUID(&IID_IPropertyBag
, riid
)) {
115 TRACE("(%p)->(IID_IPropertyBag %p)\n", This
, ppv
);
116 *ppv
= &This
->IPropertyBag_iface
;
117 }else if(IsEqualGUID(&IID_IPropertyBag2
, riid
)) {
118 TRACE("(%p)->(IID_IPropertyBag2 %p)\n", This
, ppv
);
119 *ppv
= &This
->IPropertyBag2_iface
;
121 WARN("Unsopported interface %s\n", debugstr_guid(riid
));
123 return E_NOINTERFACE
;
126 IUnknown_AddRef((IUnknown
*)*ppv
);
130 static ULONG WINAPI
PropertyBag_AddRef(IPropertyBag
*iface
)
132 PropertyBag
*This
= impl_from_IPropertyBag(iface
);
133 LONG ref
= InterlockedIncrement(&This
->ref
);
135 TRACE("(%p) ref=%d\n", This
, ref
);
140 static ULONG WINAPI
PropertyBag_Release(IPropertyBag
*iface
)
142 PropertyBag
*This
= impl_from_IPropertyBag(iface
);
143 LONG ref
= InterlockedDecrement(&This
->ref
);
145 TRACE("(%p) ref=%d\n", This
, ref
);
148 while(!list_empty(&This
->props
))
149 free_prop(LIST_ENTRY(This
->props
.next
, param_prop_t
, entry
));
156 static HRESULT WINAPI
PropertyBag_Read(IPropertyBag
*iface
, LPCOLESTR pszPropName
, VARIANT
*pVar
, IErrorLog
*pErrorLog
)
158 PropertyBag
*This
= impl_from_IPropertyBag(iface
);
162 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(pszPropName
), pVar
, pErrorLog
);
164 prop
= find_prop(This
, pszPropName
);
166 TRACE("Not found\n");
170 V_BSTR(&v
) = SysAllocString(prop
->value
);
172 return E_OUTOFMEMORY
;
174 if(V_VT(pVar
) != VT_BSTR
) {
178 hres
= VariantChangeType(pVar
, &v
, 0, V_VT(pVar
));
179 SysFreeString(V_BSTR(&v
));
183 V_BSTR(pVar
) = V_BSTR(&v
);
187 static HRESULT WINAPI
PropertyBag_Write(IPropertyBag
*iface
, LPCOLESTR pszPropName
, VARIANT
*pVar
)
189 PropertyBag
*This
= impl_from_IPropertyBag(iface
);
190 FIXME("(%p)->(%s %s)\n", This
, debugstr_w(pszPropName
), debugstr_variant(pVar
));
194 static const IPropertyBagVtbl PropertyBagVtbl
= {
195 PropertyBag_QueryInterface
,
202 static inline PropertyBag
*impl_from_IPropertyBag2(IPropertyBag2
*iface
)
204 return CONTAINING_RECORD(iface
, PropertyBag
, IPropertyBag2_iface
);
207 static HRESULT WINAPI
PropertyBag2_QueryInterface(IPropertyBag2
*iface
, REFIID riid
, void **ppv
)
209 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
210 return IPropertyBag_QueryInterface(&This
->IPropertyBag_iface
, riid
, ppv
);
213 static ULONG WINAPI
PropertyBag2_AddRef(IPropertyBag2
*iface
)
215 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
216 return IPropertyBag_AddRef(&This
->IPropertyBag_iface
);
219 static ULONG WINAPI
PropertyBag2_Release(IPropertyBag2
*iface
)
221 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
222 return IPropertyBag_Release(&This
->IPropertyBag_iface
);
225 static HRESULT WINAPI
PropertyBag2_Read(IPropertyBag2
*iface
, ULONG cProperties
, PROPBAG2
*pPropBag
,
226 IErrorLog
*pErrLog
, VARIANT
*pvarValue
, HRESULT
*phrError
)
228 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
229 FIXME("(%p)->(%d %p %p %p %p)\n", This
, cProperties
, pPropBag
, pErrLog
, pvarValue
, phrError
);
233 static HRESULT WINAPI
PropertyBag2_Write(IPropertyBag2
*iface
, ULONG cProperties
, PROPBAG2
*pPropBag
, VARIANT
*pvarValue
)
235 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
236 FIXME("(%p)->(%d %p %s)\n", This
, cProperties
, pPropBag
, debugstr_variant(pvarValue
));
240 static HRESULT WINAPI
PropertyBag2_CountProperties(IPropertyBag2
*iface
, ULONG
*pcProperties
)
242 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
243 FIXME("(%p)->(%p)\n", This
, pcProperties
);
247 static HRESULT WINAPI
PropertyBag2_GetPropertyInfo(IPropertyBag2
*iface
, ULONG iProperty
, ULONG cProperties
,
248 PROPBAG2
*pPropBag
, ULONG
*pcProperties
)
250 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
251 FIXME("(%p)->(%u %u %p %p)\n", This
, iProperty
, cProperties
, pPropBag
, pcProperties
);
255 static HRESULT WINAPI
PropertyBag2_LoadObject(IPropertyBag2
*iface
, LPCOLESTR pstrName
, DWORD dwHint
,
256 IUnknown
*pUnkObject
, IErrorLog
*pErrLog
)
258 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
259 FIXME("(%p)->(%s %x %p %p)\n", This
, debugstr_w(pstrName
), dwHint
, pUnkObject
, pErrLog
);
263 static const IPropertyBag2Vtbl PropertyBag2Vtbl
= {
264 PropertyBag2_QueryInterface
,
266 PropertyBag2_Release
,
269 PropertyBag2_CountProperties
,
270 PropertyBag2_GetPropertyInfo
,
271 PropertyBag2_LoadObject
274 static HRESULT
fill_props(nsIDOMHTMLElement
*nselem
, PropertyBag
*prop_bag
)
276 nsIDOMHTMLParamElement
*nsparam
;
277 nsAString name_str
, value_str
;
278 nsIDOMHTMLCollection
*params
;
284 static const PRUnichar paramW
[] = {'p','a','r','a','m',0};
286 nsAString_InitDepend(&name_str
, paramW
);
287 nsres
= nsIDOMHTMLElement_GetElementsByTagName(nselem
, &name_str
, ¶ms
);
288 nsAString_Finish(&name_str
);
292 nsres
= nsIDOMHTMLCollection_GetLength(params
, &length
);
296 for(i
=0; i
< length
; i
++) {
297 nsres
= nsIDOMHTMLCollection_Item(params
, i
, &nsnode
);
298 if(NS_FAILED(nsres
)) {
303 nsres
= nsIDOMNode_QueryInterface(nsnode
, &IID_nsIDOMHTMLParamElement
, (void**)&nsparam
);
304 nsIDOMNode_Release(nsnode
);
305 if(NS_FAILED(nsres
)) {
310 nsAString_Init(&name_str
, NULL
);
311 nsres
= nsIDOMHTMLParamElement_GetName(nsparam
, &name_str
);
312 if(NS_SUCCEEDED(nsres
)) {
313 nsAString_Init(&value_str
, NULL
);
314 nsres
= nsIDOMHTMLParamElement_GetValue(nsparam
, &value_str
);
315 if(NS_SUCCEEDED(nsres
)) {
316 const PRUnichar
*name
, *value
;
318 nsAString_GetData(&name_str
, &name
);
319 nsAString_GetData(&value_str
, &value
);
321 hres
= add_prop(prop_bag
, name
, value
);
323 nsAString_Finish(&value_str
);
326 nsAString_Finish(&name_str
);
327 nsIDOMHTMLParamElement_Release(nsparam
);
330 if(NS_FAILED(nsres
)) {
336 nsIDOMHTMLCollection_Release(params
);
340 HRESULT
create_param_prop_bag(nsIDOMHTMLElement
*nselem
, IPropertyBag
**ret
)
342 PropertyBag
*prop_bag
;
345 prop_bag
= heap_alloc(sizeof(*prop_bag
));
347 return E_OUTOFMEMORY
;
349 prop_bag
->IPropertyBag_iface
.lpVtbl
= &PropertyBagVtbl
;
350 prop_bag
->IPropertyBag2_iface
.lpVtbl
= &PropertyBag2Vtbl
;
353 list_init(&prop_bag
->props
);
354 hres
= fill_props(nselem
, prop_bag
);
355 if(FAILED(hres
) || list_empty(&prop_bag
->props
)) {
356 IPropertyBag_Release(&prop_bag
->IPropertyBag_iface
);
361 *ret
= &prop_bag
->IPropertyBag_iface
;