ReactOS  0.4.13-dev-101-g0ca4b50
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 {
26  0, 0, &cs_dispex_static_data,
28  0, 0, { (DWORD_PTR)(__FILE__ ": dispex_static_data") }
29 };
31 
32 
33 static const WCHAR objectW[] = {'[','o','b','j','e','c','t',']',0};
34 
35 typedef struct {
46 } func_info_t;
47 
48 struct dispex_data_t {
53 
54  struct list entry;
55 };
56 
57 typedef struct {
62 
63 #define DYNPROP_DELETED 0x01
64 
65 typedef struct {
71 } func_disp_t;
72 
73 typedef struct {
77 
83 };
84 
85 #define DISPID_DYNPROP_0 0x50000000
86 #define DISPID_DYNPROP_MAX 0x5fffffff
87 
88 #define FDEX_VERSION_MASK 0xf0000000
89 
90 static ITypeLib *typelib;
93 
94 static REFIID tid_ids[] = {
95 #define XIID(iface) &IID_ ## iface,
96 #define XDIID(iface) &DIID_ ## iface,
98 #undef XIID
99 #undef XDIID
100 };
101 
102 static HRESULT load_typelib(void)
103 {
104  HRESULT hres;
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 {
120  HRESULT hres;
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 
140  *typeinfo = typeinfos[tid];
141  return S_OK;
142 }
143 
144 void release_typelib(void)
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 {
174  HRESULT hres;
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 
213 static void add_func_info(dispex_data_t *data, DWORD *size, tid_t tid, const FUNCDESC *desc, ITypeInfo *dti)
214 {
215  func_info_t *info;
216  HRESULT hres;
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)) {
286  VARTYPE vt = VT_EMPTY;
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 
303 static 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 
308 static 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;
320  HRESULT hres;
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 
384 static 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;
396  HRESULT hres;
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 
454 static inline BOOL is_custom_dispid(DISPID id)
455 {
457 }
458 
459 static inline BOOL is_dynamic_dispid(DISPID id)
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;
558  HRESULT hres;
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;
571  HRESULT hres;
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;
608  HRESULT hres;
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 
639  if(IsEqualGUID(&IID_IUnknown, riid)) {
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);
672  heap_free(This);
673  }
674 
675  return ref;
676 }
677 
678 static const IUnknownVtbl FunctionUnkVtbl = {
682 };
683 
685 {
686  return CONTAINING_RECORD(iface, func_disp_t, dispex);
687 }
688 
690  VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
691 {
693  HRESULT hres;
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;
705  case DISPATCH_PROPERTYGET: {
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 
751 static const tid_t function_iface_tids[] = {0};
752 
755  NULL_tid,
756  NULL,
758 };
759 
761 {
762  func_disp_t *ret;
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 
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;
783  HRESULT hres;
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) {
904  HRESULT hres;
905 
906  hres = This->data->vtbl->get_dispid(This, name, grfdex, ret);
907  if(hres != DISP_E_UNKNOWNNAME)
908  return hres;
909  }
910 
911  return DISP_E_UNKNOWNNAME;
912 }
913 
915 {
916  V_VT(dst) = VT_EMPTY;
917 
918  if(caller) {
919  IVariantChangeType *change_type = NULL;
920  HRESULT hres;
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;
946  HRESULT hres;
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;
987  HRESULT hres;
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 
1191  VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
1192 {
1194  func_info_t *func;
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) {
1211  case DISPATCH_PROPERTYPUT:
1212  if(res)
1213  V_VT(res) = VT_EMPTY;
1214  hres = builtin_propput(This, func, dp, caller);
1215  break;
1216  case DISPATCH_PROPERTYGET:
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};
1270  func_info_t *func;
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 
1320 static inline DispatchEx *impl_from_IDispatchEx(IDispatchEx *iface)
1321 {
1322  return CONTAINING_RECORD(iface, DispatchEx, IDispatchEx_iface);
1323 }
1324 
1325 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
1326 {
1328 
1329  return IUnknown_QueryInterface(This->outer, riid, ppv);
1330 }
1331 
1332 static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
1333 {
1335 
1336  return IUnknown_AddRef(This->outer);
1337 }
1338 
1339 static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
1340 {
1342 
1343  return IUnknown_Release(This->outer);
1344 }
1345 
1346 static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
1347 {
1349 
1350  TRACE("(%p)->(%p)\n", This, pctinfo);
1351 
1352  *pctinfo = 1;
1353  return S_OK;
1354 }
1355 
1356 static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
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 
1392 static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
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 
1405 static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
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);
1417  if(hres != DISP_E_UNKNOWNNAME)
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 
1428 static 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);
1466  case DISPATCH_PROPERTYGET:
1467  if(prop->flags & DYNPROP_DELETED)
1468  return DISP_E_UNKNOWNNAME;
1469  V_VT(pvarRes) = VT_EMPTY;
1470  return variant_copy(pvarRes, &prop->var);
1471  case DISPATCH_PROPERTYPUT:
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 
1511 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
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 
1531 static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
1532 {
1534  FIXME("(%p)->(%x %x %p)\n", This, id, grfdexFetch, pgrfdex);
1535  return E_NOTIMPL;
1536 }
1537 
1538 static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
1539 {
1542  func_info_t *func;
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 
1574 static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
1575 {
1578  func_info_t *func;
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) {
1623  *pid = DISPID_DYNPROP_0;
1624  return S_OK;
1625  }
1626 
1627  *pid = DISPID_STARTENUM;
1628  return S_FALSE;
1629 }
1630 
1631 static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
1632 {
1634  FIXME("(%p)->(%p)\n", This, ppunk);
1635  return E_NOTIMPL;
1636 }
1637 
1638 static 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 }
VARTYPE * arg_types
Definition: dispex.c:45
GLenum func
Definition: glext.h:6028
#define DISP_E_UNKNOWNNAME
Definition: winerror.h:2515
dispex_prop_type_t
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3835
#define E_ACCESSDENIED
Definition: winerror.h:2849
#define max(a, b)
Definition: svc.c:63
HRESULT WINAPI DECLSPEC_HOTPATCH VariantChangeType(VARIANTARG *pvargDest, VARIANTARG *pvargSrc, USHORT wFlags, VARTYPE vt)
Definition: variant.c:965
#define REFIID
Definition: guiddef.h:113
#define TRUE
Definition: types.h:120
void release_typelib(void)
Definition: dispex.c:144
#define E_NOINTERFACE
Definition: winerror.h:2364
#define DISPATCH_PROPERTYGET
Definition: oleauto.h:1007
static dispex_static_data_t function_dispex
Definition: dispex.c:753
#define DWORD_PTR
Definition: treelist.c:76
DISPID id
Definition: dispex.c:36
static HRESULT WINAPI Function_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
Definition: dispex.c:633
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:342
static dispex_data_t * preprocess_dispex_data(DispatchEx *This)
Definition: dispex.c:313
static HRESULT function_invoke(DispatchEx *This, func_info_t *func, WORD flags, DISPPARAMS *dp, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
Definition: dispex.c:1103
HRESULT dispex_get_dynid(DispatchEx *This, const WCHAR *name, DISPID *id)
Definition: dispex.c:568
func_info_t ** name_table
Definition: dispex.c:51
#define BUILTIN_TYPES_SWITCH
Definition: dispex.c:196
REFIID riid
Definition: precomp.h:44
static DispatchEx * impl_from_IDispatchEx(IDispatchEx *iface)
Definition: dispex.c:1320
#define MSHTML_DISPID_CUSTOM_MIN
#define FDEX_VERSION_MASK
Definition: dispex.c:88
void dispex_unlink(DispatchEx *This)
Definition: dispex.c:1689
tid_t
Definition: ieframe.h:311
static HRESULT builtin_propput(DispatchEx *This, func_info_t *func, DISPPARAMS *dp, IServiceProvider *caller)
Definition: dispex.c:983
uint8_t entry
Definition: isohybrid.c:63
#define WARN(fmt,...)
Definition: debug.h:111
static int id_cmp(const void *p1, const void *p2)
Definition: dispex.c:384
static REFIID tid_ids[]
Definition: dispex.c:94
static const WCHAR objectW[]
Definition: dispex.c:33
static func_disp_t * impl_from_DispatchEx(DispatchEx *iface)
Definition: dispex.c:684
REFIID LPVOID * ppv
Definition: atlbase.h:39
GLdouble n
Definition: glext.h:7729
static HRESULT function_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
Definition: dispex.c:689
#define assert(x)
Definition: debug.h:53
#define DISPID_DYNPROP_MAX
Definition: dispex.c:86
static CRITICAL_SECTION_DEBUG cs_dispex_static_data_dbg
Definition: dispex.c:24
void * arg
Definition: msvc.h:12
DWORD LCID
Definition: nls.h:13
OLECHAR * BSTR
Definition: compat.h:1934
static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
Definition: dispex.c:1521
VARIANT val
Definition: dispex.c:75
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:571
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
static LPOLESTR
Definition: stg_prop.c:27
#define E_FAIL
Definition: ddrawi.h:102
short VARIANT_BOOL
Definition: compat.h:1931
Definition: send.c:47
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:70
HRESULT dispex_get_dprop_ref(DispatchEx *This, const WCHAR *name, BOOL alloc, VARIANT **ret)
Definition: dispex.c:555
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
static HRESULT get_builtin_id(DispatchEx *This, BSTR name, DWORD grfdex, DISPID *ret)
Definition: dispex.c:873
Definition: dispex.c:73
USHORT argc
Definition: dispex.c:43
#define DISPATCH_METHOD
Definition: oleauto.h:1006
GLsizei GLsizei GLuint * obj
Definition: glext.h:6042
__WINE_SERVER_LIST_INLINE struct list * list_head(const struct list *list)
Definition: list.h:131
struct _test_info info[]
Definition: SetCursorPos.c:19
#define V_DISPATCH(A)
Definition: oleauto.h:239
const char * debugstr_mshtml_guid(const GUID *iid)
Definition: main.c:535
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
GLuint * ids
Definition: glext.h:5907
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
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
static BOOL is_custom_dispid(DISPID id)
Definition: dispex.c:454
static BOOL is_arg_type_supported(VARTYPE vt)
Definition: dispex.c:203
HRESULT remove_attribute(DispatchEx *This, DISPID id, VARIANT_BOOL *success)
Definition: dispex.c:1249
GLenum const GLfloat * params
Definition: glext.h:5645
static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
Definition: dispex.c:1356
static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
Definition: dispex.c:1346
unsigned int BOOL
Definition: ntddk_ex.h:94
#define DISPID_DYNPROP_0
Definition: dispex.c:85
long LONG
Definition: pedump.c:60
#define MAX_ARGS
Definition: dispex.c:21
static ITypeLib * typelib
Definition: dispex.c:90
short SHORT
Definition: pedump.c:59
static WCHAR * heap_strdupW(const WCHAR *str)
Definition: propsheet.c:178
#define debugstr_w
Definition: kernel32.h:32
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 *))
GLenum GLint ref
Definition: glext.h:6028
#define FIXME(fmt,...)
Definition: debug.h:110
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
static PVOID ptr
Definition: dispmode.c:27
IUnknown IUnknown_iface
Definition: dispex.c:67
unsigned int idx
Definition: utils.c:41
#define S_FALSE
Definition: winerror.h:2357
static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
Definition: dispex.c:1405
static HRESULT get_func_obj_entry(DispatchEx *This, func_info_t *func, func_obj_entry_t **ret)
Definition: dispex.c:818
#define E_INVALIDARG
Definition: ddrawi.h:101
const WCHAR * str
const struct builtin_class_descr * desc
Definition: regcontrol.c:48
smooth NULL
Definition: ftsmooth.c:416
DWORD func_cnt
Definition: dispex.c:49
SHORT put_vtbl_off
Definition: dispex.c:40
static int func_name_cmp(const void *p1, const void *p2)
Definition: dispex.c:308
static ITypeInfo * typeinfos[LAST_tid]
Definition: dispex.c:91
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:241
static HRESULT load_typelib(void)
Definition: dispex.c:102
IDispatchEx IDispatchEx_iface
DWORD flags
Definition: dispex.c:60
#define debugstr_guid
Definition: kernel32.h:35
#define DISPATCH_PROPERTYPUT
Definition: oleauto.h:1008
static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
Definition: dispex.c:1511
#define TID_LIST
Definition: ieframe.h:306
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
func_disp_t * func_obj
Definition: dispex.c:74
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
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 WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
Definition: dispex.c:1631
SHORT get_vtbl_off
Definition: dispex.c:41
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
Definition: dispex.c:1538
#define BUILTIN_ARG_TYPES_SWITCH
Definition: dispex.c:188
#define TRACE(s)
Definition: solgame.cpp:4
static HRESULT dispex_value(DispatchEx *This, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
Definition: dispex.c:581
GLsizeiptr size
Definition: glext.h:5919
HRESULT hres
Definition: protocol.c:465
#define LIST_INIT(head)
Definition: queue.h:197
__wchar_t WCHAR
Definition: xmlstorage.h:180
dispex_static_data_t * data
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
static ULONG WINAPI Function_AddRef(IUnknown *iface)
Definition: dispex.c:652
LONG HRESULT
Definition: typedefs.h:77
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:1392
const GUID IID_IUnknown
static dispex_dynamic_data_t * get_dynamic_data(DispatchEx *This)
Definition: dispex.c:484
#define WINAPI
Definition: msvc.h:8
const GLubyte * c
Definition: glext.h:8905
#define LOCALE_SYSTEM_DEFAULT
static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
Definition: dispex.c:1339
static struct __wine_debug_functions funcs
Definition: debug.c:59
#define V_BOOL(A)
Definition: oleauto.h:224
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
BSTR name
Definition: dispex.c:37
static func_disp_t * impl_from_IUnknown(IUnknown *iface)
Definition: dispex.c:628
#define success(from, fromstr, to, tostr)
Definition: cookie.c:170
static REFPROPVARIANT PROPVAR_CHANGE_FLAGS VARTYPE vt
Definition: suminfo.c:85
static DWORD cb
Definition: integrity.c:41
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLbitfield flags
Definition: glext.h:7161
func_info_t * funcs
Definition: dispex.c:50
static const tid_t function_iface_tids[]
Definition: dispex.c:751
const GUID IID_IDispatch
int ret
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:651
__u8 attr
Definition: mkdosfs.c:359
static IDispatchExVtbl DispatchExVtbl
Definition: dispex.c:1638
LONG ref
Definition: dispex.c:68
#define IID_NULL
Definition: guiddef.h:93
#define InterlockedDecrement
Definition: armddk.h:52
SHORT call_vtbl_off
Definition: dispex.c:39
#define V_VT(A)
Definition: oleauto.h:211
static void add_func_info(dispex_data_t *data, DWORD *size, tid_t tid, const FUNCDESC *desc, ITypeInfo *dti)
Definition: dispex.c:213
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static int dispid_cmp(const void *p1, const void *p2)
Definition: dispex.c:303
Definition: _list.h:228
UINT WINAPI SysStringLen(BSTR str)
Definition: oleaut.c:199
static HRESULT change_type(VARIANT *dst, VARIANT *src, VARTYPE vt, IServiceProvider *caller)
Definition: dispex.c:914
GLenum src
Definition: glext.h:6340
#define err(...)
LIST_ENTRY ProcessLocksList
Definition: winbase.h:848
static BOOL is_dynamic_dispid(DISPID id)
Definition: dispex.c:459
void dispex_traverse(DispatchEx *This, nsCycleCollectionTraversalCallback *cb)
Definition: dispex.c:1674
static struct list dispex_data_list
Definition: dispex.c:92
#define V_BSTR(A)
Definition: oleauto.h:226
#define DISPATCH_PROPERTYPUTREF
Definition: oleauto.h:1009
#define strcmpiW(s1, s2)
Definition: unicode.h:39
static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
Definition: dispex.c:1531
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:519
#define ERR(fmt,...)
Definition: debug.h:109
dispex_prop_type_t get_dispid_type(DISPID id)
Definition: dispex.c:464
#define MSHTML_DISPID_CUSTOM_MAX
dispex_dynamic_data_t * dynamic_data
static HRESULT get_dynamic_prop(DispatchEx *This, const WCHAR *name, DWORD flags, dynamic_prop_t **ret)
Definition: dispex.c:499
HRESULT get_dispids(tid_t tid, DWORD *ret_size, DISPID **ret)
Definition: dispex.c:389
struct stdole::EXCEPINFO EXCEPINFO
__WINE_SERVER_LIST_INLINE int list_empty(const struct list *list)
Definition: list.h:143
static const char * debugstr_variant(const VARIANT *var)
Definition: container.c:46
#define S_OK
Definition: intsafe.h:59
static VARIANTARG static DISPID
Definition: ordinal.c:49
static dispex_data_t * get_dispex_data(DispatchEx *This)
Definition: dispex.c:439
HRESULT WINAPI LoadRegTypeLib(REFGUID rguid, WORD wVerMajor, WORD wVerMinor, LCID lcid, ITypeLib **ppTLib)
Definition: typelib.c:534
#define DISPID_THIS
Definition: olectl.h:395
static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
Definition: dispex.c:1325
#define InterlockedIncrement
Definition: armddk.h:53
const GLdouble * v
Definition: gl.h:2040
dynamic_prop_t * props
Definition: dispex.c:81
BOOL dispex_query_interface(DispatchEx *This, REFIID riid, void **ppv)
Definition: dispex.c:1656
VARIANT var
Definition: dispex.c:58
unsigned short USHORT
Definition: pedump.c:61
static HRESULT variant_copy(VARIANT *dest, VARIANT *src)
Definition: dispex.c:473
static const dispex_static_data_vtbl_t function_dispex_vtbl
Definition: dispex.c:744
struct nsCycleCollectionTraversalCallback nsCycleCollectionTraversalCallback
static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
Definition: dispex.c:1428
struct list entry
Definition: dispex.c:54
#define E_NOTIMPL
Definition: ddrawi.h:99
GLenum GLenum dst
Definition: glext.h:6340
unsigned short VARTYPE
Definition: compat.h:1895
#define min(a, b)
Definition: monoChain.cc:55
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:274
#define alloc
Definition: rosglue.h:13
#define V_ERROR(A)
Definition: oleauto.h:241
VARTYPE prop_vt
Definition: dispex.c:44
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
static func_disp_t * create_func_disp(DispatchEx *obj, func_info_t *info)
Definition: dispex.c:760
HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype)
Definition: dispex.c:940
#define E_UNEXPECTED
Definition: winerror.h:2456
Definition: name.c:36
WINE_UNICODE_INLINE int strcmpW(const WCHAR *str1, const WCHAR *str2)
Definition: unicode.h:229
static const WCHAR props[]
Definition: wbemdisp.c:288
GLuint res
Definition: glext.h:9613
struct stdole::DISPPARAMS DISPPARAMS
static HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo)
Definition: dispex.c:118
#define c
Definition: ke_i.h:80
unsigned int ULONG
Definition: retypes.h:1
IUnknown * outer
#define LOCALE_NEUTRAL
static HRESULT get_builtin_func(dispex_data_t *data, DISPID id, func_info_t **ret)
Definition: dispex.c:848
static HRESULT builtin_propget(DispatchEx *This, func_info_t *func, DISPPARAMS *dp, VARIANT *res)
Definition: dispex.c:943
static char * dest
Definition: rtl.c:135
static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
Definition: dispex.c:1372
static HRESULT typeinfo_invoke(DispatchEx *This, func_info_t *func, WORD flags, DISPPARAMS *dp, VARIANT *res, EXCEPINFO *ei)
Definition: dispex.c:602
func_obj_entry_t * func_disps
Definition: dispex.c:82
static ULONG WINAPI Function_Release(IUnknown *iface)
Definition: dispex.c:662
static HRESULT invoke_builtin_function(DispatchEx *This, func_info_t *func, DISPPARAMS *dp, VARIANT *res, IServiceProvider *caller)
Definition: dispex.c:1030
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define LIST_ENTRY(type)
Definition: queue.h:175
HRESULT WINAPI VariantCopy(VARIANTARG *pvargDest, VARIANTARG *pvargSrc)
Definition: variant.c:751
LPWSTR name
Definition: dispex.c:59
func_info_t * info
Definition: dispex.c:70
tid_t tid
Definition: dispex.c:38
SHORT func_disp_idx
Definition: dispex.c:42
static TfClientId tid
void release_dispex(DispatchEx *This)
Definition: dispex.c:1706
HRESULT WINAPI DispCallFunc(void *pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn, UINT cActuals, VARTYPE *prgvt, VARIANTARG **prgpvarg, VARIANT *pvargResult)
Definition: typelib.c:6760
DWORD func_disp_cnt
Definition: dispex.c:52
#define DYNPROP_DELETED
Definition: dispex.c:63
static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
Definition: dispex.c:1332
static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
Definition: dispex.c:1574
#define SUCCEEDED(hr)
Definition: intsafe.h:57
static CRITICAL_SECTION cs_dispex_static_data
Definition: dispex.c:23
static const IUnknownVtbl FunctionUnkVtbl
Definition: dispex.c:678
DispatchEx dispex
Definition: dispex.c:66
DispatchEx * obj
Definition: dispex.c:69
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
HRESULT get_htmldoc_classinfo(ITypeInfo **typeinfo)
Definition: dispex.c:172