Release 6.15.
[wine.git] / dlls / msscript.ocx / msscript.c
bloba760af230160ab748b5107877738f336db4a9beb
1 /*
2 * Copyright 2015 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define COBJMACROS
21 #include "windows.h"
22 #include "initguid.h"
23 #include "dispex.h"
24 #include "ole2.h"
25 #include "olectl.h"
26 #include "objsafe.h"
27 #include "activscp.h"
28 #include "rpcproxy.h"
29 #include "msscript.h"
30 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
32 #include "wine/debug.h"
33 #include "wine/heap.h"
34 #include "wine/list.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(msscript);
38 #ifdef _WIN64
40 #define IActiveScriptParse_Release IActiveScriptParse64_Release
41 #define IActiveScriptParse_InitNew IActiveScriptParse64_InitNew
42 #define IActiveScriptParse_ParseScriptText IActiveScriptParse64_ParseScriptText
44 #else
46 #define IActiveScriptParse_Release IActiveScriptParse32_Release
47 #define IActiveScriptParse_InitNew IActiveScriptParse32_InitNew
48 #define IActiveScriptParse_ParseScriptText IActiveScriptParse32_ParseScriptText
50 #endif
52 struct ScriptControl;
53 typedef struct ConnectionPoint ConnectionPoint;
54 typedef struct ScriptProcedureCollection ScriptProcedureCollection;
55 typedef struct ScriptHost ScriptHost;
57 struct ConnectionPoint {
58 IConnectionPoint IConnectionPoint_iface;
59 ScriptControl *control;
60 const IID *riid;
61 ConnectionPoint *next;
64 struct named_item {
65 struct list entry;
66 BSTR name;
67 IDispatch *disp;
70 struct module_enum {
71 IEnumVARIANT IEnumVARIANT_iface;
72 LONG ref;
74 UINT pos;
75 ScriptHost *host;
76 ScriptControl *control;
79 typedef struct {
80 IScriptModule IScriptModule_iface;
81 LONG ref;
83 BSTR name;
84 ScriptHost *host;
85 IDispatch *script_dispatch;
86 ITypeInfo *script_typeinfo;
87 ITypeComp *script_typecomp;
89 ScriptProcedureCollection *procedures;
90 } ScriptModule;
92 typedef struct {
93 IScriptProcedure IScriptProcedure_iface;
94 LONG ref;
96 ULONG hash;
97 struct list entry;
99 BSTR name;
100 USHORT num_args;
101 VARTYPE ret_type;
102 } ScriptProcedure;
104 struct ScriptProcedureCollection {
105 IScriptProcedureCollection IScriptProcedureCollection_iface;
106 LONG ref;
108 LONG count;
109 ScriptModule *module;
110 struct list hash_table[43];
113 struct procedure_enum {
114 IEnumVARIANT IEnumVARIANT_iface;
115 LONG ref;
117 WORD pos;
118 WORD count;
119 ScriptProcedureCollection *procedures;
122 typedef struct {
123 IScriptError IScriptError_iface;
124 IActiveScriptError *object;
125 LONG ref;
127 HRESULT number;
128 BSTR text;
129 BSTR source;
130 BSTR desc;
131 BSTR help_file;
132 DWORD help_context;
133 ULONG line;
134 LONG column;
136 BOOLEAN info_filled;
137 BOOLEAN text_filled;
138 BOOLEAN pos_filled;
139 } ScriptError;
141 struct ScriptHost {
142 IActiveScriptSite IActiveScriptSite_iface;
143 IActiveScriptSiteWindow IActiveScriptSiteWindow_iface;
144 IServiceProvider IServiceProvider_iface;
145 LONG ref;
147 IActiveScript *script;
148 IActiveScriptParse *parse;
149 ScriptError *error;
150 HWND site_hwnd;
151 SCRIPTSTATE script_state;
152 CLSID clsid;
154 unsigned int module_count;
155 struct list named_items;
158 struct ScriptControl {
159 IScriptControl IScriptControl_iface;
160 IPersistStreamInit IPersistStreamInit_iface;
161 IOleObject IOleObject_iface;
162 IOleControl IOleControl_iface;
163 IQuickActivate IQuickActivate_iface;
164 IViewObjectEx IViewObjectEx_iface;
165 IPointerInactive IPointerInactive_iface;
166 IConnectionPointContainer IConnectionPointContainer_iface;
167 LONG ref;
168 IOleClientSite *site;
169 HWND site_hwnd;
170 SIZEL extent;
171 LONG timeout;
172 VARIANT_BOOL allow_ui;
173 VARIANT_BOOL use_safe_subset;
175 /* connection points */
176 ConnectionPoint *cp_list;
177 ConnectionPoint cp_scsource;
178 ConnectionPoint cp_propnotif;
180 /* IViewObject sink */
181 IAdviseSink *view_sink;
182 DWORD view_sink_flags;
184 /* modules */
185 ScriptModule **modules;
186 IScriptModuleCollection IScriptModuleCollection_iface;
188 ScriptHost *host;
189 ScriptError *error;
192 typedef enum tid_t {
193 IScriptControl_tid,
194 IScriptError_tid,
195 IScriptModuleCollection_tid,
196 IScriptModule_tid,
197 IScriptProcedureCollection_tid,
198 IScriptProcedure_tid,
199 LAST_tid
200 } tid_t;
202 static ITypeLib *typelib;
203 static ITypeInfo *typeinfos[LAST_tid];
205 static REFIID tid_ids[] = {
206 &IID_IScriptControl,
207 &IID_IScriptError,
208 &IID_IScriptModuleCollection,
209 &IID_IScriptModule,
210 &IID_IScriptProcedureCollection,
211 &IID_IScriptProcedure
214 static HRESULT load_typelib(void)
216 HRESULT hres;
217 ITypeLib *tl;
219 hres = LoadRegTypeLib(&LIBID_MSScriptControl, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
220 if(FAILED(hres)) {
221 ERR("LoadRegTypeLib failed: %08x\n", hres);
222 return hres;
225 if(InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
226 ITypeLib_Release(tl);
227 return hres;
230 static HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo)
232 HRESULT hres;
234 if (!typelib)
235 hres = load_typelib();
236 if (!typelib)
237 return hres;
239 if(!typeinfos[tid]) {
240 ITypeInfo *ti;
242 hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
243 if(FAILED(hres)) {
244 ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hres);
245 return hres;
248 if(InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
249 ITypeInfo_Release(ti);
252 *typeinfo = typeinfos[tid];
253 ITypeInfo_AddRef(typeinfos[tid]);
254 return S_OK;
257 static void release_typelib(void)
259 unsigned i;
261 if(!typelib)
262 return;
264 for(i = 0; i < ARRAY_SIZE(typeinfos); i++)
265 if(typeinfos[i])
266 ITypeInfo_Release(typeinfos[i]);
268 ITypeLib_Release(typelib);
271 static inline BOOL is_power_of_2(unsigned x)
273 return !(x & (x - 1));
276 static void clear_named_items(ScriptHost *host)
278 struct named_item *item, *item1;
279 LIST_FOR_EACH_ENTRY_SAFE(item, item1, &host->named_items, struct named_item, entry) {
280 list_remove(&item->entry);
281 SysFreeString(item->name);
282 IDispatch_Release(item->disp);
283 heap_free(item);
287 static struct named_item *host_get_named_item(ScriptHost *host, const WCHAR *nameW)
289 struct named_item *item;
291 LIST_FOR_EACH_ENTRY(item, &host->named_items, struct named_item, entry) {
292 if (!wcscmp(item->name, nameW))
293 return item;
296 return NULL;
299 static HRESULT get_script_dispatch(ScriptModule *module, IDispatch **disp)
301 if (!module->script_dispatch)
303 HRESULT hr = IActiveScript_GetScriptDispatch(module->host->script,
304 module->name, &module->script_dispatch);
305 if (FAILED(hr)) return hr;
307 *disp = module->script_dispatch;
308 return S_OK;
311 static HRESULT get_script_typeinfo(ScriptModule *module, ITypeInfo **typeinfo)
313 IDispatch *disp;
314 HRESULT hr;
316 if (!module->script_typeinfo)
318 hr = get_script_dispatch(module, &disp);
319 if (FAILED(hr)) return hr;
321 hr = IDispatch_GetTypeInfo(disp, 0, LOCALE_USER_DEFAULT, &module->script_typeinfo);
322 if (FAILED(hr)) return hr;
324 *typeinfo = module->script_typeinfo;
325 return S_OK;
328 static HRESULT get_script_typecomp(ScriptModule *module, ITypeInfo *typeinfo, ITypeComp **typecomp)
330 HRESULT hr;
332 if (!module->script_typecomp)
334 hr = ITypeInfo_QueryInterface(typeinfo, &IID_ITypeComp, (void**)&module->script_typecomp);
335 if (FAILED(hr)) return hr;
337 *typecomp = module->script_typecomp;
338 return S_OK;
341 static void uncache_module_objects(ScriptModule *module)
343 if (module->script_dispatch)
345 IDispatch_Release(module->script_dispatch);
346 module->script_dispatch = NULL;
348 if (module->script_typeinfo)
350 ITypeInfo_Release(module->script_typeinfo);
351 module->script_typeinfo = NULL;
353 if (module->script_typecomp)
355 ITypeComp_Release(module->script_typecomp);
356 module->script_typecomp = NULL;
360 static HRESULT set_script_state(ScriptHost *host, SCRIPTSTATE state)
362 HRESULT hr;
364 hr = IActiveScript_SetScriptState(host->script, state);
365 if (SUCCEEDED(hr))
366 host->script_state = state;
367 return hr;
370 static HRESULT start_script(ScriptModule *module)
372 HRESULT hr = S_OK;
374 if (module->host->script_state != SCRIPTSTATE_STARTED)
376 hr = set_script_state(module->host, SCRIPTSTATE_STARTED);
377 if (SUCCEEDED(hr)) uncache_module_objects(module);
380 return hr;
383 static HRESULT add_script_object(ScriptHost *host, BSTR name, IDispatch *object, DWORD flags)
385 struct named_item *item;
386 HRESULT hr;
388 if (host_get_named_item(host, name))
389 return E_INVALIDARG;
391 item = heap_alloc(sizeof(*item));
392 if (!item)
393 return E_OUTOFMEMORY;
395 item->name = SysAllocString(name);
396 if (!item->name)
398 heap_free(item);
399 return E_OUTOFMEMORY;
401 IDispatch_AddRef(item->disp = object);
402 list_add_tail(&host->named_items, &item->entry);
404 hr = IActiveScript_AddNamedItem(host->script, name, flags);
405 if (FAILED(hr))
407 list_remove(&item->entry);
408 IDispatch_Release(item->disp);
409 SysFreeString(item->name);
410 heap_free(item);
411 return hr;
414 return hr;
417 static HRESULT parse_script_text(ScriptModule *module, BSTR script_text, DWORD flag, VARIANT *res)
419 EXCEPINFO excepinfo;
420 HRESULT hr;
422 hr = start_script(module);
423 if (FAILED(hr)) return hr;
425 uncache_module_objects(module);
426 if (module->procedures)
427 module->procedures->count = -1;
429 hr = IActiveScriptParse_ParseScriptText(module->host->parse, script_text, module->name,
430 NULL, NULL, 0, 1, flag, res, &excepinfo);
431 /* FIXME: more error handling */
432 return hr;
435 static HRESULT WINAPI sp_caller_QueryInterface(IServiceProvider *iface, REFIID riid, void **obj)
437 if (IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IServiceProvider, riid))
438 *obj = iface;
439 else
441 FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
442 *obj = NULL;
443 return E_NOINTERFACE;
446 IUnknown_AddRef((IUnknown*)*obj);
447 return S_OK;
450 static ULONG WINAPI sp_caller_AddRef(IServiceProvider *iface)
452 return 2;
455 static ULONG WINAPI sp_caller_Release(IServiceProvider *iface)
457 return 1;
460 static HRESULT WINAPI sp_caller_QueryService(IServiceProvider *iface, REFGUID service, REFIID riid, void **obj)
462 FIXME("(%p)->(%s %s %p): semi-stub\n", iface, debugstr_guid(service), debugstr_guid(riid), obj);
464 *obj = NULL;
465 if (IsEqualGUID(&SID_GetCaller, service))
466 return S_OK;
468 return E_NOINTERFACE;
471 static const IServiceProviderVtbl sp_caller_vtbl = {
472 sp_caller_QueryInterface,
473 sp_caller_AddRef,
474 sp_caller_Release,
475 sp_caller_QueryService
478 static IServiceProvider sp_caller = { &sp_caller_vtbl };
480 static HRESULT run_procedure(ScriptModule *module, BSTR procedure_name, SAFEARRAY *args, VARIANT *res)
482 IDispatchEx *dispex;
483 IDispatch *disp;
484 DISPPARAMS dp;
485 DISPID dispid;
486 HRESULT hr;
487 UINT i;
489 hr = start_script(module);
490 if (FAILED(hr)) return hr;
492 hr = get_script_dispatch(module, &disp);
493 if (FAILED(hr)) return hr;
495 hr = IDispatch_GetIDsOfNames(disp, &IID_NULL, &procedure_name, 1, LOCALE_USER_DEFAULT, &dispid);
496 if (FAILED(hr)) return hr;
498 dp.cArgs = args->rgsabound[0].cElements;
499 dp.rgdispidNamedArgs = NULL;
500 dp.cNamedArgs = 0;
501 dp.rgvarg = heap_alloc(dp.cArgs * sizeof(*dp.rgvarg));
502 if (!dp.rgvarg) return E_OUTOFMEMORY;
504 hr = SafeArrayLock(args);
505 if (SUCCEEDED(hr))
507 /* The DISPPARAMS are stored in reverse order */
508 for (i = 0; i < dp.cArgs; i++)
509 dp.rgvarg[i] = *(VARIANT*)((char*)(args->pvData) + (dp.cArgs - i - 1) * args->cbElements);
510 SafeArrayUnlock(args);
512 hr = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
513 if (FAILED(hr))
515 hr = IDispatch_Invoke(disp, dispid, &IID_NULL, LOCALE_USER_DEFAULT,
516 DISPATCH_METHOD, &dp, res, NULL, NULL);
518 else
520 hr = IDispatchEx_InvokeEx(dispex, dispid, LOCALE_USER_DEFAULT,
521 DISPATCH_METHOD, &dp, res, NULL, &sp_caller);
522 IDispatchEx_Release(dispex);
525 heap_free(dp.rgvarg);
527 return hr;
530 static inline ScriptControl *impl_from_IScriptControl(IScriptControl *iface)
532 return CONTAINING_RECORD(iface, ScriptControl, IScriptControl_iface);
535 static inline ScriptControl *impl_from_IOleObject(IOleObject *iface)
537 return CONTAINING_RECORD(iface, ScriptControl, IOleObject_iface);
540 static inline ScriptControl *impl_from_IPersistStreamInit(IPersistStreamInit *iface)
542 return CONTAINING_RECORD(iface, ScriptControl, IPersistStreamInit_iface);
545 static inline ScriptControl *impl_from_IOleControl(IOleControl *iface)
547 return CONTAINING_RECORD(iface, ScriptControl, IOleControl_iface);
550 static inline ScriptControl *impl_from_IQuickActivate(IQuickActivate *iface)
552 return CONTAINING_RECORD(iface, ScriptControl, IQuickActivate_iface);
555 static inline ScriptControl *impl_from_IViewObjectEx(IViewObjectEx *iface)
557 return CONTAINING_RECORD(iface, ScriptControl, IViewObjectEx_iface);
560 static inline ScriptControl *impl_from_IPointerInactive(IPointerInactive *iface)
562 return CONTAINING_RECORD(iface, ScriptControl, IPointerInactive_iface);
565 static inline ScriptControl *impl_from_IConnectionPointContainer(IConnectionPointContainer *iface)
567 return CONTAINING_RECORD(iface, ScriptControl, IConnectionPointContainer_iface);
570 static inline ScriptProcedure *impl_from_IScriptProcedure(IScriptProcedure *iface)
572 return CONTAINING_RECORD(iface, ScriptProcedure, IScriptProcedure_iface);
575 static inline ScriptProcedureCollection *impl_from_IScriptProcedureCollection(IScriptProcedureCollection *iface)
577 return CONTAINING_RECORD(iface, ScriptProcedureCollection, IScriptProcedureCollection_iface);
580 static inline ScriptControl *impl_from_IScriptModuleCollection(IScriptModuleCollection *iface)
582 return CONTAINING_RECORD(iface, ScriptControl, IScriptModuleCollection_iface);
585 static inline ScriptModule *impl_from_IScriptModule(IScriptModule *iface)
587 return CONTAINING_RECORD(iface, ScriptModule, IScriptModule_iface);
590 static inline ScriptError *impl_from_IScriptError(IScriptError *iface)
592 return CONTAINING_RECORD(iface, ScriptError, IScriptError_iface);
595 static inline ConnectionPoint *impl_from_IConnectionPoint(IConnectionPoint *iface)
597 return CONTAINING_RECORD(iface, ConnectionPoint, IConnectionPoint_iface);
600 static inline ScriptHost *impl_from_IActiveScriptSite(IActiveScriptSite *iface)
602 return CONTAINING_RECORD(iface, ScriptHost, IActiveScriptSite_iface);
605 static inline ScriptHost *impl_from_IActiveScriptSiteWindow(IActiveScriptSiteWindow *iface)
607 return CONTAINING_RECORD(iface, ScriptHost, IActiveScriptSiteWindow_iface);
610 static inline ScriptHost *impl_from_IServiceProvider(IServiceProvider *iface)
612 return CONTAINING_RECORD(iface, ScriptHost, IServiceProvider_iface);
615 static inline struct module_enum *module_enum_from_IEnumVARIANT(IEnumVARIANT *iface)
617 return CONTAINING_RECORD(iface, struct module_enum, IEnumVARIANT_iface);
620 static inline struct procedure_enum *procedure_enum_from_IEnumVARIANT(IEnumVARIANT *iface)
622 return CONTAINING_RECORD(iface, struct procedure_enum, IEnumVARIANT_iface);
625 /* IActiveScriptSite */
626 static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
628 ScriptHost *This = impl_from_IActiveScriptSite(iface);
630 if(IsEqualGUID(&IID_IUnknown, riid)) {
631 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
632 *ppv = &This->IActiveScriptSite_iface;
633 }else if(IsEqualGUID(&IID_IActiveScriptSite, riid)) {
634 TRACE("(%p)->(IID_IActiveScriptSite %p)\n", This, ppv);
635 *ppv = &This->IActiveScriptSite_iface;
636 }else if(IsEqualGUID(&IID_IActiveScriptSiteWindow, riid)) {
637 TRACE("(%p)->(IID_IActiveScriptSiteWindow %p)\n", This, ppv);
638 *ppv = &This->IActiveScriptSiteWindow_iface;
639 }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
640 TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
641 *ppv = &This->IServiceProvider_iface;
642 }else {
643 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
644 *ppv = NULL;
645 return E_NOINTERFACE;
648 IUnknown_AddRef((IUnknown*)*ppv);
649 return S_OK;
652 static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
654 ScriptHost *This = impl_from_IActiveScriptSite(iface);
655 LONG ref = InterlockedIncrement(&This->ref);
657 TRACE("(%p) ref=%d\n", This, ref);
659 return ref;
662 static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
664 ScriptHost *This = impl_from_IActiveScriptSite(iface);
665 LONG ref = InterlockedDecrement(&This->ref);
667 TRACE("(%p) ref=%d\n", This, ref);
669 if(!ref) {
670 clear_named_items(This);
671 heap_free(This);
674 return ref;
677 static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *lcid)
679 ScriptHost *This = impl_from_IActiveScriptSite(iface);
681 TRACE("(%p, %p)\n", This, lcid);
683 *lcid = GetUserDefaultLCID();
684 return S_OK;
687 static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR name, DWORD mask,
688 IUnknown **unk, ITypeInfo **ti)
690 ScriptHost *This = impl_from_IActiveScriptSite(iface);
691 struct named_item *item;
693 TRACE("(%p, %s, %#x, %p, %p)\n", This, debugstr_w(name), mask, unk, ti);
695 item = host_get_named_item(This, name);
696 if (!item)
697 return TYPE_E_ELEMENTNOTFOUND;
699 if (mask != SCRIPTINFO_IUNKNOWN) {
700 FIXME("mask %#x is not supported\n", mask);
701 return E_NOTIMPL;
704 *unk = (IUnknown*)item->disp;
705 IUnknown_AddRef(*unk);
707 return S_OK;
710 static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *version)
712 ScriptHost *This = impl_from_IActiveScriptSite(iface);
714 FIXME("(%p, %p)\n", This, version);
716 return E_NOTIMPL;
719 static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface, const VARIANT *result,
720 const EXCEPINFO *ei)
722 ScriptHost *This = impl_from_IActiveScriptSite(iface);
724 FIXME("(%p, %s, %p)\n", This, debugstr_variant(result), ei);
726 return E_NOTIMPL;
729 static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE state)
731 ScriptHost *This = impl_from_IActiveScriptSite(iface);
733 FIXME("(%p, %d)\n", This, state);
735 return E_NOTIMPL;
738 static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *script_error)
740 ScriptHost *This = impl_from_IActiveScriptSite(iface);
742 TRACE("(%p, %p)\n", This, script_error);
744 if (This->error)
746 IScriptError_Clear(&This->error->IScriptError_iface);
747 IActiveScriptError_AddRef(script_error);
748 This->error->object = script_error;
750 return S_FALSE;
753 static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
755 ScriptHost *This = impl_from_IActiveScriptSite(iface);
757 FIXME("(%p)\n", This);
759 return E_NOTIMPL;
762 static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
764 ScriptHost *This = impl_from_IActiveScriptSite(iface);
766 FIXME("(%p)\n", This);
768 return E_NOTIMPL;
771 static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
772 ActiveScriptSite_QueryInterface,
773 ActiveScriptSite_AddRef,
774 ActiveScriptSite_Release,
775 ActiveScriptSite_GetLCID,
776 ActiveScriptSite_GetItemInfo,
777 ActiveScriptSite_GetDocVersionString,
778 ActiveScriptSite_OnScriptTerminate,
779 ActiveScriptSite_OnStateChange,
780 ActiveScriptSite_OnScriptError,
781 ActiveScriptSite_OnEnterScript,
782 ActiveScriptSite_OnLeaveScript
785 /* IActiveScriptSiteWindow */
786 static HRESULT WINAPI ActiveScriptSiteWindow_QueryInterface(IActiveScriptSiteWindow *iface, REFIID riid, void **obj)
788 ScriptHost *This = impl_from_IActiveScriptSiteWindow(iface);
789 return IActiveScriptSite_QueryInterface(&This->IActiveScriptSite_iface, riid, obj);
792 static ULONG WINAPI ActiveScriptSiteWindow_AddRef(IActiveScriptSiteWindow *iface)
794 ScriptHost *This = impl_from_IActiveScriptSiteWindow(iface);
795 return IActiveScriptSite_AddRef(&This->IActiveScriptSite_iface);
798 static ULONG WINAPI ActiveScriptSiteWindow_Release(IActiveScriptSiteWindow *iface)
800 ScriptHost *This = impl_from_IActiveScriptSiteWindow(iface);
801 return IActiveScriptSite_Release(&This->IActiveScriptSite_iface);
804 static HRESULT WINAPI ActiveScriptSiteWindow_GetWindow(IActiveScriptSiteWindow *iface, HWND *hwnd)
806 ScriptHost *This = impl_from_IActiveScriptSiteWindow(iface);
808 TRACE("(%p, %p)\n", This, hwnd);
810 if (!hwnd) return E_POINTER;
811 if (This->site_hwnd == ((HWND)-1)) return E_FAIL;
813 *hwnd = This->site_hwnd;
814 return S_OK;
817 static HRESULT WINAPI ActiveScriptSiteWindow_EnableModeless(IActiveScriptSiteWindow *iface, BOOL enable)
819 ScriptHost *This = impl_from_IActiveScriptSiteWindow(iface);
821 FIXME("(%p, %d): stub\n", This, enable);
823 return S_OK;
826 static const IActiveScriptSiteWindowVtbl ActiveScriptSiteWindowVtbl = {
827 ActiveScriptSiteWindow_QueryInterface,
828 ActiveScriptSiteWindow_AddRef,
829 ActiveScriptSiteWindow_Release,
830 ActiveScriptSiteWindow_GetWindow,
831 ActiveScriptSiteWindow_EnableModeless
834 /* IServiceProvider */
835 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **obj)
837 ScriptHost *This = impl_from_IServiceProvider(iface);
838 return IActiveScriptSite_QueryInterface(&This->IActiveScriptSite_iface, riid, obj);
841 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
843 ScriptHost *This = impl_from_IServiceProvider(iface);
844 return IActiveScriptSite_AddRef(&This->IActiveScriptSite_iface);
847 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
849 ScriptHost *This = impl_from_IServiceProvider(iface);
850 return IActiveScriptSite_Release(&This->IActiveScriptSite_iface);
853 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID service,
854 REFIID riid, void **obj)
856 ScriptHost *This = impl_from_IServiceProvider(iface);
858 FIXME("(%p)->(%s %s %p)\n", This, debugstr_guid(service), debugstr_guid(riid), obj);
860 return E_NOTIMPL;
863 static const IServiceProviderVtbl ServiceProviderVtbl = {
864 ServiceProvider_QueryInterface,
865 ServiceProvider_AddRef,
866 ServiceProvider_Release,
867 ServiceProvider_QueryService
870 static HRESULT WINAPI ScriptProcedure_QueryInterface(IScriptProcedure *iface, REFIID riid, void **ppv)
872 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
874 if (IsEqualGUID(&IID_IDispatch, riid) || IsEqualGUID(&IID_IUnknown, riid) ||
875 IsEqualGUID(&IID_IScriptProcedure, riid))
877 *ppv = &This->IScriptProcedure_iface;
879 else
881 WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
882 *ppv = NULL;
883 return E_NOINTERFACE;
886 IUnknown_AddRef((IUnknown*)*ppv);
887 return S_OK;
890 static ULONG WINAPI ScriptProcedure_AddRef(IScriptProcedure *iface)
892 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
893 LONG ref = InterlockedIncrement(&This->ref);
895 TRACE("(%p) ref=%d\n", This, ref);
897 return ref;
900 static ULONG WINAPI ScriptProcedure_Release(IScriptProcedure *iface)
902 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
903 LONG ref = InterlockedDecrement(&This->ref);
905 TRACE("(%p) ref=%d\n", This, ref);
907 if (!ref)
909 list_remove(&This->entry);
910 SysFreeString(This->name);
911 heap_free(This);
913 return ref;
916 static HRESULT WINAPI ScriptProcedure_GetTypeInfoCount(IScriptProcedure *iface, UINT *pctinfo)
918 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
920 TRACE("(%p)->(%p)\n", This, pctinfo);
922 *pctinfo = 1;
923 return S_OK;
926 static HRESULT WINAPI ScriptProcedure_GetTypeInfo(IScriptProcedure *iface, UINT iTInfo,
927 LCID lcid, ITypeInfo **ppTInfo)
929 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
931 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
933 return get_typeinfo(IScriptProcedure_tid, ppTInfo);
936 static HRESULT WINAPI ScriptProcedure_GetIDsOfNames(IScriptProcedure *iface, REFIID riid,
937 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
939 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
940 ITypeInfo *typeinfo;
941 HRESULT hr;
943 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
945 hr = get_typeinfo(IScriptProcedure_tid, &typeinfo);
946 if (SUCCEEDED(hr))
948 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
949 ITypeInfo_Release(typeinfo);
952 return hr;
955 static HRESULT WINAPI ScriptProcedure_Invoke(IScriptProcedure *iface, DISPID dispIdMember,
956 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
957 EXCEPINFO *pExcepInfo, UINT *puArgErr)
959 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
960 ITypeInfo *typeinfo;
961 HRESULT hr;
963 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
964 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
966 hr = get_typeinfo(IScriptProcedure_tid, &typeinfo);
967 if(SUCCEEDED(hr))
969 hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
970 pDispParams, pVarResult, pExcepInfo, puArgErr);
971 ITypeInfo_Release(typeinfo);
974 return hr;
977 static HRESULT WINAPI ScriptProcedure_get_Name(IScriptProcedure *iface, BSTR *pbstrName)
979 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
981 TRACE("(%p)->(%p)\n", This, pbstrName);
983 if (!pbstrName) return E_POINTER;
985 *pbstrName = SysAllocString(This->name);
986 return *pbstrName ? S_OK : E_OUTOFMEMORY;
989 static HRESULT WINAPI ScriptProcedure_get_NumArgs(IScriptProcedure *iface, LONG *pcArgs)
991 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
993 TRACE("(%p)->(%p)\n", This, pcArgs);
995 if (!pcArgs) return E_POINTER;
997 *pcArgs = This->num_args;
998 return S_OK;
1001 static HRESULT WINAPI ScriptProcedure_get_HasReturnValue(IScriptProcedure *iface, VARIANT_BOOL *pfHasReturnValue)
1003 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
1005 TRACE("(%p)->(%p)\n", This, pfHasReturnValue);
1007 if (!pfHasReturnValue) return E_POINTER;
1009 *pfHasReturnValue = (This->ret_type == VT_VOID) ? VARIANT_FALSE : VARIANT_TRUE;
1010 return S_OK;
1013 static const IScriptProcedureVtbl ScriptProcedureVtbl = {
1014 ScriptProcedure_QueryInterface,
1015 ScriptProcedure_AddRef,
1016 ScriptProcedure_Release,
1017 ScriptProcedure_GetTypeInfoCount,
1018 ScriptProcedure_GetTypeInfo,
1019 ScriptProcedure_GetIDsOfNames,
1020 ScriptProcedure_Invoke,
1021 ScriptProcedure_get_Name,
1022 ScriptProcedure_get_NumArgs,
1023 ScriptProcedure_get_HasReturnValue
1026 /* This function always releases the FUNCDESC passed in */
1027 static HRESULT get_script_procedure(ScriptProcedureCollection *procedures, ITypeInfo *typeinfo,
1028 FUNCDESC *desc, IScriptProcedure **procedure)
1030 struct list *proc_list;
1031 ScriptProcedure *proc;
1032 ULONG hash;
1033 HRESULT hr;
1034 BSTR str;
1035 UINT len;
1037 hr = ITypeInfo_GetNames(typeinfo, desc->memid, &str, 1, &len);
1038 if (FAILED(hr)) goto done;
1040 len = SysStringLen(str);
1041 hash = LHashValOfNameSys(sizeof(void*) == 8 ? SYS_WIN64 : SYS_WIN32, LOCALE_USER_DEFAULT, str);
1042 proc_list = &procedures->hash_table[hash % ARRAY_SIZE(procedures->hash_table)];
1044 /* Try to find it in the hash table */
1045 LIST_FOR_EACH_ENTRY(proc, proc_list, ScriptProcedure, entry)
1047 if (proc->hash == hash && SysStringLen(proc->name) == len &&
1048 !memcmp(proc->name, str, len * sizeof(*str)))
1050 SysFreeString(str);
1051 IScriptProcedure_AddRef(&proc->IScriptProcedure_iface);
1052 *procedure = &proc->IScriptProcedure_iface;
1053 goto done;
1057 if (!(proc = heap_alloc(sizeof(*proc))))
1059 hr = E_OUTOFMEMORY;
1060 SysFreeString(str);
1061 goto done;
1064 proc->IScriptProcedure_iface.lpVtbl = &ScriptProcedureVtbl;
1065 proc->ref = 1;
1066 proc->hash = hash;
1067 proc->name = str;
1068 proc->num_args = desc->cParams + desc->cParamsOpt;
1069 proc->ret_type = desc->elemdescFunc.tdesc.vt;
1070 list_add_tail(proc_list, &proc->entry);
1072 *procedure = &proc->IScriptProcedure_iface;
1074 done:
1075 ITypeInfo_ReleaseFuncDesc(typeinfo, desc);
1076 return hr;
1079 static HRESULT WINAPI procedure_enum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv)
1081 struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
1083 if (IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IEnumVARIANT, riid))
1085 *ppv = &This->IEnumVARIANT_iface;
1087 else
1089 WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
1090 *ppv = NULL;
1091 return E_NOINTERFACE;
1094 IUnknown_AddRef((IUnknown*)*ppv);
1095 return S_OK;
1098 static ULONG WINAPI procedure_enum_AddRef(IEnumVARIANT *iface)
1100 struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
1101 LONG ref = InterlockedIncrement(&This->ref);
1103 TRACE("(%p) ref=%d\n", This, ref);
1105 return ref;
1108 static ULONG WINAPI procedure_enum_Release(IEnumVARIANT *iface)
1110 struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
1111 LONG ref = InterlockedDecrement(&This->ref);
1113 TRACE("(%p) ref=%d\n", This, ref);
1115 if (!ref)
1117 IScriptProcedureCollection_Release(&This->procedures->IScriptProcedureCollection_iface);
1118 heap_free(This);
1121 return ref;
1124 static HRESULT WINAPI procedure_enum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
1126 struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
1127 FUNCDESC *desc;
1128 ITypeInfo *ti;
1129 UINT i, num;
1130 HRESULT hr;
1132 TRACE("(%p)->(%u %p %p)\n", This, celt, rgVar, pCeltFetched);
1134 if (!rgVar) return E_POINTER;
1135 if (!This->procedures->module->host) return E_FAIL;
1137 hr = start_script(This->procedures->module);
1138 if (FAILED(hr)) return hr;
1140 hr = get_script_typeinfo(This->procedures->module, &ti);
1141 if (FAILED(hr)) return hr;
1143 num = min(celt, This->count - This->pos);
1144 for (i = 0; i < num; i++)
1146 hr = ITypeInfo_GetFuncDesc(ti, This->pos + i, &desc);
1147 if (FAILED(hr)) break;
1149 hr = get_script_procedure(This->procedures, ti, desc, (IScriptProcedure**)&V_DISPATCH(rgVar + i));
1150 if (FAILED(hr)) break;
1152 V_VT(rgVar + i) = VT_DISPATCH;
1155 if (FAILED(hr))
1157 while (i--)
1158 VariantClear(rgVar + i);
1159 if (pCeltFetched) *pCeltFetched = 0;
1160 return hr;
1163 This->pos += i;
1165 if (pCeltFetched) *pCeltFetched = i;
1166 return i == celt ? S_OK : S_FALSE;
1169 static HRESULT WINAPI procedure_enum_Skip(IEnumVARIANT *iface, ULONG celt)
1171 struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
1173 TRACE("(%p)->(%u)\n", This, celt);
1175 if (This->count - This->pos < celt)
1177 This->pos = This->count;
1178 return S_FALSE;
1180 This->pos += celt;
1181 return S_OK;
1184 static HRESULT WINAPI procedure_enum_Reset(IEnumVARIANT *iface)
1186 struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
1188 TRACE("(%p)\n", This);
1190 This->pos = 0;
1191 return S_OK;
1194 static HRESULT WINAPI procedure_enum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
1196 struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
1197 struct procedure_enum *clone;
1199 TRACE("(%p)->(%p)\n", This, ppEnum);
1201 if (!ppEnum) return E_POINTER;
1203 if (!(clone = heap_alloc(sizeof(*clone))))
1204 return E_OUTOFMEMORY;
1206 *clone = *This;
1207 clone->ref = 1;
1208 IScriptProcedureCollection_AddRef(&This->procedures->IScriptProcedureCollection_iface);
1210 *ppEnum = &clone->IEnumVARIANT_iface;
1211 return S_OK;
1214 static const IEnumVARIANTVtbl procedure_enum_vtbl = {
1215 procedure_enum_QueryInterface,
1216 procedure_enum_AddRef,
1217 procedure_enum_Release,
1218 procedure_enum_Next,
1219 procedure_enum_Skip,
1220 procedure_enum_Reset,
1221 procedure_enum_Clone
1224 static HRESULT WINAPI ScriptProcedureCollection_QueryInterface(IScriptProcedureCollection *iface, REFIID riid, void **ppv)
1226 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1228 if (IsEqualGUID(&IID_IDispatch, riid) || IsEqualGUID(&IID_IUnknown, riid) ||
1229 IsEqualGUID(&IID_IScriptProcedureCollection, riid))
1231 *ppv = &This->IScriptProcedureCollection_iface;
1233 else
1235 WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
1236 *ppv = NULL;
1237 return E_NOINTERFACE;
1240 IUnknown_AddRef((IUnknown*)*ppv);
1241 return S_OK;
1244 static ULONG WINAPI ScriptProcedureCollection_AddRef(IScriptProcedureCollection *iface)
1246 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1247 LONG ref = InterlockedIncrement(&This->ref);
1249 TRACE("(%p) ref=%d\n", This, ref);
1251 return ref;
1254 static ULONG WINAPI ScriptProcedureCollection_Release(IScriptProcedureCollection *iface)
1256 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1257 LONG ref = InterlockedDecrement(&This->ref);
1258 UINT i;
1260 TRACE("(%p) ref=%d\n", This, ref);
1262 if (!ref)
1264 /* Unlink any dangling items from the hash table */
1265 for (i = 0; i < ARRAY_SIZE(This->hash_table); i++)
1266 list_remove(&This->hash_table[i]);
1268 This->module->procedures = NULL;
1269 IScriptModule_Release(&This->module->IScriptModule_iface);
1270 heap_free(This);
1272 return ref;
1275 static HRESULT WINAPI ScriptProcedureCollection_GetTypeInfoCount(IScriptProcedureCollection *iface, UINT *pctinfo)
1277 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1279 TRACE("(%p)->(%p)\n", This, pctinfo);
1281 *pctinfo = 1;
1282 return S_OK;
1285 static HRESULT WINAPI ScriptProcedureCollection_GetTypeInfo(IScriptProcedureCollection *iface, UINT iTInfo,
1286 LCID lcid, ITypeInfo **ppTInfo)
1288 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1290 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
1292 return get_typeinfo(IScriptProcedureCollection_tid, ppTInfo);
1295 static HRESULT WINAPI ScriptProcedureCollection_GetIDsOfNames(IScriptProcedureCollection *iface, REFIID riid,
1296 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1298 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1299 ITypeInfo *typeinfo;
1300 HRESULT hr;
1302 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
1304 hr = get_typeinfo(IScriptProcedureCollection_tid, &typeinfo);
1305 if (SUCCEEDED(hr))
1307 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
1308 ITypeInfo_Release(typeinfo);
1311 return hr;
1314 static HRESULT WINAPI ScriptProcedureCollection_Invoke(IScriptProcedureCollection *iface, DISPID dispIdMember,
1315 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
1316 EXCEPINFO *pExcepInfo, UINT *puArgErr)
1318 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1319 ITypeInfo *typeinfo;
1320 HRESULT hr;
1322 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1323 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1325 hr = get_typeinfo(IScriptProcedureCollection_tid, &typeinfo);
1326 if(SUCCEEDED(hr))
1328 hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
1329 pDispParams, pVarResult, pExcepInfo, puArgErr);
1330 ITypeInfo_Release(typeinfo);
1333 return hr;
1336 static HRESULT WINAPI ScriptProcedureCollection_get__NewEnum(IScriptProcedureCollection *iface, IUnknown **ppenumProcedures)
1338 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1339 struct procedure_enum *proc_enum;
1340 TYPEATTR *attr;
1341 ITypeInfo *ti;
1342 UINT count;
1343 HRESULT hr;
1345 TRACE("(%p)->(%p)\n", This, ppenumProcedures);
1347 if (!ppenumProcedures) return E_POINTER;
1348 if (!This->module->host) return E_FAIL;
1350 hr = start_script(This->module);
1351 if (FAILED(hr)) return hr;
1353 hr = get_script_typeinfo(This->module, &ti);
1354 if (FAILED(hr)) return hr;
1356 hr = ITypeInfo_GetTypeAttr(ti, &attr);
1357 if (FAILED(hr)) return hr;
1359 count = attr->cFuncs;
1360 ITypeInfo_ReleaseTypeAttr(ti, attr);
1362 if (!(proc_enum = heap_alloc(sizeof(*proc_enum))))
1363 return E_OUTOFMEMORY;
1365 proc_enum->IEnumVARIANT_iface.lpVtbl = &procedure_enum_vtbl;
1366 proc_enum->ref = 1;
1367 proc_enum->pos = 0;
1368 proc_enum->count = count;
1369 proc_enum->procedures = This;
1370 IScriptProcedureCollection_AddRef(&This->IScriptProcedureCollection_iface);
1372 *ppenumProcedures = (IUnknown*)&proc_enum->IEnumVARIANT_iface;
1373 return S_OK;
1376 static HRESULT WINAPI ScriptProcedureCollection_get_Item(IScriptProcedureCollection *iface, VARIANT index,
1377 IScriptProcedure **ppdispProcedure)
1379 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1380 ITypeInfo *typeinfo;
1381 FUNCDESC *desc;
1382 HRESULT hr;
1384 TRACE("(%p)->(%s %p)\n", This, wine_dbgstr_variant(&index), ppdispProcedure);
1386 if (!ppdispProcedure) return E_POINTER;
1387 if (!This->module->host) return E_FAIL;
1389 hr = start_script(This->module);
1390 if (FAILED(hr)) return hr;
1392 hr = get_script_typeinfo(This->module, &typeinfo);
1393 if (FAILED(hr)) return hr;
1395 if (V_VT(&index) == VT_BSTR)
1397 struct list *proc_list;
1398 ScriptProcedure *proc;
1399 ITypeComp *comp;
1400 BINDPTR bindptr;
1401 DESCKIND kind;
1402 ULONG hash;
1403 UINT len;
1405 len = SysStringLen(V_BSTR(&index));
1406 hash = LHashValOfNameSys(sizeof(void*) == 8 ? SYS_WIN64 : SYS_WIN32, LOCALE_USER_DEFAULT, V_BSTR(&index));
1407 proc_list = &This->hash_table[hash % ARRAY_SIZE(This->hash_table)];
1409 /* Try to find it in the hash table */
1410 LIST_FOR_EACH_ENTRY(proc, proc_list, ScriptProcedure, entry)
1412 if (proc->hash == hash && SysStringLen(proc->name) == len &&
1413 !memcmp(proc->name, V_BSTR(&index), len * sizeof(WCHAR)))
1415 IScriptProcedure_AddRef(&proc->IScriptProcedure_iface);
1416 *ppdispProcedure = &proc->IScriptProcedure_iface;
1417 return S_OK;
1421 hr = get_script_typecomp(This->module, typeinfo, &comp);
1422 if (FAILED(hr)) return hr;
1424 hr = ITypeComp_Bind(comp, V_BSTR(&index), hash, INVOKE_FUNC, &typeinfo, &kind, &bindptr);
1425 if (FAILED(hr)) return hr;
1427 switch (kind)
1429 case DESCKIND_FUNCDESC:
1430 hr = get_script_procedure(This, typeinfo, bindptr.lpfuncdesc, ppdispProcedure);
1431 ITypeInfo_Release(typeinfo);
1432 return hr;
1433 case DESCKIND_IMPLICITAPPOBJ:
1434 case DESCKIND_VARDESC:
1435 ITypeInfo_ReleaseVarDesc(typeinfo, bindptr.lpvardesc);
1436 ITypeInfo_Release(typeinfo);
1437 break;
1438 case DESCKIND_TYPECOMP:
1439 ITypeComp_Release(bindptr.lptcomp);
1440 break;
1441 default:
1442 break;
1444 return CTL_E_ILLEGALFUNCTIONCALL;
1447 hr = VariantChangeType(&index, &index, 0, VT_INT);
1448 if (FAILED(hr)) return hr;
1449 if (V_INT(&index) <= 0) return 0x800a0009;
1451 hr = ITypeInfo_GetFuncDesc(typeinfo, V_INT(&index) - 1, &desc);
1452 if (FAILED(hr)) return hr;
1454 return get_script_procedure(This, typeinfo, desc, ppdispProcedure);
1457 static HRESULT WINAPI ScriptProcedureCollection_get_Count(IScriptProcedureCollection *iface, LONG *plCount)
1459 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1460 TYPEATTR *attr;
1461 ITypeInfo *ti;
1462 HRESULT hr;
1464 TRACE("(%p)->(%p)\n", This, plCount);
1466 if (!plCount) return E_POINTER;
1467 if (!This->module->host) return E_FAIL;
1469 if (This->count == -1)
1471 hr = start_script(This->module);
1472 if (FAILED(hr)) return hr;
1474 hr = get_script_typeinfo(This->module, &ti);
1475 if (FAILED(hr)) return hr;
1477 hr = ITypeInfo_GetTypeAttr(ti, &attr);
1478 if (FAILED(hr)) return hr;
1480 This->count = attr->cFuncs;
1481 ITypeInfo_ReleaseTypeAttr(ti, attr);
1484 *plCount = This->count;
1485 return S_OK;
1488 static const IScriptProcedureCollectionVtbl ScriptProcedureCollectionVtbl = {
1489 ScriptProcedureCollection_QueryInterface,
1490 ScriptProcedureCollection_AddRef,
1491 ScriptProcedureCollection_Release,
1492 ScriptProcedureCollection_GetTypeInfoCount,
1493 ScriptProcedureCollection_GetTypeInfo,
1494 ScriptProcedureCollection_GetIDsOfNames,
1495 ScriptProcedureCollection_Invoke,
1496 ScriptProcedureCollection_get__NewEnum,
1497 ScriptProcedureCollection_get_Item,
1498 ScriptProcedureCollection_get_Count
1501 static void detach_script_host(ScriptHost *host)
1503 if (--host->module_count)
1504 return;
1506 if (host->script) {
1507 IActiveScript_Close(host->script);
1508 IActiveScript_Release(host->script);
1511 if (host->parse)
1512 IActiveScriptParse_Release(host->parse);
1514 if (host->error)
1515 IScriptError_Release(&host->error->IScriptError_iface);
1517 host->parse = NULL;
1518 host->error = NULL;
1519 host->script = NULL;
1522 static void detach_module(ScriptModule *module)
1524 ScriptHost *host = module->host;
1526 if (host) {
1527 module->host = NULL;
1528 detach_script_host(host);
1529 IActiveScriptSite_Release(&host->IActiveScriptSite_iface);
1533 static HRESULT WINAPI ScriptModule_QueryInterface(IScriptModule *iface, REFIID riid, void **ppv)
1535 ScriptModule *This = impl_from_IScriptModule(iface);
1537 if (IsEqualGUID(&IID_IDispatch, riid) || IsEqualGUID(&IID_IUnknown, riid) ||
1538 IsEqualGUID(&IID_IScriptModule, riid))
1540 *ppv = &This->IScriptModule_iface;
1542 else
1544 WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
1545 *ppv = NULL;
1546 return E_NOINTERFACE;
1549 IUnknown_AddRef((IUnknown*)*ppv);
1550 return S_OK;
1553 static ULONG WINAPI ScriptModule_AddRef(IScriptModule *iface)
1555 ScriptModule *This = impl_from_IScriptModule(iface);
1556 LONG ref = InterlockedIncrement(&This->ref);
1558 TRACE("(%p) ref=%d\n", This, ref);
1560 return ref;
1563 static ULONG WINAPI ScriptModule_Release(IScriptModule *iface)
1565 ScriptModule *This = impl_from_IScriptModule(iface);
1566 LONG ref = InterlockedDecrement(&This->ref);
1568 TRACE("(%p) ref=%d\n", This, ref);
1570 if (!ref)
1572 detach_module(This);
1573 SysFreeString(This->name);
1574 uncache_module_objects(This);
1575 heap_free(This);
1578 return ref;
1581 static HRESULT WINAPI ScriptModule_GetTypeInfoCount(IScriptModule *iface, UINT *pctinfo)
1583 ScriptModule *This = impl_from_IScriptModule(iface);
1585 TRACE("(%p)->(%p)\n", This, pctinfo);
1587 *pctinfo = 1;
1588 return S_OK;
1591 static HRESULT WINAPI ScriptModule_GetTypeInfo(IScriptModule *iface, UINT iTInfo,
1592 LCID lcid, ITypeInfo **ppTInfo)
1594 ScriptModule *This = impl_from_IScriptModule(iface);
1596 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
1598 return get_typeinfo(IScriptModule_tid, ppTInfo);
1601 static HRESULT WINAPI ScriptModule_GetIDsOfNames(IScriptModule *iface, REFIID riid,
1602 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1604 ScriptModule *This = impl_from_IScriptModule(iface);
1605 ITypeInfo *typeinfo;
1606 HRESULT hr;
1608 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
1610 hr = get_typeinfo(IScriptModule_tid, &typeinfo);
1611 if (SUCCEEDED(hr))
1613 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
1614 ITypeInfo_Release(typeinfo);
1617 return hr;
1620 static HRESULT WINAPI ScriptModule_Invoke(IScriptModule *iface, DISPID dispIdMember,
1621 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
1622 EXCEPINFO *pExcepInfo, UINT *puArgErr)
1624 ScriptModule *This = impl_from_IScriptModule(iface);
1625 ITypeInfo *typeinfo;
1626 HRESULT hr;
1628 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1629 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1631 hr = get_typeinfo(IScriptModule_tid, &typeinfo);
1632 if(SUCCEEDED(hr))
1634 hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
1635 pDispParams, pVarResult, pExcepInfo, puArgErr);
1636 ITypeInfo_Release(typeinfo);
1639 return hr;
1642 static HRESULT WINAPI ScriptModule_get_Name(IScriptModule *iface, BSTR *pbstrName)
1644 ScriptModule *This = impl_from_IScriptModule(iface);
1646 TRACE("(%p)->(%p)\n", This, pbstrName);
1648 if (!pbstrName) return E_POINTER;
1649 if (!This->host) return E_FAIL;
1651 *pbstrName = SysAllocString(This->name ? This->name : L"Global");
1652 return *pbstrName ? S_OK : E_OUTOFMEMORY;
1655 static HRESULT WINAPI ScriptModule_get_CodeObject(IScriptModule *iface, IDispatch **ppdispObject)
1657 ScriptModule *This = impl_from_IScriptModule(iface);
1658 HRESULT hr;
1660 TRACE("(%p)->(%p)\n", This, ppdispObject);
1662 if (!This->host) return E_FAIL;
1664 hr = start_script(This);
1665 if (FAILED(hr)) return hr;
1667 hr = get_script_dispatch(This, ppdispObject);
1668 if (FAILED(hr)) return hr;
1670 IDispatch_AddRef(*ppdispObject);
1671 return hr;
1674 static HRESULT WINAPI ScriptModule_get_Procedures(IScriptModule *iface, IScriptProcedureCollection **ppdispProcedures)
1676 ScriptModule *This = impl_from_IScriptModule(iface);
1678 TRACE("(%p)->(%p)\n", This, ppdispProcedures);
1680 if (!This->host)
1681 return E_FAIL;
1683 if (This->procedures)
1684 IScriptProcedureCollection_AddRef(&This->procedures->IScriptProcedureCollection_iface);
1685 else
1687 ScriptProcedureCollection *procs;
1688 UINT i;
1690 if (!(procs = heap_alloc(sizeof(*procs))))
1691 return E_OUTOFMEMORY;
1693 procs->IScriptProcedureCollection_iface.lpVtbl = &ScriptProcedureCollectionVtbl;
1694 procs->ref = 1;
1695 procs->count = -1;
1696 procs->module = This;
1697 for (i = 0; i < ARRAY_SIZE(procs->hash_table); i++)
1698 list_init(&procs->hash_table[i]);
1700 This->procedures = procs;
1701 IScriptModule_AddRef(&This->IScriptModule_iface);
1704 *ppdispProcedures = &This->procedures->IScriptProcedureCollection_iface;
1705 return S_OK;
1708 static HRESULT WINAPI ScriptModule_AddCode(IScriptModule *iface, BSTR code)
1710 ScriptModule *This = impl_from_IScriptModule(iface);
1712 TRACE("(%p)->(%s)\n", This, debugstr_w(code));
1714 if (!This->host)
1715 return E_FAIL;
1717 return parse_script_text(This, code, SCRIPTTEXT_ISVISIBLE, NULL);
1720 static HRESULT WINAPI ScriptModule_Eval(IScriptModule *iface, BSTR expression, VARIANT *res)
1722 ScriptModule *This = impl_from_IScriptModule(iface);
1724 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(expression), res);
1726 if (!res)
1727 return E_POINTER;
1728 V_VT(res) = VT_EMPTY;
1729 if (!This->host)
1730 return E_FAIL;
1732 return parse_script_text(This, expression, SCRIPTTEXT_ISEXPRESSION, res);
1735 static HRESULT WINAPI ScriptModule_ExecuteStatement(IScriptModule *iface, BSTR statement)
1737 ScriptModule *This = impl_from_IScriptModule(iface);
1739 TRACE("(%p)->(%s)\n", This, debugstr_w(statement));
1741 if (!This->host)
1742 return E_FAIL;
1744 return parse_script_text(This, statement, 0, NULL);
1747 static HRESULT WINAPI ScriptModule_Run(IScriptModule *iface, BSTR procedure_name, SAFEARRAY **parameters, VARIANT *res)
1749 ScriptModule *This = impl_from_IScriptModule(iface);
1750 SAFEARRAY *sa;
1752 TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(procedure_name), parameters, res);
1754 if (!parameters || !res) return E_POINTER;
1755 if (!(sa = *parameters)) return E_POINTER;
1757 V_VT(res) = VT_EMPTY;
1758 if (sa->cDims == 0) return DISP_E_BADINDEX;
1759 if (!(sa->fFeatures & FADF_VARIANT)) return DISP_E_BADVARTYPE;
1760 if (!This->host) return E_FAIL;
1762 return run_procedure(This, procedure_name, sa, res);
1765 static const IScriptModuleVtbl ScriptModuleVtbl = {
1766 ScriptModule_QueryInterface,
1767 ScriptModule_AddRef,
1768 ScriptModule_Release,
1769 ScriptModule_GetTypeInfoCount,
1770 ScriptModule_GetTypeInfo,
1771 ScriptModule_GetIDsOfNames,
1772 ScriptModule_Invoke,
1773 ScriptModule_get_Name,
1774 ScriptModule_get_CodeObject,
1775 ScriptModule_get_Procedures,
1776 ScriptModule_AddCode,
1777 ScriptModule_Eval,
1778 ScriptModule_ExecuteStatement,
1779 ScriptModule_Run
1782 static HRESULT WINAPI module_enum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv)
1784 struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
1786 if (IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IEnumVARIANT, riid))
1788 *ppv = &This->IEnumVARIANT_iface;
1790 else
1792 WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
1793 *ppv = NULL;
1794 return E_NOINTERFACE;
1797 IUnknown_AddRef((IUnknown*)*ppv);
1798 return S_OK;
1801 static ULONG WINAPI module_enum_AddRef(IEnumVARIANT *iface)
1803 struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
1804 LONG ref = InterlockedIncrement(&This->ref);
1806 TRACE("(%p) ref=%d\n", This, ref);
1808 return ref;
1811 static ULONG WINAPI module_enum_Release(IEnumVARIANT *iface)
1813 struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
1814 LONG ref = InterlockedDecrement(&This->ref);
1816 TRACE("(%p) ref=%d\n", This, ref);
1818 if (!ref)
1820 IActiveScriptSite_Release(&This->host->IActiveScriptSite_iface);
1821 IScriptControl_Release(&This->control->IScriptControl_iface);
1822 heap_free(This);
1825 return ref;
1828 static HRESULT WINAPI module_enum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
1830 struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
1831 unsigned int i, num;
1833 TRACE("(%p)->(%u %p %p)\n", This, celt, rgVar, pCeltFetched);
1835 if (!rgVar) return E_POINTER;
1836 if (This->host != This->control->host) return E_FAIL;
1838 num = min(celt, This->host->module_count - This->pos);
1839 for (i = 0; i < num; i++)
1841 V_VT(rgVar + i) = VT_DISPATCH;
1842 V_DISPATCH(rgVar + i) = (IDispatch*)(&This->control->modules[This->pos++]->IScriptModule_iface);
1843 IDispatch_AddRef(V_DISPATCH(rgVar + i));
1846 if (pCeltFetched) *pCeltFetched = i;
1847 return i == celt ? S_OK : S_FALSE;
1850 static HRESULT WINAPI module_enum_Skip(IEnumVARIANT *iface, ULONG celt)
1852 struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
1854 TRACE("(%p)->(%u)\n", This, celt);
1856 if (This->host != This->control->host) return E_FAIL;
1858 if (This->host->module_count - This->pos < celt)
1860 This->pos = This->host->module_count;
1861 return S_FALSE;
1863 This->pos += celt;
1864 return S_OK;
1867 static HRESULT WINAPI module_enum_Reset(IEnumVARIANT *iface)
1869 struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
1871 TRACE("(%p)\n", This);
1873 if (This->host != This->control->host) return E_FAIL;
1875 This->pos = 0;
1876 return S_OK;
1879 static HRESULT WINAPI module_enum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
1881 struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
1882 struct module_enum *clone;
1884 TRACE("(%p)->(%p)\n", This, ppEnum);
1886 if (!ppEnum) return E_POINTER;
1887 if (This->host != This->control->host) return E_FAIL;
1889 if (!(clone = heap_alloc(sizeof(*clone))))
1890 return E_OUTOFMEMORY;
1892 *clone = *This;
1893 clone->ref = 1;
1894 IActiveScriptSite_AddRef(&This->host->IActiveScriptSite_iface);
1895 IScriptControl_AddRef(&This->control->IScriptControl_iface);
1897 *ppEnum = &clone->IEnumVARIANT_iface;
1898 return S_OK;
1901 static const IEnumVARIANTVtbl module_enum_vtbl = {
1902 module_enum_QueryInterface,
1903 module_enum_AddRef,
1904 module_enum_Release,
1905 module_enum_Next,
1906 module_enum_Skip,
1907 module_enum_Reset,
1908 module_enum_Clone
1911 static ScriptModule *create_module(ScriptHost *host, BSTR name)
1913 ScriptModule *module;
1915 if (!(module = heap_alloc_zero(sizeof(*module)))) return NULL;
1917 module->IScriptModule_iface.lpVtbl = &ScriptModuleVtbl;
1918 module->ref = 1;
1919 if (name && !(module->name = SysAllocString(name)))
1921 heap_free(module);
1922 return NULL;
1924 module->host = host;
1925 IActiveScriptSite_AddRef(&host->IActiveScriptSite_iface);
1926 return module;
1929 static void release_modules(ScriptControl *control, BOOL force_detach)
1931 unsigned int i, module_count = control->host->module_count;
1933 for (i = 0; i < module_count; i++) {
1934 if (force_detach) detach_module(control->modules[i]);
1935 IScriptModule_Release(&control->modules[i]->IScriptModule_iface);
1938 heap_free(control->modules);
1941 static ScriptModule *find_module(ScriptControl *control, BSTR name)
1943 unsigned int i;
1945 if (!wcsicmp(name, L"Global"))
1946 return control->modules[0];
1948 for (i = 1; i < control->host->module_count; i++)
1950 if (!wcsicmp(name, control->modules[i]->name))
1951 return control->modules[i];
1953 return NULL;
1956 static HRESULT WINAPI ScriptModuleCollection_QueryInterface(IScriptModuleCollection *iface, REFIID riid, void **ppv)
1958 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
1960 if (IsEqualGUID(&IID_IDispatch, riid) || IsEqualGUID(&IID_IUnknown, riid) ||
1961 IsEqualGUID(&IID_IScriptModuleCollection, riid))
1963 *ppv = &This->IScriptModuleCollection_iface;
1965 else
1967 WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
1968 *ppv = NULL;
1969 return E_NOINTERFACE;
1972 IUnknown_AddRef((IUnknown*)*ppv);
1973 return S_OK;
1976 static ULONG WINAPI ScriptModuleCollection_AddRef(IScriptModuleCollection *iface)
1978 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
1979 return IScriptControl_AddRef(&This->IScriptControl_iface);
1982 static ULONG WINAPI ScriptModuleCollection_Release(IScriptModuleCollection *iface)
1984 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
1985 return IScriptControl_Release(&This->IScriptControl_iface);
1988 static HRESULT WINAPI ScriptModuleCollection_GetTypeInfoCount(IScriptModuleCollection *iface, UINT *pctinfo)
1990 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
1992 TRACE("(%p)->(%p)\n", This, pctinfo);
1994 *pctinfo = 1;
1995 return S_OK;
1998 static HRESULT WINAPI ScriptModuleCollection_GetTypeInfo(IScriptModuleCollection *iface, UINT iTInfo,
1999 LCID lcid, ITypeInfo **ppTInfo)
2001 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
2003 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
2005 return get_typeinfo(IScriptModuleCollection_tid, ppTInfo);
2008 static HRESULT WINAPI ScriptModuleCollection_GetIDsOfNames(IScriptModuleCollection *iface, REFIID riid,
2009 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
2011 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
2012 ITypeInfo *typeinfo;
2013 HRESULT hr;
2015 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
2017 hr = get_typeinfo(IScriptModuleCollection_tid, &typeinfo);
2018 if (SUCCEEDED(hr))
2020 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
2021 ITypeInfo_Release(typeinfo);
2024 return hr;
2027 static HRESULT WINAPI ScriptModuleCollection_Invoke(IScriptModuleCollection *iface, DISPID dispIdMember,
2028 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
2029 EXCEPINFO *pExcepInfo, UINT *puArgErr)
2031 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
2032 ITypeInfo *typeinfo;
2033 HRESULT hr;
2035 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
2036 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2038 hr = get_typeinfo(IScriptModuleCollection_tid, &typeinfo);
2039 if(SUCCEEDED(hr))
2041 hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
2042 pDispParams, pVarResult, pExcepInfo, puArgErr);
2043 ITypeInfo_Release(typeinfo);
2046 return hr;
2049 static HRESULT WINAPI ScriptModuleCollection_get__NewEnum(IScriptModuleCollection *iface, IUnknown **ppenumContexts)
2051 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
2052 struct module_enum *module_enum;
2054 TRACE("(%p)->(%p)\n", This, ppenumContexts);
2056 if (!ppenumContexts) return E_POINTER;
2057 if (!This->host) return E_FAIL;
2059 if (!(module_enum = heap_alloc(sizeof(*module_enum))))
2060 return E_OUTOFMEMORY;
2062 module_enum->IEnumVARIANT_iface.lpVtbl = &module_enum_vtbl;
2063 module_enum->ref = 1;
2064 module_enum->pos = 0;
2065 module_enum->host = This->host;
2066 module_enum->control = This;
2067 IActiveScriptSite_AddRef(&This->host->IActiveScriptSite_iface);
2068 IScriptControl_AddRef(&This->IScriptControl_iface);
2070 *ppenumContexts = (IUnknown*)&module_enum->IEnumVARIANT_iface;
2071 return S_OK;
2074 static HRESULT WINAPI ScriptModuleCollection_get_Item(IScriptModuleCollection *iface, VARIANT index,
2075 IScriptModule **ppmod)
2077 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
2078 ScriptModule *module;
2079 unsigned int i;
2080 HRESULT hr;
2082 TRACE("(%p)->(%s %p)\n", This, wine_dbgstr_variant(&index), ppmod);
2084 if (!ppmod) return E_POINTER;
2085 if (!This->host) return E_FAIL;
2087 if (V_VT(&index) == VT_BSTR)
2089 module = find_module(This, V_BSTR(&index));
2090 if (!module) return CTL_E_ILLEGALFUNCTIONCALL;
2092 else
2094 hr = VariantChangeType(&index, &index, 0, VT_INT);
2095 if (FAILED(hr)) return hr;
2097 i = V_INT(&index) - 1;
2098 if (i >= This->host->module_count) return 0x800a0009;
2100 module = This->modules[i];
2103 *ppmod = &module->IScriptModule_iface;
2104 IScriptModule_AddRef(*ppmod);
2105 return S_OK;
2108 static HRESULT WINAPI ScriptModuleCollection_get_Count(IScriptModuleCollection *iface, LONG *plCount)
2110 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
2112 TRACE("(%p)->(%p)\n", This, plCount);
2114 if (!plCount) return E_POINTER;
2115 if (!This->host) return E_FAIL;
2117 *plCount = This->host->module_count;
2118 return S_OK;
2121 static HRESULT WINAPI ScriptModuleCollection_Add(IScriptModuleCollection *iface, BSTR name,
2122 VARIANT *object, IScriptModule **ppmod)
2124 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
2125 ScriptModule *module, **modules;
2126 ScriptHost *host = This->host;
2127 HRESULT hr;
2129 TRACE("(%p)->(%s %s %p)\n", This, wine_dbgstr_w(name), wine_dbgstr_variant(object), ppmod);
2131 if (!ppmod) return E_POINTER;
2132 if (!name || V_VT(object) != VT_DISPATCH) return E_INVALIDARG;
2133 if (!host) return E_FAIL;
2134 if (find_module(This, name)) return E_INVALIDARG;
2136 /* See if we need to grow the array */
2137 if (is_power_of_2(host->module_count))
2139 modules = heap_realloc(This->modules, host->module_count * 2 * sizeof(*This->modules));
2140 if (!modules) return E_OUTOFMEMORY;
2141 This->modules = modules;
2144 if (!(module = create_module(host, name)))
2145 return E_OUTOFMEMORY;
2147 /* If no object, Windows only calls AddNamedItem without adding a NULL object */
2148 if (V_DISPATCH(object))
2149 hr = add_script_object(host, name, V_DISPATCH(object), 0);
2150 else
2151 hr = IActiveScript_AddNamedItem(host->script, name, SCRIPTITEM_CODEONLY);
2153 if (FAILED(hr))
2155 IScriptModule_Release(&module->IScriptModule_iface);
2156 return hr;
2158 This->modules[host->module_count++] = module;
2160 *ppmod = &module->IScriptModule_iface;
2161 IScriptModule_AddRef(*ppmod);
2162 return S_OK;
2165 static const IScriptModuleCollectionVtbl ScriptModuleCollectionVtbl = {
2166 ScriptModuleCollection_QueryInterface,
2167 ScriptModuleCollection_AddRef,
2168 ScriptModuleCollection_Release,
2169 ScriptModuleCollection_GetTypeInfoCount,
2170 ScriptModuleCollection_GetTypeInfo,
2171 ScriptModuleCollection_GetIDsOfNames,
2172 ScriptModuleCollection_Invoke,
2173 ScriptModuleCollection_get__NewEnum,
2174 ScriptModuleCollection_get_Item,
2175 ScriptModuleCollection_get_Count,
2176 ScriptModuleCollection_Add
2179 static void fill_error_info(ScriptError *error)
2181 EXCEPINFO info;
2183 if (error->info_filled) return;
2184 error->info_filled = TRUE;
2186 if (!error->object)
2187 return;
2188 if (FAILED(IActiveScriptError_GetExceptionInfo(error->object, &info)))
2189 return;
2190 if (info.pfnDeferredFillIn)
2191 info.pfnDeferredFillIn(&info);
2193 error->number = info.scode;
2194 error->source = info.bstrSource;
2195 error->desc = info.bstrDescription;
2196 error->help_file = info.bstrHelpFile;
2197 error->help_context = info.dwHelpContext;
2200 static void fill_error_text(ScriptError *error)
2202 if (error->text_filled) return;
2203 error->text_filled = TRUE;
2205 if (error->object)
2206 IActiveScriptError_GetSourceLineText(error->object, &error->text);
2209 static void fill_error_pos(ScriptError *error)
2211 DWORD context;
2212 LONG column;
2213 ULONG line;
2215 if (error->pos_filled) return;
2216 error->pos_filled = TRUE;
2218 if (!error->object)
2219 return;
2220 if (FAILED(IActiveScriptError_GetSourcePosition(error->object, &context, &line, &column)))
2221 return;
2223 error->line = line;
2224 error->column = column;
2227 static HRESULT WINAPI ScriptError_QueryInterface(IScriptError *iface, REFIID riid, void **ppv)
2229 ScriptError *This = impl_from_IScriptError(iface);
2231 if (IsEqualGUID(&IID_IDispatch, riid) || IsEqualGUID(&IID_IUnknown, riid) ||
2232 IsEqualGUID(&IID_IScriptError, riid))
2234 *ppv = &This->IScriptError_iface;
2236 else
2238 WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
2239 *ppv = NULL;
2240 return E_NOINTERFACE;
2243 IUnknown_AddRef((IUnknown*)*ppv);
2244 return S_OK;
2247 static ULONG WINAPI ScriptError_AddRef(IScriptError *iface)
2249 ScriptError *This = impl_from_IScriptError(iface);
2250 LONG ref = InterlockedIncrement(&This->ref);
2252 TRACE("(%p) ref=%d\n", This, ref);
2254 return ref;
2257 static ULONG WINAPI ScriptError_Release(IScriptError *iface)
2259 ScriptError *This = impl_from_IScriptError(iface);
2260 LONG ref = InterlockedDecrement(&This->ref);
2262 TRACE("(%p) ref=%d\n", This, ref);
2264 if (!ref)
2266 IScriptError_Clear(&This->IScriptError_iface);
2267 heap_free(This);
2270 return ref;
2273 static HRESULT WINAPI ScriptError_GetTypeInfoCount(IScriptError *iface, UINT *pctinfo)
2275 ScriptError *This = impl_from_IScriptError(iface);
2277 TRACE("(%p)->(%p)\n", This, pctinfo);
2279 *pctinfo = 1;
2280 return S_OK;
2283 static HRESULT WINAPI ScriptError_GetTypeInfo(IScriptError *iface, UINT iTInfo,
2284 LCID lcid, ITypeInfo **ppTInfo)
2286 ScriptError *This = impl_from_IScriptError(iface);
2288 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
2290 return get_typeinfo(IScriptError_tid, ppTInfo);
2293 static HRESULT WINAPI ScriptError_GetIDsOfNames(IScriptError *iface, REFIID riid,
2294 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
2296 ScriptError *This = impl_from_IScriptError(iface);
2297 ITypeInfo *typeinfo;
2298 HRESULT hr;
2300 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
2302 hr = get_typeinfo(IScriptError_tid, &typeinfo);
2303 if (SUCCEEDED(hr))
2305 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
2306 ITypeInfo_Release(typeinfo);
2309 return hr;
2312 static HRESULT WINAPI ScriptError_Invoke(IScriptError *iface, DISPID dispIdMember,
2313 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
2314 EXCEPINFO *pExcepInfo, UINT *puArgErr)
2316 ScriptError *This = impl_from_IScriptError(iface);
2317 ITypeInfo *typeinfo;
2318 HRESULT hr;
2320 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
2321 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2323 hr = get_typeinfo(IScriptError_tid, &typeinfo);
2324 if(SUCCEEDED(hr))
2326 hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
2327 pDispParams, pVarResult, pExcepInfo, puArgErr);
2328 ITypeInfo_Release(typeinfo);
2331 return hr;
2334 static HRESULT WINAPI ScriptError_get_Number(IScriptError *iface, LONG *plNumber)
2336 ScriptError *This = impl_from_IScriptError(iface);
2338 TRACE("(%p)->(%p)\n", This, plNumber);
2340 fill_error_info(This);
2341 *plNumber = This->number;
2342 return S_OK;
2345 static HRESULT WINAPI ScriptError_get_Source(IScriptError *iface, BSTR *pbstrSource)
2347 ScriptError *This = impl_from_IScriptError(iface);
2349 TRACE("(%p)->(%p)\n", This, pbstrSource);
2351 fill_error_info(This);
2352 *pbstrSource = SysAllocString(This->source);
2353 return S_OK;
2356 static HRESULT WINAPI ScriptError_get_Description(IScriptError *iface, BSTR *pbstrDescription)
2358 ScriptError *This = impl_from_IScriptError(iface);
2360 TRACE("(%p)->(%p)\n", This, pbstrDescription);
2362 fill_error_info(This);
2363 *pbstrDescription = SysAllocString(This->desc);
2364 return S_OK;
2367 static HRESULT WINAPI ScriptError_get_HelpFile(IScriptError *iface, BSTR *pbstrHelpFile)
2369 ScriptError *This = impl_from_IScriptError(iface);
2371 TRACE("(%p)->(%p)\n", This, pbstrHelpFile);
2373 fill_error_info(This);
2374 *pbstrHelpFile = SysAllocString(This->help_file);
2375 return S_OK;
2378 static HRESULT WINAPI ScriptError_get_HelpContext(IScriptError *iface, LONG *plHelpContext)
2380 ScriptError *This = impl_from_IScriptError(iface);
2382 TRACE("(%p)->(%p)\n", This, plHelpContext);
2384 fill_error_info(This);
2385 *plHelpContext = This->help_context;
2386 return S_OK;
2389 static HRESULT WINAPI ScriptError_get_Text(IScriptError *iface, BSTR *pbstrText)
2391 ScriptError *This = impl_from_IScriptError(iface);
2393 TRACE("(%p)->(%p)\n", This, pbstrText);
2395 fill_error_text(This);
2396 *pbstrText = SysAllocString(This->text);
2397 return S_OK;
2400 static HRESULT WINAPI ScriptError_get_Line(IScriptError *iface, LONG *plLine)
2402 ScriptError *This = impl_from_IScriptError(iface);
2404 TRACE("(%p)->(%p)\n", This, plLine);
2406 fill_error_pos(This);
2407 *plLine = This->line;
2408 return S_OK;
2411 static HRESULT WINAPI ScriptError_get_Column(IScriptError *iface, LONG *plColumn)
2413 ScriptError *This = impl_from_IScriptError(iface);
2415 TRACE("(%p)->(%p)\n", This, plColumn);
2417 fill_error_pos(This);
2418 *plColumn = This->column;
2419 return S_OK;
2422 static HRESULT WINAPI ScriptError_Clear(IScriptError *iface)
2424 ScriptError *This = impl_from_IScriptError(iface);
2426 TRACE("(%p)->()\n", This);
2428 if (This->object)
2430 IActiveScriptError_Release(This->object);
2431 This->object = NULL;
2433 SysFreeString(This->text);
2434 SysFreeString(This->source);
2435 SysFreeString(This->desc);
2436 SysFreeString(This->help_file);
2438 This->number = 0;
2439 This->text = NULL;
2440 This->source = NULL;
2441 This->desc = NULL;
2442 This->help_file = NULL;
2443 This->help_context = 0;
2444 This->line = 0;
2445 This->column = 0;
2447 This->info_filled = FALSE;
2448 This->text_filled = FALSE;
2449 This->pos_filled = FALSE;
2450 return S_OK;
2453 static const IScriptErrorVtbl ScriptErrorVtbl = {
2454 ScriptError_QueryInterface,
2455 ScriptError_AddRef,
2456 ScriptError_Release,
2457 ScriptError_GetTypeInfoCount,
2458 ScriptError_GetTypeInfo,
2459 ScriptError_GetIDsOfNames,
2460 ScriptError_Invoke,
2461 ScriptError_get_Number,
2462 ScriptError_get_Source,
2463 ScriptError_get_Description,
2464 ScriptError_get_HelpFile,
2465 ScriptError_get_HelpContext,
2466 ScriptError_get_Text,
2467 ScriptError_get_Line,
2468 ScriptError_get_Column,
2469 ScriptError_Clear
2472 static HRESULT set_safety_opts(IActiveScript *script, VARIANT_BOOL use_safe_subset)
2474 IObjectSafety *objsafety;
2475 HRESULT hr;
2477 hr = IActiveScript_QueryInterface(script, &IID_IObjectSafety, (void**)&objsafety);
2478 if (FAILED(hr)) {
2479 FIXME("Could not get IObjectSafety, %#x\n", hr);
2480 return hr;
2483 hr = IObjectSafety_SetInterfaceSafetyOptions(objsafety, &IID_IActiveScriptParse, INTERFACESAFE_FOR_UNTRUSTED_DATA,
2484 use_safe_subset ? INTERFACESAFE_FOR_UNTRUSTED_DATA : 0);
2485 IObjectSafety_Release(objsafety);
2486 if (FAILED(hr)) {
2487 FIXME("SetInterfaceSafetyOptions failed, %#x\n", hr);
2488 return hr;
2491 return hr;
2494 static HRESULT init_script_host(ScriptControl *control, const CLSID *clsid, ScriptHost **ret)
2496 ScriptHost *host;
2497 HRESULT hr;
2499 *ret = NULL;
2501 host = heap_alloc(sizeof(*host));
2502 if (!host)
2503 return E_OUTOFMEMORY;
2505 host->IActiveScriptSite_iface.lpVtbl = &ActiveScriptSiteVtbl;
2506 host->IActiveScriptSiteWindow_iface.lpVtbl = &ActiveScriptSiteWindowVtbl;
2507 host->IServiceProvider_iface.lpVtbl = &ServiceProviderVtbl;
2508 host->ref = 1;
2509 host->script = NULL;
2510 host->parse = NULL;
2511 host->clsid = *clsid;
2512 host->module_count = 1;
2513 list_init(&host->named_items);
2515 hr = CoCreateInstance(&host->clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2516 &IID_IActiveScript, (void**)&host->script);
2517 if (FAILED(hr)) {
2518 WARN("Failed to create an instance for %s, %#x\n", debugstr_guid(clsid), hr);
2519 goto failed;
2522 hr = set_safety_opts(host->script, control->use_safe_subset);
2523 if (FAILED(hr)) goto failed;
2525 hr = IActiveScript_SetScriptSite(host->script, &host->IActiveScriptSite_iface);
2526 if (FAILED(hr)) {
2527 WARN("SetScriptSite failed, %#x\n", hr);
2528 goto failed;
2531 hr = IActiveScript_QueryInterface(host->script, &IID_IActiveScriptParse, (void**)&host->parse);
2532 if (FAILED(hr)) {
2533 WARN("Failed to get IActiveScriptParse, %#x\n", hr);
2534 goto failed;
2537 hr = IActiveScriptParse_InitNew(host->parse);
2538 if (FAILED(hr)) {
2539 WARN("InitNew failed, %#x\n", hr);
2540 goto failed;
2542 host->script_state = SCRIPTSTATE_INITIALIZED;
2543 host->site_hwnd = control->allow_ui ? control->site_hwnd : ((HWND)-1);
2544 host->error = control->error;
2545 IScriptError_AddRef(&host->error->IScriptError_iface);
2547 *ret = host;
2548 return S_OK;
2550 failed:
2551 detach_script_host(host);
2552 return hr;
2555 static HRESULT WINAPI ScriptControl_QueryInterface(IScriptControl *iface, REFIID riid, void **ppv)
2557 ScriptControl *This = impl_from_IScriptControl(iface);
2559 if(IsEqualGUID(&IID_IUnknown, riid)) {
2560 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
2561 *ppv = &This->IScriptControl_iface;
2562 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
2563 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
2564 *ppv = &This->IScriptControl_iface;
2565 }else if(IsEqualGUID(&IID_IScriptControl, riid)) {
2566 TRACE("(%p)->(IID_IScriptControl %p)\n", This, ppv);
2567 *ppv = &This->IScriptControl_iface;
2568 }else if(IsEqualGUID(&IID_IOleObject, riid)) {
2569 TRACE("(%p)->(IID_IOleObject %p)\n", This, ppv);
2570 *ppv = &This->IOleObject_iface;
2571 }else if(IsEqualGUID(&IID_IPersistStreamInit, riid)) {
2572 TRACE("(%p)->(IID_IPersistStreamInit %p)\n", This, ppv);
2573 *ppv = &This->IPersistStreamInit_iface;
2574 }else if(IsEqualGUID(&IID_IPersist, riid)) {
2575 TRACE("(%p)->(IID_IPersist %p)\n", This, ppv);
2576 *ppv = &This->IPersistStreamInit_iface;
2577 }else if(IsEqualGUID(&IID_IOleControl, riid)) {
2578 TRACE("(%p)->(IID_IOleControl %p)\n", This, ppv);
2579 *ppv = &This->IOleControl_iface;
2580 }else if(IsEqualGUID(&IID_IQuickActivate, riid)) {
2581 TRACE("(%p)->(IID_IQuickActivate %p)\n", This, ppv);
2582 *ppv = &This->IQuickActivate_iface;
2583 }else if(IsEqualGUID(&IID_IViewObject, riid)) {
2584 TRACE("(%p)->(IID_IViewObject %p)\n", This, ppv);
2585 *ppv = &This->IViewObjectEx_iface;
2586 }else if(IsEqualGUID(&IID_IViewObject2, riid)) {
2587 TRACE("(%p)->(IID_IViewObject2 %p)\n", This, ppv);
2588 *ppv = &This->IViewObjectEx_iface;
2589 }else if(IsEqualGUID(&IID_IViewObjectEx, riid)) {
2590 TRACE("(%p)->(IID_IViewObjectEx %p)\n", This, ppv);
2591 *ppv = &This->IViewObjectEx_iface;
2592 }else if(IsEqualGUID(&IID_IPointerInactive, riid)) {
2593 TRACE("(%p)->(IID_IPointerInactive %p)\n", This, ppv);
2594 *ppv = &This->IPointerInactive_iface;
2595 }else if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) {
2596 TRACE("(%p)->(IID_IConnectionPointContainer %p)\n", This, ppv);
2597 *ppv = &This->IConnectionPointContainer_iface;
2598 }else {
2599 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
2600 *ppv = NULL;
2601 return E_NOINTERFACE;
2604 IUnknown_AddRef((IUnknown*)*ppv);
2605 return S_OK;
2608 static ULONG WINAPI ScriptControl_AddRef(IScriptControl *iface)
2610 ScriptControl *This = impl_from_IScriptControl(iface);
2611 LONG ref = InterlockedIncrement(&This->ref);
2613 TRACE("(%p) ref=%d\n", This, ref);
2615 return ref;
2618 static ULONG WINAPI ScriptControl_Release(IScriptControl *iface)
2620 ScriptControl *This = impl_from_IScriptControl(iface);
2621 LONG ref = InterlockedDecrement(&This->ref);
2623 TRACE("(%p) ref=%d\n", This, ref);
2625 if(!ref) {
2626 if (This->site)
2627 IOleClientSite_Release(This->site);
2628 if (This->host)
2630 release_modules(This, FALSE);
2631 IActiveScriptSite_Release(&This->host->IActiveScriptSite_iface);
2633 IScriptError_Release(&This->error->IScriptError_iface);
2634 heap_free(This);
2637 return ref;
2640 static HRESULT WINAPI ScriptControl_GetTypeInfoCount(IScriptControl *iface, UINT *pctinfo)
2642 ScriptControl *This = impl_from_IScriptControl(iface);
2643 TRACE("(%p)->(%p)\n", This, pctinfo);
2644 *pctinfo = 1;
2645 return S_OK;
2648 static HRESULT WINAPI ScriptControl_GetTypeInfo(IScriptControl *iface, UINT iTInfo,
2649 LCID lcid, ITypeInfo **ppTInfo)
2651 ScriptControl *This = impl_from_IScriptControl(iface);
2652 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
2653 return get_typeinfo(IScriptControl_tid, ppTInfo);
2656 static HRESULT WINAPI ScriptControl_GetIDsOfNames(IScriptControl *iface, REFIID riid,
2657 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
2659 ScriptControl *This = impl_from_IScriptControl(iface);
2660 ITypeInfo *typeinfo;
2661 HRESULT hres;
2663 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
2665 hres = get_typeinfo(IScriptControl_tid, &typeinfo);
2666 if(SUCCEEDED(hres)) {
2667 hres = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
2668 ITypeInfo_Release(typeinfo);
2671 return hres;
2674 static HRESULT WINAPI ScriptControl_Invoke(IScriptControl *iface, DISPID dispIdMember,
2675 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
2676 EXCEPINFO *pExcepInfo, UINT *puArgErr)
2678 ScriptControl *This = impl_from_IScriptControl(iface);
2679 ITypeInfo *typeinfo;
2680 HRESULT hres;
2682 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
2683 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2685 hres = get_typeinfo(IScriptControl_tid, &typeinfo);
2686 if(SUCCEEDED(hres)) {
2687 hres = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
2688 pDispParams, pVarResult, pExcepInfo, puArgErr);
2689 ITypeInfo_Release(typeinfo);
2692 return hres;
2695 static HRESULT WINAPI ScriptControl_get_Language(IScriptControl *iface, BSTR *p)
2697 ScriptControl *This = impl_from_IScriptControl(iface);
2698 LPOLESTR progidW;
2699 HRESULT hr;
2701 TRACE("(%p)->(%p)\n", This, p);
2703 if (!p)
2704 return E_POINTER;
2706 *p = NULL;
2708 if (!This->host)
2709 return S_OK;
2711 hr = ProgIDFromCLSID(&This->host->clsid, &progidW);
2712 if (FAILED(hr))
2713 return hr;
2715 *p = SysAllocString(progidW);
2716 CoTaskMemFree(progidW);
2717 return *p ? S_OK : E_OUTOFMEMORY;
2720 static HRESULT WINAPI ScriptControl_put_Language(IScriptControl *iface, BSTR language)
2722 ScriptControl *This = impl_from_IScriptControl(iface);
2723 CLSID clsid;
2724 HRESULT hres;
2726 TRACE("(%p)->(%s)\n", This, debugstr_w(language));
2728 if (language && FAILED(CLSIDFromProgID(language, &clsid)))
2729 return CTL_E_INVALIDPROPERTYVALUE;
2731 if (This->host) {
2732 release_modules(This, TRUE);
2733 IActiveScriptSite_Release(&This->host->IActiveScriptSite_iface);
2734 This->host = NULL;
2737 if (!language)
2738 return S_OK;
2740 hres = init_script_host(This, &clsid, &This->host);
2741 if (FAILED(hres))
2742 return hres;
2744 /* Alloc global module */
2745 This->modules = heap_alloc_zero(sizeof(*This->modules));
2746 if (This->modules) {
2747 This->modules[0] = create_module(This->host, NULL);
2748 if (!This->modules[0]) {
2749 heap_free(This->modules);
2750 This->modules = NULL;
2751 hres = E_OUTOFMEMORY;
2754 else
2755 hres = E_OUTOFMEMORY;
2757 if (FAILED(hres)) {
2758 detach_script_host(This->host);
2759 This->host = NULL;
2761 return hres;
2764 static HRESULT WINAPI ScriptControl_get_State(IScriptControl *iface, ScriptControlStates *p)
2766 ScriptControl *This = impl_from_IScriptControl(iface);
2767 SCRIPTSTATE state;
2768 HRESULT hres;
2770 TRACE("(%p)->(%p)\n", This, p);
2772 if(!p)
2773 return E_POINTER;
2775 if(!This->host)
2776 return E_FAIL;
2778 hres = IActiveScript_GetScriptState(This->host->script, &state);
2779 if (FAILED(hres)) return hres;
2781 switch (state)
2783 case SCRIPTSTATE_INITIALIZED:
2784 case SCRIPTSTATE_STARTED:
2785 *p = Initialized;
2786 break;
2787 case SCRIPTSTATE_CONNECTED:
2788 *p = Connected;
2789 break;
2790 default:
2791 WARN("unexpected state %d\n", state);
2792 return E_FAIL;
2794 return S_OK;
2797 static HRESULT WINAPI ScriptControl_put_State(IScriptControl *iface, ScriptControlStates state)
2799 ScriptControl *This = impl_from_IScriptControl(iface);
2800 TRACE("(%p)->(%x)\n", This, state);
2802 if(!This->host)
2803 return E_FAIL;
2805 if(state != Initialized && state != Connected)
2806 return CTL_E_INVALIDPROPERTYVALUE;
2808 return IActiveScript_SetScriptState(This->host->script, state == Connected ? SCRIPTSTATE_CONNECTED : SCRIPTSTATE_STARTED);
2811 static HRESULT WINAPI ScriptControl_put_SitehWnd(IScriptControl *iface, LONG hwnd)
2813 ScriptControl *This = impl_from_IScriptControl(iface);
2815 TRACE("(%p)->(%x)\n", This, hwnd);
2817 if (hwnd && !IsWindow(LongToHandle(hwnd)))
2818 return CTL_E_INVALIDPROPERTYVALUE;
2820 This->site_hwnd = LongToHandle(hwnd);
2821 if (This->host)
2822 This->host->site_hwnd = This->allow_ui ? This->site_hwnd : ((HWND)-1);
2823 return S_OK;
2826 static HRESULT WINAPI ScriptControl_get_SitehWnd(IScriptControl *iface, LONG *p)
2828 ScriptControl *This = impl_from_IScriptControl(iface);
2830 TRACE("(%p)->(%p)\n", This, p);
2832 if (!p) return E_POINTER;
2834 *p = HandleToLong(This->site_hwnd);
2835 return S_OK;
2838 static HRESULT WINAPI ScriptControl_get_Timeout(IScriptControl *iface, LONG *p)
2840 ScriptControl *This = impl_from_IScriptControl(iface);
2842 TRACE("(%p)->(%p)\n", This, p);
2844 if (!p)
2845 return E_POINTER;
2847 *p = This->timeout;
2848 return S_OK;
2851 static HRESULT WINAPI ScriptControl_put_Timeout(IScriptControl *iface, LONG timeout)
2853 ScriptControl *This = impl_from_IScriptControl(iface);
2855 TRACE("(%p)->(%d)\n", This, timeout);
2857 if (timeout < -1)
2858 return CTL_E_INVALIDPROPERTYVALUE;
2860 if (timeout != -1)
2861 FIXME("execution timeout ignored\n");
2863 This->timeout = timeout;
2864 return S_OK;
2867 static HRESULT WINAPI ScriptControl_get_AllowUI(IScriptControl *iface, VARIANT_BOOL *p)
2869 ScriptControl *This = impl_from_IScriptControl(iface);
2870 TRACE("(%p)->(%p)\n", This, p);
2872 if(!p)
2873 return E_POINTER;
2875 *p = This->allow_ui;
2876 return S_OK;
2879 static HRESULT WINAPI ScriptControl_put_AllowUI(IScriptControl *iface, VARIANT_BOOL allow_ui)
2881 ScriptControl *This = impl_from_IScriptControl(iface);
2882 TRACE("(%p)->(%x)\n", This, allow_ui);
2884 This->allow_ui = allow_ui;
2885 if (This->host)
2886 This->host->site_hwnd = allow_ui ? This->site_hwnd : ((HWND)-1);
2887 return S_OK;
2890 static HRESULT WINAPI ScriptControl_get_UseSafeSubset(IScriptControl *iface, VARIANT_BOOL *p)
2892 ScriptControl *This = impl_from_IScriptControl(iface);
2893 TRACE("(%p)->(%p)\n", This, p);
2895 if(!p)
2896 return E_POINTER;
2898 *p = This->use_safe_subset;
2899 return S_OK;
2902 static HRESULT WINAPI ScriptControl_put_UseSafeSubset(IScriptControl *iface, VARIANT_BOOL use_safe_subset)
2904 ScriptControl *This = impl_from_IScriptControl(iface);
2905 TRACE("(%p)->(%x)\n", This, use_safe_subset);
2907 if (This->host && This->use_safe_subset != use_safe_subset)
2908 set_safety_opts(This->host->script, use_safe_subset);
2910 This->use_safe_subset = use_safe_subset;
2911 return S_OK;
2914 static HRESULT WINAPI ScriptControl_get_Modules(IScriptControl *iface, IScriptModuleCollection **p)
2916 ScriptControl *This = impl_from_IScriptControl(iface);
2918 TRACE("(%p)->(%p)\n", This, p);
2920 if (!This->host) return E_FAIL;
2922 *p = &This->IScriptModuleCollection_iface;
2923 IScriptControl_AddRef(iface);
2924 return S_OK;
2927 static HRESULT WINAPI ScriptControl_get_Error(IScriptControl *iface, IScriptError **p)
2929 ScriptControl *This = impl_from_IScriptControl(iface);
2931 TRACE("(%p)->(%p)\n", This, p);
2933 if (!p) return E_POINTER;
2935 *p = &This->error->IScriptError_iface;
2936 IScriptError_AddRef(*p);
2937 return S_OK;
2940 static HRESULT WINAPI ScriptControl_get_CodeObject(IScriptControl *iface, IDispatch **p)
2942 ScriptControl *This = impl_from_IScriptControl(iface);
2944 TRACE("(%p)->(%p)\n", This, p);
2946 if (!This->host) return E_FAIL;
2948 return IScriptModule_get_CodeObject(&This->modules[0]->IScriptModule_iface, p);
2951 static HRESULT WINAPI ScriptControl_get_Procedures(IScriptControl *iface, IScriptProcedureCollection **p)
2953 ScriptControl *This = impl_from_IScriptControl(iface);
2955 TRACE("(%p)->(%p)\n", This, p);
2957 if (!This->host) return E_FAIL;
2959 return IScriptModule_get_Procedures(&This->modules[0]->IScriptModule_iface, p);
2962 static HRESULT WINAPI ScriptControl__AboutBox(IScriptControl *iface)
2964 ScriptControl *This = impl_from_IScriptControl(iface);
2965 FIXME("(%p)\n", This);
2966 return E_NOTIMPL;
2969 static HRESULT WINAPI ScriptControl_AddObject(IScriptControl *iface, BSTR name, IDispatch *object, VARIANT_BOOL add_members)
2971 ScriptControl *This = impl_from_IScriptControl(iface);
2972 DWORD flags = SCRIPTITEM_ISVISIBLE | SCRIPTITEM_ISSOURCE;
2974 TRACE("(%p)->(%s %p %x)\n", This, debugstr_w(name), object, add_members);
2976 if (!object)
2977 return E_INVALIDARG;
2979 if (!This->host)
2980 return E_FAIL;
2982 if (add_members)
2983 flags |= SCRIPTITEM_GLOBALMEMBERS;
2984 return add_script_object(This->host, name, object, flags);
2987 static HRESULT WINAPI ScriptControl_Reset(IScriptControl *iface)
2989 ScriptControl *This = impl_from_IScriptControl(iface);
2991 TRACE("(%p)\n", This);
2993 if (!This->host)
2994 return E_FAIL;
2996 clear_named_items(This->host);
2997 return set_script_state(This->host, SCRIPTSTATE_INITIALIZED);
3000 static HRESULT WINAPI ScriptControl_AddCode(IScriptControl *iface, BSTR code)
3002 ScriptControl *This = impl_from_IScriptControl(iface);
3004 TRACE("(%p)->(%s).\n", This, debugstr_w(code));
3006 if (!This->host)
3007 return E_FAIL;
3009 return parse_script_text(This->modules[0], code, SCRIPTTEXT_ISVISIBLE, NULL);
3012 static HRESULT WINAPI ScriptControl_Eval(IScriptControl *iface, BSTR expression, VARIANT *res)
3014 ScriptControl *This = impl_from_IScriptControl(iface);
3016 TRACE("(%p)->(%s, %p).\n", This, debugstr_w(expression), res);
3018 if (!res)
3019 return E_POINTER;
3020 V_VT(res) = VT_EMPTY;
3021 if (!This->host)
3022 return E_FAIL;
3024 return parse_script_text(This->modules[0], expression, SCRIPTTEXT_ISEXPRESSION, res);
3027 static HRESULT WINAPI ScriptControl_ExecuteStatement(IScriptControl *iface, BSTR statement)
3029 ScriptControl *This = impl_from_IScriptControl(iface);
3031 TRACE("(%p)->(%s)\n", This, debugstr_w(statement));
3033 if (!This->host)
3034 return E_FAIL;
3036 return parse_script_text(This->modules[0], statement, 0, NULL);
3039 static HRESULT WINAPI ScriptControl_Run(IScriptControl *iface, BSTR procedure_name, SAFEARRAY **parameters, VARIANT *res)
3041 ScriptControl *This = impl_from_IScriptControl(iface);
3042 SAFEARRAY *sa;
3044 TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(procedure_name), parameters, res);
3046 if (!parameters || !res) return E_POINTER;
3047 if (!(sa = *parameters)) return E_POINTER;
3049 V_VT(res) = VT_EMPTY;
3050 if (sa->cDims == 0) return DISP_E_BADINDEX;
3051 if (!(sa->fFeatures & FADF_VARIANT)) return DISP_E_BADVARTYPE;
3052 if (!This->host) return E_FAIL;
3054 return run_procedure(This->modules[0], procedure_name, sa, res);
3057 static const IScriptControlVtbl ScriptControlVtbl = {
3058 ScriptControl_QueryInterface,
3059 ScriptControl_AddRef,
3060 ScriptControl_Release,
3061 ScriptControl_GetTypeInfoCount,
3062 ScriptControl_GetTypeInfo,
3063 ScriptControl_GetIDsOfNames,
3064 ScriptControl_Invoke,
3065 ScriptControl_get_Language,
3066 ScriptControl_put_Language,
3067 ScriptControl_get_State,
3068 ScriptControl_put_State,
3069 ScriptControl_put_SitehWnd,
3070 ScriptControl_get_SitehWnd,
3071 ScriptControl_get_Timeout,
3072 ScriptControl_put_Timeout,
3073 ScriptControl_get_AllowUI,
3074 ScriptControl_put_AllowUI,
3075 ScriptControl_get_UseSafeSubset,
3076 ScriptControl_put_UseSafeSubset,
3077 ScriptControl_get_Modules,
3078 ScriptControl_get_Error,
3079 ScriptControl_get_CodeObject,
3080 ScriptControl_get_Procedures,
3081 ScriptControl__AboutBox,
3082 ScriptControl_AddObject,
3083 ScriptControl_Reset,
3084 ScriptControl_AddCode,
3085 ScriptControl_Eval,
3086 ScriptControl_ExecuteStatement,
3087 ScriptControl_Run
3090 static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **obj)
3092 ScriptControl *This = impl_from_IOleObject(iface);
3093 return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
3096 static ULONG WINAPI OleObject_AddRef(IOleObject *iface)
3098 ScriptControl *This = impl_from_IOleObject(iface);
3099 return IScriptControl_AddRef(&This->IScriptControl_iface);
3102 static ULONG WINAPI OleObject_Release(IOleObject *iface)
3104 ScriptControl *This = impl_from_IOleObject(iface);
3105 return IScriptControl_Release(&This->IScriptControl_iface);
3108 static HRESULT WINAPI OleObject_SetClientSite(IOleObject *iface, IOleClientSite *site)
3110 ScriptControl *This = impl_from_IOleObject(iface);
3112 TRACE("(%p)->(%p)\n", This, site);
3114 if (This->site)
3115 IOleClientSite_Release(This->site);
3117 if ((This->site = site))
3118 IOleClientSite_AddRef(site);
3120 return S_OK;
3123 static HRESULT WINAPI OleObject_GetClientSite(IOleObject *iface, IOleClientSite **site)
3125 ScriptControl *This = impl_from_IOleObject(iface);
3127 TRACE("(%p)->(%p)\n", This, site);
3129 if (!site)
3130 return E_POINTER;
3132 if ((*site = This->site))
3133 IOleClientSite_AddRef(*site);
3135 return S_OK;
3138 static HRESULT WINAPI OleObject_SetHostNames(IOleObject *iface, LPCOLESTR containerapp, LPCOLESTR containerobj)
3140 ScriptControl *This = impl_from_IOleObject(iface);
3142 FIXME("(%p)->(%s %s)\n", This, debugstr_w(containerapp), debugstr_w(containerobj));
3144 return E_NOTIMPL;
3147 static HRESULT WINAPI OleObject_Close(IOleObject *iface, DWORD save)
3149 ScriptControl *This = impl_from_IOleObject(iface);
3151 FIXME("(%p)->(%d)\n", This, save);
3153 return E_NOTIMPL;
3156 static HRESULT WINAPI OleObject_SetMoniker(IOleObject *iface, DWORD which, IMoniker *moniker)
3158 ScriptControl *This = impl_from_IOleObject(iface);
3160 FIXME("(%p)->(%d %p)\n", This, which, moniker);
3162 return E_NOTIMPL;
3165 static HRESULT WINAPI OleObject_GetMoniker(IOleObject *iface, DWORD assign, DWORD which, IMoniker **moniker)
3167 ScriptControl *This = impl_from_IOleObject(iface);
3169 FIXME("(%p)->(%d %d %p)\n", This, assign, which, moniker);
3171 return E_NOTIMPL;
3174 static HRESULT WINAPI OleObject_InitFromData(IOleObject *iface, IDataObject *dataobj, BOOL creation,
3175 DWORD reserved)
3177 ScriptControl *This = impl_from_IOleObject(iface);
3179 FIXME("(%p)->(%p %d %d)\n", This, dataobj, creation, reserved);
3181 return E_NOTIMPL;
3184 static HRESULT WINAPI OleObject_GetClipboardData(IOleObject *iface, DWORD reserved, IDataObject **dataobj)
3186 ScriptControl *This = impl_from_IOleObject(iface);
3188 FIXME("(%p)->(%d %p)\n", This, reserved, dataobj);
3190 return E_NOTIMPL;
3193 static HRESULT WINAPI OleObject_DoVerb(IOleObject *iface, LONG verb, LPMSG msg, IOleClientSite *active_site,
3194 LONG index, HWND hwndParent, LPCRECT rect)
3196 ScriptControl *This = impl_from_IOleObject(iface);
3198 FIXME("(%p)->(%d %p %p %d %p %p)\n", This, verb, msg, active_site, index, hwndParent, rect);
3200 return E_NOTIMPL;
3203 static HRESULT WINAPI OleObject_EnumVerbs(IOleObject *iface, IEnumOLEVERB **enumoleverb)
3205 ScriptControl *This = impl_from_IOleObject(iface);
3207 FIXME("(%p)->(%p)\n", This, enumoleverb);
3209 return E_NOTIMPL;
3212 static HRESULT WINAPI OleObject_Update(IOleObject *iface)
3214 ScriptControl *This = impl_from_IOleObject(iface);
3216 FIXME("(%p)\n", This);
3218 return E_NOTIMPL;
3221 static HRESULT WINAPI OleObject_IsUpToDate(IOleObject *iface)
3223 ScriptControl *This = impl_from_IOleObject(iface);
3225 FIXME("(%p)\n", This);
3227 return E_NOTIMPL;
3230 static HRESULT WINAPI OleObject_GetUserClassID(IOleObject *iface, CLSID *clsid)
3232 ScriptControl *This = impl_from_IOleObject(iface);
3234 FIXME("(%p)->(%p)\n", This, clsid);
3236 return E_NOTIMPL;
3239 static HRESULT WINAPI OleObject_GetUserType(IOleObject *iface, DWORD form_of_type, LPOLESTR *usertype)
3241 ScriptControl *This = impl_from_IOleObject(iface);
3243 FIXME("(%p)->(%d %p)\n", This, form_of_type, usertype);
3245 return E_NOTIMPL;
3248 static HRESULT WINAPI OleObject_SetExtent(IOleObject *iface, DWORD aspect, SIZEL *size)
3250 ScriptControl *This = impl_from_IOleObject(iface);
3252 FIXME("(%p)->(%d %p)\n", This, aspect, size);
3254 return E_NOTIMPL;
3257 static HRESULT WINAPI OleObject_GetExtent(IOleObject *iface, DWORD aspect, SIZEL *size)
3259 ScriptControl *This = impl_from_IOleObject(iface);
3261 TRACE("(%p)->(%d %p)\n", This, aspect, size);
3263 if (aspect != DVASPECT_CONTENT)
3264 return DV_E_DVASPECT;
3266 *size = This->extent;
3267 return S_OK;
3270 static HRESULT WINAPI OleObject_Advise(IOleObject *iface, IAdviseSink *sink, DWORD *connection)
3272 ScriptControl *This = impl_from_IOleObject(iface);
3274 FIXME("(%p)->(%p %p)\n", This, sink, connection);
3276 return E_NOTIMPL;
3279 static HRESULT WINAPI OleObject_Unadvise(IOleObject *iface, DWORD connection)
3281 ScriptControl *This = impl_from_IOleObject(iface);
3283 FIXME("(%p)->(%d)\n", This, connection);
3285 return E_NOTIMPL;
3288 static HRESULT WINAPI OleObject_EnumAdvise(IOleObject *iface, IEnumSTATDATA **enumadvise)
3290 ScriptControl *This = impl_from_IOleObject(iface);
3292 FIXME("(%p)->(%p)\n", This, enumadvise);
3294 return E_NOTIMPL;
3297 static HRESULT WINAPI OleObject_GetMiscStatus(IOleObject *iface, DWORD aspect, DWORD *status)
3299 ScriptControl *This = impl_from_IOleObject(iface);
3301 TRACE("(%p)->(%d %p)\n", This, aspect, status);
3303 return OleRegGetMiscStatus(&CLSID_ScriptControl, aspect, status);
3306 static HRESULT WINAPI OleObject_SetColorScheme(IOleObject *iface, LOGPALETTE *logpal)
3308 ScriptControl *This = impl_from_IOleObject(iface);
3310 FIXME("(%p)->(%p)\n", This, logpal);
3312 return E_NOTIMPL;
3315 static const IOleObjectVtbl OleObjectVtbl = {
3316 OleObject_QueryInterface,
3317 OleObject_AddRef,
3318 OleObject_Release,
3319 OleObject_SetClientSite,
3320 OleObject_GetClientSite,
3321 OleObject_SetHostNames,
3322 OleObject_Close,
3323 OleObject_SetMoniker,
3324 OleObject_GetMoniker,
3325 OleObject_InitFromData,
3326 OleObject_GetClipboardData,
3327 OleObject_DoVerb,
3328 OleObject_EnumVerbs,
3329 OleObject_Update,
3330 OleObject_IsUpToDate,
3331 OleObject_GetUserClassID,
3332 OleObject_GetUserType,
3333 OleObject_SetExtent,
3334 OleObject_GetExtent,
3335 OleObject_Advise,
3336 OleObject_Unadvise,
3337 OleObject_EnumAdvise,
3338 OleObject_GetMiscStatus,
3339 OleObject_SetColorScheme
3342 static HRESULT WINAPI PersistStreamInit_QueryInterface(IPersistStreamInit *iface, REFIID riid, void **obj)
3344 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3345 return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
3348 static ULONG WINAPI PersistStreamInit_AddRef(IPersistStreamInit *iface)
3350 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3351 return IScriptControl_AddRef(&This->IScriptControl_iface);
3354 static ULONG WINAPI PersistStreamInit_Release(IPersistStreamInit *iface)
3356 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3357 return IScriptControl_Release(&This->IScriptControl_iface);
3360 static HRESULT WINAPI PersistStreamInit_GetClassID(IPersistStreamInit *iface, CLSID *clsid)
3362 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3364 FIXME("(%p)->(%p)\n", This, clsid);
3366 return E_NOTIMPL;
3369 static HRESULT WINAPI PersistStreamInit_IsDirty(IPersistStreamInit *iface)
3371 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3373 FIXME("(%p)\n", This);
3375 return E_NOTIMPL;
3378 static HRESULT WINAPI PersistStreamInit_Load(IPersistStreamInit *iface, IStream *stream)
3380 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3382 FIXME("(%p)->(%p)\n", This, stream);
3384 return E_NOTIMPL;
3387 static HRESULT WINAPI PersistStreamInit_Save(IPersistStreamInit *iface, IStream *stream, BOOL clear_dirty)
3389 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3391 FIXME("(%p)->(%p %d)\n", This, stream, clear_dirty);
3393 return E_NOTIMPL;
3396 static HRESULT WINAPI PersistStreamInit_GetSizeMax(IPersistStreamInit *iface, ULARGE_INTEGER *size)
3398 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3400 FIXME("(%p)->(%p)\n", This, size);
3402 return E_NOTIMPL;
3405 static HRESULT WINAPI PersistStreamInit_InitNew(IPersistStreamInit *iface)
3407 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3409 FIXME("(%p)\n", This);
3411 return S_OK;
3414 static const IPersistStreamInitVtbl PersistStreamInitVtbl = {
3415 PersistStreamInit_QueryInterface,
3416 PersistStreamInit_AddRef,
3417 PersistStreamInit_Release,
3418 PersistStreamInit_GetClassID,
3419 PersistStreamInit_IsDirty,
3420 PersistStreamInit_Load,
3421 PersistStreamInit_Save,
3422 PersistStreamInit_GetSizeMax,
3423 PersistStreamInit_InitNew
3426 static HRESULT WINAPI OleControl_QueryInterface(IOleControl *iface, REFIID riid, void **obj)
3428 ScriptControl *This = impl_from_IOleControl(iface);
3429 return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
3432 static ULONG WINAPI OleControl_AddRef(IOleControl *iface)
3434 ScriptControl *This = impl_from_IOleControl(iface);
3435 return IScriptControl_AddRef(&This->IScriptControl_iface);
3438 static ULONG WINAPI OleControl_Release(IOleControl *iface)
3440 ScriptControl *This = impl_from_IOleControl(iface);
3441 return IScriptControl_Release(&This->IScriptControl_iface);
3444 static HRESULT WINAPI OleControl_GetControlInfo(IOleControl *iface, CONTROLINFO *info)
3446 ScriptControl *This = impl_from_IOleControl(iface);
3448 TRACE("(%p)->(%p)\n", This, info);
3450 if (!info)
3451 return E_POINTER;
3453 info->hAccel = NULL;
3454 info->cAccel = 0;
3456 return S_OK;
3459 static HRESULT WINAPI OleControl_OnMnemonic(IOleControl *iface, MSG *msg)
3461 ScriptControl *This = impl_from_IOleControl(iface);
3463 FIXME("(%p)->(%p)\n", This, msg);
3465 return E_NOTIMPL;
3468 static HRESULT WINAPI OleControl_OnAmbientPropertyChange(IOleControl *iface, DISPID dispid)
3470 ScriptControl *This = impl_from_IOleControl(iface);
3472 FIXME("(%p)->(%#x)\n", This, dispid);
3474 return E_NOTIMPL;
3477 static HRESULT WINAPI OleControl_FreezeEvents(IOleControl *iface, BOOL freeze)
3479 ScriptControl *This = impl_from_IOleControl(iface);
3481 FIXME("(%p)->(%d)\n", This, freeze);
3483 return E_NOTIMPL;
3486 static const IOleControlVtbl OleControlVtbl = {
3487 OleControl_QueryInterface,
3488 OleControl_AddRef,
3489 OleControl_Release,
3490 OleControl_GetControlInfo,
3491 OleControl_OnMnemonic,
3492 OleControl_OnAmbientPropertyChange,
3493 OleControl_FreezeEvents
3496 static HRESULT WINAPI QuickActivate_QueryInterface(IQuickActivate *iface, REFIID riid, void **obj)
3498 ScriptControl *This = impl_from_IQuickActivate(iface);
3499 return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
3502 static ULONG WINAPI QuickActivate_AddRef(IQuickActivate *iface)
3504 ScriptControl *This = impl_from_IQuickActivate(iface);
3505 return IScriptControl_AddRef(&This->IScriptControl_iface);
3508 static ULONG WINAPI QuickActivate_Release(IQuickActivate *iface)
3510 ScriptControl *This = impl_from_IQuickActivate(iface);
3511 return IScriptControl_Release(&This->IScriptControl_iface);
3514 static HRESULT WINAPI QuickActivate_QuickActivate(IQuickActivate *iface, QACONTAINER *container, QACONTROL *control)
3516 ScriptControl *This = impl_from_IQuickActivate(iface);
3518 FIXME("(%p)->(%p %p)\n", This, container, control);
3520 return E_NOTIMPL;
3523 static HRESULT WINAPI QuickActivate_SetContentExtent(IQuickActivate *iface, SIZEL *size)
3525 ScriptControl *This = impl_from_IQuickActivate(iface);
3527 FIXME("(%p)->(%p)\n", This, size);
3529 return E_NOTIMPL;
3532 static HRESULT WINAPI QuickActivate_GetContentExtent(IQuickActivate *iface, SIZEL *size)
3534 ScriptControl *This = impl_from_IQuickActivate(iface);
3536 FIXME("(%p)->(%p)\n", This, size);
3538 return E_NOTIMPL;
3541 static const IQuickActivateVtbl QuickActivateVtbl = {
3542 QuickActivate_QueryInterface,
3543 QuickActivate_AddRef,
3544 QuickActivate_Release,
3545 QuickActivate_QuickActivate,
3546 QuickActivate_SetContentExtent,
3547 QuickActivate_GetContentExtent
3550 static HRESULT WINAPI ViewObject_QueryInterface(IViewObjectEx *iface, REFIID riid, void **obj)
3552 ScriptControl *This = impl_from_IViewObjectEx(iface);
3553 return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
3556 static ULONG WINAPI ViewObject_AddRef(IViewObjectEx *iface)
3558 ScriptControl *This = impl_from_IViewObjectEx(iface);
3559 return IScriptControl_AddRef(&This->IScriptControl_iface);
3562 static ULONG WINAPI ViewObject_Release(IViewObjectEx *iface)
3564 ScriptControl *This = impl_from_IViewObjectEx(iface);
3565 return IScriptControl_Release(&This->IScriptControl_iface);
3568 static HRESULT WINAPI ViewObject_Draw(IViewObjectEx *iface, DWORD drawaspect, LONG index, void *aspect,
3569 DVTARGETDEVICE *device, HDC target_dev, HDC hdc_draw, const RECTL *bounds, const RECTL *win_bounds,
3570 BOOL (STDMETHODCALLTYPE *fn_continue)(ULONG_PTR cont), ULONG_PTR cont)
3572 ScriptControl *This = impl_from_IViewObjectEx(iface);
3574 FIXME("(%p)->(%d %d %p %p %p %p %p %p %p %lu)\n", This, drawaspect, index, aspect, device, target_dev,
3575 hdc_draw, bounds, win_bounds, fn_continue, cont);
3577 return E_NOTIMPL;
3580 static HRESULT WINAPI ViewObject_GetColorSet(IViewObjectEx *iface, DWORD drawaspect, LONG index, void *aspect,
3581 DVTARGETDEVICE *device, HDC hic_target, LOGPALETTE **colorset)
3583 ScriptControl *This = impl_from_IViewObjectEx(iface);
3585 FIXME("(%p)->(%d %d %p %p %p %p)\n", This, drawaspect, index, aspect, device, hic_target,
3586 colorset);
3588 return E_NOTIMPL;
3591 static HRESULT WINAPI ViewObject_Freeze(IViewObjectEx *iface, DWORD drawaspect, LONG index, void *aspect,
3592 DWORD *freeze)
3594 ScriptControl *This = impl_from_IViewObjectEx(iface);
3596 FIXME("(%p)->(%d %d %p %p)\n", This, drawaspect, index, aspect, freeze);
3598 return E_NOTIMPL;
3601 static HRESULT WINAPI ViewObject_Unfreeze(IViewObjectEx *iface, DWORD freeze)
3603 ScriptControl *This = impl_from_IViewObjectEx(iface);
3605 FIXME("(%p)->(%d)\n", This, freeze);
3607 return E_NOTIMPL;
3610 static HRESULT WINAPI ViewObject_SetAdvise(IViewObjectEx *iface, DWORD aspects, DWORD flags, IAdviseSink *sink)
3612 ScriptControl *This = impl_from_IViewObjectEx(iface);
3614 TRACE("(%p)->(%d %#x %p)\n", This, aspects, flags, sink);
3616 if (aspects != DVASPECT_CONTENT)
3617 return DV_E_DVASPECT;
3619 This->view_sink_flags = flags;
3620 if (This->view_sink)
3621 IAdviseSink_Release(This->view_sink);
3622 This->view_sink = sink;
3623 if (This->view_sink)
3624 IAdviseSink_AddRef(This->view_sink);
3626 return S_OK;
3629 static HRESULT WINAPI ViewObject_GetAdvise(IViewObjectEx *iface, DWORD *aspects, DWORD *flags, IAdviseSink **sink)
3631 ScriptControl *This = impl_from_IViewObjectEx(iface);
3633 TRACE("(%p)->(%p %p %p)\n", This, aspects, flags, sink);
3635 if (aspects)
3636 *aspects = DVASPECT_CONTENT;
3637 if (flags)
3638 *flags = This->view_sink_flags;
3639 if (sink) {
3640 *sink = This->view_sink;
3641 if (*sink)
3642 IAdviseSink_AddRef(*sink);
3645 return S_OK;
3648 static HRESULT WINAPI ViewObject_GetExtent(IViewObjectEx *iface, DWORD draw_aspect, LONG index,
3649 DVTARGETDEVICE *device, SIZEL *size)
3651 ScriptControl *This = impl_from_IViewObjectEx(iface);
3653 FIXME("(%p)->(%d %d %p %p)\n", This, draw_aspect, index, device, size);
3655 return E_NOTIMPL;
3658 static HRESULT WINAPI ViewObject_GetRect(IViewObjectEx *iface, DWORD aspect, RECTL *rect)
3660 ScriptControl *This = impl_from_IViewObjectEx(iface);
3662 FIXME("(%p)->(%d %p)\n", This, aspect, rect);
3664 return E_NOTIMPL;
3667 static HRESULT WINAPI ViewObject_GetViewStatus(IViewObjectEx *iface, DWORD *status)
3669 ScriptControl *This = impl_from_IViewObjectEx(iface);
3671 TRACE("(%p)->(%p)\n", This, status);
3673 *status = VIEWSTATUS_OPAQUE;
3674 return S_OK;
3677 static HRESULT WINAPI ViewObject_QueryHitPoint(IViewObjectEx *iface, DWORD aspect, const RECT *bounds,
3678 POINT pt, LONG close_hint, DWORD *hit_result)
3680 ScriptControl *This = impl_from_IViewObjectEx(iface);
3682 FIXME("(%p)->(%d %s %s %d %p)\n", This, aspect, wine_dbgstr_rect(bounds), wine_dbgstr_point(&pt), close_hint, hit_result);
3684 return E_NOTIMPL;
3687 static HRESULT WINAPI ViewObject_QueryHitRect(IViewObjectEx *iface, DWORD aspect, const RECT *bounds,
3688 const RECT *loc, LONG close_hint, DWORD *hit_result)
3690 ScriptControl *This = impl_from_IViewObjectEx(iface);
3692 FIXME("(%p)->(%d %s %s %d %p)\n", This, aspect, wine_dbgstr_rect(bounds), wine_dbgstr_rect(loc), close_hint, hit_result);
3694 return E_NOTIMPL;
3697 static HRESULT WINAPI ViewObject_GetNaturalExtent(IViewObjectEx *iface, DWORD aspect, LONG index,
3698 DVTARGETDEVICE *device, HDC target_hdc, DVEXTENTINFO *extent_info, SIZEL *size)
3700 ScriptControl *This = impl_from_IViewObjectEx(iface);
3702 FIXME("(%p)->(%d %d %p %p %p %p)\n", This, aspect, index, device, target_hdc, extent_info, size);
3704 return E_NOTIMPL;
3707 static const IViewObjectExVtbl ViewObjectExVtbl = {
3708 ViewObject_QueryInterface,
3709 ViewObject_AddRef,
3710 ViewObject_Release,
3711 ViewObject_Draw,
3712 ViewObject_GetColorSet,
3713 ViewObject_Freeze,
3714 ViewObject_Unfreeze,
3715 ViewObject_SetAdvise,
3716 ViewObject_GetAdvise,
3717 ViewObject_GetExtent,
3718 ViewObject_GetRect,
3719 ViewObject_GetViewStatus,
3720 ViewObject_QueryHitPoint,
3721 ViewObject_QueryHitRect,
3722 ViewObject_GetNaturalExtent
3725 static HRESULT WINAPI PointerInactive_QueryInterface(IPointerInactive *iface, REFIID riid, void **obj)
3727 ScriptControl *This = impl_from_IPointerInactive(iface);
3728 return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
3731 static ULONG WINAPI PointerInactive_AddRef(IPointerInactive *iface)
3733 ScriptControl *This = impl_from_IPointerInactive(iface);
3734 return IScriptControl_AddRef(&This->IScriptControl_iface);
3737 static ULONG WINAPI PointerInactive_Release(IPointerInactive *iface)
3739 ScriptControl *This = impl_from_IPointerInactive(iface);
3740 return IScriptControl_Release(&This->IScriptControl_iface);
3743 static HRESULT WINAPI PointerInactive_GetActivationPolicy(IPointerInactive *iface, DWORD *policy)
3745 ScriptControl *This = impl_from_IPointerInactive(iface);
3747 TRACE("(%p)->(%p)\n", This, policy);
3749 if (!policy)
3750 return E_POINTER;
3752 *policy = 0;
3753 return S_OK;
3756 static HRESULT WINAPI PointerInactive_OnInactiveMouseMove(IPointerInactive *iface, const RECT *bounds,
3757 LONG x, LONG y, DWORD key_state)
3759 ScriptControl *This = impl_from_IPointerInactive(iface);
3761 FIXME("(%p)->(%s %d %d %#x)\n", This, wine_dbgstr_rect(bounds), x, y, key_state);
3763 return E_NOTIMPL;
3766 static HRESULT WINAPI PointerInactive_OnInactiveSetCursor(IPointerInactive *iface, const RECT *bounds,
3767 LONG x, LONG y, DWORD msg, BOOL set_always)
3769 ScriptControl *This = impl_from_IPointerInactive(iface);
3771 FIXME("(%p)->(%s %d %d %#x %d)\n", This, wine_dbgstr_rect(bounds), x, y, msg, set_always);
3773 return E_NOTIMPL;
3776 static const IPointerInactiveVtbl PointerInactiveVtbl = {
3777 PointerInactive_QueryInterface,
3778 PointerInactive_AddRef,
3779 PointerInactive_Release,
3780 PointerInactive_GetActivationPolicy,
3781 PointerInactive_OnInactiveMouseMove,
3782 PointerInactive_OnInactiveSetCursor
3785 static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface, REFIID riid, void **obj)
3787 ScriptControl *This = impl_from_IConnectionPointContainer(iface);
3788 return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
3791 static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface)
3793 ScriptControl *This = impl_from_IConnectionPointContainer(iface);
3794 return IScriptControl_AddRef(&This->IScriptControl_iface);
3797 static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface)
3799 ScriptControl *This = impl_from_IConnectionPointContainer(iface);
3800 return IScriptControl_Release(&This->IScriptControl_iface);
3803 static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface, IEnumConnectionPoints **enum_points)
3805 ScriptControl *This = impl_from_IConnectionPointContainer(iface);
3807 FIXME("(%p)->(%p)\n", This, enum_points);
3809 return E_NOTIMPL;
3812 static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface, REFIID riid, IConnectionPoint **cp)
3814 ScriptControl *This = impl_from_IConnectionPointContainer(iface);
3815 ConnectionPoint *iter;
3817 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), cp);
3819 *cp = NULL;
3821 for (iter = This->cp_list; iter; iter = iter->next) {
3822 if (IsEqualIID(iter->riid, riid))
3823 *cp = &iter->IConnectionPoint_iface;
3826 if (*cp) {
3827 IConnectionPoint_AddRef(*cp);
3828 return S_OK;
3831 FIXME("unsupported connection point %s\n", debugstr_guid(riid));
3832 return CONNECT_E_NOCONNECTION;
3835 static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl = {
3836 ConnectionPointContainer_QueryInterface,
3837 ConnectionPointContainer_AddRef,
3838 ConnectionPointContainer_Release,
3839 ConnectionPointContainer_EnumConnectionPoints,
3840 ConnectionPointContainer_FindConnectionPoint
3843 static HRESULT WINAPI ConnectionPoint_QueryInterface(IConnectionPoint *iface,
3844 REFIID riid, void **ppv)
3846 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
3848 if(IsEqualGUID(&IID_IUnknown, riid)) {
3849 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
3850 *ppv = &This->IConnectionPoint_iface;
3851 }else if(IsEqualGUID(&IID_IConnectionPoint, riid)) {
3852 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
3853 *ppv = &This->IConnectionPoint_iface;
3854 }else {
3855 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
3856 *ppv = NULL;
3857 return E_NOINTERFACE;
3860 IUnknown_AddRef((IUnknown*)*ppv);
3861 return S_OK;
3864 static ULONG WINAPI ConnectionPoint_AddRef(IConnectionPoint *iface)
3866 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
3867 return IConnectionPointContainer_AddRef(&This->control->IConnectionPointContainer_iface);
3870 static ULONG WINAPI ConnectionPoint_Release(IConnectionPoint *iface)
3872 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
3873 return IConnectionPointContainer_Release(&This->control->IConnectionPointContainer_iface);
3876 static HRESULT WINAPI ConnectionPoint_GetConnectionInterface(IConnectionPoint *iface, IID *iid)
3878 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
3880 TRACE("(%p)->(%p)\n", This, iid);
3882 *iid = *This->riid;
3883 return S_OK;
3886 static HRESULT WINAPI ConnectionPoint_GetConnectionPointContainer(IConnectionPoint *iface,
3887 IConnectionPointContainer **container)
3889 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
3891 TRACE("(%p)->(%p)\n", This, container);
3893 if (!container)
3894 return E_POINTER;
3896 *container = &This->control->IConnectionPointContainer_iface;
3897 IConnectionPointContainer_AddRef(*container);
3899 return S_OK;
3902 static HRESULT WINAPI ConnectionPoint_Advise(IConnectionPoint *iface, IUnknown *unk_sink,
3903 DWORD *cookie)
3905 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
3907 FIXME("(%p)->(%p %p)\n", This, unk_sink, cookie);
3909 return E_NOTIMPL;
3912 static HRESULT WINAPI ConnectionPoint_Unadvise(IConnectionPoint *iface, DWORD cookie)
3914 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
3916 FIXME("(%p)->(%d)\n", This, cookie);
3918 return E_NOTIMPL;
3921 static HRESULT WINAPI ConnectionPoint_EnumConnections(IConnectionPoint *iface,
3922 IEnumConnections **ppEnum)
3924 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
3926 FIXME("(%p)->(%p): stub\n", This, ppEnum);
3928 return E_NOTIMPL;
3931 static const IConnectionPointVtbl ConnectionPointVtbl =
3933 ConnectionPoint_QueryInterface,
3934 ConnectionPoint_AddRef,
3935 ConnectionPoint_Release,
3936 ConnectionPoint_GetConnectionInterface,
3937 ConnectionPoint_GetConnectionPointContainer,
3938 ConnectionPoint_Advise,
3939 ConnectionPoint_Unadvise,
3940 ConnectionPoint_EnumConnections
3943 static void ConnectionPoint_Init(ConnectionPoint *cp, ScriptControl *sc, REFIID riid)
3945 cp->IConnectionPoint_iface.lpVtbl = &ConnectionPointVtbl;
3946 cp->control = sc;
3947 cp->riid = riid;
3949 cp->next = sc->cp_list;
3950 sc->cp_list = cp;
3953 static HRESULT WINAPI ScriptControl_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
3955 ScriptControl *script_control;
3956 DWORD dpi_x, dpi_y;
3957 HRESULT hres;
3958 HDC hdc;
3960 TRACE("(%p %s %p)\n", outer, debugstr_guid(riid), ppv);
3962 script_control = heap_alloc_zero(sizeof(*script_control));
3963 if(!script_control)
3964 return E_OUTOFMEMORY;
3966 script_control->error = heap_alloc_zero(sizeof(*script_control->error));
3967 if(!script_control->error)
3969 heap_free(script_control);
3970 return E_OUTOFMEMORY;
3973 script_control->IScriptControl_iface.lpVtbl = &ScriptControlVtbl;
3974 script_control->IPersistStreamInit_iface.lpVtbl = &PersistStreamInitVtbl;
3975 script_control->IOleObject_iface.lpVtbl = &OleObjectVtbl;
3976 script_control->IOleControl_iface.lpVtbl = &OleControlVtbl;
3977 script_control->IQuickActivate_iface.lpVtbl = &QuickActivateVtbl;
3978 script_control->IViewObjectEx_iface.lpVtbl = &ViewObjectExVtbl;
3979 script_control->IPointerInactive_iface.lpVtbl = &PointerInactiveVtbl;
3980 script_control->IConnectionPointContainer_iface.lpVtbl = &ConnectionPointContainerVtbl;
3981 script_control->IScriptModuleCollection_iface.lpVtbl = &ScriptModuleCollectionVtbl;
3982 script_control->ref = 1;
3983 script_control->timeout = 10000;
3984 script_control->allow_ui = VARIANT_TRUE;
3985 script_control->use_safe_subset = VARIANT_FALSE;
3987 script_control->error->IScriptError_iface.lpVtbl = &ScriptErrorVtbl;
3988 script_control->error->ref = 1;
3990 ConnectionPoint_Init(&script_control->cp_scsource, script_control, &DIID_DScriptControlSource);
3991 ConnectionPoint_Init(&script_control->cp_propnotif, script_control, &IID_IPropertyNotifySink);
3993 hdc = GetDC(0);
3994 dpi_x = GetDeviceCaps(hdc, LOGPIXELSX);
3995 dpi_y = GetDeviceCaps(hdc, LOGPIXELSY);
3996 ReleaseDC(0, hdc);
3998 script_control->extent.cx = MulDiv(38, 2540, dpi_x);
3999 script_control->extent.cy = MulDiv(38, 2540, dpi_y);
4001 hres = IScriptControl_QueryInterface(&script_control->IScriptControl_iface, riid, ppv);
4002 IScriptControl_Release(&script_control->IScriptControl_iface);
4003 return hres;
4006 /******************************************************************
4007 * DllMain (msscript.ocx.@)
4009 BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
4011 TRACE("(%p %d %p)\n", instance, reason, reserved);
4013 switch(reason) {
4014 case DLL_PROCESS_ATTACH:
4015 DisableThreadLibraryCalls(instance);
4016 break;
4017 case DLL_PROCESS_DETACH:
4018 if(!reserved)
4019 release_typelib();
4020 break;
4023 return TRUE;
4026 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
4028 *ppv = NULL;
4030 if(IsEqualGUID(&IID_IUnknown, riid)) {
4031 TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
4032 *ppv = iface;
4033 }else if(IsEqualGUID(&IID_IClassFactory, riid)) {
4034 TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv);
4035 *ppv = iface;
4038 if(*ppv) {
4039 IUnknown_AddRef((IUnknown*)*ppv);
4040 return S_OK;
4043 WARN("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
4044 return E_NOINTERFACE;
4047 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
4049 TRACE("(%p)\n", iface);
4050 return 2;
4053 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
4055 TRACE("(%p)\n", iface);
4056 return 1;
4059 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock)
4061 TRACE("(%p)->(%x)\n", iface, fLock);
4062 return S_OK;
4065 static const IClassFactoryVtbl ScriptControlFactoryVtbl = {
4066 ClassFactory_QueryInterface,
4067 ClassFactory_AddRef,
4068 ClassFactory_Release,
4069 ScriptControl_CreateInstance,
4070 ClassFactory_LockServer
4073 static IClassFactory ScriptControlFactory = { &ScriptControlFactoryVtbl };
4075 /***********************************************************************
4076 * DllGetClassObject (msscript.ocx.@)
4078 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
4080 if(IsEqualGUID(&CLSID_ScriptControl, rclsid)) {
4081 TRACE("(CLSID_ScriptControl %s %p)\n", debugstr_guid(riid), ppv);
4082 return IClassFactory_QueryInterface(&ScriptControlFactory, riid, ppv);
4085 FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
4086 return CLASS_E_CLASSNOTAVAILABLE;