msscript.ocx: Uncache the module objects when script is restarted, but not the Proced...
[wine.git] / dlls / msscript.ocx / msscript.c
blobee0cf2537e4c127011cf52a5848c5907d915d051
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 SCRIPTSTATE script_state;
151 CLSID clsid;
153 unsigned int module_count;
154 struct list named_items;
157 struct ScriptControl {
158 IScriptControl IScriptControl_iface;
159 IPersistStreamInit IPersistStreamInit_iface;
160 IOleObject IOleObject_iface;
161 IOleControl IOleControl_iface;
162 IQuickActivate IQuickActivate_iface;
163 IViewObjectEx IViewObjectEx_iface;
164 IPointerInactive IPointerInactive_iface;
165 IConnectionPointContainer IConnectionPointContainer_iface;
166 LONG ref;
167 IOleClientSite *site;
168 SIZEL extent;
169 LONG timeout;
170 VARIANT_BOOL allow_ui;
171 VARIANT_BOOL use_safe_subset;
173 /* connection points */
174 ConnectionPoint *cp_list;
175 ConnectionPoint cp_scsource;
176 ConnectionPoint cp_propnotif;
178 /* IViewObject sink */
179 IAdviseSink *view_sink;
180 DWORD view_sink_flags;
182 /* modules */
183 ScriptModule **modules;
184 IScriptModuleCollection IScriptModuleCollection_iface;
186 ScriptHost *host;
187 ScriptError *error;
190 static HINSTANCE msscript_instance;
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 run_procedure(ScriptModule *module, BSTR procedure_name, SAFEARRAY *args, VARIANT *res)
437 IDispatchEx *dispex;
438 IDispatch *disp;
439 DISPPARAMS dp;
440 DISPID dispid;
441 HRESULT hr;
442 UINT i;
444 hr = start_script(module);
445 if (FAILED(hr)) return hr;
447 hr = get_script_dispatch(module, &disp);
448 if (FAILED(hr)) return hr;
450 hr = IDispatch_GetIDsOfNames(disp, &IID_NULL, &procedure_name, 1, LOCALE_USER_DEFAULT, &dispid);
451 if (FAILED(hr)) return hr;
453 dp.cArgs = args->rgsabound[0].cElements;
454 dp.rgdispidNamedArgs = NULL;
455 dp.cNamedArgs = 0;
456 dp.rgvarg = heap_alloc(dp.cArgs * sizeof(*dp.rgvarg));
457 if (!dp.rgvarg) return E_OUTOFMEMORY;
459 hr = SafeArrayLock(args);
460 if (SUCCEEDED(hr))
462 /* The DISPPARAMS are stored in reverse order */
463 for (i = 0; i < dp.cArgs; i++)
464 dp.rgvarg[i] = *(VARIANT*)((char*)(args->pvData) + (dp.cArgs - i - 1) * args->cbElements);
465 SafeArrayUnlock(args);
467 hr = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
468 if (FAILED(hr))
470 hr = IDispatch_Invoke(disp, dispid, &IID_NULL, LOCALE_USER_DEFAULT,
471 DISPATCH_METHOD, &dp, res, NULL, NULL);
473 else
475 hr = IDispatchEx_InvokeEx(dispex, dispid, LOCALE_USER_DEFAULT,
476 DISPATCH_METHOD, &dp, res, NULL, NULL);
477 IDispatchEx_Release(dispex);
480 heap_free(dp.rgvarg);
482 return hr;
485 static inline ScriptControl *impl_from_IScriptControl(IScriptControl *iface)
487 return CONTAINING_RECORD(iface, ScriptControl, IScriptControl_iface);
490 static inline ScriptControl *impl_from_IOleObject(IOleObject *iface)
492 return CONTAINING_RECORD(iface, ScriptControl, IOleObject_iface);
495 static inline ScriptControl *impl_from_IPersistStreamInit(IPersistStreamInit *iface)
497 return CONTAINING_RECORD(iface, ScriptControl, IPersistStreamInit_iface);
500 static inline ScriptControl *impl_from_IOleControl(IOleControl *iface)
502 return CONTAINING_RECORD(iface, ScriptControl, IOleControl_iface);
505 static inline ScriptControl *impl_from_IQuickActivate(IQuickActivate *iface)
507 return CONTAINING_RECORD(iface, ScriptControl, IQuickActivate_iface);
510 static inline ScriptControl *impl_from_IViewObjectEx(IViewObjectEx *iface)
512 return CONTAINING_RECORD(iface, ScriptControl, IViewObjectEx_iface);
515 static inline ScriptControl *impl_from_IPointerInactive(IPointerInactive *iface)
517 return CONTAINING_RECORD(iface, ScriptControl, IPointerInactive_iface);
520 static inline ScriptControl *impl_from_IConnectionPointContainer(IConnectionPointContainer *iface)
522 return CONTAINING_RECORD(iface, ScriptControl, IConnectionPointContainer_iface);
525 static inline ScriptProcedure *impl_from_IScriptProcedure(IScriptProcedure *iface)
527 return CONTAINING_RECORD(iface, ScriptProcedure, IScriptProcedure_iface);
530 static inline ScriptProcedureCollection *impl_from_IScriptProcedureCollection(IScriptProcedureCollection *iface)
532 return CONTAINING_RECORD(iface, ScriptProcedureCollection, IScriptProcedureCollection_iface);
535 static inline ScriptControl *impl_from_IScriptModuleCollection(IScriptModuleCollection *iface)
537 return CONTAINING_RECORD(iface, ScriptControl, IScriptModuleCollection_iface);
540 static inline ScriptModule *impl_from_IScriptModule(IScriptModule *iface)
542 return CONTAINING_RECORD(iface, ScriptModule, IScriptModule_iface);
545 static inline ScriptError *impl_from_IScriptError(IScriptError *iface)
547 return CONTAINING_RECORD(iface, ScriptError, IScriptError_iface);
550 static inline ConnectionPoint *impl_from_IConnectionPoint(IConnectionPoint *iface)
552 return CONTAINING_RECORD(iface, ConnectionPoint, IConnectionPoint_iface);
555 static inline ScriptHost *impl_from_IActiveScriptSite(IActiveScriptSite *iface)
557 return CONTAINING_RECORD(iface, ScriptHost, IActiveScriptSite_iface);
560 static inline ScriptHost *impl_from_IActiveScriptSiteWindow(IActiveScriptSiteWindow *iface)
562 return CONTAINING_RECORD(iface, ScriptHost, IActiveScriptSiteWindow_iface);
565 static inline ScriptHost *impl_from_IServiceProvider(IServiceProvider *iface)
567 return CONTAINING_RECORD(iface, ScriptHost, IServiceProvider_iface);
570 static inline struct module_enum *module_enum_from_IEnumVARIANT(IEnumVARIANT *iface)
572 return CONTAINING_RECORD(iface, struct module_enum, IEnumVARIANT_iface);
575 static inline struct procedure_enum *procedure_enum_from_IEnumVARIANT(IEnumVARIANT *iface)
577 return CONTAINING_RECORD(iface, struct procedure_enum, IEnumVARIANT_iface);
580 /* IActiveScriptSite */
581 static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
583 ScriptHost *This = impl_from_IActiveScriptSite(iface);
585 if(IsEqualGUID(&IID_IUnknown, riid)) {
586 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
587 *ppv = &This->IActiveScriptSite_iface;
588 }else if(IsEqualGUID(&IID_IActiveScriptSite, riid)) {
589 TRACE("(%p)->(IID_IActiveScriptSite %p)\n", This, ppv);
590 *ppv = &This->IActiveScriptSite_iface;
591 }else if(IsEqualGUID(&IID_IActiveScriptSiteWindow, riid)) {
592 TRACE("(%p)->(IID_IActiveScriptSiteWindow %p)\n", This, ppv);
593 *ppv = &This->IActiveScriptSiteWindow_iface;
594 }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
595 TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
596 *ppv = &This->IServiceProvider_iface;
597 }else {
598 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
599 *ppv = NULL;
600 return E_NOINTERFACE;
603 IUnknown_AddRef((IUnknown*)*ppv);
604 return S_OK;
607 static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
609 ScriptHost *This = impl_from_IActiveScriptSite(iface);
610 LONG ref = InterlockedIncrement(&This->ref);
612 TRACE("(%p) ref=%d\n", This, ref);
614 return ref;
617 static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
619 ScriptHost *This = impl_from_IActiveScriptSite(iface);
620 LONG ref = InterlockedDecrement(&This->ref);
622 TRACE("(%p) ref=%d\n", This, ref);
624 if(!ref) {
625 clear_named_items(This);
626 heap_free(This);
629 return ref;
632 static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *lcid)
634 ScriptHost *This = impl_from_IActiveScriptSite(iface);
636 TRACE("(%p, %p)\n", This, lcid);
638 *lcid = GetUserDefaultLCID();
639 return S_OK;
642 static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR name, DWORD mask,
643 IUnknown **unk, ITypeInfo **ti)
645 ScriptHost *This = impl_from_IActiveScriptSite(iface);
646 struct named_item *item;
648 TRACE("(%p, %s, %#x, %p, %p)\n", This, debugstr_w(name), mask, unk, ti);
650 item = host_get_named_item(This, name);
651 if (!item)
652 return TYPE_E_ELEMENTNOTFOUND;
654 if (mask != SCRIPTINFO_IUNKNOWN) {
655 FIXME("mask %#x is not supported\n", mask);
656 return E_NOTIMPL;
659 *unk = (IUnknown*)item->disp;
660 IUnknown_AddRef(*unk);
662 return S_OK;
665 static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *version)
667 ScriptHost *This = impl_from_IActiveScriptSite(iface);
669 FIXME("(%p, %p)\n", This, version);
671 return E_NOTIMPL;
674 static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface, const VARIANT *result,
675 const EXCEPINFO *ei)
677 ScriptHost *This = impl_from_IActiveScriptSite(iface);
679 FIXME("(%p, %s, %p)\n", This, debugstr_variant(result), ei);
681 return E_NOTIMPL;
684 static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE state)
686 ScriptHost *This = impl_from_IActiveScriptSite(iface);
688 FIXME("(%p, %d)\n", This, state);
690 return E_NOTIMPL;
693 static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *script_error)
695 ScriptHost *This = impl_from_IActiveScriptSite(iface);
697 TRACE("(%p, %p)\n", This, script_error);
699 if (This->error)
701 IScriptError_Clear(&This->error->IScriptError_iface);
702 IActiveScriptError_AddRef(script_error);
703 This->error->object = script_error;
705 return S_FALSE;
708 static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
710 ScriptHost *This = impl_from_IActiveScriptSite(iface);
712 FIXME("(%p)\n", This);
714 return E_NOTIMPL;
717 static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
719 ScriptHost *This = impl_from_IActiveScriptSite(iface);
721 FIXME("(%p)\n", This);
723 return E_NOTIMPL;
726 static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
727 ActiveScriptSite_QueryInterface,
728 ActiveScriptSite_AddRef,
729 ActiveScriptSite_Release,
730 ActiveScriptSite_GetLCID,
731 ActiveScriptSite_GetItemInfo,
732 ActiveScriptSite_GetDocVersionString,
733 ActiveScriptSite_OnScriptTerminate,
734 ActiveScriptSite_OnStateChange,
735 ActiveScriptSite_OnScriptError,
736 ActiveScriptSite_OnEnterScript,
737 ActiveScriptSite_OnLeaveScript
740 /* IActiveScriptSiteWindow */
741 static HRESULT WINAPI ActiveScriptSiteWindow_QueryInterface(IActiveScriptSiteWindow *iface, REFIID riid, void **obj)
743 ScriptHost *This = impl_from_IActiveScriptSiteWindow(iface);
744 return IActiveScriptSite_QueryInterface(&This->IActiveScriptSite_iface, riid, obj);
747 static ULONG WINAPI ActiveScriptSiteWindow_AddRef(IActiveScriptSiteWindow *iface)
749 ScriptHost *This = impl_from_IActiveScriptSiteWindow(iface);
750 return IActiveScriptSite_AddRef(&This->IActiveScriptSite_iface);
753 static ULONG WINAPI ActiveScriptSiteWindow_Release(IActiveScriptSiteWindow *iface)
755 ScriptHost *This = impl_from_IActiveScriptSiteWindow(iface);
756 return IActiveScriptSite_Release(&This->IActiveScriptSite_iface);
759 static HRESULT WINAPI ActiveScriptSiteWindow_GetWindow(IActiveScriptSiteWindow *iface, HWND *hwnd)
761 ScriptHost *This = impl_from_IActiveScriptSiteWindow(iface);
763 FIXME("(%p, %p)\n", This, hwnd);
765 return E_NOTIMPL;
768 static HRESULT WINAPI ActiveScriptSiteWindow_EnableModeless(IActiveScriptSiteWindow *iface, BOOL enable)
770 ScriptHost *This = impl_from_IActiveScriptSiteWindow(iface);
772 FIXME("(%p, %d)\n", This, enable);
774 return E_NOTIMPL;
777 static const IActiveScriptSiteWindowVtbl ActiveScriptSiteWindowVtbl = {
778 ActiveScriptSiteWindow_QueryInterface,
779 ActiveScriptSiteWindow_AddRef,
780 ActiveScriptSiteWindow_Release,
781 ActiveScriptSiteWindow_GetWindow,
782 ActiveScriptSiteWindow_EnableModeless
785 /* IServiceProvider */
786 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **obj)
788 ScriptHost *This = impl_from_IServiceProvider(iface);
789 return IActiveScriptSite_QueryInterface(&This->IActiveScriptSite_iface, riid, obj);
792 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
794 ScriptHost *This = impl_from_IServiceProvider(iface);
795 return IActiveScriptSite_AddRef(&This->IActiveScriptSite_iface);
798 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
800 ScriptHost *This = impl_from_IServiceProvider(iface);
801 return IActiveScriptSite_Release(&This->IActiveScriptSite_iface);
804 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID service,
805 REFIID riid, void **obj)
807 ScriptHost *This = impl_from_IServiceProvider(iface);
809 FIXME("(%p)->(%s %s %p)\n", This, debugstr_guid(service), debugstr_guid(riid), obj);
811 return E_NOTIMPL;
814 static const IServiceProviderVtbl ServiceProviderVtbl = {
815 ServiceProvider_QueryInterface,
816 ServiceProvider_AddRef,
817 ServiceProvider_Release,
818 ServiceProvider_QueryService
821 static HRESULT WINAPI ScriptProcedure_QueryInterface(IScriptProcedure *iface, REFIID riid, void **ppv)
823 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
825 if (IsEqualGUID(&IID_IDispatch, riid) || IsEqualGUID(&IID_IUnknown, riid) ||
826 IsEqualGUID(&IID_IScriptProcedure, riid))
828 *ppv = &This->IScriptProcedure_iface;
830 else
832 WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
833 *ppv = NULL;
834 return E_NOINTERFACE;
837 IUnknown_AddRef((IUnknown*)*ppv);
838 return S_OK;
841 static ULONG WINAPI ScriptProcedure_AddRef(IScriptProcedure *iface)
843 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
844 LONG ref = InterlockedIncrement(&This->ref);
846 TRACE("(%p) ref=%d\n", This, ref);
848 return ref;
851 static ULONG WINAPI ScriptProcedure_Release(IScriptProcedure *iface)
853 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
854 LONG ref = InterlockedDecrement(&This->ref);
856 TRACE("(%p) ref=%d\n", This, ref);
858 if (!ref)
860 list_remove(&This->entry);
861 SysFreeString(This->name);
862 heap_free(This);
864 return ref;
867 static HRESULT WINAPI ScriptProcedure_GetTypeInfoCount(IScriptProcedure *iface, UINT *pctinfo)
869 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
871 TRACE("(%p)->(%p)\n", This, pctinfo);
873 *pctinfo = 1;
874 return S_OK;
877 static HRESULT WINAPI ScriptProcedure_GetTypeInfo(IScriptProcedure *iface, UINT iTInfo,
878 LCID lcid, ITypeInfo **ppTInfo)
880 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
882 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
884 return get_typeinfo(IScriptProcedure_tid, ppTInfo);
887 static HRESULT WINAPI ScriptProcedure_GetIDsOfNames(IScriptProcedure *iface, REFIID riid,
888 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
890 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
891 ITypeInfo *typeinfo;
892 HRESULT hr;
894 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
896 hr = get_typeinfo(IScriptProcedure_tid, &typeinfo);
897 if (SUCCEEDED(hr))
899 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
900 ITypeInfo_Release(typeinfo);
903 return hr;
906 static HRESULT WINAPI ScriptProcedure_Invoke(IScriptProcedure *iface, DISPID dispIdMember,
907 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
908 EXCEPINFO *pExcepInfo, UINT *puArgErr)
910 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
911 ITypeInfo *typeinfo;
912 HRESULT hr;
914 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
915 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
917 hr = get_typeinfo(IScriptProcedure_tid, &typeinfo);
918 if(SUCCEEDED(hr))
920 hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
921 pDispParams, pVarResult, pExcepInfo, puArgErr);
922 ITypeInfo_Release(typeinfo);
925 return hr;
928 static HRESULT WINAPI ScriptProcedure_get_Name(IScriptProcedure *iface, BSTR *pbstrName)
930 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
932 TRACE("(%p)->(%p)\n", This, pbstrName);
934 if (!pbstrName) return E_POINTER;
936 *pbstrName = SysAllocString(This->name);
937 return *pbstrName ? S_OK : E_OUTOFMEMORY;
940 static HRESULT WINAPI ScriptProcedure_get_NumArgs(IScriptProcedure *iface, LONG *pcArgs)
942 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
944 TRACE("(%p)->(%p)\n", This, pcArgs);
946 if (!pcArgs) return E_POINTER;
948 *pcArgs = This->num_args;
949 return S_OK;
952 static HRESULT WINAPI ScriptProcedure_get_HasReturnValue(IScriptProcedure *iface, VARIANT_BOOL *pfHasReturnValue)
954 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
956 TRACE("(%p)->(%p)\n", This, pfHasReturnValue);
958 if (!pfHasReturnValue) return E_POINTER;
960 *pfHasReturnValue = (This->ret_type == VT_VOID) ? VARIANT_FALSE : VARIANT_TRUE;
961 return S_OK;
964 static const IScriptProcedureVtbl ScriptProcedureVtbl = {
965 ScriptProcedure_QueryInterface,
966 ScriptProcedure_AddRef,
967 ScriptProcedure_Release,
968 ScriptProcedure_GetTypeInfoCount,
969 ScriptProcedure_GetTypeInfo,
970 ScriptProcedure_GetIDsOfNames,
971 ScriptProcedure_Invoke,
972 ScriptProcedure_get_Name,
973 ScriptProcedure_get_NumArgs,
974 ScriptProcedure_get_HasReturnValue
977 /* This function always releases the FUNCDESC passed in */
978 static HRESULT get_script_procedure(ScriptProcedureCollection *procedures, ITypeInfo *typeinfo,
979 FUNCDESC *desc, IScriptProcedure **procedure)
981 struct list *proc_list;
982 ScriptProcedure *proc;
983 ULONG hash;
984 HRESULT hr;
985 BSTR str;
986 UINT len;
988 hr = ITypeInfo_GetNames(typeinfo, desc->memid, &str, 1, &len);
989 if (FAILED(hr)) goto done;
991 len = SysStringLen(str);
992 hash = LHashValOfNameSys(sizeof(void*) == 8 ? SYS_WIN64 : SYS_WIN32, LOCALE_USER_DEFAULT, str);
993 proc_list = &procedures->hash_table[hash % ARRAY_SIZE(procedures->hash_table)];
995 /* Try to find it in the hash table */
996 LIST_FOR_EACH_ENTRY(proc, proc_list, ScriptProcedure, entry)
998 if (proc->hash == hash && SysStringLen(proc->name) == len &&
999 !memcmp(proc->name, str, len * sizeof(*str)))
1001 SysFreeString(str);
1002 IScriptProcedure_AddRef(&proc->IScriptProcedure_iface);
1003 *procedure = &proc->IScriptProcedure_iface;
1004 goto done;
1008 if (!(proc = heap_alloc(sizeof(*proc))))
1010 hr = E_OUTOFMEMORY;
1011 SysFreeString(str);
1012 goto done;
1015 proc->IScriptProcedure_iface.lpVtbl = &ScriptProcedureVtbl;
1016 proc->ref = 1;
1017 proc->hash = hash;
1018 proc->name = str;
1019 proc->num_args = desc->cParams + desc->cParamsOpt;
1020 proc->ret_type = desc->elemdescFunc.tdesc.vt;
1021 list_add_tail(proc_list, &proc->entry);
1023 *procedure = &proc->IScriptProcedure_iface;
1025 done:
1026 ITypeInfo_ReleaseFuncDesc(typeinfo, desc);
1027 return hr;
1030 static HRESULT WINAPI procedure_enum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv)
1032 struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
1034 if (IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IEnumVARIANT, riid))
1036 *ppv = &This->IEnumVARIANT_iface;
1038 else
1040 WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
1041 *ppv = NULL;
1042 return E_NOINTERFACE;
1045 IUnknown_AddRef((IUnknown*)*ppv);
1046 return S_OK;
1049 static ULONG WINAPI procedure_enum_AddRef(IEnumVARIANT *iface)
1051 struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
1052 LONG ref = InterlockedIncrement(&This->ref);
1054 TRACE("(%p) ref=%d\n", This, ref);
1056 return ref;
1059 static ULONG WINAPI procedure_enum_Release(IEnumVARIANT *iface)
1061 struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
1062 LONG ref = InterlockedDecrement(&This->ref);
1064 TRACE("(%p) ref=%d\n", This, ref);
1066 if (!ref)
1068 IScriptProcedureCollection_Release(&This->procedures->IScriptProcedureCollection_iface);
1069 heap_free(This);
1072 return ref;
1075 static HRESULT WINAPI procedure_enum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
1077 struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
1078 FUNCDESC *desc;
1079 ITypeInfo *ti;
1080 UINT i, num;
1081 HRESULT hr;
1083 TRACE("(%p)->(%u %p %p)\n", This, celt, rgVar, pCeltFetched);
1085 if (!rgVar) return E_POINTER;
1086 if (!This->procedures->module->host) return E_FAIL;
1088 hr = start_script(This->procedures->module);
1089 if (FAILED(hr)) return hr;
1091 hr = get_script_typeinfo(This->procedures->module, &ti);
1092 if (FAILED(hr)) return hr;
1094 num = min(celt, This->count - This->pos);
1095 for (i = 0; i < num; i++)
1097 hr = ITypeInfo_GetFuncDesc(ti, This->pos + i, &desc);
1098 if (FAILED(hr)) break;
1100 hr = get_script_procedure(This->procedures, ti, desc, (IScriptProcedure**)&V_DISPATCH(rgVar + i));
1101 if (FAILED(hr)) break;
1103 V_VT(rgVar + i) = VT_DISPATCH;
1106 if (FAILED(hr))
1108 while (i--)
1109 VariantClear(rgVar + i);
1110 if (pCeltFetched) *pCeltFetched = 0;
1111 return hr;
1114 This->pos += i;
1116 if (pCeltFetched) *pCeltFetched = i;
1117 return i == celt ? S_OK : S_FALSE;
1120 static HRESULT WINAPI procedure_enum_Skip(IEnumVARIANT *iface, ULONG celt)
1122 struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
1124 TRACE("(%p)->(%u)\n", This, celt);
1126 if (This->count - This->pos < celt)
1128 This->pos = This->count;
1129 return S_FALSE;
1131 This->pos += celt;
1132 return S_OK;
1135 static HRESULT WINAPI procedure_enum_Reset(IEnumVARIANT *iface)
1137 struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
1139 TRACE("(%p)\n", This);
1141 This->pos = 0;
1142 return S_OK;
1145 static HRESULT WINAPI procedure_enum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
1147 struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
1148 struct procedure_enum *clone;
1150 TRACE("(%p)->(%p)\n", This, ppEnum);
1152 if (!ppEnum) return E_POINTER;
1154 if (!(clone = heap_alloc(sizeof(*clone))))
1155 return E_OUTOFMEMORY;
1157 *clone = *This;
1158 clone->ref = 1;
1159 IScriptProcedureCollection_AddRef(&This->procedures->IScriptProcedureCollection_iface);
1161 *ppEnum = &clone->IEnumVARIANT_iface;
1162 return S_OK;
1165 static const IEnumVARIANTVtbl procedure_enum_vtbl = {
1166 procedure_enum_QueryInterface,
1167 procedure_enum_AddRef,
1168 procedure_enum_Release,
1169 procedure_enum_Next,
1170 procedure_enum_Skip,
1171 procedure_enum_Reset,
1172 procedure_enum_Clone
1175 static HRESULT WINAPI ScriptProcedureCollection_QueryInterface(IScriptProcedureCollection *iface, REFIID riid, void **ppv)
1177 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1179 if (IsEqualGUID(&IID_IDispatch, riid) || IsEqualGUID(&IID_IUnknown, riid) ||
1180 IsEqualGUID(&IID_IScriptProcedureCollection, riid))
1182 *ppv = &This->IScriptProcedureCollection_iface;
1184 else
1186 WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
1187 *ppv = NULL;
1188 return E_NOINTERFACE;
1191 IUnknown_AddRef((IUnknown*)*ppv);
1192 return S_OK;
1195 static ULONG WINAPI ScriptProcedureCollection_AddRef(IScriptProcedureCollection *iface)
1197 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1198 LONG ref = InterlockedIncrement(&This->ref);
1200 TRACE("(%p) ref=%d\n", This, ref);
1202 return ref;
1205 static ULONG WINAPI ScriptProcedureCollection_Release(IScriptProcedureCollection *iface)
1207 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1208 LONG ref = InterlockedDecrement(&This->ref);
1209 UINT i;
1211 TRACE("(%p) ref=%d\n", This, ref);
1213 if (!ref)
1215 /* Unlink any dangling items from the hash table */
1216 for (i = 0; i < ARRAY_SIZE(This->hash_table); i++)
1217 list_remove(&This->hash_table[i]);
1219 This->module->procedures = NULL;
1220 IScriptModule_Release(&This->module->IScriptModule_iface);
1221 heap_free(This);
1223 return ref;
1226 static HRESULT WINAPI ScriptProcedureCollection_GetTypeInfoCount(IScriptProcedureCollection *iface, UINT *pctinfo)
1228 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1230 TRACE("(%p)->(%p)\n", This, pctinfo);
1232 *pctinfo = 1;
1233 return S_OK;
1236 static HRESULT WINAPI ScriptProcedureCollection_GetTypeInfo(IScriptProcedureCollection *iface, UINT iTInfo,
1237 LCID lcid, ITypeInfo **ppTInfo)
1239 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1241 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
1243 return get_typeinfo(IScriptProcedureCollection_tid, ppTInfo);
1246 static HRESULT WINAPI ScriptProcedureCollection_GetIDsOfNames(IScriptProcedureCollection *iface, REFIID riid,
1247 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1249 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1250 ITypeInfo *typeinfo;
1251 HRESULT hr;
1253 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
1255 hr = get_typeinfo(IScriptProcedureCollection_tid, &typeinfo);
1256 if (SUCCEEDED(hr))
1258 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
1259 ITypeInfo_Release(typeinfo);
1262 return hr;
1265 static HRESULT WINAPI ScriptProcedureCollection_Invoke(IScriptProcedureCollection *iface, DISPID dispIdMember,
1266 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
1267 EXCEPINFO *pExcepInfo, UINT *puArgErr)
1269 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1270 ITypeInfo *typeinfo;
1271 HRESULT hr;
1273 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1274 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1276 hr = get_typeinfo(IScriptProcedureCollection_tid, &typeinfo);
1277 if(SUCCEEDED(hr))
1279 hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
1280 pDispParams, pVarResult, pExcepInfo, puArgErr);
1281 ITypeInfo_Release(typeinfo);
1284 return hr;
1287 static HRESULT WINAPI ScriptProcedureCollection_get__NewEnum(IScriptProcedureCollection *iface, IUnknown **ppenumProcedures)
1289 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1290 struct procedure_enum *proc_enum;
1291 TYPEATTR *attr;
1292 ITypeInfo *ti;
1293 UINT count;
1294 HRESULT hr;
1296 TRACE("(%p)->(%p)\n", This, ppenumProcedures);
1298 if (!ppenumProcedures) return E_POINTER;
1299 if (!This->module->host) return E_FAIL;
1301 hr = start_script(This->module);
1302 if (FAILED(hr)) return hr;
1304 hr = get_script_typeinfo(This->module, &ti);
1305 if (FAILED(hr)) return hr;
1307 hr = ITypeInfo_GetTypeAttr(ti, &attr);
1308 if (FAILED(hr)) return hr;
1310 count = attr->cFuncs;
1311 ITypeInfo_ReleaseTypeAttr(ti, attr);
1313 if (!(proc_enum = heap_alloc(sizeof(*proc_enum))))
1314 return E_OUTOFMEMORY;
1316 proc_enum->IEnumVARIANT_iface.lpVtbl = &procedure_enum_vtbl;
1317 proc_enum->ref = 1;
1318 proc_enum->pos = 0;
1319 proc_enum->count = count;
1320 proc_enum->procedures = This;
1321 IScriptProcedureCollection_AddRef(&This->IScriptProcedureCollection_iface);
1323 *ppenumProcedures = (IUnknown*)&proc_enum->IEnumVARIANT_iface;
1324 return S_OK;
1327 static HRESULT WINAPI ScriptProcedureCollection_get_Item(IScriptProcedureCollection *iface, VARIANT index,
1328 IScriptProcedure **ppdispProcedure)
1330 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1331 ITypeInfo *typeinfo;
1332 FUNCDESC *desc;
1333 HRESULT hr;
1335 TRACE("(%p)->(%s %p)\n", This, wine_dbgstr_variant(&index), ppdispProcedure);
1337 if (!ppdispProcedure) return E_POINTER;
1338 if (!This->module->host) return E_FAIL;
1340 hr = start_script(This->module);
1341 if (FAILED(hr)) return hr;
1343 hr = get_script_typeinfo(This->module, &typeinfo);
1344 if (FAILED(hr)) return hr;
1346 if (V_VT(&index) == VT_BSTR)
1348 struct list *proc_list;
1349 ScriptProcedure *proc;
1350 ITypeComp *comp;
1351 BINDPTR bindptr;
1352 DESCKIND kind;
1353 ULONG hash;
1354 UINT len;
1356 len = SysStringLen(V_BSTR(&index));
1357 hash = LHashValOfNameSys(sizeof(void*) == 8 ? SYS_WIN64 : SYS_WIN32, LOCALE_USER_DEFAULT, V_BSTR(&index));
1358 proc_list = &This->hash_table[hash % ARRAY_SIZE(This->hash_table)];
1360 /* Try to find it in the hash table */
1361 LIST_FOR_EACH_ENTRY(proc, proc_list, ScriptProcedure, entry)
1363 if (proc->hash == hash && SysStringLen(proc->name) == len &&
1364 !memcmp(proc->name, V_BSTR(&index), len * sizeof(WCHAR)))
1366 IScriptProcedure_AddRef(&proc->IScriptProcedure_iface);
1367 *ppdispProcedure = &proc->IScriptProcedure_iface;
1368 return S_OK;
1372 hr = get_script_typecomp(This->module, typeinfo, &comp);
1373 if (FAILED(hr)) return hr;
1375 hr = ITypeComp_Bind(comp, V_BSTR(&index), hash, INVOKE_FUNC, &typeinfo, &kind, &bindptr);
1376 if (FAILED(hr)) return hr;
1378 switch (kind)
1380 case DESCKIND_FUNCDESC:
1381 hr = get_script_procedure(This, typeinfo, bindptr.lpfuncdesc, ppdispProcedure);
1382 ITypeInfo_Release(typeinfo);
1383 return hr;
1384 case DESCKIND_IMPLICITAPPOBJ:
1385 case DESCKIND_VARDESC:
1386 ITypeInfo_ReleaseVarDesc(typeinfo, bindptr.lpvardesc);
1387 ITypeInfo_Release(typeinfo);
1388 break;
1389 case DESCKIND_TYPECOMP:
1390 ITypeComp_Release(bindptr.lptcomp);
1391 break;
1392 default:
1393 break;
1395 return CTL_E_ILLEGALFUNCTIONCALL;
1398 hr = VariantChangeType(&index, &index, 0, VT_INT);
1399 if (FAILED(hr)) return hr;
1400 if (V_INT(&index) <= 0) return 0x800a0009;
1402 hr = ITypeInfo_GetFuncDesc(typeinfo, V_INT(&index) - 1, &desc);
1403 if (FAILED(hr)) return hr;
1405 return get_script_procedure(This, typeinfo, desc, ppdispProcedure);
1408 static HRESULT WINAPI ScriptProcedureCollection_get_Count(IScriptProcedureCollection *iface, LONG *plCount)
1410 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1411 TYPEATTR *attr;
1412 ITypeInfo *ti;
1413 HRESULT hr;
1415 TRACE("(%p)->(%p)\n", This, plCount);
1417 if (!plCount) return E_POINTER;
1418 if (!This->module->host) return E_FAIL;
1420 if (This->count == -1)
1422 hr = start_script(This->module);
1423 if (FAILED(hr)) return hr;
1425 hr = get_script_typeinfo(This->module, &ti);
1426 if (FAILED(hr)) return hr;
1428 hr = ITypeInfo_GetTypeAttr(ti, &attr);
1429 if (FAILED(hr)) return hr;
1431 This->count = attr->cFuncs;
1432 ITypeInfo_ReleaseTypeAttr(ti, attr);
1435 *plCount = This->count;
1436 return S_OK;
1439 static const IScriptProcedureCollectionVtbl ScriptProcedureCollectionVtbl = {
1440 ScriptProcedureCollection_QueryInterface,
1441 ScriptProcedureCollection_AddRef,
1442 ScriptProcedureCollection_Release,
1443 ScriptProcedureCollection_GetTypeInfoCount,
1444 ScriptProcedureCollection_GetTypeInfo,
1445 ScriptProcedureCollection_GetIDsOfNames,
1446 ScriptProcedureCollection_Invoke,
1447 ScriptProcedureCollection_get__NewEnum,
1448 ScriptProcedureCollection_get_Item,
1449 ScriptProcedureCollection_get_Count
1452 static void detach_script_host(ScriptHost *host)
1454 if (--host->module_count)
1455 return;
1457 if (host->script) {
1458 IActiveScript_Close(host->script);
1459 IActiveScript_Release(host->script);
1462 if (host->parse)
1463 IActiveScriptParse_Release(host->parse);
1465 if (host->error)
1466 IScriptError_Release(&host->error->IScriptError_iface);
1468 host->parse = NULL;
1469 host->error = NULL;
1470 host->script = NULL;
1473 static void detach_module(ScriptModule *module)
1475 ScriptHost *host = module->host;
1477 if (host) {
1478 module->host = NULL;
1479 detach_script_host(host);
1480 IActiveScriptSite_Release(&host->IActiveScriptSite_iface);
1484 static HRESULT WINAPI ScriptModule_QueryInterface(IScriptModule *iface, REFIID riid, void **ppv)
1486 ScriptModule *This = impl_from_IScriptModule(iface);
1488 if (IsEqualGUID(&IID_IDispatch, riid) || IsEqualGUID(&IID_IUnknown, riid) ||
1489 IsEqualGUID(&IID_IScriptModule, riid))
1491 *ppv = &This->IScriptModule_iface;
1493 else
1495 WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
1496 *ppv = NULL;
1497 return E_NOINTERFACE;
1500 IUnknown_AddRef((IUnknown*)*ppv);
1501 return S_OK;
1504 static ULONG WINAPI ScriptModule_AddRef(IScriptModule *iface)
1506 ScriptModule *This = impl_from_IScriptModule(iface);
1507 LONG ref = InterlockedIncrement(&This->ref);
1509 TRACE("(%p) ref=%d\n", This, ref);
1511 return ref;
1514 static ULONG WINAPI ScriptModule_Release(IScriptModule *iface)
1516 ScriptModule *This = impl_from_IScriptModule(iface);
1517 LONG ref = InterlockedDecrement(&This->ref);
1519 TRACE("(%p) ref=%d\n", This, ref);
1521 if (!ref)
1523 detach_module(This);
1524 SysFreeString(This->name);
1525 uncache_module_objects(This);
1526 heap_free(This);
1529 return ref;
1532 static HRESULT WINAPI ScriptModule_GetTypeInfoCount(IScriptModule *iface, UINT *pctinfo)
1534 ScriptModule *This = impl_from_IScriptModule(iface);
1536 TRACE("(%p)->(%p)\n", This, pctinfo);
1538 *pctinfo = 1;
1539 return S_OK;
1542 static HRESULT WINAPI ScriptModule_GetTypeInfo(IScriptModule *iface, UINT iTInfo,
1543 LCID lcid, ITypeInfo **ppTInfo)
1545 ScriptModule *This = impl_from_IScriptModule(iface);
1547 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
1549 return get_typeinfo(IScriptModule_tid, ppTInfo);
1552 static HRESULT WINAPI ScriptModule_GetIDsOfNames(IScriptModule *iface, REFIID riid,
1553 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1555 ScriptModule *This = impl_from_IScriptModule(iface);
1556 ITypeInfo *typeinfo;
1557 HRESULT hr;
1559 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
1561 hr = get_typeinfo(IScriptModule_tid, &typeinfo);
1562 if (SUCCEEDED(hr))
1564 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
1565 ITypeInfo_Release(typeinfo);
1568 return hr;
1571 static HRESULT WINAPI ScriptModule_Invoke(IScriptModule *iface, DISPID dispIdMember,
1572 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
1573 EXCEPINFO *pExcepInfo, UINT *puArgErr)
1575 ScriptModule *This = impl_from_IScriptModule(iface);
1576 ITypeInfo *typeinfo;
1577 HRESULT hr;
1579 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1580 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1582 hr = get_typeinfo(IScriptModule_tid, &typeinfo);
1583 if(SUCCEEDED(hr))
1585 hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
1586 pDispParams, pVarResult, pExcepInfo, puArgErr);
1587 ITypeInfo_Release(typeinfo);
1590 return hr;
1593 static HRESULT WINAPI ScriptModule_get_Name(IScriptModule *iface, BSTR *pbstrName)
1595 ScriptModule *This = impl_from_IScriptModule(iface);
1597 TRACE("(%p)->(%p)\n", This, pbstrName);
1599 if (!pbstrName) return E_POINTER;
1600 if (!This->host) return E_FAIL;
1602 *pbstrName = SysAllocString(This->name ? This->name : L"Global");
1603 return *pbstrName ? S_OK : E_OUTOFMEMORY;
1606 static HRESULT WINAPI ScriptModule_get_CodeObject(IScriptModule *iface, IDispatch **ppdispObject)
1608 ScriptModule *This = impl_from_IScriptModule(iface);
1609 HRESULT hr;
1611 TRACE("(%p)->(%p)\n", This, ppdispObject);
1613 if (!This->host) return E_FAIL;
1615 hr = start_script(This);
1616 if (FAILED(hr)) return hr;
1618 hr = get_script_dispatch(This, ppdispObject);
1619 if (FAILED(hr)) return hr;
1621 IDispatch_AddRef(*ppdispObject);
1622 return hr;
1625 static HRESULT WINAPI ScriptModule_get_Procedures(IScriptModule *iface, IScriptProcedureCollection **ppdispProcedures)
1627 ScriptModule *This = impl_from_IScriptModule(iface);
1629 TRACE("(%p)->(%p)\n", This, ppdispProcedures);
1631 if (!This->host)
1632 return E_FAIL;
1634 if (This->procedures)
1635 IScriptProcedureCollection_AddRef(&This->procedures->IScriptProcedureCollection_iface);
1636 else
1638 ScriptProcedureCollection *procs;
1639 UINT i;
1641 if (!(procs = heap_alloc(sizeof(*procs))))
1642 return E_OUTOFMEMORY;
1644 procs->IScriptProcedureCollection_iface.lpVtbl = &ScriptProcedureCollectionVtbl;
1645 procs->ref = 1;
1646 procs->count = -1;
1647 procs->module = This;
1648 for (i = 0; i < ARRAY_SIZE(procs->hash_table); i++)
1649 list_init(&procs->hash_table[i]);
1651 This->procedures = procs;
1652 IScriptModule_AddRef(&This->IScriptModule_iface);
1655 *ppdispProcedures = &This->procedures->IScriptProcedureCollection_iface;
1656 return S_OK;
1659 static HRESULT WINAPI ScriptModule_AddCode(IScriptModule *iface, BSTR code)
1661 ScriptModule *This = impl_from_IScriptModule(iface);
1663 TRACE("(%p)->(%s)\n", This, debugstr_w(code));
1665 if (!This->host)
1666 return E_FAIL;
1668 return parse_script_text(This, code, SCRIPTTEXT_ISVISIBLE, NULL);
1671 static HRESULT WINAPI ScriptModule_Eval(IScriptModule *iface, BSTR expression, VARIANT *res)
1673 ScriptModule *This = impl_from_IScriptModule(iface);
1675 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(expression), res);
1677 if (!res)
1678 return E_POINTER;
1679 V_VT(res) = VT_EMPTY;
1680 if (!This->host)
1681 return E_FAIL;
1683 return parse_script_text(This, expression, SCRIPTTEXT_ISEXPRESSION, res);
1686 static HRESULT WINAPI ScriptModule_ExecuteStatement(IScriptModule *iface, BSTR statement)
1688 ScriptModule *This = impl_from_IScriptModule(iface);
1690 TRACE("(%p)->(%s)\n", This, debugstr_w(statement));
1692 if (!This->host)
1693 return E_FAIL;
1695 return parse_script_text(This, statement, 0, NULL);
1698 static HRESULT WINAPI ScriptModule_Run(IScriptModule *iface, BSTR procedure_name, SAFEARRAY **parameters, VARIANT *res)
1700 ScriptModule *This = impl_from_IScriptModule(iface);
1701 SAFEARRAY *sa;
1703 TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(procedure_name), parameters, res);
1705 if (!parameters || !res) return E_POINTER;
1706 if (!(sa = *parameters)) return E_POINTER;
1708 V_VT(res) = VT_EMPTY;
1709 if (sa->cDims == 0) return DISP_E_BADINDEX;
1710 if (!(sa->fFeatures & FADF_VARIANT)) return DISP_E_BADVARTYPE;
1711 if (!This->host) return E_FAIL;
1713 return run_procedure(This, procedure_name, sa, res);
1716 static const IScriptModuleVtbl ScriptModuleVtbl = {
1717 ScriptModule_QueryInterface,
1718 ScriptModule_AddRef,
1719 ScriptModule_Release,
1720 ScriptModule_GetTypeInfoCount,
1721 ScriptModule_GetTypeInfo,
1722 ScriptModule_GetIDsOfNames,
1723 ScriptModule_Invoke,
1724 ScriptModule_get_Name,
1725 ScriptModule_get_CodeObject,
1726 ScriptModule_get_Procedures,
1727 ScriptModule_AddCode,
1728 ScriptModule_Eval,
1729 ScriptModule_ExecuteStatement,
1730 ScriptModule_Run
1733 static HRESULT WINAPI module_enum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv)
1735 struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
1737 if (IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IEnumVARIANT, riid))
1739 *ppv = &This->IEnumVARIANT_iface;
1741 else
1743 WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
1744 *ppv = NULL;
1745 return E_NOINTERFACE;
1748 IUnknown_AddRef((IUnknown*)*ppv);
1749 return S_OK;
1752 static ULONG WINAPI module_enum_AddRef(IEnumVARIANT *iface)
1754 struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
1755 LONG ref = InterlockedIncrement(&This->ref);
1757 TRACE("(%p) ref=%d\n", This, ref);
1759 return ref;
1762 static ULONG WINAPI module_enum_Release(IEnumVARIANT *iface)
1764 struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
1765 LONG ref = InterlockedDecrement(&This->ref);
1767 TRACE("(%p) ref=%d\n", This, ref);
1769 if (!ref)
1771 IActiveScriptSite_Release(&This->host->IActiveScriptSite_iface);
1772 IScriptControl_Release(&This->control->IScriptControl_iface);
1773 heap_free(This);
1776 return ref;
1779 static HRESULT WINAPI module_enum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
1781 struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
1782 unsigned int i, num;
1784 TRACE("(%p)->(%u %p %p)\n", This, celt, rgVar, pCeltFetched);
1786 if (!rgVar) return E_POINTER;
1787 if (This->host != This->control->host) return E_FAIL;
1789 num = min(celt, This->host->module_count - This->pos);
1790 for (i = 0; i < num; i++)
1792 V_VT(rgVar + i) = VT_DISPATCH;
1793 V_DISPATCH(rgVar + i) = (IDispatch*)(&This->control->modules[This->pos++]->IScriptModule_iface);
1794 IDispatch_AddRef(V_DISPATCH(rgVar + i));
1797 if (pCeltFetched) *pCeltFetched = i;
1798 return i == celt ? S_OK : S_FALSE;
1801 static HRESULT WINAPI module_enum_Skip(IEnumVARIANT *iface, ULONG celt)
1803 struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
1805 TRACE("(%p)->(%u)\n", This, celt);
1807 if (This->host != This->control->host) return E_FAIL;
1809 if (This->host->module_count - This->pos < celt)
1811 This->pos = This->host->module_count;
1812 return S_FALSE;
1814 This->pos += celt;
1815 return S_OK;
1818 static HRESULT WINAPI module_enum_Reset(IEnumVARIANT *iface)
1820 struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
1822 TRACE("(%p)\n", This);
1824 if (This->host != This->control->host) return E_FAIL;
1826 This->pos = 0;
1827 return S_OK;
1830 static HRESULT WINAPI module_enum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
1832 struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
1833 struct module_enum *clone;
1835 TRACE("(%p)->(%p)\n", This, ppEnum);
1837 if (!ppEnum) return E_POINTER;
1838 if (This->host != This->control->host) return E_FAIL;
1840 if (!(clone = heap_alloc(sizeof(*clone))))
1841 return E_OUTOFMEMORY;
1843 *clone = *This;
1844 clone->ref = 1;
1845 IActiveScriptSite_AddRef(&This->host->IActiveScriptSite_iface);
1846 IScriptControl_AddRef(&This->control->IScriptControl_iface);
1848 *ppEnum = &clone->IEnumVARIANT_iface;
1849 return S_OK;
1852 static const IEnumVARIANTVtbl module_enum_vtbl = {
1853 module_enum_QueryInterface,
1854 module_enum_AddRef,
1855 module_enum_Release,
1856 module_enum_Next,
1857 module_enum_Skip,
1858 module_enum_Reset,
1859 module_enum_Clone
1862 static ScriptModule *create_module(ScriptHost *host, BSTR name)
1864 ScriptModule *module;
1866 if (!(module = heap_alloc_zero(sizeof(*module)))) return NULL;
1868 module->IScriptModule_iface.lpVtbl = &ScriptModuleVtbl;
1869 module->ref = 1;
1870 if (name && !(module->name = SysAllocString(name)))
1872 heap_free(module);
1873 return NULL;
1875 module->host = host;
1876 IActiveScriptSite_AddRef(&host->IActiveScriptSite_iface);
1877 return module;
1880 static void release_modules(ScriptControl *control, BOOL force_detach)
1882 unsigned int i, module_count = control->host->module_count;
1884 for (i = 0; i < module_count; i++) {
1885 if (force_detach) detach_module(control->modules[i]);
1886 IScriptModule_Release(&control->modules[i]->IScriptModule_iface);
1889 heap_free(control->modules);
1892 static ScriptModule *find_module(ScriptControl *control, BSTR name)
1894 unsigned int i;
1896 if (!wcsicmp(name, L"Global"))
1897 return control->modules[0];
1899 for (i = 1; i < control->host->module_count; i++)
1901 if (!wcsicmp(name, control->modules[i]->name))
1902 return control->modules[i];
1904 return NULL;
1907 static HRESULT WINAPI ScriptModuleCollection_QueryInterface(IScriptModuleCollection *iface, REFIID riid, void **ppv)
1909 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
1911 if (IsEqualGUID(&IID_IDispatch, riid) || IsEqualGUID(&IID_IUnknown, riid) ||
1912 IsEqualGUID(&IID_IScriptModuleCollection, riid))
1914 *ppv = &This->IScriptModuleCollection_iface;
1916 else
1918 WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
1919 *ppv = NULL;
1920 return E_NOINTERFACE;
1923 IUnknown_AddRef((IUnknown*)*ppv);
1924 return S_OK;
1927 static ULONG WINAPI ScriptModuleCollection_AddRef(IScriptModuleCollection *iface)
1929 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
1930 return IScriptControl_AddRef(&This->IScriptControl_iface);
1933 static ULONG WINAPI ScriptModuleCollection_Release(IScriptModuleCollection *iface)
1935 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
1936 return IScriptControl_Release(&This->IScriptControl_iface);
1939 static HRESULT WINAPI ScriptModuleCollection_GetTypeInfoCount(IScriptModuleCollection *iface, UINT *pctinfo)
1941 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
1943 TRACE("(%p)->(%p)\n", This, pctinfo);
1945 *pctinfo = 1;
1946 return S_OK;
1949 static HRESULT WINAPI ScriptModuleCollection_GetTypeInfo(IScriptModuleCollection *iface, UINT iTInfo,
1950 LCID lcid, ITypeInfo **ppTInfo)
1952 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
1954 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
1956 return get_typeinfo(IScriptModuleCollection_tid, ppTInfo);
1959 static HRESULT WINAPI ScriptModuleCollection_GetIDsOfNames(IScriptModuleCollection *iface, REFIID riid,
1960 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1962 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
1963 ITypeInfo *typeinfo;
1964 HRESULT hr;
1966 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
1968 hr = get_typeinfo(IScriptModuleCollection_tid, &typeinfo);
1969 if (SUCCEEDED(hr))
1971 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
1972 ITypeInfo_Release(typeinfo);
1975 return hr;
1978 static HRESULT WINAPI ScriptModuleCollection_Invoke(IScriptModuleCollection *iface, DISPID dispIdMember,
1979 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
1980 EXCEPINFO *pExcepInfo, UINT *puArgErr)
1982 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
1983 ITypeInfo *typeinfo;
1984 HRESULT hr;
1986 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1987 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1989 hr = get_typeinfo(IScriptModuleCollection_tid, &typeinfo);
1990 if(SUCCEEDED(hr))
1992 hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
1993 pDispParams, pVarResult, pExcepInfo, puArgErr);
1994 ITypeInfo_Release(typeinfo);
1997 return hr;
2000 static HRESULT WINAPI ScriptModuleCollection_get__NewEnum(IScriptModuleCollection *iface, IUnknown **ppenumContexts)
2002 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
2003 struct module_enum *module_enum;
2005 TRACE("(%p)->(%p)\n", This, ppenumContexts);
2007 if (!ppenumContexts) return E_POINTER;
2008 if (!This->host) return E_FAIL;
2010 if (!(module_enum = heap_alloc(sizeof(*module_enum))))
2011 return E_OUTOFMEMORY;
2013 module_enum->IEnumVARIANT_iface.lpVtbl = &module_enum_vtbl;
2014 module_enum->ref = 1;
2015 module_enum->pos = 0;
2016 module_enum->host = This->host;
2017 module_enum->control = This;
2018 IActiveScriptSite_AddRef(&This->host->IActiveScriptSite_iface);
2019 IScriptControl_AddRef(&This->IScriptControl_iface);
2021 *ppenumContexts = (IUnknown*)&module_enum->IEnumVARIANT_iface;
2022 return S_OK;
2025 static HRESULT WINAPI ScriptModuleCollection_get_Item(IScriptModuleCollection *iface, VARIANT index,
2026 IScriptModule **ppmod)
2028 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
2029 ScriptModule *module;
2030 unsigned int i;
2031 HRESULT hr;
2033 TRACE("(%p)->(%s %p)\n", This, wine_dbgstr_variant(&index), ppmod);
2035 if (!ppmod) return E_POINTER;
2036 if (!This->host) return E_FAIL;
2038 if (V_VT(&index) == VT_BSTR)
2040 module = find_module(This, V_BSTR(&index));
2041 if (!module) return CTL_E_ILLEGALFUNCTIONCALL;
2043 else
2045 hr = VariantChangeType(&index, &index, 0, VT_INT);
2046 if (FAILED(hr)) return hr;
2048 i = V_INT(&index) - 1;
2049 if (i >= This->host->module_count) return 0x800a0009;
2051 module = This->modules[i];
2054 *ppmod = &module->IScriptModule_iface;
2055 IScriptModule_AddRef(*ppmod);
2056 return S_OK;
2059 static HRESULT WINAPI ScriptModuleCollection_get_Count(IScriptModuleCollection *iface, LONG *plCount)
2061 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
2063 TRACE("(%p)->(%p)\n", This, plCount);
2065 if (!plCount) return E_POINTER;
2066 if (!This->host) return E_FAIL;
2068 *plCount = This->host->module_count;
2069 return S_OK;
2072 static HRESULT WINAPI ScriptModuleCollection_Add(IScriptModuleCollection *iface, BSTR name,
2073 VARIANT *object, IScriptModule **ppmod)
2075 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
2076 ScriptModule *module, **modules;
2077 ScriptHost *host = This->host;
2078 HRESULT hr;
2080 TRACE("(%p)->(%s %s %p)\n", This, wine_dbgstr_w(name), wine_dbgstr_variant(object), ppmod);
2082 if (!ppmod) return E_POINTER;
2083 if (!name || V_VT(object) != VT_DISPATCH) return E_INVALIDARG;
2084 if (!host) return E_FAIL;
2085 if (find_module(This, name)) return E_INVALIDARG;
2087 /* See if we need to grow the array */
2088 if (is_power_of_2(host->module_count))
2090 modules = heap_realloc(This->modules, host->module_count * 2 * sizeof(*This->modules));
2091 if (!modules) return E_OUTOFMEMORY;
2092 This->modules = modules;
2095 if (!(module = create_module(host, name)))
2096 return E_OUTOFMEMORY;
2098 /* If no object, Windows only calls AddNamedItem without adding a NULL object */
2099 if (V_DISPATCH(object))
2100 hr = add_script_object(host, name, V_DISPATCH(object), 0);
2101 else
2102 hr = IActiveScript_AddNamedItem(host->script, name, SCRIPTITEM_CODEONLY);
2104 if (FAILED(hr))
2106 IScriptModule_Release(&module->IScriptModule_iface);
2107 return hr;
2109 This->modules[host->module_count++] = module;
2111 *ppmod = &module->IScriptModule_iface;
2112 IScriptModule_AddRef(*ppmod);
2113 return S_OK;
2116 static const IScriptModuleCollectionVtbl ScriptModuleCollectionVtbl = {
2117 ScriptModuleCollection_QueryInterface,
2118 ScriptModuleCollection_AddRef,
2119 ScriptModuleCollection_Release,
2120 ScriptModuleCollection_GetTypeInfoCount,
2121 ScriptModuleCollection_GetTypeInfo,
2122 ScriptModuleCollection_GetIDsOfNames,
2123 ScriptModuleCollection_Invoke,
2124 ScriptModuleCollection_get__NewEnum,
2125 ScriptModuleCollection_get_Item,
2126 ScriptModuleCollection_get_Count,
2127 ScriptModuleCollection_Add
2130 static void fill_error_info(ScriptError *error)
2132 EXCEPINFO info;
2134 if (error->info_filled) return;
2135 error->info_filled = TRUE;
2137 if (!error->object)
2138 return;
2139 if (FAILED(IActiveScriptError_GetExceptionInfo(error->object, &info)))
2140 return;
2141 if (info.pfnDeferredFillIn)
2142 info.pfnDeferredFillIn(&info);
2144 error->number = info.scode;
2145 error->source = info.bstrSource;
2146 error->desc = info.bstrDescription;
2147 error->help_file = info.bstrHelpFile;
2148 error->help_context = info.dwHelpContext;
2151 static void fill_error_text(ScriptError *error)
2153 if (error->text_filled) return;
2154 error->text_filled = TRUE;
2156 if (error->object)
2157 IActiveScriptError_GetSourceLineText(error->object, &error->text);
2160 static void fill_error_pos(ScriptError *error)
2162 DWORD context;
2163 LONG column;
2164 ULONG line;
2166 if (error->pos_filled) return;
2167 error->pos_filled = TRUE;
2169 if (!error->object)
2170 return;
2171 if (FAILED(IActiveScriptError_GetSourcePosition(error->object, &context, &line, &column)))
2172 return;
2174 error->line = line;
2175 error->column = column;
2178 static HRESULT WINAPI ScriptError_QueryInterface(IScriptError *iface, REFIID riid, void **ppv)
2180 ScriptError *This = impl_from_IScriptError(iface);
2182 if (IsEqualGUID(&IID_IDispatch, riid) || IsEqualGUID(&IID_IUnknown, riid) ||
2183 IsEqualGUID(&IID_IScriptError, riid))
2185 *ppv = &This->IScriptError_iface;
2187 else
2189 WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
2190 *ppv = NULL;
2191 return E_NOINTERFACE;
2194 IUnknown_AddRef((IUnknown*)*ppv);
2195 return S_OK;
2198 static ULONG WINAPI ScriptError_AddRef(IScriptError *iface)
2200 ScriptError *This = impl_from_IScriptError(iface);
2201 LONG ref = InterlockedIncrement(&This->ref);
2203 TRACE("(%p) ref=%d\n", This, ref);
2205 return ref;
2208 static ULONG WINAPI ScriptError_Release(IScriptError *iface)
2210 ScriptError *This = impl_from_IScriptError(iface);
2211 LONG ref = InterlockedDecrement(&This->ref);
2213 TRACE("(%p) ref=%d\n", This, ref);
2215 if (!ref)
2217 IScriptError_Clear(&This->IScriptError_iface);
2218 heap_free(This);
2221 return ref;
2224 static HRESULT WINAPI ScriptError_GetTypeInfoCount(IScriptError *iface, UINT *pctinfo)
2226 ScriptError *This = impl_from_IScriptError(iface);
2228 TRACE("(%p)->(%p)\n", This, pctinfo);
2230 *pctinfo = 1;
2231 return S_OK;
2234 static HRESULT WINAPI ScriptError_GetTypeInfo(IScriptError *iface, UINT iTInfo,
2235 LCID lcid, ITypeInfo **ppTInfo)
2237 ScriptError *This = impl_from_IScriptError(iface);
2239 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
2241 return get_typeinfo(IScriptError_tid, ppTInfo);
2244 static HRESULT WINAPI ScriptError_GetIDsOfNames(IScriptError *iface, REFIID riid,
2245 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
2247 ScriptError *This = impl_from_IScriptError(iface);
2248 ITypeInfo *typeinfo;
2249 HRESULT hr;
2251 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
2253 hr = get_typeinfo(IScriptError_tid, &typeinfo);
2254 if (SUCCEEDED(hr))
2256 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
2257 ITypeInfo_Release(typeinfo);
2260 return hr;
2263 static HRESULT WINAPI ScriptError_Invoke(IScriptError *iface, DISPID dispIdMember,
2264 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
2265 EXCEPINFO *pExcepInfo, UINT *puArgErr)
2267 ScriptError *This = impl_from_IScriptError(iface);
2268 ITypeInfo *typeinfo;
2269 HRESULT hr;
2271 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
2272 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2274 hr = get_typeinfo(IScriptError_tid, &typeinfo);
2275 if(SUCCEEDED(hr))
2277 hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
2278 pDispParams, pVarResult, pExcepInfo, puArgErr);
2279 ITypeInfo_Release(typeinfo);
2282 return hr;
2285 static HRESULT WINAPI ScriptError_get_Number(IScriptError *iface, LONG *plNumber)
2287 ScriptError *This = impl_from_IScriptError(iface);
2289 TRACE("(%p)->(%p)\n", This, plNumber);
2291 fill_error_info(This);
2292 *plNumber = This->number;
2293 return S_OK;
2296 static HRESULT WINAPI ScriptError_get_Source(IScriptError *iface, BSTR *pbstrSource)
2298 ScriptError *This = impl_from_IScriptError(iface);
2300 TRACE("(%p)->(%p)\n", This, pbstrSource);
2302 fill_error_info(This);
2303 *pbstrSource = SysAllocString(This->source);
2304 return S_OK;
2307 static HRESULT WINAPI ScriptError_get_Description(IScriptError *iface, BSTR *pbstrDescription)
2309 ScriptError *This = impl_from_IScriptError(iface);
2311 TRACE("(%p)->(%p)\n", This, pbstrDescription);
2313 fill_error_info(This);
2314 *pbstrDescription = SysAllocString(This->desc);
2315 return S_OK;
2318 static HRESULT WINAPI ScriptError_get_HelpFile(IScriptError *iface, BSTR *pbstrHelpFile)
2320 ScriptError *This = impl_from_IScriptError(iface);
2322 TRACE("(%p)->(%p)\n", This, pbstrHelpFile);
2324 fill_error_info(This);
2325 *pbstrHelpFile = SysAllocString(This->help_file);
2326 return S_OK;
2329 static HRESULT WINAPI ScriptError_get_HelpContext(IScriptError *iface, LONG *plHelpContext)
2331 ScriptError *This = impl_from_IScriptError(iface);
2333 TRACE("(%p)->(%p)\n", This, plHelpContext);
2335 fill_error_info(This);
2336 *plHelpContext = This->help_context;
2337 return S_OK;
2340 static HRESULT WINAPI ScriptError_get_Text(IScriptError *iface, BSTR *pbstrText)
2342 ScriptError *This = impl_from_IScriptError(iface);
2344 TRACE("(%p)->(%p)\n", This, pbstrText);
2346 fill_error_text(This);
2347 *pbstrText = SysAllocString(This->text);
2348 return S_OK;
2351 static HRESULT WINAPI ScriptError_get_Line(IScriptError *iface, LONG *plLine)
2353 ScriptError *This = impl_from_IScriptError(iface);
2355 TRACE("(%p)->(%p)\n", This, plLine);
2357 fill_error_pos(This);
2358 *plLine = This->line;
2359 return S_OK;
2362 static HRESULT WINAPI ScriptError_get_Column(IScriptError *iface, LONG *plColumn)
2364 ScriptError *This = impl_from_IScriptError(iface);
2366 TRACE("(%p)->(%p)\n", This, plColumn);
2368 fill_error_pos(This);
2369 *plColumn = This->column;
2370 return S_OK;
2373 static HRESULT WINAPI ScriptError_Clear(IScriptError *iface)
2375 ScriptError *This = impl_from_IScriptError(iface);
2377 TRACE("(%p)->()\n", This);
2379 if (This->object)
2381 IActiveScriptError_Release(This->object);
2382 This->object = NULL;
2384 SysFreeString(This->text);
2385 SysFreeString(This->source);
2386 SysFreeString(This->desc);
2387 SysFreeString(This->help_file);
2389 This->number = 0;
2390 This->text = NULL;
2391 This->source = NULL;
2392 This->desc = NULL;
2393 This->help_file = NULL;
2394 This->help_context = 0;
2395 This->line = 0;
2396 This->column = 0;
2398 This->info_filled = FALSE;
2399 This->text_filled = FALSE;
2400 This->pos_filled = FALSE;
2401 return S_OK;
2404 static const IScriptErrorVtbl ScriptErrorVtbl = {
2405 ScriptError_QueryInterface,
2406 ScriptError_AddRef,
2407 ScriptError_Release,
2408 ScriptError_GetTypeInfoCount,
2409 ScriptError_GetTypeInfo,
2410 ScriptError_GetIDsOfNames,
2411 ScriptError_Invoke,
2412 ScriptError_get_Number,
2413 ScriptError_get_Source,
2414 ScriptError_get_Description,
2415 ScriptError_get_HelpFile,
2416 ScriptError_get_HelpContext,
2417 ScriptError_get_Text,
2418 ScriptError_get_Line,
2419 ScriptError_get_Column,
2420 ScriptError_Clear
2423 static HRESULT init_script_host(ScriptControl *control, const CLSID *clsid, ScriptHost **ret)
2425 IObjectSafety *objsafety;
2426 ScriptHost *host;
2427 HRESULT hr;
2429 *ret = NULL;
2431 host = heap_alloc(sizeof(*host));
2432 if (!host)
2433 return E_OUTOFMEMORY;
2435 host->IActiveScriptSite_iface.lpVtbl = &ActiveScriptSiteVtbl;
2436 host->IActiveScriptSiteWindow_iface.lpVtbl = &ActiveScriptSiteWindowVtbl;
2437 host->IServiceProvider_iface.lpVtbl = &ServiceProviderVtbl;
2438 host->ref = 1;
2439 host->script = NULL;
2440 host->parse = NULL;
2441 host->clsid = *clsid;
2442 host->module_count = 1;
2443 list_init(&host->named_items);
2445 hr = CoCreateInstance(&host->clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2446 &IID_IActiveScript, (void**)&host->script);
2447 if (FAILED(hr)) {
2448 WARN("Failed to create an instance for %s, %#x\n", debugstr_guid(clsid), hr);
2449 goto failed;
2452 hr = IActiveScript_QueryInterface(host->script, &IID_IObjectSafety, (void**)&objsafety);
2453 if (FAILED(hr)) {
2454 FIXME("Could not get IObjectSafety, %#x\n", hr);
2455 goto failed;
2458 hr = IObjectSafety_SetInterfaceSafetyOptions(objsafety, &IID_IActiveScriptParse, INTERFACESAFE_FOR_UNTRUSTED_DATA, 0);
2459 IObjectSafety_Release(objsafety);
2460 if (FAILED(hr)) {
2461 FIXME("SetInterfaceSafetyOptions failed, %#x\n", hr);
2462 goto failed;
2465 hr = IActiveScript_SetScriptSite(host->script, &host->IActiveScriptSite_iface);
2466 if (FAILED(hr)) {
2467 WARN("SetScriptSite failed, %#x\n", hr);
2468 goto failed;
2471 hr = IActiveScript_QueryInterface(host->script, &IID_IActiveScriptParse, (void**)&host->parse);
2472 if (FAILED(hr)) {
2473 WARN("Failed to get IActiveScriptParse, %#x\n", hr);
2474 goto failed;
2477 hr = IActiveScriptParse_InitNew(host->parse);
2478 if (FAILED(hr)) {
2479 WARN("InitNew failed, %#x\n", hr);
2480 goto failed;
2482 host->script_state = SCRIPTSTATE_INITIALIZED;
2483 host->error = control->error;
2484 IScriptError_AddRef(&host->error->IScriptError_iface);
2486 *ret = host;
2487 return S_OK;
2489 failed:
2490 detach_script_host(host);
2491 return hr;
2494 static HRESULT WINAPI ScriptControl_QueryInterface(IScriptControl *iface, REFIID riid, void **ppv)
2496 ScriptControl *This = impl_from_IScriptControl(iface);
2498 if(IsEqualGUID(&IID_IUnknown, riid)) {
2499 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
2500 *ppv = &This->IScriptControl_iface;
2501 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
2502 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
2503 *ppv = &This->IScriptControl_iface;
2504 }else if(IsEqualGUID(&IID_IScriptControl, riid)) {
2505 TRACE("(%p)->(IID_IScriptControl %p)\n", This, ppv);
2506 *ppv = &This->IScriptControl_iface;
2507 }else if(IsEqualGUID(&IID_IOleObject, riid)) {
2508 TRACE("(%p)->(IID_IOleObject %p)\n", This, ppv);
2509 *ppv = &This->IOleObject_iface;
2510 }else if(IsEqualGUID(&IID_IPersistStreamInit, riid)) {
2511 TRACE("(%p)->(IID_IPersistStreamInit %p)\n", This, ppv);
2512 *ppv = &This->IPersistStreamInit_iface;
2513 }else if(IsEqualGUID(&IID_IPersist, riid)) {
2514 TRACE("(%p)->(IID_IPersist %p)\n", This, ppv);
2515 *ppv = &This->IPersistStreamInit_iface;
2516 }else if(IsEqualGUID(&IID_IOleControl, riid)) {
2517 TRACE("(%p)->(IID_IOleControl %p)\n", This, ppv);
2518 *ppv = &This->IOleControl_iface;
2519 }else if(IsEqualGUID(&IID_IQuickActivate, riid)) {
2520 TRACE("(%p)->(IID_IQuickActivate %p)\n", This, ppv);
2521 *ppv = &This->IQuickActivate_iface;
2522 }else if(IsEqualGUID(&IID_IViewObject, riid)) {
2523 TRACE("(%p)->(IID_IViewObject %p)\n", This, ppv);
2524 *ppv = &This->IViewObjectEx_iface;
2525 }else if(IsEqualGUID(&IID_IViewObject2, riid)) {
2526 TRACE("(%p)->(IID_IViewObject2 %p)\n", This, ppv);
2527 *ppv = &This->IViewObjectEx_iface;
2528 }else if(IsEqualGUID(&IID_IViewObjectEx, riid)) {
2529 TRACE("(%p)->(IID_IViewObjectEx %p)\n", This, ppv);
2530 *ppv = &This->IViewObjectEx_iface;
2531 }else if(IsEqualGUID(&IID_IPointerInactive, riid)) {
2532 TRACE("(%p)->(IID_IPointerInactive %p)\n", This, ppv);
2533 *ppv = &This->IPointerInactive_iface;
2534 }else if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) {
2535 TRACE("(%p)->(IID_IConnectionPointContainer %p)\n", This, ppv);
2536 *ppv = &This->IConnectionPointContainer_iface;
2537 }else {
2538 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
2539 *ppv = NULL;
2540 return E_NOINTERFACE;
2543 IUnknown_AddRef((IUnknown*)*ppv);
2544 return S_OK;
2547 static ULONG WINAPI ScriptControl_AddRef(IScriptControl *iface)
2549 ScriptControl *This = impl_from_IScriptControl(iface);
2550 LONG ref = InterlockedIncrement(&This->ref);
2552 TRACE("(%p) ref=%d\n", This, ref);
2554 return ref;
2557 static ULONG WINAPI ScriptControl_Release(IScriptControl *iface)
2559 ScriptControl *This = impl_from_IScriptControl(iface);
2560 LONG ref = InterlockedDecrement(&This->ref);
2562 TRACE("(%p) ref=%d\n", This, ref);
2564 if(!ref) {
2565 if (This->site)
2566 IOleClientSite_Release(This->site);
2567 if (This->host)
2569 release_modules(This, FALSE);
2570 IActiveScriptSite_Release(&This->host->IActiveScriptSite_iface);
2572 IScriptError_Release(&This->error->IScriptError_iface);
2573 heap_free(This);
2576 return ref;
2579 static HRESULT WINAPI ScriptControl_GetTypeInfoCount(IScriptControl *iface, UINT *pctinfo)
2581 ScriptControl *This = impl_from_IScriptControl(iface);
2582 TRACE("(%p)->(%p)\n", This, pctinfo);
2583 *pctinfo = 1;
2584 return S_OK;
2587 static HRESULT WINAPI ScriptControl_GetTypeInfo(IScriptControl *iface, UINT iTInfo,
2588 LCID lcid, ITypeInfo **ppTInfo)
2590 ScriptControl *This = impl_from_IScriptControl(iface);
2591 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
2592 return get_typeinfo(IScriptControl_tid, ppTInfo);
2595 static HRESULT WINAPI ScriptControl_GetIDsOfNames(IScriptControl *iface, REFIID riid,
2596 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
2598 ScriptControl *This = impl_from_IScriptControl(iface);
2599 ITypeInfo *typeinfo;
2600 HRESULT hres;
2602 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
2604 hres = get_typeinfo(IScriptControl_tid, &typeinfo);
2605 if(SUCCEEDED(hres)) {
2606 hres = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
2607 ITypeInfo_Release(typeinfo);
2610 return hres;
2613 static HRESULT WINAPI ScriptControl_Invoke(IScriptControl *iface, DISPID dispIdMember,
2614 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
2615 EXCEPINFO *pExcepInfo, UINT *puArgErr)
2617 ScriptControl *This = impl_from_IScriptControl(iface);
2618 ITypeInfo *typeinfo;
2619 HRESULT hres;
2621 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
2622 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2624 hres = get_typeinfo(IScriptControl_tid, &typeinfo);
2625 if(SUCCEEDED(hres)) {
2626 hres = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
2627 pDispParams, pVarResult, pExcepInfo, puArgErr);
2628 ITypeInfo_Release(typeinfo);
2631 return hres;
2634 static HRESULT WINAPI ScriptControl_get_Language(IScriptControl *iface, BSTR *p)
2636 ScriptControl *This = impl_from_IScriptControl(iface);
2637 LPOLESTR progidW;
2638 HRESULT hr;
2640 TRACE("(%p)->(%p)\n", This, p);
2642 if (!p)
2643 return E_POINTER;
2645 *p = NULL;
2647 if (!This->host)
2648 return S_OK;
2650 hr = ProgIDFromCLSID(&This->host->clsid, &progidW);
2651 if (FAILED(hr))
2652 return hr;
2654 *p = SysAllocString(progidW);
2655 CoTaskMemFree(progidW);
2656 return *p ? S_OK : E_OUTOFMEMORY;
2659 static HRESULT WINAPI ScriptControl_put_Language(IScriptControl *iface, BSTR language)
2661 ScriptControl *This = impl_from_IScriptControl(iface);
2662 CLSID clsid;
2663 HRESULT hres;
2665 TRACE("(%p)->(%s)\n", This, debugstr_w(language));
2667 if (language && FAILED(CLSIDFromProgID(language, &clsid)))
2668 return CTL_E_INVALIDPROPERTYVALUE;
2670 if (This->host) {
2671 release_modules(This, TRUE);
2672 IActiveScriptSite_Release(&This->host->IActiveScriptSite_iface);
2673 This->host = NULL;
2676 if (!language)
2677 return S_OK;
2679 hres = init_script_host(This, &clsid, &This->host);
2680 if (FAILED(hres))
2681 return hres;
2683 /* Alloc global module */
2684 This->modules = heap_alloc_zero(sizeof(*This->modules));
2685 if (This->modules) {
2686 This->modules[0] = create_module(This->host, NULL);
2687 if (!This->modules[0]) {
2688 heap_free(This->modules);
2689 This->modules = NULL;
2690 hres = E_OUTOFMEMORY;
2693 else
2694 hres = E_OUTOFMEMORY;
2696 if (FAILED(hres)) {
2697 detach_script_host(This->host);
2698 This->host = NULL;
2700 return hres;
2703 static HRESULT WINAPI ScriptControl_get_State(IScriptControl *iface, ScriptControlStates *p)
2705 ScriptControl *This = impl_from_IScriptControl(iface);
2706 SCRIPTSTATE state;
2707 HRESULT hres;
2709 TRACE("(%p)->(%p)\n", This, p);
2711 if(!p)
2712 return E_POINTER;
2714 if(!This->host)
2715 return E_FAIL;
2717 hres = IActiveScript_GetScriptState(This->host->script, &state);
2718 if (FAILED(hres)) return hres;
2720 switch (state)
2722 case SCRIPTSTATE_INITIALIZED:
2723 case SCRIPTSTATE_STARTED:
2724 *p = Initialized;
2725 break;
2726 case SCRIPTSTATE_CONNECTED:
2727 *p = Connected;
2728 break;
2729 default:
2730 WARN("unexpected state %d\n", state);
2731 return E_FAIL;
2733 return S_OK;
2736 static HRESULT WINAPI ScriptControl_put_State(IScriptControl *iface, ScriptControlStates state)
2738 ScriptControl *This = impl_from_IScriptControl(iface);
2739 TRACE("(%p)->(%x)\n", This, state);
2741 if(!This->host)
2742 return E_FAIL;
2744 if(state != Initialized && state != Connected)
2745 return CTL_E_INVALIDPROPERTYVALUE;
2747 return IActiveScript_SetScriptState(This->host->script, state == Connected ? SCRIPTSTATE_CONNECTED : SCRIPTSTATE_STARTED);
2750 static HRESULT WINAPI ScriptControl_put_SitehWnd(IScriptControl *iface, LONG hwnd)
2752 ScriptControl *This = impl_from_IScriptControl(iface);
2754 FIXME("(%p)->(%x)\n", This, hwnd);
2756 return S_OK;
2759 static HRESULT WINAPI ScriptControl_get_SitehWnd(IScriptControl *iface, LONG *p)
2761 ScriptControl *This = impl_from_IScriptControl(iface);
2762 FIXME("(%p)->(%p)\n", This, p);
2763 return E_NOTIMPL;
2766 static HRESULT WINAPI ScriptControl_get_Timeout(IScriptControl *iface, LONG *p)
2768 ScriptControl *This = impl_from_IScriptControl(iface);
2770 TRACE("(%p)->(%p)\n", This, p);
2772 if (!p)
2773 return E_POINTER;
2775 *p = This->timeout;
2776 return S_OK;
2779 static HRESULT WINAPI ScriptControl_put_Timeout(IScriptControl *iface, LONG timeout)
2781 ScriptControl *This = impl_from_IScriptControl(iface);
2783 TRACE("(%p)->(%d)\n", This, timeout);
2785 if (timeout < -1)
2786 return CTL_E_INVALIDPROPERTYVALUE;
2788 if (timeout != -1)
2789 FIXME("execution timeout ignored\n");
2791 This->timeout = timeout;
2792 return S_OK;
2795 static HRESULT WINAPI ScriptControl_get_AllowUI(IScriptControl *iface, VARIANT_BOOL *p)
2797 ScriptControl *This = impl_from_IScriptControl(iface);
2798 TRACE("(%p)->(%p)\n", This, p);
2800 if(!p)
2801 return E_POINTER;
2803 *p = This->allow_ui;
2804 return S_OK;
2807 static HRESULT WINAPI ScriptControl_put_AllowUI(IScriptControl *iface, VARIANT_BOOL allow_ui)
2809 ScriptControl *This = impl_from_IScriptControl(iface);
2810 TRACE("(%p)->(%x)\n", This, allow_ui);
2812 This->allow_ui = allow_ui;
2813 return S_OK;
2816 static HRESULT WINAPI ScriptControl_get_UseSafeSubset(IScriptControl *iface, VARIANT_BOOL *p)
2818 ScriptControl *This = impl_from_IScriptControl(iface);
2819 TRACE("(%p)->(%p)\n", This, p);
2821 if(!p)
2822 return E_POINTER;
2824 *p = This->use_safe_subset;
2825 return S_OK;
2828 static HRESULT WINAPI ScriptControl_put_UseSafeSubset(IScriptControl *iface, VARIANT_BOOL use_safe_subset)
2830 ScriptControl *This = impl_from_IScriptControl(iface);
2831 TRACE("(%p)->(%x)\n", This, use_safe_subset);
2833 This->use_safe_subset = use_safe_subset;
2834 return S_OK;
2837 static HRESULT WINAPI ScriptControl_get_Modules(IScriptControl *iface, IScriptModuleCollection **p)
2839 ScriptControl *This = impl_from_IScriptControl(iface);
2841 TRACE("(%p)->(%p)\n", This, p);
2843 if (!This->host) return E_FAIL;
2845 *p = &This->IScriptModuleCollection_iface;
2846 IScriptControl_AddRef(iface);
2847 return S_OK;
2850 static HRESULT WINAPI ScriptControl_get_Error(IScriptControl *iface, IScriptError **p)
2852 ScriptControl *This = impl_from_IScriptControl(iface);
2854 TRACE("(%p)->(%p)\n", This, p);
2856 if (!p) return E_POINTER;
2858 *p = &This->error->IScriptError_iface;
2859 IScriptError_AddRef(*p);
2860 return S_OK;
2863 static HRESULT WINAPI ScriptControl_get_CodeObject(IScriptControl *iface, IDispatch **p)
2865 ScriptControl *This = impl_from_IScriptControl(iface);
2867 TRACE("(%p)->(%p)\n", This, p);
2869 if (!This->host) return E_FAIL;
2871 return IScriptModule_get_CodeObject(&This->modules[0]->IScriptModule_iface, p);
2874 static HRESULT WINAPI ScriptControl_get_Procedures(IScriptControl *iface, IScriptProcedureCollection **p)
2876 ScriptControl *This = impl_from_IScriptControl(iface);
2878 TRACE("(%p)->(%p)\n", This, p);
2880 if (!This->host) return E_FAIL;
2882 return IScriptModule_get_Procedures(&This->modules[0]->IScriptModule_iface, p);
2885 static HRESULT WINAPI ScriptControl__AboutBox(IScriptControl *iface)
2887 ScriptControl *This = impl_from_IScriptControl(iface);
2888 FIXME("(%p)\n", This);
2889 return E_NOTIMPL;
2892 static HRESULT WINAPI ScriptControl_AddObject(IScriptControl *iface, BSTR name, IDispatch *object, VARIANT_BOOL add_members)
2894 ScriptControl *This = impl_from_IScriptControl(iface);
2895 DWORD flags = SCRIPTITEM_ISVISIBLE | SCRIPTITEM_ISSOURCE;
2897 TRACE("(%p)->(%s %p %x)\n", This, debugstr_w(name), object, add_members);
2899 if (!object)
2900 return E_INVALIDARG;
2902 if (!This->host)
2903 return E_FAIL;
2905 if (add_members)
2906 flags |= SCRIPTITEM_GLOBALMEMBERS;
2907 return add_script_object(This->host, name, object, flags);
2910 static HRESULT WINAPI ScriptControl_Reset(IScriptControl *iface)
2912 ScriptControl *This = impl_from_IScriptControl(iface);
2914 TRACE("(%p)\n", This);
2916 if (!This->host)
2917 return E_FAIL;
2919 clear_named_items(This->host);
2920 return set_script_state(This->host, SCRIPTSTATE_INITIALIZED);
2923 static HRESULT WINAPI ScriptControl_AddCode(IScriptControl *iface, BSTR code)
2925 ScriptControl *This = impl_from_IScriptControl(iface);
2927 TRACE("(%p)->(%s).\n", This, debugstr_w(code));
2929 if (!This->host)
2930 return E_FAIL;
2932 return parse_script_text(This->modules[0], code, SCRIPTTEXT_ISVISIBLE, NULL);
2935 static HRESULT WINAPI ScriptControl_Eval(IScriptControl *iface, BSTR expression, VARIANT *res)
2937 ScriptControl *This = impl_from_IScriptControl(iface);
2939 TRACE("(%p)->(%s, %p).\n", This, debugstr_w(expression), res);
2941 if (!res)
2942 return E_POINTER;
2943 V_VT(res) = VT_EMPTY;
2944 if (!This->host)
2945 return E_FAIL;
2947 return parse_script_text(This->modules[0], expression, SCRIPTTEXT_ISEXPRESSION, res);
2950 static HRESULT WINAPI ScriptControl_ExecuteStatement(IScriptControl *iface, BSTR statement)
2952 ScriptControl *This = impl_from_IScriptControl(iface);
2954 TRACE("(%p)->(%s)\n", This, debugstr_w(statement));
2956 if (!This->host)
2957 return E_FAIL;
2959 return parse_script_text(This->modules[0], statement, 0, NULL);
2962 static HRESULT WINAPI ScriptControl_Run(IScriptControl *iface, BSTR procedure_name, SAFEARRAY **parameters, VARIANT *res)
2964 ScriptControl *This = impl_from_IScriptControl(iface);
2965 SAFEARRAY *sa;
2967 TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(procedure_name), parameters, res);
2969 if (!parameters || !res) return E_POINTER;
2970 if (!(sa = *parameters)) return E_POINTER;
2972 V_VT(res) = VT_EMPTY;
2973 if (sa->cDims == 0) return DISP_E_BADINDEX;
2974 if (!(sa->fFeatures & FADF_VARIANT)) return DISP_E_BADVARTYPE;
2975 if (!This->host) return E_FAIL;
2977 return run_procedure(This->modules[0], procedure_name, sa, res);
2980 static const IScriptControlVtbl ScriptControlVtbl = {
2981 ScriptControl_QueryInterface,
2982 ScriptControl_AddRef,
2983 ScriptControl_Release,
2984 ScriptControl_GetTypeInfoCount,
2985 ScriptControl_GetTypeInfo,
2986 ScriptControl_GetIDsOfNames,
2987 ScriptControl_Invoke,
2988 ScriptControl_get_Language,
2989 ScriptControl_put_Language,
2990 ScriptControl_get_State,
2991 ScriptControl_put_State,
2992 ScriptControl_put_SitehWnd,
2993 ScriptControl_get_SitehWnd,
2994 ScriptControl_get_Timeout,
2995 ScriptControl_put_Timeout,
2996 ScriptControl_get_AllowUI,
2997 ScriptControl_put_AllowUI,
2998 ScriptControl_get_UseSafeSubset,
2999 ScriptControl_put_UseSafeSubset,
3000 ScriptControl_get_Modules,
3001 ScriptControl_get_Error,
3002 ScriptControl_get_CodeObject,
3003 ScriptControl_get_Procedures,
3004 ScriptControl__AboutBox,
3005 ScriptControl_AddObject,
3006 ScriptControl_Reset,
3007 ScriptControl_AddCode,
3008 ScriptControl_Eval,
3009 ScriptControl_ExecuteStatement,
3010 ScriptControl_Run
3013 static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **obj)
3015 ScriptControl *This = impl_from_IOleObject(iface);
3016 return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
3019 static ULONG WINAPI OleObject_AddRef(IOleObject *iface)
3021 ScriptControl *This = impl_from_IOleObject(iface);
3022 return IScriptControl_AddRef(&This->IScriptControl_iface);
3025 static ULONG WINAPI OleObject_Release(IOleObject *iface)
3027 ScriptControl *This = impl_from_IOleObject(iface);
3028 return IScriptControl_Release(&This->IScriptControl_iface);
3031 static HRESULT WINAPI OleObject_SetClientSite(IOleObject *iface, IOleClientSite *site)
3033 ScriptControl *This = impl_from_IOleObject(iface);
3035 TRACE("(%p)->(%p)\n", This, site);
3037 if (This->site)
3038 IOleClientSite_Release(This->site);
3040 if ((This->site = site))
3041 IOleClientSite_AddRef(site);
3043 return S_OK;
3046 static HRESULT WINAPI OleObject_GetClientSite(IOleObject *iface, IOleClientSite **site)
3048 ScriptControl *This = impl_from_IOleObject(iface);
3050 TRACE("(%p)->(%p)\n", This, site);
3052 if (!site)
3053 return E_POINTER;
3055 if ((*site = This->site))
3056 IOleClientSite_AddRef(*site);
3058 return S_OK;
3061 static HRESULT WINAPI OleObject_SetHostNames(IOleObject *iface, LPCOLESTR containerapp, LPCOLESTR containerobj)
3063 ScriptControl *This = impl_from_IOleObject(iface);
3065 FIXME("(%p)->(%s %s)\n", This, debugstr_w(containerapp), debugstr_w(containerobj));
3067 return E_NOTIMPL;
3070 static HRESULT WINAPI OleObject_Close(IOleObject *iface, DWORD save)
3072 ScriptControl *This = impl_from_IOleObject(iface);
3074 FIXME("(%p)->(%d)\n", This, save);
3076 return E_NOTIMPL;
3079 static HRESULT WINAPI OleObject_SetMoniker(IOleObject *iface, DWORD which, IMoniker *moniker)
3081 ScriptControl *This = impl_from_IOleObject(iface);
3083 FIXME("(%p)->(%d %p)\n", This, which, moniker);
3085 return E_NOTIMPL;
3088 static HRESULT WINAPI OleObject_GetMoniker(IOleObject *iface, DWORD assign, DWORD which, IMoniker **moniker)
3090 ScriptControl *This = impl_from_IOleObject(iface);
3092 FIXME("(%p)->(%d %d %p)\n", This, assign, which, moniker);
3094 return E_NOTIMPL;
3097 static HRESULT WINAPI OleObject_InitFromData(IOleObject *iface, IDataObject *dataobj, BOOL creation,
3098 DWORD reserved)
3100 ScriptControl *This = impl_from_IOleObject(iface);
3102 FIXME("(%p)->(%p %d %d)\n", This, dataobj, creation, reserved);
3104 return E_NOTIMPL;
3107 static HRESULT WINAPI OleObject_GetClipboardData(IOleObject *iface, DWORD reserved, IDataObject **dataobj)
3109 ScriptControl *This = impl_from_IOleObject(iface);
3111 FIXME("(%p)->(%d %p)\n", This, reserved, dataobj);
3113 return E_NOTIMPL;
3116 static HRESULT WINAPI OleObject_DoVerb(IOleObject *iface, LONG verb, LPMSG msg, IOleClientSite *active_site,
3117 LONG index, HWND hwndParent, LPCRECT rect)
3119 ScriptControl *This = impl_from_IOleObject(iface);
3121 FIXME("(%p)->(%d %p %p %d %p %p)\n", This, verb, msg, active_site, index, hwndParent, rect);
3123 return E_NOTIMPL;
3126 static HRESULT WINAPI OleObject_EnumVerbs(IOleObject *iface, IEnumOLEVERB **enumoleverb)
3128 ScriptControl *This = impl_from_IOleObject(iface);
3130 FIXME("(%p)->(%p)\n", This, enumoleverb);
3132 return E_NOTIMPL;
3135 static HRESULT WINAPI OleObject_Update(IOleObject *iface)
3137 ScriptControl *This = impl_from_IOleObject(iface);
3139 FIXME("(%p)\n", This);
3141 return E_NOTIMPL;
3144 static HRESULT WINAPI OleObject_IsUpToDate(IOleObject *iface)
3146 ScriptControl *This = impl_from_IOleObject(iface);
3148 FIXME("(%p)\n", This);
3150 return E_NOTIMPL;
3153 static HRESULT WINAPI OleObject_GetUserClassID(IOleObject *iface, CLSID *clsid)
3155 ScriptControl *This = impl_from_IOleObject(iface);
3157 FIXME("(%p)->(%p)\n", This, clsid);
3159 return E_NOTIMPL;
3162 static HRESULT WINAPI OleObject_GetUserType(IOleObject *iface, DWORD form_of_type, LPOLESTR *usertype)
3164 ScriptControl *This = impl_from_IOleObject(iface);
3166 FIXME("(%p)->(%d %p)\n", This, form_of_type, usertype);
3168 return E_NOTIMPL;
3171 static HRESULT WINAPI OleObject_SetExtent(IOleObject *iface, DWORD aspect, SIZEL *size)
3173 ScriptControl *This = impl_from_IOleObject(iface);
3175 FIXME("(%p)->(%d %p)\n", This, aspect, size);
3177 return E_NOTIMPL;
3180 static HRESULT WINAPI OleObject_GetExtent(IOleObject *iface, DWORD aspect, SIZEL *size)
3182 ScriptControl *This = impl_from_IOleObject(iface);
3184 TRACE("(%p)->(%d %p)\n", This, aspect, size);
3186 if (aspect != DVASPECT_CONTENT)
3187 return DV_E_DVASPECT;
3189 *size = This->extent;
3190 return S_OK;
3193 static HRESULT WINAPI OleObject_Advise(IOleObject *iface, IAdviseSink *sink, DWORD *connection)
3195 ScriptControl *This = impl_from_IOleObject(iface);
3197 FIXME("(%p)->(%p %p)\n", This, sink, connection);
3199 return E_NOTIMPL;
3202 static HRESULT WINAPI OleObject_Unadvise(IOleObject *iface, DWORD connection)
3204 ScriptControl *This = impl_from_IOleObject(iface);
3206 FIXME("(%p)->(%d)\n", This, connection);
3208 return E_NOTIMPL;
3211 static HRESULT WINAPI OleObject_EnumAdvise(IOleObject *iface, IEnumSTATDATA **enumadvise)
3213 ScriptControl *This = impl_from_IOleObject(iface);
3215 FIXME("(%p)->(%p)\n", This, enumadvise);
3217 return E_NOTIMPL;
3220 static HRESULT WINAPI OleObject_GetMiscStatus(IOleObject *iface, DWORD aspect, DWORD *status)
3222 ScriptControl *This = impl_from_IOleObject(iface);
3224 TRACE("(%p)->(%d %p)\n", This, aspect, status);
3226 return OleRegGetMiscStatus(&CLSID_ScriptControl, aspect, status);
3229 static HRESULT WINAPI OleObject_SetColorScheme(IOleObject *iface, LOGPALETTE *logpal)
3231 ScriptControl *This = impl_from_IOleObject(iface);
3233 FIXME("(%p)->(%p)\n", This, logpal);
3235 return E_NOTIMPL;
3238 static const IOleObjectVtbl OleObjectVtbl = {
3239 OleObject_QueryInterface,
3240 OleObject_AddRef,
3241 OleObject_Release,
3242 OleObject_SetClientSite,
3243 OleObject_GetClientSite,
3244 OleObject_SetHostNames,
3245 OleObject_Close,
3246 OleObject_SetMoniker,
3247 OleObject_GetMoniker,
3248 OleObject_InitFromData,
3249 OleObject_GetClipboardData,
3250 OleObject_DoVerb,
3251 OleObject_EnumVerbs,
3252 OleObject_Update,
3253 OleObject_IsUpToDate,
3254 OleObject_GetUserClassID,
3255 OleObject_GetUserType,
3256 OleObject_SetExtent,
3257 OleObject_GetExtent,
3258 OleObject_Advise,
3259 OleObject_Unadvise,
3260 OleObject_EnumAdvise,
3261 OleObject_GetMiscStatus,
3262 OleObject_SetColorScheme
3265 static HRESULT WINAPI PersistStreamInit_QueryInterface(IPersistStreamInit *iface, REFIID riid, void **obj)
3267 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3268 return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
3271 static ULONG WINAPI PersistStreamInit_AddRef(IPersistStreamInit *iface)
3273 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3274 return IScriptControl_AddRef(&This->IScriptControl_iface);
3277 static ULONG WINAPI PersistStreamInit_Release(IPersistStreamInit *iface)
3279 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3280 return IScriptControl_Release(&This->IScriptControl_iface);
3283 static HRESULT WINAPI PersistStreamInit_GetClassID(IPersistStreamInit *iface, CLSID *clsid)
3285 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3287 FIXME("(%p)->(%p)\n", This, clsid);
3289 return E_NOTIMPL;
3292 static HRESULT WINAPI PersistStreamInit_IsDirty(IPersistStreamInit *iface)
3294 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3296 FIXME("(%p)\n", This);
3298 return E_NOTIMPL;
3301 static HRESULT WINAPI PersistStreamInit_Load(IPersistStreamInit *iface, IStream *stream)
3303 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3305 FIXME("(%p)->(%p)\n", This, stream);
3307 return E_NOTIMPL;
3310 static HRESULT WINAPI PersistStreamInit_Save(IPersistStreamInit *iface, IStream *stream, BOOL clear_dirty)
3312 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3314 FIXME("(%p)->(%p %d)\n", This, stream, clear_dirty);
3316 return E_NOTIMPL;
3319 static HRESULT WINAPI PersistStreamInit_GetSizeMax(IPersistStreamInit *iface, ULARGE_INTEGER *size)
3321 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3323 FIXME("(%p)->(%p)\n", This, size);
3325 return E_NOTIMPL;
3328 static HRESULT WINAPI PersistStreamInit_InitNew(IPersistStreamInit *iface)
3330 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3332 FIXME("(%p)\n", This);
3334 return S_OK;
3337 static const IPersistStreamInitVtbl PersistStreamInitVtbl = {
3338 PersistStreamInit_QueryInterface,
3339 PersistStreamInit_AddRef,
3340 PersistStreamInit_Release,
3341 PersistStreamInit_GetClassID,
3342 PersistStreamInit_IsDirty,
3343 PersistStreamInit_Load,
3344 PersistStreamInit_Save,
3345 PersistStreamInit_GetSizeMax,
3346 PersistStreamInit_InitNew
3349 static HRESULT WINAPI OleControl_QueryInterface(IOleControl *iface, REFIID riid, void **obj)
3351 ScriptControl *This = impl_from_IOleControl(iface);
3352 return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
3355 static ULONG WINAPI OleControl_AddRef(IOleControl *iface)
3357 ScriptControl *This = impl_from_IOleControl(iface);
3358 return IScriptControl_AddRef(&This->IScriptControl_iface);
3361 static ULONG WINAPI OleControl_Release(IOleControl *iface)
3363 ScriptControl *This = impl_from_IOleControl(iface);
3364 return IScriptControl_Release(&This->IScriptControl_iface);
3367 static HRESULT WINAPI OleControl_GetControlInfo(IOleControl *iface, CONTROLINFO *info)
3369 ScriptControl *This = impl_from_IOleControl(iface);
3371 TRACE("(%p)->(%p)\n", This, info);
3373 if (!info)
3374 return E_POINTER;
3376 info->hAccel = NULL;
3377 info->cAccel = 0;
3379 return S_OK;
3382 static HRESULT WINAPI OleControl_OnMnemonic(IOleControl *iface, MSG *msg)
3384 ScriptControl *This = impl_from_IOleControl(iface);
3386 FIXME("(%p)->(%p)\n", This, msg);
3388 return E_NOTIMPL;
3391 static HRESULT WINAPI OleControl_OnAmbientPropertyChange(IOleControl *iface, DISPID dispid)
3393 ScriptControl *This = impl_from_IOleControl(iface);
3395 FIXME("(%p)->(%#x)\n", This, dispid);
3397 return E_NOTIMPL;
3400 static HRESULT WINAPI OleControl_FreezeEvents(IOleControl *iface, BOOL freeze)
3402 ScriptControl *This = impl_from_IOleControl(iface);
3404 FIXME("(%p)->(%d)\n", This, freeze);
3406 return E_NOTIMPL;
3409 static const IOleControlVtbl OleControlVtbl = {
3410 OleControl_QueryInterface,
3411 OleControl_AddRef,
3412 OleControl_Release,
3413 OleControl_GetControlInfo,
3414 OleControl_OnMnemonic,
3415 OleControl_OnAmbientPropertyChange,
3416 OleControl_FreezeEvents
3419 static HRESULT WINAPI QuickActivate_QueryInterface(IQuickActivate *iface, REFIID riid, void **obj)
3421 ScriptControl *This = impl_from_IQuickActivate(iface);
3422 return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
3425 static ULONG WINAPI QuickActivate_AddRef(IQuickActivate *iface)
3427 ScriptControl *This = impl_from_IQuickActivate(iface);
3428 return IScriptControl_AddRef(&This->IScriptControl_iface);
3431 static ULONG WINAPI QuickActivate_Release(IQuickActivate *iface)
3433 ScriptControl *This = impl_from_IQuickActivate(iface);
3434 return IScriptControl_Release(&This->IScriptControl_iface);
3437 static HRESULT WINAPI QuickActivate_QuickActivate(IQuickActivate *iface, QACONTAINER *container, QACONTROL *control)
3439 ScriptControl *This = impl_from_IQuickActivate(iface);
3441 FIXME("(%p)->(%p %p)\n", This, container, control);
3443 return E_NOTIMPL;
3446 static HRESULT WINAPI QuickActivate_SetContentExtent(IQuickActivate *iface, SIZEL *size)
3448 ScriptControl *This = impl_from_IQuickActivate(iface);
3450 FIXME("(%p)->(%p)\n", This, size);
3452 return E_NOTIMPL;
3455 static HRESULT WINAPI QuickActivate_GetContentExtent(IQuickActivate *iface, SIZEL *size)
3457 ScriptControl *This = impl_from_IQuickActivate(iface);
3459 FIXME("(%p)->(%p)\n", This, size);
3461 return E_NOTIMPL;
3464 static const IQuickActivateVtbl QuickActivateVtbl = {
3465 QuickActivate_QueryInterface,
3466 QuickActivate_AddRef,
3467 QuickActivate_Release,
3468 QuickActivate_QuickActivate,
3469 QuickActivate_SetContentExtent,
3470 QuickActivate_GetContentExtent
3473 static HRESULT WINAPI ViewObject_QueryInterface(IViewObjectEx *iface, REFIID riid, void **obj)
3475 ScriptControl *This = impl_from_IViewObjectEx(iface);
3476 return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
3479 static ULONG WINAPI ViewObject_AddRef(IViewObjectEx *iface)
3481 ScriptControl *This = impl_from_IViewObjectEx(iface);
3482 return IScriptControl_AddRef(&This->IScriptControl_iface);
3485 static ULONG WINAPI ViewObject_Release(IViewObjectEx *iface)
3487 ScriptControl *This = impl_from_IViewObjectEx(iface);
3488 return IScriptControl_Release(&This->IScriptControl_iface);
3491 static HRESULT WINAPI ViewObject_Draw(IViewObjectEx *iface, DWORD drawaspect, LONG index, void *aspect,
3492 DVTARGETDEVICE *device, HDC target_dev, HDC hdc_draw, const RECTL *bounds, const RECTL *win_bounds,
3493 BOOL (STDMETHODCALLTYPE *fn_continue)(ULONG_PTR cont), ULONG_PTR cont)
3495 ScriptControl *This = impl_from_IViewObjectEx(iface);
3497 FIXME("(%p)->(%d %d %p %p %p %p %p %p %p %lu)\n", This, drawaspect, index, aspect, device, target_dev,
3498 hdc_draw, bounds, win_bounds, fn_continue, cont);
3500 return E_NOTIMPL;
3503 static HRESULT WINAPI ViewObject_GetColorSet(IViewObjectEx *iface, DWORD drawaspect, LONG index, void *aspect,
3504 DVTARGETDEVICE *device, HDC hic_target, LOGPALETTE **colorset)
3506 ScriptControl *This = impl_from_IViewObjectEx(iface);
3508 FIXME("(%p)->(%d %d %p %p %p %p)\n", This, drawaspect, index, aspect, device, hic_target,
3509 colorset);
3511 return E_NOTIMPL;
3514 static HRESULT WINAPI ViewObject_Freeze(IViewObjectEx *iface, DWORD drawaspect, LONG index, void *aspect,
3515 DWORD *freeze)
3517 ScriptControl *This = impl_from_IViewObjectEx(iface);
3519 FIXME("(%p)->(%d %d %p %p)\n", This, drawaspect, index, aspect, freeze);
3521 return E_NOTIMPL;
3524 static HRESULT WINAPI ViewObject_Unfreeze(IViewObjectEx *iface, DWORD freeze)
3526 ScriptControl *This = impl_from_IViewObjectEx(iface);
3528 FIXME("(%p)->(%d)\n", This, freeze);
3530 return E_NOTIMPL;
3533 static HRESULT WINAPI ViewObject_SetAdvise(IViewObjectEx *iface, DWORD aspects, DWORD flags, IAdviseSink *sink)
3535 ScriptControl *This = impl_from_IViewObjectEx(iface);
3537 TRACE("(%p)->(%d %#x %p)\n", This, aspects, flags, sink);
3539 if (aspects != DVASPECT_CONTENT)
3540 return DV_E_DVASPECT;
3542 This->view_sink_flags = flags;
3543 if (This->view_sink)
3544 IAdviseSink_Release(This->view_sink);
3545 This->view_sink = sink;
3546 if (This->view_sink)
3547 IAdviseSink_AddRef(This->view_sink);
3549 return S_OK;
3552 static HRESULT WINAPI ViewObject_GetAdvise(IViewObjectEx *iface, DWORD *aspects, DWORD *flags, IAdviseSink **sink)
3554 ScriptControl *This = impl_from_IViewObjectEx(iface);
3556 TRACE("(%p)->(%p %p %p)\n", This, aspects, flags, sink);
3558 if (aspects)
3559 *aspects = DVASPECT_CONTENT;
3560 if (flags)
3561 *flags = This->view_sink_flags;
3562 if (sink) {
3563 *sink = This->view_sink;
3564 if (*sink)
3565 IAdviseSink_AddRef(*sink);
3568 return S_OK;
3571 static HRESULT WINAPI ViewObject_GetExtent(IViewObjectEx *iface, DWORD draw_aspect, LONG index,
3572 DVTARGETDEVICE *device, SIZEL *size)
3574 ScriptControl *This = impl_from_IViewObjectEx(iface);
3576 FIXME("(%p)->(%d %d %p %p)\n", This, draw_aspect, index, device, size);
3578 return E_NOTIMPL;
3581 static HRESULT WINAPI ViewObject_GetRect(IViewObjectEx *iface, DWORD aspect, RECTL *rect)
3583 ScriptControl *This = impl_from_IViewObjectEx(iface);
3585 FIXME("(%p)->(%d %p)\n", This, aspect, rect);
3587 return E_NOTIMPL;
3590 static HRESULT WINAPI ViewObject_GetViewStatus(IViewObjectEx *iface, DWORD *status)
3592 ScriptControl *This = impl_from_IViewObjectEx(iface);
3594 TRACE("(%p)->(%p)\n", This, status);
3596 *status = VIEWSTATUS_OPAQUE;
3597 return S_OK;
3600 static HRESULT WINAPI ViewObject_QueryHitPoint(IViewObjectEx *iface, DWORD aspect, const RECT *bounds,
3601 POINT pt, LONG close_hint, DWORD *hit_result)
3603 ScriptControl *This = impl_from_IViewObjectEx(iface);
3605 FIXME("(%p)->(%d %s %s %d %p)\n", This, aspect, wine_dbgstr_rect(bounds), wine_dbgstr_point(&pt), close_hint, hit_result);
3607 return E_NOTIMPL;
3610 static HRESULT WINAPI ViewObject_QueryHitRect(IViewObjectEx *iface, DWORD aspect, const RECT *bounds,
3611 const RECT *loc, LONG close_hint, DWORD *hit_result)
3613 ScriptControl *This = impl_from_IViewObjectEx(iface);
3615 FIXME("(%p)->(%d %s %s %d %p)\n", This, aspect, wine_dbgstr_rect(bounds), wine_dbgstr_rect(loc), close_hint, hit_result);
3617 return E_NOTIMPL;
3620 static HRESULT WINAPI ViewObject_GetNaturalExtent(IViewObjectEx *iface, DWORD aspect, LONG index,
3621 DVTARGETDEVICE *device, HDC target_hdc, DVEXTENTINFO *extent_info, SIZEL *size)
3623 ScriptControl *This = impl_from_IViewObjectEx(iface);
3625 FIXME("(%p)->(%d %d %p %p %p %p)\n", This, aspect, index, device, target_hdc, extent_info, size);
3627 return E_NOTIMPL;
3630 static const IViewObjectExVtbl ViewObjectExVtbl = {
3631 ViewObject_QueryInterface,
3632 ViewObject_AddRef,
3633 ViewObject_Release,
3634 ViewObject_Draw,
3635 ViewObject_GetColorSet,
3636 ViewObject_Freeze,
3637 ViewObject_Unfreeze,
3638 ViewObject_SetAdvise,
3639 ViewObject_GetAdvise,
3640 ViewObject_GetExtent,
3641 ViewObject_GetRect,
3642 ViewObject_GetViewStatus,
3643 ViewObject_QueryHitPoint,
3644 ViewObject_QueryHitRect,
3645 ViewObject_GetNaturalExtent
3648 static HRESULT WINAPI PointerInactive_QueryInterface(IPointerInactive *iface, REFIID riid, void **obj)
3650 ScriptControl *This = impl_from_IPointerInactive(iface);
3651 return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
3654 static ULONG WINAPI PointerInactive_AddRef(IPointerInactive *iface)
3656 ScriptControl *This = impl_from_IPointerInactive(iface);
3657 return IScriptControl_AddRef(&This->IScriptControl_iface);
3660 static ULONG WINAPI PointerInactive_Release(IPointerInactive *iface)
3662 ScriptControl *This = impl_from_IPointerInactive(iface);
3663 return IScriptControl_Release(&This->IScriptControl_iface);
3666 static HRESULT WINAPI PointerInactive_GetActivationPolicy(IPointerInactive *iface, DWORD *policy)
3668 ScriptControl *This = impl_from_IPointerInactive(iface);
3670 TRACE("(%p)->(%p)\n", This, policy);
3672 if (!policy)
3673 return E_POINTER;
3675 *policy = 0;
3676 return S_OK;
3679 static HRESULT WINAPI PointerInactive_OnInactiveMouseMove(IPointerInactive *iface, const RECT *bounds,
3680 LONG x, LONG y, DWORD key_state)
3682 ScriptControl *This = impl_from_IPointerInactive(iface);
3684 FIXME("(%p)->(%s %d %d %#x)\n", This, wine_dbgstr_rect(bounds), x, y, key_state);
3686 return E_NOTIMPL;
3689 static HRESULT WINAPI PointerInactive_OnInactiveSetCursor(IPointerInactive *iface, const RECT *bounds,
3690 LONG x, LONG y, DWORD msg, BOOL set_always)
3692 ScriptControl *This = impl_from_IPointerInactive(iface);
3694 FIXME("(%p)->(%s %d %d %#x %d)\n", This, wine_dbgstr_rect(bounds), x, y, msg, set_always);
3696 return E_NOTIMPL;
3699 static const IPointerInactiveVtbl PointerInactiveVtbl = {
3700 PointerInactive_QueryInterface,
3701 PointerInactive_AddRef,
3702 PointerInactive_Release,
3703 PointerInactive_GetActivationPolicy,
3704 PointerInactive_OnInactiveMouseMove,
3705 PointerInactive_OnInactiveSetCursor
3708 static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface, REFIID riid, void **obj)
3710 ScriptControl *This = impl_from_IConnectionPointContainer(iface);
3711 return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
3714 static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface)
3716 ScriptControl *This = impl_from_IConnectionPointContainer(iface);
3717 return IScriptControl_AddRef(&This->IScriptControl_iface);
3720 static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface)
3722 ScriptControl *This = impl_from_IConnectionPointContainer(iface);
3723 return IScriptControl_Release(&This->IScriptControl_iface);
3726 static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface, IEnumConnectionPoints **enum_points)
3728 ScriptControl *This = impl_from_IConnectionPointContainer(iface);
3730 FIXME("(%p)->(%p)\n", This, enum_points);
3732 return E_NOTIMPL;
3735 static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface, REFIID riid, IConnectionPoint **cp)
3737 ScriptControl *This = impl_from_IConnectionPointContainer(iface);
3738 ConnectionPoint *iter;
3740 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), cp);
3742 *cp = NULL;
3744 for (iter = This->cp_list; iter; iter = iter->next) {
3745 if (IsEqualIID(iter->riid, riid))
3746 *cp = &iter->IConnectionPoint_iface;
3749 if (*cp) {
3750 IConnectionPoint_AddRef(*cp);
3751 return S_OK;
3754 FIXME("unsupported connection point %s\n", debugstr_guid(riid));
3755 return CONNECT_E_NOCONNECTION;
3758 static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl = {
3759 ConnectionPointContainer_QueryInterface,
3760 ConnectionPointContainer_AddRef,
3761 ConnectionPointContainer_Release,
3762 ConnectionPointContainer_EnumConnectionPoints,
3763 ConnectionPointContainer_FindConnectionPoint
3766 static HRESULT WINAPI ConnectionPoint_QueryInterface(IConnectionPoint *iface,
3767 REFIID riid, void **ppv)
3769 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
3771 if(IsEqualGUID(&IID_IUnknown, riid)) {
3772 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
3773 *ppv = &This->IConnectionPoint_iface;
3774 }else if(IsEqualGUID(&IID_IConnectionPoint, riid)) {
3775 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
3776 *ppv = &This->IConnectionPoint_iface;
3777 }else {
3778 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
3779 *ppv = NULL;
3780 return E_NOINTERFACE;
3783 IUnknown_AddRef((IUnknown*)*ppv);
3784 return S_OK;
3787 static ULONG WINAPI ConnectionPoint_AddRef(IConnectionPoint *iface)
3789 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
3790 return IConnectionPointContainer_AddRef(&This->control->IConnectionPointContainer_iface);
3793 static ULONG WINAPI ConnectionPoint_Release(IConnectionPoint *iface)
3795 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
3796 return IConnectionPointContainer_Release(&This->control->IConnectionPointContainer_iface);
3799 static HRESULT WINAPI ConnectionPoint_GetConnectionInterface(IConnectionPoint *iface, IID *iid)
3801 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
3803 TRACE("(%p)->(%p)\n", This, iid);
3805 *iid = *This->riid;
3806 return S_OK;
3809 static HRESULT WINAPI ConnectionPoint_GetConnectionPointContainer(IConnectionPoint *iface,
3810 IConnectionPointContainer **container)
3812 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
3814 TRACE("(%p)->(%p)\n", This, container);
3816 if (!container)
3817 return E_POINTER;
3819 *container = &This->control->IConnectionPointContainer_iface;
3820 IConnectionPointContainer_AddRef(*container);
3822 return S_OK;
3825 static HRESULT WINAPI ConnectionPoint_Advise(IConnectionPoint *iface, IUnknown *unk_sink,
3826 DWORD *cookie)
3828 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
3830 FIXME("(%p)->(%p %p)\n", This, unk_sink, cookie);
3832 return E_NOTIMPL;
3835 static HRESULT WINAPI ConnectionPoint_Unadvise(IConnectionPoint *iface, DWORD cookie)
3837 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
3839 FIXME("(%p)->(%d)\n", This, cookie);
3841 return E_NOTIMPL;
3844 static HRESULT WINAPI ConnectionPoint_EnumConnections(IConnectionPoint *iface,
3845 IEnumConnections **ppEnum)
3847 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
3849 FIXME("(%p)->(%p): stub\n", This, ppEnum);
3851 return E_NOTIMPL;
3854 static const IConnectionPointVtbl ConnectionPointVtbl =
3856 ConnectionPoint_QueryInterface,
3857 ConnectionPoint_AddRef,
3858 ConnectionPoint_Release,
3859 ConnectionPoint_GetConnectionInterface,
3860 ConnectionPoint_GetConnectionPointContainer,
3861 ConnectionPoint_Advise,
3862 ConnectionPoint_Unadvise,
3863 ConnectionPoint_EnumConnections
3866 static void ConnectionPoint_Init(ConnectionPoint *cp, ScriptControl *sc, REFIID riid)
3868 cp->IConnectionPoint_iface.lpVtbl = &ConnectionPointVtbl;
3869 cp->control = sc;
3870 cp->riid = riid;
3872 cp->next = sc->cp_list;
3873 sc->cp_list = cp;
3876 static HRESULT WINAPI ScriptControl_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
3878 ScriptControl *script_control;
3879 DWORD dpi_x, dpi_y;
3880 HRESULT hres;
3881 HDC hdc;
3883 TRACE("(%p %s %p)\n", outer, debugstr_guid(riid), ppv);
3885 script_control = heap_alloc_zero(sizeof(*script_control));
3886 if(!script_control)
3887 return E_OUTOFMEMORY;
3889 script_control->error = heap_alloc_zero(sizeof(*script_control->error));
3890 if(!script_control->error)
3892 heap_free(script_control);
3893 return E_OUTOFMEMORY;
3896 script_control->IScriptControl_iface.lpVtbl = &ScriptControlVtbl;
3897 script_control->IPersistStreamInit_iface.lpVtbl = &PersistStreamInitVtbl;
3898 script_control->IOleObject_iface.lpVtbl = &OleObjectVtbl;
3899 script_control->IOleControl_iface.lpVtbl = &OleControlVtbl;
3900 script_control->IQuickActivate_iface.lpVtbl = &QuickActivateVtbl;
3901 script_control->IViewObjectEx_iface.lpVtbl = &ViewObjectExVtbl;
3902 script_control->IPointerInactive_iface.lpVtbl = &PointerInactiveVtbl;
3903 script_control->IConnectionPointContainer_iface.lpVtbl = &ConnectionPointContainerVtbl;
3904 script_control->IScriptModuleCollection_iface.lpVtbl = &ScriptModuleCollectionVtbl;
3905 script_control->ref = 1;
3906 script_control->timeout = 10000;
3907 script_control->allow_ui = VARIANT_TRUE;
3908 script_control->use_safe_subset = VARIANT_FALSE;
3910 script_control->error->IScriptError_iface.lpVtbl = &ScriptErrorVtbl;
3911 script_control->error->ref = 1;
3913 ConnectionPoint_Init(&script_control->cp_scsource, script_control, &DIID_DScriptControlSource);
3914 ConnectionPoint_Init(&script_control->cp_propnotif, script_control, &IID_IPropertyNotifySink);
3916 hdc = GetDC(0);
3917 dpi_x = GetDeviceCaps(hdc, LOGPIXELSX);
3918 dpi_y = GetDeviceCaps(hdc, LOGPIXELSY);
3919 ReleaseDC(0, hdc);
3921 script_control->extent.cx = MulDiv(38, 2540, dpi_x);
3922 script_control->extent.cy = MulDiv(38, 2540, dpi_y);
3924 hres = IScriptControl_QueryInterface(&script_control->IScriptControl_iface, riid, ppv);
3925 IScriptControl_Release(&script_control->IScriptControl_iface);
3926 return hres;
3929 /******************************************************************
3930 * DllMain (msscript.ocx.@)
3932 BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
3934 TRACE("(%p %d %p)\n", instance, reason, reserved);
3936 switch(reason) {
3937 case DLL_WINE_PREATTACH:
3938 return FALSE; /* prefer native version */
3939 case DLL_PROCESS_ATTACH:
3940 msscript_instance = instance;
3941 DisableThreadLibraryCalls(instance);
3942 break;
3943 case DLL_PROCESS_DETACH:
3944 if(!reserved)
3945 release_typelib();
3946 break;
3949 return TRUE;
3952 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
3954 *ppv = NULL;
3956 if(IsEqualGUID(&IID_IUnknown, riid)) {
3957 TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
3958 *ppv = iface;
3959 }else if(IsEqualGUID(&IID_IClassFactory, riid)) {
3960 TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv);
3961 *ppv = iface;
3964 if(*ppv) {
3965 IUnknown_AddRef((IUnknown*)*ppv);
3966 return S_OK;
3969 WARN("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
3970 return E_NOINTERFACE;
3973 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
3975 TRACE("(%p)\n", iface);
3976 return 2;
3979 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
3981 TRACE("(%p)\n", iface);
3982 return 1;
3985 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock)
3987 TRACE("(%p)->(%x)\n", iface, fLock);
3988 return S_OK;
3991 static const IClassFactoryVtbl ScriptControlFactoryVtbl = {
3992 ClassFactory_QueryInterface,
3993 ClassFactory_AddRef,
3994 ClassFactory_Release,
3995 ScriptControl_CreateInstance,
3996 ClassFactory_LockServer
3999 static IClassFactory ScriptControlFactory = { &ScriptControlFactoryVtbl };
4001 /***********************************************************************
4002 * DllGetClassObject (msscript.ocx.@)
4004 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
4006 if(IsEqualGUID(&CLSID_ScriptControl, rclsid)) {
4007 TRACE("(CLSID_ScriptControl %s %p)\n", debugstr_guid(riid), ppv);
4008 return IClassFactory_QueryInterface(&ScriptControlFactory, riid, ppv);
4011 FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
4012 return CLASS_E_CLASSNOTAVAILABLE;
4015 /***********************************************************************
4016 * DllCanUnloadNow (msscript.ocx.@)
4018 HRESULT WINAPI DllCanUnloadNow(void)
4020 TRACE("\n");
4021 return S_FALSE;
4024 /***********************************************************************
4025 * DllRegisterServer (msscript.ocx.@)
4027 HRESULT WINAPI DllRegisterServer(void)
4029 TRACE("()\n");
4030 return __wine_register_resources(msscript_instance);
4033 /***********************************************************************
4034 * DllUnregisterServer (msscript.ocx.@)
4036 HRESULT WINAPI DllUnregisterServer(void)
4038 TRACE("()\n");
4039 return __wine_unregister_resources(msscript_instance);