ReactOS 0.4.16-dev-197-g92996da
dispex.c
Go to the documentation of this file.
1/*
2 * Copyright 2008-2009 Jacek Caban for CodeWeavers
3 *
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.
8 *
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.
13 *
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
17 */
18
19#include "mshtml_private.h"
20
21#define MAX_ARGS 16
22
25{
28 0, 0, { (DWORD_PTR)(__FILE__ ": dispex_static_data") }
29};
31
32
33static const WCHAR objectW[] = {'[','o','b','j','e','c','t',']',0};
34
35typedef struct {
47
53
54 struct list entry;
55};
56
57typedef struct {
62
63#define DYNPROP_DELETED 0x01
64
65typedef struct {
72
73typedef struct {
77
83};
84
85#define DISPID_DYNPROP_0 0x50000000
86#define DISPID_DYNPROP_MAX 0x5fffffff
87
88#define FDEX_VERSION_MASK 0xf0000000
89
93
94static REFIID tid_ids[] = {
95#define XIID(iface) &IID_ ## iface,
96#define XDIID(iface) &DIID_ ## iface,
98#undef XIID
99#undef XDIID
100};
101
103{
105 ITypeLib *tl;
106
107 hres = LoadRegTypeLib(&LIBID_MSHTML, 4, 0, LOCALE_SYSTEM_DEFAULT, &tl);
108 if(FAILED(hres)) {
109 ERR("LoadRegTypeLib failed: %08x\n", hres);
110 return hres;
111 }
112
114 ITypeLib_Release(tl);
115 return hres;
116}
117
119{
121
122 if (!typelib)
123 hres = load_typelib();
124 if (!typelib)
125 return hres;
126
127 if(!typeinfos[tid]) {
128 ITypeInfo *ti;
129
130 hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
131 if(FAILED(hres)) {
132 ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_mshtml_guid(tid_ids[tid]), hres);
133 return hres;
134 }
135
137 ITypeInfo_Release(ti);
138 }
139
141 return S_OK;
142}
143
145{
146 dispex_data_t *iter;
147 unsigned i;
148
149 while(!list_empty(&dispex_data_list)) {
151 list_remove(&iter->entry);
152
153 for(i=0; i < iter->func_cnt; i++)
154 SysFreeString(iter->funcs[i].name);
155
156 heap_free(iter->funcs);
157 heap_free(iter->name_table);
158 heap_free(iter);
159 }
160
161 if(!typelib)
162 return;
163
164 for(i=0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++)
165 if(typeinfos[i])
166 ITypeInfo_Release(typeinfos[i]);
167
168 ITypeLib_Release(typelib);
170}
171
173{
175
176 if (!typelib)
177 hres = load_typelib();
178 if (!typelib)
179 return hres;
180
181 hres = ITypeLib_GetTypeInfoOfGuid(typelib, &CLSID_HTMLDocument, typeinfo);
182 if(FAILED(hres))
183 ERR("GetTypeInfoOfGuid failed: %08x\n", hres);
184 return hres;
185}
186
187/* Not all argument types are supported yet */
188#define BUILTIN_ARG_TYPES_SWITCH \
189 CASE_VT(VT_I2, INT16, V_I2); \
190 CASE_VT(VT_I4, INT32, V_I4); \
191 CASE_VT(VT_R4, float, V_R4); \
192 CASE_VT(VT_BSTR, BSTR, V_BSTR); \
193 CASE_VT(VT_BOOL, VARIANT_BOOL, V_BOOL)
194
195/* List all types used by IDispatchEx-based properties */
196#define BUILTIN_TYPES_SWITCH \
197 BUILTIN_ARG_TYPES_SWITCH; \
198 CASE_VT(VT_VARIANT, VARIANT, *); \
199 CASE_VT(VT_PTR, void*, V_BYREF); \
200 CASE_VT(VT_UNKNOWN, IUnknown*, V_UNKNOWN); \
201 CASE_VT(VT_DISPATCH, IDispatch*, V_DISPATCH)
202
204{
205 switch(vt) {
206#define CASE_VT(x,a,b) case x: return TRUE
208#undef CASE_VT
209 }
210 return FALSE;
211}
212
213static void add_func_info(dispex_data_t *data, DWORD *size, tid_t tid, const FUNCDESC *desc, ITypeInfo *dti)
214{
217
218 for(info = data->funcs; info < data->funcs+data->func_cnt; info++) {
219 if(info->id == desc->memid) {
220 if(info->tid != tid)
221 return; /* Duplicated in other interface */
222 break;
223 }
224 }
225
226 if(info == data->funcs+data->func_cnt) {
227 if(data->func_cnt == *size)
228 data->funcs = heap_realloc_zero(data->funcs, (*size <<= 1)*sizeof(func_info_t));
229
230 info = data->funcs+data->func_cnt;
231 hres = ITypeInfo_GetDocumentation(dti, desc->memid, &info->name, NULL, NULL, NULL);
232 if(FAILED(hres))
233 return;
234
235 data->func_cnt++;
236
237 info->id = desc->memid;
238 info->tid = tid;
239 info->func_disp_idx = -1;
240 info->prop_vt = VT_EMPTY;
241 }
242
243 if(desc->invkind & DISPATCH_METHOD) {
244 unsigned i;
245
246 info->func_disp_idx = data->func_disp_cnt++;
247 info->argc = desc->cParams;
248
249 assert(info->argc < MAX_ARGS);
250 assert(desc->funckind == FUNC_DISPATCH);
251
252 info->arg_types = heap_alloc(sizeof(*info->arg_types) * info->argc);
253 if(!info->arg_types)
254 return; /* FIXME: real error instead of fallback */
255
256 for(i=0; i < info->argc; i++)
257 info->arg_types[i] = desc->lprgelemdescParam[i].tdesc.vt;
258
259 info->prop_vt = desc->elemdescFunc.tdesc.vt;
260 if(info->prop_vt != VT_VOID && !is_arg_type_supported(info->prop_vt)) {
261 TRACE("%s: return type %d\n", debugstr_w(info->name), info->prop_vt);
262 return; /* Fallback to ITypeInfo::Invoke */
263 }
264
265 if(desc->cParamsOpt) {
266 TRACE("%s: optional params\n", debugstr_w(info->name));
267 return; /* Fallback to ITypeInfo::Invoke */
268 }
269
270 for(i=0; i < info->argc; i++) {
271 if(!is_arg_type_supported(info->arg_types[i])) {
272 return; /* Fallback to ITypeInfo for unsupported arg types */
273 }
274
275 if(desc->lprgelemdescParam[i].u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) {
276 TRACE("%s param %d: default value\n", debugstr_w(info->name), i);
277 return; /* Fallback to ITypeInfo::Invoke */
278 }
279 }
280
281 assert(info->argc <= MAX_ARGS);
282 assert(desc->callconv == CC_STDCALL);
283
284 info->call_vtbl_off = desc->oVft/sizeof(void*);
285 }else if(desc->invkind & (DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYGET)) {
287
288 if(desc->invkind & DISPATCH_PROPERTYGET) {
289 vt = desc->elemdescFunc.tdesc.vt;
290 info->get_vtbl_off = desc->oVft/sizeof(void*);
291 }
292 if(desc->invkind & DISPATCH_PROPERTYPUT) {
293 assert(desc->cParams == 1);
294 vt = desc->lprgelemdescParam->tdesc.vt;
295 info->put_vtbl_off = desc->oVft/sizeof(void*);
296 }
297
298 assert(info->prop_vt == VT_EMPTY || vt == info->prop_vt);
299 info->prop_vt = vt;
300 }
301}
302
303static int dispid_cmp(const void *p1, const void *p2)
304{
305 return ((const func_info_t*)p1)->id - ((const func_info_t*)p2)->id;
306}
307
308static int func_name_cmp(const void *p1, const void *p2)
309{
310 return strcmpiW((*(func_info_t* const*)p1)->name, (*(func_info_t* const*)p2)->name);
311}
312
314{
315 const tid_t *tid = This->data->iface_tids;
316 FUNCDESC *funcdesc;
318 DWORD size = 16, i;
319 ITypeInfo *ti, *dti;
321
322 TRACE("(%p)\n", This);
323
324 if(This->data->disp_tid) {
325 hres = get_typeinfo(This->data->disp_tid, &dti);
326 if(FAILED(hres)) {
327 ERR("Could not get disp type info: %08x\n", hres);
328 return NULL;
329 }
330 }
331
332 data = heap_alloc(sizeof(dispex_data_t));
333 if (!data) {
334 ERR("Out of memory\n");
335 return NULL;
336 }
337 data->func_cnt = 0;
338 data->func_disp_cnt = 0;
339 data->funcs = heap_alloc_zero(size*sizeof(func_info_t));
340 if (!data->funcs) {
341 heap_free (data);
342 ERR("Out of memory\n");
343 return NULL;
344 }
346
347 while(*tid) {
348 hres = get_typeinfo(*tid, &ti);
349 if(FAILED(hres))
350 break;
351
352 i=7;
353 while(1) {
354 hres = ITypeInfo_GetFuncDesc(ti, i++, &funcdesc);
355 if(FAILED(hres))
356 break;
357
358 add_func_info(data, &size, *tid, funcdesc, dti);
359 ITypeInfo_ReleaseFuncDesc(ti, funcdesc);
360 }
361
362 tid++;
363 }
364
365 if(!data->func_cnt) {
366 heap_free(data->funcs);
367 data->name_table = NULL;
368 data->funcs = NULL;
369 return data;
370 }
371
372
373 data->funcs = heap_realloc(data->funcs, data->func_cnt * sizeof(func_info_t));
374 qsort(data->funcs, data->func_cnt, sizeof(func_info_t), dispid_cmp);
375
376 data->name_table = heap_alloc(data->func_cnt * sizeof(func_info_t*));
377 for(i=0; i < data->func_cnt; i++)
378 data->name_table[i] = data->funcs+i;
379 qsort(data->name_table, data->func_cnt, sizeof(func_info_t*), func_name_cmp);
380
381 return data;
382}
383
384static int id_cmp(const void *p1, const void *p2)
385{
386 return *(const DISPID*)p1 - *(const DISPID*)p2;
387}
388
390{
391 unsigned i, func_cnt;
392 FUNCDESC *funcdesc;
393 ITypeInfo *ti;
394 TYPEATTR *attr;
395 DISPID *ids;
397
398 hres = get_typeinfo(tid, &ti);
399 if(FAILED(hres))
400 return hres;
401
402 hres = ITypeInfo_GetTypeAttr(ti, &attr);
403 if(FAILED(hres)) {
404 ITypeInfo_Release(ti);
405 return hres;
406 }
407
408 func_cnt = attr->cFuncs;
409 ITypeInfo_ReleaseTypeAttr(ti, attr);
410
411 ids = heap_alloc(func_cnt*sizeof(DISPID));
412 if(!ids) {
413 ITypeInfo_Release(ti);
414 return E_OUTOFMEMORY;
415 }
416
417 for(i=0; i < func_cnt; i++) {
418 hres = ITypeInfo_GetFuncDesc(ti, i, &funcdesc);
419 if(FAILED(hres))
420 break;
421
422 ids[i] = funcdesc->memid;
423 ITypeInfo_ReleaseFuncDesc(ti, funcdesc);
424 }
425
426 ITypeInfo_Release(ti);
427 if(FAILED(hres)) {
428 heap_free(ids);
429 return hres;
430 }
431
432 qsort(ids, func_cnt, sizeof(DISPID), id_cmp);
433
434 *ret_size = func_cnt;
435 *ret = ids;
436 return S_OK;
437}
438
440{
441 if(This->data->data)
442 return This->data->data;
443
445
446 if(!This->data->data)
447 This->data->data = preprocess_dispex_data(This);
448
450
451 return This->data->data;
452}
453
454static inline BOOL is_custom_dispid(DISPID id)
455{
457}
458
460{
461 return DISPID_DYNPROP_0 <= id && id <= DISPID_DYNPROP_MAX;
462}
463
465{
466 if(is_dynamic_dispid(id))
467 return DISPEXPROP_DYNAMIC;
468 if(is_custom_dispid(id))
469 return DISPEXPROP_CUSTOM;
470 return DISPEXPROP_BUILTIN;
471}
472
474{
475 if(V_VT(src) == VT_BSTR && !V_BSTR(src)) {
476 V_VT(dest) = VT_BSTR;
477 V_BSTR(dest) = NULL;
478 return S_OK;
479 }
480
481 return VariantCopy(dest, src);
482}
483
485{
486 if(This->dynamic_data)
487 return This->dynamic_data;
488
489 This->dynamic_data = heap_alloc_zero(sizeof(dispex_dynamic_data_t));
490 if(!This->dynamic_data)
491 return NULL;
492
493 if(This->data->vtbl && This->data->vtbl->populate_props)
494 This->data->vtbl->populate_props(This);
495
496 return This->dynamic_data;
497}
498
500{
501 const BOOL alloc = flags & fdexNameEnsure;
503 dynamic_prop_t *prop;
504
506 if(!data)
507 return E_OUTOFMEMORY;
508
509 for(prop = data->props; prop < data->props+data->prop_cnt; prop++) {
510 if(flags & fdexNameCaseInsensitive ? !strcmpiW(prop->name, name) : !strcmpW(prop->name, name)) {
511 if(prop->flags & DYNPROP_DELETED) {
512 if(!alloc)
513 return DISP_E_UNKNOWNNAME;
514 prop->flags &= ~DYNPROP_DELETED;
515 }
516 *ret = prop;
517 return S_OK;
518 }
519 }
520
521 if(!alloc)
522 return DISP_E_UNKNOWNNAME;
523
524 TRACE("creating dynamic prop %s\n", debugstr_w(name));
525
526 if(!data->buf_size) {
527 data->props = heap_alloc(sizeof(dynamic_prop_t)*4);
528 if(!data->props)
529 return E_OUTOFMEMORY;
530 data->buf_size = 4;
531 }else if(data->buf_size == data->prop_cnt) {
532 dynamic_prop_t *new_props;
533
534 new_props = heap_realloc(data->props, sizeof(dynamic_prop_t)*(data->buf_size<<1));
535 if(!new_props)
536 return E_OUTOFMEMORY;
537
538 data->props = new_props;
539 data->buf_size <<= 1;
540 }
541
542 prop = data->props + data->prop_cnt;
543
544 prop->name = heap_strdupW(name);
545 if(!prop->name)
546 return E_OUTOFMEMORY;
547
548 VariantInit(&prop->var);
549 prop->flags = 0;
550 data->prop_cnt++;
551 *ret = prop;
552 return S_OK;
553}
554
556{
557 dynamic_prop_t *prop;
559
560 hres = get_dynamic_prop(This, name, alloc ? fdexNameEnsure : 0, &prop);
561 if(FAILED(hres))
562 return hres;
563
564 *ret = &prop->var;
565 return S_OK;
566}
567
569{
570 dynamic_prop_t *prop;
572
573 hres = get_dynamic_prop(This, name, fdexNameEnsure, &prop);
574 if(FAILED(hres))
575 return hres;
576
577 *id = DISPID_DYNPROP_0 + (prop - This->dynamic_data->props);
578 return S_OK;
579}
580
582 VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
583{
584 if(This->data->vtbl && This->data->vtbl->value)
585 return This->data->vtbl->value(This, lcid, flags, params, res, ei, caller);
586
587 switch(flags) {
589 V_VT(res) = VT_BSTR;
591 if(!V_BSTR(res))
592 return E_OUTOFMEMORY;
593 break;
594 default:
595 FIXME("Unimplemented flags %x\n", flags);
596 return E_NOTIMPL;
597 }
598
599 return S_OK;
600}
601
603 EXCEPINFO *ei)
604{
605 ITypeInfo *ti;
606 IUnknown *unk;
607 UINT argerr=0;
609
610 hres = get_typeinfo(func->tid, &ti);
611 if(FAILED(hres)) {
612 ERR("Could not get type info: %08x\n", hres);
613 return hres;
614 }
615
616 hres = IUnknown_QueryInterface(This->outer, tid_ids[func->tid], (void**)&unk);
617 if(FAILED(hres)) {
618 ERR("Could not get iface %s: %08x\n", debugstr_mshtml_guid(tid_ids[func->tid]), hres);
619 return E_FAIL;
620 }
621
622 hres = ITypeInfo_Invoke(ti, unk, func->id, flags, dp, res, ei, &argerr);
623
624 IUnknown_Release(unk);
625 return hres;
626}
627
629{
630 return CONTAINING_RECORD(iface, func_disp_t, IUnknown_iface);
631}
632
634{
636
637 TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
638
640 *ppv = &This->IUnknown_iface;
641 }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
642 return *ppv ? S_OK : E_NOINTERFACE;
643 }else {
644 *ppv = NULL;
645 return E_NOINTERFACE;
646 }
647
648 IUnknown_AddRef((IUnknown*)*ppv);
649 return S_OK;
650}
651
653{
656
657 TRACE("(%p) ref=%d\n", This, ref);
658
659 return ref;
660}
661
663{
666
667 TRACE("(%p) ref=%d\n", This, ref);
668
669 if(!ref) {
670 assert(!This->obj);
671 release_dispex(&This->dispex);
673 }
674
675 return ref;
676}
677
678static const IUnknownVtbl FunctionUnkVtbl = {
682};
683
685{
686 return CONTAINING_RECORD(iface, func_disp_t, dispex);
687}
688
689static HRESULT function_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *params,
690 VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
691{
694
695 switch(flags) {
697 if(!res)
698 return E_INVALIDARG;
699 /* fall through */
700 case DISPATCH_METHOD:
701 if(!This->obj)
702 return E_UNEXPECTED;
703 hres = typeinfo_invoke(This->obj, This->info, flags, params, res, ei);
704 break;
706 unsigned name_len;
707 WCHAR *ptr;
708 BSTR str;
709
710 static const WCHAR func_prefixW[] =
711 {'\n','f','u','n','c','t','i','o','n',' '};
712 static const WCHAR func_suffixW[] =
713 {'(',')',' ','{','\n',' ',' ',' ',' ','[','n','a','t','i','v','e',' ','c','o','d','e',']','\n','}','\n'};
714
715 /* FIXME: This probably should be more generic. Also we should try to get IID_IActiveScriptSite and SID_GetCaller. */
716 if(!caller)
717 return E_ACCESSDENIED;
718
719 name_len = SysStringLen(This->info->name);
720 ptr = str = SysAllocStringLen(NULL, name_len + (sizeof(func_prefixW)+sizeof(func_suffixW))/sizeof(WCHAR));
721 if(!str)
722 return E_OUTOFMEMORY;
723
724 memcpy(ptr, func_prefixW, sizeof(func_prefixW));
725 ptr += sizeof(func_prefixW)/sizeof(WCHAR);
726
727 memcpy(ptr, This->info->name, name_len*sizeof(WCHAR));
728 ptr += name_len;
729
730 memcpy(ptr, func_suffixW, sizeof(func_suffixW));
731
732 V_VT(res) = VT_BSTR;
733 V_BSTR(res) = str;
734 return S_OK;
735 }
736 default:
737 FIXME("Unimplemented flags %x\n", flags);
738 hres = E_NOTIMPL;
739 }
740
741 return hres;
742}
743
746 NULL,
747 NULL,
748 NULL
749};
750
751static const tid_t function_iface_tids[] = {0};
752
755 NULL_tid,
756 NULL,
758};
759
761{
763
764 ret = heap_alloc_zero(sizeof(func_disp_t));
765 if(!ret)
766 return NULL;
767
768 ret->IUnknown_iface.lpVtbl = &FunctionUnkVtbl;
769 init_dispex(&ret->dispex, &ret->IUnknown_iface, &function_dispex);
770 ret->ref = 1;
771 ret->obj = obj;
772 ret->info = info;
773
774 return ret;
775}
776
777static HRESULT invoke_disp_value(DispatchEx *This, IDispatch *func_disp, LCID lcid, WORD flags, DISPPARAMS *dp,
778 VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
779{
780 DISPID named_arg = DISPID_THIS;
781 DISPPARAMS new_dp = {NULL, &named_arg, 0, 1};
782 IDispatchEx *dispex;
784
785 if(dp->cNamedArgs) {
786 FIXME("named args not supported\n");
787 return E_NOTIMPL;
788 }
789
790 new_dp.rgvarg = heap_alloc((dp->cArgs+1)*sizeof(VARIANTARG));
791 if(!new_dp.rgvarg)
792 return E_OUTOFMEMORY;
793
794 new_dp.cArgs = dp->cArgs+1;
795 memcpy(new_dp.rgvarg+1, dp->rgvarg, dp->cArgs*sizeof(VARIANTARG));
796
797 V_VT(new_dp.rgvarg) = VT_DISPATCH;
798 V_DISPATCH(new_dp.rgvarg) = (IDispatch*)&This->IDispatchEx_iface;
799
800 hres = IDispatch_QueryInterface(func_disp, &IID_IDispatchEx, (void**)&dispex);
801 TRACE(">>>\n");
802 if(SUCCEEDED(hres)) {
803 hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, lcid, flags, &new_dp, res, ei, caller);
804 IDispatchEx_Release(dispex);
805 }else {
806 ULONG err = 0;
807 hres = IDispatch_Invoke(func_disp, DISPID_VALUE, &IID_NULL, lcid, flags, &new_dp, res, ei, &err);
808 }
809 if(SUCCEEDED(hres))
810 TRACE("<<< %s\n", debugstr_variant(res));
811 else
812 WARN("<<< %08x\n", hres);
813
814 heap_free(new_dp.rgvarg);
815 return hres;
816}
817
819{
820 dispex_dynamic_data_t *dynamic_data;
822
823 dynamic_data = get_dynamic_data(This);
824 if(!dynamic_data)
825 return E_OUTOFMEMORY;
826
827 if(!dynamic_data->func_disps) {
828 dynamic_data->func_disps = heap_alloc_zero(This->data->data->func_disp_cnt * sizeof(*dynamic_data->func_disps));
829 if(!dynamic_data->func_disps)
830 return E_OUTOFMEMORY;
831 }
832
833 entry = dynamic_data->func_disps + func->func_disp_idx;
834 if(!entry->func_obj) {
835 entry->func_obj = create_func_disp(This, func);
836 if(!entry->func_obj)
837 return E_OUTOFMEMORY;
838
839 IDispatchEx_AddRef(&entry->func_obj->dispex.IDispatchEx_iface);
840 V_VT(&entry->val) = VT_DISPATCH;
841 V_DISPATCH(&entry->val) = (IDispatch*)&entry->func_obj->dispex.IDispatchEx_iface;
842 }
843
844 *ret = entry;
845 return S_OK;
846}
847
849{
850 int min, max, n;
851
852 min = 0;
853 max = data->func_cnt-1;
854
855 while(min <= max) {
856 n = (min+max)/2;
857
858 if(data->funcs[n].id == id) {
859 *ret = data->funcs+n;
860 return S_OK;
861 }
862
863 if(data->funcs[n].id < id)
864 min = n+1;
865 else
866 max = n-1;
867 }
868
869 WARN("invalid id %x\n", id);
870 return DISP_E_UNKNOWNNAME;
871}
872
874{
876 int min, max, n, c;
877
879 if(!data)
880 return E_FAIL;
881
882 min = 0;
883 max = data->func_cnt-1;
884
885 while(min <= max) {
886 n = (min+max)/2;
887
888 c = strcmpiW(data->name_table[n]->name, name);
889 if(!c) {
890 if((grfdex & fdexNameCaseSensitive) && strcmpW(data->name_table[n]->name, name))
891 break;
892
893 *ret = data->name_table[n]->id;
894 return S_OK;
895 }
896
897 if(c > 0)
898 max = n-1;
899 else
900 min = n+1;
901 }
902
903 if(This->data->vtbl && This->data->vtbl->get_dispid) {
905
906 hres = This->data->vtbl->get_dispid(This, name, grfdex, ret);
908 return hres;
909 }
910
911 return DISP_E_UNKNOWNNAME;
912}
913
915{
916 V_VT(dst) = VT_EMPTY;
917
918 if(caller) {
921
922 hres = IServiceProvider_QueryService(caller, &SID_VariantConversion, &IID_IVariantChangeType, (void**)&change_type);
923 if(SUCCEEDED(hres)) {
924 hres = IVariantChangeType_ChangeType(change_type, dst, src, LOCALE_NEUTRAL, vt);
925 IVariantChangeType_Release(change_type);
926 return hres;
927 }
928 }
929
930 switch(vt) {
931 case VT_BOOL:
932 if(V_VT(src) == VT_BSTR) {
933 V_VT(dst) = VT_BOOL;
934 V_BOOL(dst) = V_BSTR(src) && *V_BSTR(src) ? VARIANT_TRUE : VARIANT_FALSE;
935 return S_OK;
936 }
937 break;
938 }
939
940 return VariantChangeType(dst, src, 0, vt);
941}
942
944{
945 IUnknown *iface;
947
948 if(dp && dp->cArgs) {
949 FIXME("cArgs %d\n", dp->cArgs);
950 return E_NOTIMPL;
951 }
952
953 assert(func->get_vtbl_off);
954
955 hres = IUnknown_QueryInterface(This->outer, tid_ids[func->tid], (void**)&iface);
956 if(SUCCEEDED(hres)) {
957 switch(func->prop_vt) {
958#define CASE_VT(vt,type,access) \
959 case vt: { \
960 type val; \
961 hres = ((HRESULT (WINAPI*)(IUnknown*,type*))((void**)iface->lpVtbl)[func->get_vtbl_off])(iface,&val); \
962 if(SUCCEEDED(hres)) \
963 access(res) = val; \
964 } \
965 break
967#undef CASE_VT
968 default:
969 FIXME("Unhandled vt %d\n", func->prop_vt);
970 hres = E_NOTIMPL;
971 }
972 IUnknown_Release(iface);
973 }
974
975 if(FAILED(hres))
976 return hres;
977
978 if(func->prop_vt != VT_VARIANT)
979 V_VT(res) = func->prop_vt == VT_PTR ? VT_DISPATCH : func->prop_vt;
980 return S_OK;
981}
982
984{
985 VARIANT *v, tmpv;
986 IUnknown *iface;
988
989 if(dp->cArgs != 1 || (dp->cNamedArgs == 1 && *dp->rgdispidNamedArgs != DISPID_PROPERTYPUT)
990 || dp->cNamedArgs > 1) {
991 FIXME("invalid args\n");
992 return E_INVALIDARG;
993 }
994
995 if(!func->put_vtbl_off) {
996 FIXME("No setter\n");
997 return E_FAIL;
998 }
999
1000 v = dp->rgvarg;
1001 if(func->prop_vt != VT_VARIANT && V_VT(v) != func->prop_vt) {
1002 hres = change_type(&tmpv, v, func->prop_vt, caller);
1003 if(FAILED(hres))
1004 return hres;
1005 v = &tmpv;
1006 }
1007
1008 hres = IUnknown_QueryInterface(This->outer, tid_ids[func->tid], (void**)&iface);
1009 if(SUCCEEDED(hres)) {
1010 switch(func->prop_vt) {
1011#define CASE_VT(vt,type,access) \
1012 case vt: \
1013 hres = ((HRESULT (WINAPI*)(IUnknown*,type))((void**)iface->lpVtbl)[func->put_vtbl_off])(iface,access(v)); \
1014 break
1016#undef CASE_VT
1017 default:
1018 FIXME("Unimplemented vt %d\n", func->prop_vt);
1019 hres = E_NOTIMPL;
1020 }
1021
1022 IUnknown_Release(iface);
1023 }
1024
1025 if(v == &tmpv)
1026 VariantClear(v);
1027 return hres;
1028}
1029
1031{
1032 VARIANT arg_buf[MAX_ARGS], *arg_ptrs[MAX_ARGS], *arg, retv, ret_ref, vhres;
1033 unsigned i, nconv = 0;
1034 IUnknown *iface;
1035 HRESULT hres;
1036
1037 if(dp->cNamedArgs) {
1038 FIXME("Named arguments not supported\n");
1039 return E_NOTIMPL;
1040 }
1041
1042 if(dp->cArgs != func->argc) {
1043 FIXME("Invalid argument count (expected %u, got %u)\n", func->argc, dp->cArgs);
1044 return E_INVALIDARG;
1045 }
1046
1047 hres = IUnknown_QueryInterface(This->outer, tid_ids[func->tid], (void**)&iface);
1048 if(FAILED(hres))
1049 return hres;
1050
1051 for(i=0; i < func->argc; i++) {
1052 arg = dp->rgvarg+dp->cArgs-i-1;
1053 if(func->arg_types[i] == V_VT(arg)) {
1054 arg_ptrs[i] = arg;
1055 }else {
1056 hres = change_type(arg_buf+nconv, arg, func->arg_types[i], caller);
1057 if(FAILED(hres))
1058 break;
1059 arg_ptrs[i] = arg_buf + nconv++;
1060 }
1061 }
1062
1063 if(SUCCEEDED(hres)) {
1064 if(func->prop_vt == VT_VOID) {
1065 V_VT(&retv) = VT_EMPTY;
1066 }else {
1067 V_VT(&retv) = func->prop_vt;
1068 arg_ptrs[func->argc] = &ret_ref;
1069 V_VT(&ret_ref) = VT_BYREF|func->prop_vt;
1070
1071 switch(func->prop_vt) {
1072#define CASE_VT(vt,type,access) \
1073 case vt: \
1074 V_BYREF(&ret_ref) = &access(&retv); \
1075 break
1077#undef CASE_VT
1078 default:
1079 assert(0);
1080 }
1081 }
1082
1083 V_VT(&vhres) = VT_ERROR;
1084 hres = DispCallFunc(iface, func->call_vtbl_off*sizeof(void*), CC_STDCALL, VT_ERROR,
1085 func->argc + (func->prop_vt == VT_VOID ? 0 : 1), func->arg_types, arg_ptrs, &vhres);
1086 }
1087
1088 while(nconv--)
1089 VariantClear(arg_buf+nconv);
1090 IUnknown_Release(iface);
1091 if(FAILED(hres))
1092 return hres;
1093 if(FAILED(V_ERROR(&vhres)))
1094 return V_ERROR(&vhres);
1095
1096 if(res)
1097 *res = retv;
1098 else
1099 VariantClear(&retv);
1100 return V_ERROR(&vhres);
1101}
1102
1104 EXCEPINFO *ei, IServiceProvider *caller)
1105{
1106 HRESULT hres;
1107
1108 switch(flags) {
1110 if(!res)
1111 return E_INVALIDARG;
1112 /* fall through */
1113 case DISPATCH_METHOD:
1114 if(This->dynamic_data && This->dynamic_data->func_disps
1115 && This->dynamic_data->func_disps[func->func_disp_idx].func_obj) {
1116 func_obj_entry_t *entry = This->dynamic_data->func_disps + func->func_disp_idx;
1117
1118 if(V_VT(&entry->val) != VT_DISPATCH) {
1119 FIXME("calling %s not supported\n", debugstr_variant(&entry->val));
1120 return E_NOTIMPL;
1121 }
1122
1123 if((IDispatch*)&entry->func_obj->dispex.IDispatchEx_iface != V_DISPATCH(&entry->val)) {
1124 if(!V_DISPATCH(&entry->val)) {
1125 FIXME("Calling null\n");
1126 return E_FAIL;
1127 }
1128
1129 hres = invoke_disp_value(This, V_DISPATCH(&entry->val), 0, flags, dp, res, ei, NULL);
1130 break;
1131 }
1132 }
1133
1134 if(func->call_vtbl_off)
1135 hres = invoke_builtin_function(This, func, dp, res, caller);
1136 else
1137 hres = typeinfo_invoke(This, func, flags, dp, res, ei);
1138 break;
1139 case DISPATCH_PROPERTYGET: {
1141
1142 if(func->id == DISPID_VALUE) {
1143 BSTR ret;
1144
1146 if(!ret)
1147 return E_OUTOFMEMORY;
1148
1149 V_VT(res) = VT_BSTR;
1150 V_BSTR(res) = ret;
1151 return S_OK;
1152 }
1153
1155 if(FAILED(hres))
1156 return hres;
1157
1158 V_VT(res) = VT_EMPTY;
1159 return VariantCopy(res, &entry->val);
1160 }
1161 case DISPATCH_PROPERTYPUT: {
1163
1164 if(dp->cArgs != 1 || (dp->cNamedArgs == 1 && *dp->rgdispidNamedArgs != DISPID_PROPERTYPUT)
1165 || dp->cNamedArgs > 1) {
1166 FIXME("invalid args\n");
1167 return E_INVALIDARG;
1168 }
1169
1170 /*
1171 * NOTE: Although we have IDispatchEx tests showing, that it's not allowed to set
1172 * function property using InvokeEx, it's possible to do that from jscript.
1173 * Native probably uses some undocumented interface in this case, but it should
1174 * be fine for us to allow IDispatchEx handle that.
1175 */
1177 if(FAILED(hres))
1178 return hres;
1179
1180 return VariantCopy(&entry->val, dp->rgvarg);
1181 }
1182 default:
1183 FIXME("Unimplemented flags %x\n", flags);
1184 hres = E_NOTIMPL;
1185 }
1186
1187 return hres;
1188}
1189
1190static HRESULT invoke_builtin_prop(DispatchEx *This, DISPID id, LCID lcid, WORD flags, DISPPARAMS *dp,
1191 VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
1192{
1195 HRESULT hres;
1196
1198 if(!data)
1199 return E_FAIL;
1200
1201 hres = get_builtin_func(data, id, &func);
1202 if(id == DISPID_VALUE && hres == DISP_E_UNKNOWNNAME)
1203 return dispex_value(This, lcid, flags, dp, res, ei, caller);
1204 if(FAILED(hres))
1205 return hres;
1206
1207 if(func->func_disp_idx != -1)
1208 return function_invoke(This, func, flags, dp, res, ei, caller);
1209
1210 switch(flags) {
1212 if(res)
1213 V_VT(res) = VT_EMPTY;
1214 hres = builtin_propput(This, func, dp, caller);
1215 break;
1217 hres = builtin_propget(This, func, dp, res);
1218 break;
1219 default:
1220 if(!func->get_vtbl_off) {
1221 hres = typeinfo_invoke(This, func, flags, dp, res, ei);
1222 }else {
1223 VARIANT v;
1224
1226 if(FAILED(hres))
1227 return hres;
1228
1229 if(flags != (DISPATCH_PROPERTYGET|DISPATCH_METHOD) || dp->cArgs) {
1230 if(V_VT(&v) != VT_DISPATCH) {
1231 FIXME("Not a function %s flags %08x\n", debugstr_variant(&v), flags);
1232 VariantClear(&v);
1233 return E_FAIL;
1234 }
1235
1236 hres = invoke_disp_value(This, V_DISPATCH(&v), lcid, flags, dp, res, ei, caller);
1237 IDispatch_Release(V_DISPATCH(&v));
1238 }else if(res) {
1239 *res = v;
1240 }else {
1241 VariantClear(&v);
1242 }
1243 }
1244 }
1245
1246 return hres;
1247}
1248
1250{
1251 switch(get_dispid_type(id)) {
1252 case DISPEXPROP_CUSTOM:
1253 FIXME("DISPEXPROP_CUSTOM not supported\n");
1254 return E_NOTIMPL;
1255
1256 case DISPEXPROP_DYNAMIC: {
1257 DWORD idx = id - DISPID_DYNPROP_0;
1258 dynamic_prop_t *prop;
1259
1260 prop = This->dynamic_data->props+idx;
1261 VariantClear(&prop->var);
1262 prop->flags |= DYNPROP_DELETED;
1263 *success = VARIANT_TRUE;
1264 return S_OK;
1265 }
1266 case DISPEXPROP_BUILTIN: {
1267 VARIANT var;
1268 DISPPARAMS dp = {&var,NULL,1,0};
1271 HRESULT hres;
1272
1274 if(!data)
1275 return E_FAIL;
1276
1277 hres = get_builtin_func(data, id, &func);
1278 if(FAILED(hres))
1279 return hres;
1280
1281 /* For builtin functions, we set their value to the original function. */
1282 if(func->func_disp_idx != -1) {
1284
1285 if(!This->dynamic_data || !This->dynamic_data->func_disps
1286 || !This->dynamic_data->func_disps[func->func_disp_idx].func_obj) {
1287 *success = VARIANT_FALSE;
1288 return S_OK;
1289 }
1290
1291 entry = This->dynamic_data->func_disps + func->func_disp_idx;
1292 if(V_VT(&entry->val) == VT_DISPATCH
1293 && V_DISPATCH(&entry->val) == (IDispatch*)&entry->func_obj->dispex.IDispatchEx_iface) {
1294 *success = VARIANT_FALSE;
1295 return S_OK;
1296 }
1297
1298 VariantClear(&entry->val);
1299 V_VT(&entry->val) = VT_DISPATCH;
1300 V_DISPATCH(&entry->val) = (IDispatch*)&entry->func_obj->dispex.IDispatchEx_iface;
1301 IDispatch_AddRef(V_DISPATCH(&entry->val));
1302 *success = VARIANT_TRUE;
1303 return S_OK;
1304 }
1305
1306 V_VT(&var) = VT_EMPTY;
1307 hres = builtin_propput(This, func, &dp, NULL);
1308 if(FAILED(hres))
1309 return hres;
1310
1311 *success = VARIANT_TRUE;
1312 return S_OK;
1313 }
1314 default:
1315 assert(0);
1316 return E_FAIL;
1317 }
1318}
1319
1321{
1322 return CONTAINING_RECORD(iface, DispatchEx, IDispatchEx_iface);
1323}
1324
1326{
1328
1329 return IUnknown_QueryInterface(This->outer, riid, ppv);
1330}
1331
1333{
1335
1336 return IUnknown_AddRef(This->outer);
1337}
1338
1340{
1342
1343 return IUnknown_Release(This->outer);
1344}
1345
1347{
1349
1350 TRACE("(%p)->(%p)\n", This, pctinfo);
1351
1352 *pctinfo = 1;
1353 return S_OK;
1354}
1355
1357 LCID lcid, ITypeInfo **ppTInfo)
1358{
1360 HRESULT hres;
1361
1362 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
1363
1364 hres = get_typeinfo(This->data->disp_tid, ppTInfo);
1365 if(FAILED(hres))
1366 return hres;
1367
1368 ITypeInfo_AddRef(*ppTInfo);
1369 return S_OK;
1370}
1371
1373 LPOLESTR *rgszNames, UINT cNames,
1374 LCID lcid, DISPID *rgDispId)
1375{
1377 UINT i;
1378 HRESULT hres;
1379
1380 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
1381 lcid, rgDispId);
1382
1383 for(i=0; i < cNames; i++) {
1384 hres = IDispatchEx_GetDispID(&This->IDispatchEx_iface, rgszNames[i], 0, rgDispId+i);
1385 if(FAILED(hres))
1386 return hres;
1387 }
1388
1389 return S_OK;
1390}
1391
1393 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1394 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1395{
1397
1398 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1399 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1400
1401 return IDispatchEx_InvokeEx(&This->IDispatchEx_iface, dispIdMember, lcid, wFlags, pDispParams,
1402 pVarResult, pExcepInfo, NULL);
1403}
1404
1406{
1408 dynamic_prop_t *dprop;
1409 HRESULT hres;
1410
1411 TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid);
1412
1413 if(grfdex & ~(fdexNameCaseSensitive|fdexNameCaseInsensitive|fdexNameEnsure|fdexNameImplicit|FDEX_VERSION_MASK))
1414 FIXME("Unsupported grfdex %x\n", grfdex);
1415
1416 hres = get_builtin_id(This, bstrName, grfdex, pid);
1418 return hres;
1419
1420 hres = get_dynamic_prop(This, bstrName, grfdex, &dprop);
1421 if(FAILED(hres))
1422 return hres;
1423
1424 *pid = DISPID_DYNPROP_0 + (dprop - This->dynamic_data->props);
1425 return S_OK;
1426}
1427
1428static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
1429 VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
1430{
1432 HRESULT hres;
1433
1434 TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
1435
1438
1439 switch(get_dispid_type(id)) {
1440 case DISPEXPROP_CUSTOM:
1441 if(!This->data->vtbl || !This->data->vtbl->invoke)
1442 return DISP_E_UNKNOWNNAME;
1443 return This->data->vtbl->invoke(This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
1444
1445 case DISPEXPROP_DYNAMIC: {
1446 DWORD idx = id - DISPID_DYNPROP_0;
1447 dynamic_prop_t *prop;
1448
1449 if(!get_dynamic_data(This) || This->dynamic_data->prop_cnt <= idx)
1450 return DISP_E_UNKNOWNNAME;
1451
1452 prop = This->dynamic_data->props+idx;
1453
1454 switch(wFlags) {
1456 if(!pvarRes)
1457 return E_INVALIDARG;
1458 /* fall through */
1459 case DISPATCH_METHOD:
1460 if(V_VT(&prop->var) != VT_DISPATCH) {
1461 FIXME("invoke %s\n", debugstr_variant(&prop->var));
1462 return E_NOTIMPL;
1463 }
1464
1465 return invoke_disp_value(This, V_DISPATCH(&prop->var), lcid, wFlags, pdp, pvarRes, pei, pspCaller);
1467 if(prop->flags & DYNPROP_DELETED)
1468 return DISP_E_UNKNOWNNAME;
1469 V_VT(pvarRes) = VT_EMPTY;
1470 return variant_copy(pvarRes, &prop->var);
1472 if(pdp->cArgs != 1 || (pdp->cNamedArgs == 1 && *pdp->rgdispidNamedArgs != DISPID_PROPERTYPUT)
1473 || pdp->cNamedArgs > 1) {
1474 FIXME("invalid args\n");
1475 return E_INVALIDARG;
1476 }
1477
1478 TRACE("put %s\n", debugstr_variant(pdp->rgvarg));
1479 VariantClear(&prop->var);
1480 hres = variant_copy(&prop->var, pdp->rgvarg);
1481 if(FAILED(hres))
1482 return hres;
1483
1484 prop->flags &= ~DYNPROP_DELETED;
1485 return S_OK;
1486 default:
1487 FIXME("unhandled wFlags %x\n", wFlags);
1488 return E_NOTIMPL;
1489 }
1490 }
1491 case DISPEXPROP_BUILTIN:
1492 if(wFlags == DISPATCH_CONSTRUCT) {
1493 if(id == DISPID_VALUE) {
1494 if(This->data->vtbl && This->data->vtbl->value) {
1495 return This->data->vtbl->value(This, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
1496 }
1497 FIXME("DISPATCH_CONSTRUCT flag but missing value function\n");
1498 return E_FAIL;
1499 }
1500 FIXME("DISPATCH_CONSTRUCT flag without DISPID_VALUE\n");
1501 return E_FAIL;
1502 }
1503
1504 return invoke_builtin_prop(This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
1505 default:
1506 assert(0);
1507 return E_FAIL;
1508 }
1509}
1510
1512{
1514
1515 TRACE("(%p)->(%s %x)\n", This, debugstr_w(bstrName), grfdex);
1516
1517 /* Not implemented by IE */
1518 return E_NOTIMPL;
1519}
1520
1522{
1524
1525 TRACE("(%p)->(%x)\n", This, id);
1526
1527 /* Not implemented by IE */
1528 return E_NOTIMPL;
1529}
1530
1532{
1534 FIXME("(%p)->(%x %x %p)\n", This, id, grfdexFetch, pgrfdex);
1535 return E_NOTIMPL;
1536}
1537
1539{
1543 HRESULT hres;
1544
1545 TRACE("(%p)->(%x %p)\n", This, id, pbstrName);
1546
1547 if(is_dynamic_dispid(id)) {
1548 DWORD idx = id - DISPID_DYNPROP_0;
1549
1550 if(!get_dynamic_data(This) || This->dynamic_data->prop_cnt <= idx)
1551 return DISP_E_UNKNOWNNAME;
1552
1553 *pbstrName = SysAllocString(This->dynamic_data->props[idx].name);
1554 if(!*pbstrName)
1555 return E_OUTOFMEMORY;
1556
1557 return S_OK;
1558 }
1559
1561 if(!data)
1562 return E_FAIL;
1563
1564 hres = get_builtin_func(data, id, &func);
1565 if(FAILED(hres))
1566 return hres;
1567
1568 *pbstrName = SysAllocString(func->name);
1569 if(!*pbstrName)
1570 return E_OUTOFMEMORY;
1571 return S_OK;
1572}
1573
1575{
1579 HRESULT hres;
1580
1581 TRACE("(%p)->(%x %x %p)\n", This, grfdex, id, pid);
1582
1583 if(is_dynamic_dispid(id)) {
1584 DWORD idx = id - DISPID_DYNPROP_0;
1585
1586 if(!get_dynamic_data(This) || This->dynamic_data->prop_cnt <= idx)
1587 return DISP_E_UNKNOWNNAME;
1588
1589 while(++idx < This->dynamic_data->prop_cnt && This->dynamic_data->props[idx].flags & DYNPROP_DELETED);
1590
1591 if(idx == This->dynamic_data->prop_cnt) {
1592 *pid = DISPID_STARTENUM;
1593 return S_FALSE;
1594 }
1595
1597 return S_OK;
1598 }
1599
1601 if(!data)
1602 return E_FAIL;
1603
1604 if(id == DISPID_STARTENUM) {
1605 func = data->funcs;
1606 }else {
1607 hres = get_builtin_func(data, id, &func);
1608 if(FAILED(hres))
1609 return hres;
1610 func++;
1611 }
1612
1613 while(func < data->funcs+data->func_cnt) {
1614 /* FIXME: Skip hidden properties */
1615 if(func->func_disp_idx == -1) {
1616 *pid = func->id;
1617 return S_OK;
1618 }
1619 func++;
1620 }
1621
1622 if(get_dynamic_data(This) && This->dynamic_data->prop_cnt) {
1624 return S_OK;
1625 }
1626
1627 *pid = DISPID_STARTENUM;
1628 return S_FALSE;
1629}
1630
1632{
1634 FIXME("(%p)->(%p)\n", This, ppunk);
1635 return E_NOTIMPL;
1636}
1637
1638static IDispatchExVtbl DispatchExVtbl = {
1654};
1655
1657{
1659 *ppv = &This->IDispatchEx_iface;
1660 else if(IsEqualGUID(&IID_IDispatchEx, riid))
1661 *ppv = &This->IDispatchEx_iface;
1662 else if(IsEqualGUID(&IID_IDispatchJS, riid))
1663 *ppv = NULL;
1664 else if(IsEqualGUID(&IID_UndocumentedScriptIface, riid))
1665 *ppv = NULL;
1666 else
1667 return FALSE;
1668
1669 if(*ppv)
1670 IUnknown_AddRef((IUnknown*)*ppv);
1671 return TRUE;
1672}
1673
1675{
1676 dynamic_prop_t *prop;
1677
1678 if(!This->dynamic_data)
1679 return;
1680
1681 for(prop = This->dynamic_data->props; prop < This->dynamic_data->props + This->dynamic_data->prop_cnt; prop++) {
1682 if(V_VT(&prop->var) == VT_DISPATCH)
1683 note_cc_edge((nsISupports*)V_DISPATCH(&prop->var), "dispex_data", cb);
1684 }
1685
1686 /* FIXME: Traverse func_disps */
1687}
1688
1690{
1691 dynamic_prop_t *prop;
1692
1693 if(!This->dynamic_data)
1694 return;
1695
1696 for(prop = This->dynamic_data->props; prop < This->dynamic_data->props + This->dynamic_data->prop_cnt; prop++) {
1697 if(V_VT(&prop->var) == VT_DISPATCH) {
1698 V_VT(&prop->var) = VT_EMPTY;
1699 IDispatch_Release(V_DISPATCH(&prop->var));
1700 }else {
1701 VariantClear(&prop->var);
1702 }
1703 }
1704}
1705
1707{
1708 dynamic_prop_t *prop;
1709
1710 if(!This->dynamic_data)
1711 return;
1712
1713 for(prop = This->dynamic_data->props; prop < This->dynamic_data->props + This->dynamic_data->prop_cnt; prop++) {
1714 VariantClear(&prop->var);
1715 heap_free(prop->name);
1716 }
1717
1718 heap_free(This->dynamic_data->props);
1719
1720 if(This->dynamic_data->func_disps) {
1721 func_obj_entry_t *iter;
1722
1723 for(iter = This->dynamic_data->func_disps; iter < This->dynamic_data->func_disps+This->data->data->func_disp_cnt; iter++) {
1724 if(iter->func_obj) {
1725 iter->func_obj->obj = NULL;
1726 IDispatchEx_Release(&iter->func_obj->dispex.IDispatchEx_iface);
1727 }
1728 VariantClear(&iter->val);
1729 }
1730
1731 heap_free(This->dynamic_data->func_disps);
1732 }
1733
1734 heap_free(This->dynamic_data);
1735}
1736
1738{
1739 dispex->IDispatchEx_iface.lpVtbl = &DispatchExVtbl;
1740 dispex->outer = outer;
1741 dispex->data = data;
1742 dispex->dynamic_data = NULL;
1743}
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:71
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static int list_empty(struct list_entry *head)
Definition: list.h:58
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
const GUID IID_IUnknown
Definition: list.h:37
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int idx
Definition: utils.c:41
static WCHAR * heap_strdupW(const WCHAR *str)
Definition: edit.c:4312
OLECHAR * BSTR
Definition: compat.h:2293
unsigned short VARTYPE
Definition: compat.h:2254
short VARIANT_BOOL
Definition: compat.h:2290
@ VT_BSTR
Definition: compat.h:2303
@ VT_VOID
Definition: compat.h:2318
@ VT_BYREF
Definition: compat.h:2342
@ VT_PTR
Definition: compat.h:2320
@ VT_ERROR
Definition: compat.h:2305
@ VT_VARIANT
Definition: compat.h:2307
@ VT_BOOL
Definition: compat.h:2306
@ VT_EMPTY
Definition: compat.h:2295
@ VT_DISPATCH
Definition: compat.h:2304
const char * debugstr_mshtml_guid(const GUID *iid)
Definition: main.c:542
static REFPROPVARIANT PROPVAR_CHANGE_FLAGS VARTYPE vt
Definition: suminfo.c:91
HRESULT WINAPI LoadRegTypeLib(REFGUID rguid, WORD wVerMajor, WORD wVerMinor, LCID lcid, ITypeLib **ppTLib)
Definition: typelib.c:531
HRESULT WINAPI DispCallFunc(void *pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn, UINT cActuals, VARTYPE *prgvt, VARIANTARG **prgpvarg, VARIANT *pvargResult)
Definition: typelib.c:7071
#define assert(x)
Definition: debug.h:53
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
const GLdouble * v
Definition: gl.h:2040
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLenum func
Definition: glext.h:6028
GLdouble n
Definition: glext.h:7729
GLuint res
Definition: glext.h:9613
GLenum src
Definition: glext.h:6340
GLuint * ids
Definition: glext.h:5907
const GLubyte * c
Definition: glext.h:8905
GLenum const GLfloat * params
Definition: glext.h:5645
GLenum GLenum dst
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
tid_t
Definition: ieframe.h:311
@ LAST_tid
Definition: ieframe.h:317
#define TID_LIST
Definition: ieframe.h:306
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
#define FDEX_VERSION_MASK
Definition: dispex.c:27
static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
Definition: dispex.c:703
static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
Definition: dispex.c:845
static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
Definition: dispex.c:628
static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
Definition: dispex.c:656
static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
Definition: dispex.c:828
static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
Definition: dispex.c:883
static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
Definition: dispex.c:689
static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: dispex.c:676
static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
Definition: dispex.c:852
static jsdisp_t * impl_from_IDispatchEx(IDispatchEx *iface)
Definition: dispex.c:593
static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
Definition: dispex.c:870
static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
Definition: dispex.c:598
HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype)
Definition: dispex.c:919
static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
Definition: dispex.c:621
static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
Definition: dispex.c:648
static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
Definition: dispex.c:805
static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
Definition: dispex.c:638
static IDispatchExVtbl DispatchExVtbl
Definition: dispex.c:890
#define c
Definition: ke_i.h:80
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
static const WCHAR desc[]
Definition: protectdata.c:36
const char * var
Definition: shader.c:5666
static const char * debugstr_variant(const VARIANT *var)
Definition: container.c:46
HRESULT hres
Definition: protocol.c:465
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
static TfClientId tid
static char * dest
Definition: rtl.c:135
static LPOLESTR
Definition: stg_prop.c:27
static VARIANTARG static DISPID
Definition: ordinal.c:52
#define min(a, b)
Definition: monoChain.cc:55
static HRESULT builtin_propput(DispatchEx *This, func_info_t *func, DISPPARAMS *dp, IServiceProvider *caller)
Definition: dispex.c:983
#define DISPID_DYNPROP_MAX
Definition: dispex.c:86
static HRESULT get_dynamic_prop(DispatchEx *This, const WCHAR *name, DWORD flags, dynamic_prop_t **ret)
Definition: dispex.c:499
static dispex_data_t * preprocess_dispex_data(DispatchEx *This)
Definition: dispex.c:313
void release_dispex(DispatchEx *This)
Definition: dispex.c:1706
static struct list dispex_data_list
Definition: dispex.c:92
static int func_name_cmp(const void *p1, const void *p2)
Definition: dispex.c:308
#define MAX_ARGS
Definition: dispex.c:21
void dispex_traverse(DispatchEx *This, nsCycleCollectionTraversalCallback *cb)
Definition: dispex.c:1674
static HRESULT variant_copy(VARIANT *dest, VARIANT *src)
Definition: dispex.c:473
static HRESULT get_func_obj_entry(DispatchEx *This, func_info_t *func, func_obj_entry_t **ret)
Definition: dispex.c:818
static CRITICAL_SECTION cs_dispex_static_data
Definition: dispex.c:23
static void add_func_info(dispex_data_t *data, DWORD *size, tid_t tid, const FUNCDESC *desc, ITypeInfo *dti)
Definition: dispex.c:213
void dispex_unlink(DispatchEx *This)
Definition: dispex.c:1689
static ITypeLib * typelib
Definition: dispex.c:90
static BOOL is_custom_dispid(DISPID id)
Definition: dispex.c:454
HRESULT remove_attribute(DispatchEx *This, DISPID id, VARIANT_BOOL *success)
Definition: dispex.c:1249
#define BUILTIN_TYPES_SWITCH
Definition: dispex.c:196
static HRESULT WINAPI Function_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
Definition: dispex.c:633
static BOOL is_dynamic_dispid(DISPID id)
Definition: dispex.c:459
static HRESULT get_builtin_func(dispex_data_t *data, DISPID id, func_info_t **ret)
Definition: dispex.c:848
static dispex_static_data_t function_dispex
Definition: dispex.c:753
BOOL dispex_query_interface(DispatchEx *This, REFIID riid, void **ppv)
Definition: dispex.c:1656
static HRESULT invoke_builtin_prop(DispatchEx *This, DISPID id, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
Definition: dispex.c:1190
static HRESULT invoke_builtin_function(DispatchEx *This, func_info_t *func, DISPPARAMS *dp, VARIANT *res, IServiceProvider *caller)
Definition: dispex.c:1030
static HRESULT invoke_disp_value(DispatchEx *This, IDispatch *func_disp, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
Definition: dispex.c:777
HRESULT get_dispids(tid_t tid, DWORD *ret_size, DISPID **ret)
Definition: dispex.c:389
static int id_cmp(const void *p1, const void *p2)
Definition: dispex.c:384
static HRESULT function_invoke(DispatchEx *This, func_info_t *func, WORD flags, DISPPARAMS *dp, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
Definition: dispex.c:1103
static ULONG WINAPI Function_AddRef(IUnknown *iface)
Definition: dispex.c:652
#define BUILTIN_ARG_TYPES_SWITCH
Definition: dispex.c:188
static HRESULT typeinfo_invoke(DispatchEx *This, func_info_t *func, WORD flags, DISPPARAMS *dp, VARIANT *res, EXCEPINFO *ei)
Definition: dispex.c:602
static dispex_dynamic_data_t * get_dynamic_data(DispatchEx *This)
Definition: dispex.c:484
HRESULT dispex_get_dynid(DispatchEx *This, const WCHAR *name, DISPID *id)
Definition: dispex.c:568
static int dispid_cmp(const void *p1, const void *p2)
Definition: dispex.c:303
static ULONG WINAPI Function_Release(IUnknown *iface)
Definition: dispex.c:662
#define DYNPROP_DELETED
Definition: dispex.c:63
static CRITICAL_SECTION_DEBUG cs_dispex_static_data_dbg
Definition: dispex.c:24
void release_typelib(void)
Definition: dispex.c:144
static HRESULT load_typelib(void)
Definition: dispex.c:102
static HRESULT dispex_value(DispatchEx *This, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
Definition: dispex.c:581
dispex_prop_type_t get_dispid_type(DISPID id)
Definition: dispex.c:464
static REFIID tid_ids[]
Definition: dispex.c:94
static HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo)
Definition: dispex.c:118
static HRESULT get_builtin_id(DispatchEx *This, BSTR name, DWORD grfdex, DISPID *ret)
Definition: dispex.c:873
static BOOL is_arg_type_supported(VARTYPE vt)
Definition: dispex.c:203
static func_disp_t * impl_from_IUnknown(IUnknown *iface)
Definition: dispex.c:628
static HRESULT builtin_propget(DispatchEx *This, func_info_t *func, DISPPARAMS *dp, VARIANT *res)
Definition: dispex.c:943
static const WCHAR objectW[]
Definition: dispex.c:33
HRESULT dispex_get_dprop_ref(DispatchEx *This, const WCHAR *name, BOOL alloc, VARIANT **ret)
Definition: dispex.c:555
static func_disp_t * impl_from_DispatchEx(DispatchEx *iface)
Definition: dispex.c:684
static const IUnknownVtbl FunctionUnkVtbl
Definition: dispex.c:678
static const dispex_static_data_vtbl_t function_dispex_vtbl
Definition: dispex.c:744
static HRESULT change_type(VARIANT *dst, VARIANT *src, VARTYPE vt, IServiceProvider *caller)
Definition: dispex.c:914
static dispex_data_t * get_dispex_data(DispatchEx *This)
Definition: dispex.c:439
static HRESULT function_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
Definition: dispex.c:689
static const tid_t function_iface_tids[]
Definition: dispex.c:751
#define DISPID_DYNPROP_0
Definition: dispex.c:85
HRESULT get_htmldoc_classinfo(ITypeInfo **typeinfo)
Definition: dispex.c:172
static func_disp_t * create_func_disp(DispatchEx *obj, func_info_t *info)
Definition: dispex.c:760
static ITypeInfo * typeinfos[LAST_tid]
Definition: dispex.c:91
dispex_prop_type_t
@ DISPEXPROP_CUSTOM
@ DISPEXPROP_DYNAMIC
@ DISPEXPROP_BUILTIN
struct nsCycleCollectionTraversalCallback nsCycleCollectionTraversalCallback
#define MSHTML_DISPID_CUSTOM_MIN
#define MSHTML_DISPID_CUSTOM_MAX
@ NULL_tid
Definition: msxml_private.h:45
unsigned int UINT
Definition: ndis.h:50
#define LOCALE_NEUTRAL
#define LOCALE_SYSTEM_DEFAULT
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
UINT WINAPI SysStringLen(BSTR str)
Definition: oleaut.c:196
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:339
#define V_ERROR(A)
Definition: oleauto.h:241
#define V_BOOL(A)
Definition: oleauto.h:224
#define DISPATCH_PROPERTYPUT
Definition: oleauto.h:1008
#define DISPATCH_METHOD
Definition: oleauto.h:1006
#define V_VT(A)
Definition: oleauto.h:211
#define V_BSTR(A)
Definition: oleauto.h:226
#define V_DISPATCH(A)
Definition: oleauto.h:239
#define DISPATCH_PROPERTYGET
Definition: oleauto.h:1007
#define DISPATCH_PROPERTYPUTREF
Definition: oleauto.h:1009
#define DISPID_THIS
Definition: olectl.h:395
const GUID IID_IDispatch
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define IID_NULL
Definition: guiddef.h:98
#define strcmpW(s1, s2)
Definition: unicode.h:44
#define strcmpiW(s1, s2)
Definition: unicode.h:45
#define err(...)
#define alloc
Definition: rosglue.h:13
const WCHAR * str
DWORD LCID
Definition: nls.h:13
static struct __wine_debug_functions funcs
Definition: debug.c:59
void __cdecl qsort(_Inout_updates_bytes_(_NumOfElements *_SizeOfElements) void *_Base, _In_ size_t _NumOfElements, _In_ size_t _SizeOfElements, _In_ int(__cdecl *_PtFuncCompare)(const void *, const void *))
#define TRACE(s)
Definition: solgame.cpp:4
@ CC_STDCALL
Definition: spec2def.c:93
dispex_static_data_t * data
IDispatchEx IDispatchEx_iface
dispex_dynamic_data_t * dynamic_data
IUnknown * outer
LIST_ENTRY ProcessLocksList
Definition: winbase.h:907
Definition: cookie.c:202
func_info_t * funcs
Definition: dispex.c:50
DWORD func_disp_cnt
Definition: dispex.c:52
DWORD func_cnt
Definition: dispex.c:49
func_info_t ** name_table
Definition: dispex.c:51
struct list entry
Definition: dispex.c:54
func_obj_entry_t * func_disps
Definition: dispex.c:82
dynamic_prop_t * props
Definition: dispex.c:81
DWORD flags
Definition: dispex.c:60
LPWSTR name
Definition: dispex.c:59
VARIANT var
Definition: dispex.c:58
func_info_t * info
Definition: dispex.c:70
DispatchEx dispex
Definition: dispex.c:66
LONG ref
Definition: dispex.c:68
DispatchEx * obj
Definition: dispex.c:69
IUnknown IUnknown_iface
Definition: dispex.c:67
tid_t tid
Definition: dispex.c:38
VARTYPE prop_vt
Definition: dispex.c:44
DISPID id
Definition: dispex.c:36
BSTR name
Definition: dispex.c:37
SHORT get_vtbl_off
Definition: dispex.c:41
SHORT func_disp_idx
Definition: dispex.c:42
USHORT argc
Definition: dispex.c:43
VARTYPE * arg_types
Definition: dispex.c:45
SHORT put_vtbl_off
Definition: dispex.c:40
SHORT call_vtbl_off
Definition: dispex.c:39
Definition: dispex.c:73
VARIANT val
Definition: dispex.c:75
func_disp_t * func_obj
Definition: dispex.c:74
Definition: list.h:15
Definition: name.c:39
Definition: send.c:48
#define max(a, b)
Definition: svc.c:63
#define LIST_INIT(head)
Definition: queue.h:197
#define LIST_ENTRY(type)
Definition: queue.h:175
#define DWORD_PTR
Definition: treelist.c:76
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
HRESULT WINAPI DECLSPEC_HOTPATCH VariantChangeType(VARIANTARG *pvargDest, VARIANTARG *pvargSrc, USHORT wFlags, VARTYPE vt)
Definition: variant.c:962
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:568
HRESULT WINAPI VariantCopy(VARIANTARG *pvargDest, VARIANTARG *pvargSrc)
Definition: variant.c:748
static const WCHAR props[]
Definition: wbemdisp.c:288
int ret
#define success(from, fromstr, to, tostr)
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:531
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3837
void * arg
Definition: msvc.h:10
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define E_NOINTERFACE
Definition: winerror.h:2364
#define E_ACCESSDENIED
Definition: winerror.h:2849
#define E_UNEXPECTED
Definition: winerror.h:2456
#define DISP_E_UNKNOWNNAME
Definition: winerror.h:2515
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184