msscript.ocx: Implement IScriptError::get_Number.
[wine.git] / dlls / msscript.ocx / msscript.c
blob0b316afa8958cac1c9babceb4f514be6a1ae78ec
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;
129 BOOLEAN info_filled;
130 } ScriptError;
132 struct ScriptHost {
133 IActiveScriptSite IActiveScriptSite_iface;
134 IActiveScriptSiteWindow IActiveScriptSiteWindow_iface;
135 IServiceProvider IServiceProvider_iface;
136 LONG ref;
138 IActiveScript *script;
139 IActiveScriptParse *parse;
140 ScriptError *error;
141 SCRIPTSTATE script_state;
142 CLSID clsid;
144 unsigned int module_count;
145 struct list named_items;
148 struct ScriptControl {
149 IScriptControl IScriptControl_iface;
150 IPersistStreamInit IPersistStreamInit_iface;
151 IOleObject IOleObject_iface;
152 IOleControl IOleControl_iface;
153 IQuickActivate IQuickActivate_iface;
154 IViewObjectEx IViewObjectEx_iface;
155 IPointerInactive IPointerInactive_iface;
156 IConnectionPointContainer IConnectionPointContainer_iface;
157 LONG ref;
158 IOleClientSite *site;
159 SIZEL extent;
160 LONG timeout;
161 VARIANT_BOOL allow_ui;
162 VARIANT_BOOL use_safe_subset;
164 /* connection points */
165 ConnectionPoint *cp_list;
166 ConnectionPoint cp_scsource;
167 ConnectionPoint cp_propnotif;
169 /* IViewObject sink */
170 IAdviseSink *view_sink;
171 DWORD view_sink_flags;
173 /* modules */
174 ScriptModule **modules;
175 IScriptModuleCollection IScriptModuleCollection_iface;
177 ScriptHost *host;
178 ScriptError *error;
181 static HINSTANCE msscript_instance;
183 typedef enum tid_t {
184 IScriptControl_tid,
185 IScriptError_tid,
186 IScriptModuleCollection_tid,
187 IScriptModule_tid,
188 IScriptProcedureCollection_tid,
189 IScriptProcedure_tid,
190 LAST_tid
191 } tid_t;
193 static ITypeLib *typelib;
194 static ITypeInfo *typeinfos[LAST_tid];
196 static REFIID tid_ids[] = {
197 &IID_IScriptControl,
198 &IID_IScriptError,
199 &IID_IScriptModuleCollection,
200 &IID_IScriptModule,
201 &IID_IScriptProcedureCollection,
202 &IID_IScriptProcedure
205 static HRESULT load_typelib(void)
207 HRESULT hres;
208 ITypeLib *tl;
210 hres = LoadRegTypeLib(&LIBID_MSScriptControl, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl);
211 if(FAILED(hres)) {
212 ERR("LoadRegTypeLib failed: %08x\n", hres);
213 return hres;
216 if(InterlockedCompareExchangePointer((void**)&typelib, tl, NULL))
217 ITypeLib_Release(tl);
218 return hres;
221 static HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo)
223 HRESULT hres;
225 if (!typelib)
226 hres = load_typelib();
227 if (!typelib)
228 return hres;
230 if(!typeinfos[tid]) {
231 ITypeInfo *ti;
233 hres = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti);
234 if(FAILED(hres)) {
235 ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hres);
236 return hres;
239 if(InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL))
240 ITypeInfo_Release(ti);
243 *typeinfo = typeinfos[tid];
244 ITypeInfo_AddRef(typeinfos[tid]);
245 return S_OK;
248 static void release_typelib(void)
250 unsigned i;
252 if(!typelib)
253 return;
255 for(i = 0; i < ARRAY_SIZE(typeinfos); i++)
256 if(typeinfos[i])
257 ITypeInfo_Release(typeinfos[i]);
259 ITypeLib_Release(typelib);
262 static inline BOOL is_power_of_2(unsigned x)
264 return !(x & (x - 1));
267 static void clear_named_items(ScriptHost *host)
269 struct named_item *item, *item1;
270 LIST_FOR_EACH_ENTRY_SAFE(item, item1, &host->named_items, struct named_item, entry) {
271 list_remove(&item->entry);
272 SysFreeString(item->name);
273 IDispatch_Release(item->disp);
274 heap_free(item);
278 static struct named_item *host_get_named_item(ScriptHost *host, const WCHAR *nameW)
280 struct named_item *item;
282 LIST_FOR_EACH_ENTRY(item, &host->named_items, struct named_item, entry) {
283 if (!wcscmp(item->name, nameW))
284 return item;
287 return NULL;
290 static HRESULT get_script_dispatch(ScriptModule *module, IDispatch **disp)
292 if (!module->script_dispatch)
294 HRESULT hr = IActiveScript_GetScriptDispatch(module->host->script,
295 module->name, &module->script_dispatch);
296 if (FAILED(hr)) return hr;
298 *disp = module->script_dispatch;
299 return S_OK;
302 static HRESULT get_script_typeinfo(ScriptModule *module, ITypeInfo **typeinfo)
304 IDispatch *disp;
305 HRESULT hr;
307 if (!module->script_typeinfo)
309 hr = get_script_dispatch(module, &disp);
310 if (FAILED(hr)) return hr;
312 hr = IDispatch_GetTypeInfo(disp, 0, LOCALE_USER_DEFAULT, &module->script_typeinfo);
313 if (FAILED(hr)) return hr;
315 *typeinfo = module->script_typeinfo;
316 return S_OK;
319 static HRESULT get_script_typecomp(ScriptModule *module, ITypeInfo *typeinfo, ITypeComp **typecomp)
321 HRESULT hr;
323 if (!module->script_typecomp)
325 hr = ITypeInfo_QueryInterface(typeinfo, &IID_ITypeComp, (void**)&module->script_typecomp);
326 if (FAILED(hr)) return hr;
328 *typecomp = module->script_typecomp;
329 return S_OK;
332 static void uncache_module_objects(ScriptModule *module)
334 if (module->script_dispatch)
336 IDispatch_Release(module->script_dispatch);
337 module->script_dispatch = NULL;
339 if (module->script_typeinfo)
341 ITypeInfo_Release(module->script_typeinfo);
342 module->script_typeinfo = NULL;
344 if (module->script_typecomp)
346 ITypeComp_Release(module->script_typecomp);
347 module->script_typecomp = NULL;
349 if (module->procedures)
350 module->procedures->count = -1;
353 static HRESULT set_script_state(ScriptHost *host, SCRIPTSTATE state)
355 HRESULT hr;
357 hr = IActiveScript_SetScriptState(host->script, state);
358 if (SUCCEEDED(hr))
359 host->script_state = state;
360 return hr;
363 static HRESULT start_script(ScriptHost *host)
365 HRESULT hr = S_OK;
367 if (host->script_state != SCRIPTSTATE_STARTED)
368 hr = set_script_state(host, SCRIPTSTATE_STARTED);
370 return hr;
373 static HRESULT add_script_object(ScriptHost *host, BSTR name, IDispatch *object, DWORD flags)
375 struct named_item *item;
376 HRESULT hr;
378 if (host_get_named_item(host, name))
379 return E_INVALIDARG;
381 item = heap_alloc(sizeof(*item));
382 if (!item)
383 return E_OUTOFMEMORY;
385 item->name = SysAllocString(name);
386 if (!item->name)
388 heap_free(item);
389 return E_OUTOFMEMORY;
391 IDispatch_AddRef(item->disp = object);
392 list_add_tail(&host->named_items, &item->entry);
394 hr = IActiveScript_AddNamedItem(host->script, name, flags);
395 if (FAILED(hr))
397 list_remove(&item->entry);
398 IDispatch_Release(item->disp);
399 SysFreeString(item->name);
400 heap_free(item);
401 return hr;
404 return hr;
407 static HRESULT parse_script_text(ScriptModule *module, BSTR script_text, DWORD flag, VARIANT *res)
409 EXCEPINFO excepinfo;
410 HRESULT hr;
412 hr = start_script(module->host);
413 if (FAILED(hr)) return hr;
415 uncache_module_objects(module);
417 hr = IActiveScriptParse_ParseScriptText(module->host->parse, script_text, module->name,
418 NULL, NULL, 0, 1, flag, res, &excepinfo);
419 /* FIXME: more error handling */
420 return hr;
423 static HRESULT run_procedure(ScriptModule *module, BSTR procedure_name, SAFEARRAY *args, VARIANT *res)
425 IDispatchEx *dispex;
426 IDispatch *disp;
427 DISPPARAMS dp;
428 DISPID dispid;
429 HRESULT hr;
430 UINT i;
432 hr = start_script(module->host);
433 if (FAILED(hr)) return hr;
435 hr = get_script_dispatch(module, &disp);
436 if (FAILED(hr)) return hr;
438 hr = IDispatch_GetIDsOfNames(disp, &IID_NULL, &procedure_name, 1, LOCALE_USER_DEFAULT, &dispid);
439 if (FAILED(hr)) return hr;
441 dp.cArgs = args->rgsabound[0].cElements;
442 dp.rgdispidNamedArgs = NULL;
443 dp.cNamedArgs = 0;
444 dp.rgvarg = heap_alloc(dp.cArgs * sizeof(*dp.rgvarg));
445 if (!dp.rgvarg) return E_OUTOFMEMORY;
447 hr = SafeArrayLock(args);
448 if (SUCCEEDED(hr))
450 /* The DISPPARAMS are stored in reverse order */
451 for (i = 0; i < dp.cArgs; i++)
452 dp.rgvarg[i] = *(VARIANT*)((char*)(args->pvData) + (dp.cArgs - i - 1) * args->cbElements);
453 SafeArrayUnlock(args);
455 hr = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
456 if (FAILED(hr))
458 hr = IDispatch_Invoke(disp, dispid, &IID_NULL, LOCALE_USER_DEFAULT,
459 DISPATCH_METHOD, &dp, res, NULL, NULL);
461 else
463 hr = IDispatchEx_InvokeEx(dispex, dispid, LOCALE_USER_DEFAULT,
464 DISPATCH_METHOD, &dp, res, NULL, NULL);
465 IDispatchEx_Release(dispex);
468 heap_free(dp.rgvarg);
470 return hr;
473 static inline ScriptControl *impl_from_IScriptControl(IScriptControl *iface)
475 return CONTAINING_RECORD(iface, ScriptControl, IScriptControl_iface);
478 static inline ScriptControl *impl_from_IOleObject(IOleObject *iface)
480 return CONTAINING_RECORD(iface, ScriptControl, IOleObject_iface);
483 static inline ScriptControl *impl_from_IPersistStreamInit(IPersistStreamInit *iface)
485 return CONTAINING_RECORD(iface, ScriptControl, IPersistStreamInit_iface);
488 static inline ScriptControl *impl_from_IOleControl(IOleControl *iface)
490 return CONTAINING_RECORD(iface, ScriptControl, IOleControl_iface);
493 static inline ScriptControl *impl_from_IQuickActivate(IQuickActivate *iface)
495 return CONTAINING_RECORD(iface, ScriptControl, IQuickActivate_iface);
498 static inline ScriptControl *impl_from_IViewObjectEx(IViewObjectEx *iface)
500 return CONTAINING_RECORD(iface, ScriptControl, IViewObjectEx_iface);
503 static inline ScriptControl *impl_from_IPointerInactive(IPointerInactive *iface)
505 return CONTAINING_RECORD(iface, ScriptControl, IPointerInactive_iface);
508 static inline ScriptControl *impl_from_IConnectionPointContainer(IConnectionPointContainer *iface)
510 return CONTAINING_RECORD(iface, ScriptControl, IConnectionPointContainer_iface);
513 static inline ScriptProcedure *impl_from_IScriptProcedure(IScriptProcedure *iface)
515 return CONTAINING_RECORD(iface, ScriptProcedure, IScriptProcedure_iface);
518 static inline ScriptProcedureCollection *impl_from_IScriptProcedureCollection(IScriptProcedureCollection *iface)
520 return CONTAINING_RECORD(iface, ScriptProcedureCollection, IScriptProcedureCollection_iface);
523 static inline ScriptControl *impl_from_IScriptModuleCollection(IScriptModuleCollection *iface)
525 return CONTAINING_RECORD(iface, ScriptControl, IScriptModuleCollection_iface);
528 static inline ScriptModule *impl_from_IScriptModule(IScriptModule *iface)
530 return CONTAINING_RECORD(iface, ScriptModule, IScriptModule_iface);
533 static inline ScriptError *impl_from_IScriptError(IScriptError *iface)
535 return CONTAINING_RECORD(iface, ScriptError, IScriptError_iface);
538 static inline ConnectionPoint *impl_from_IConnectionPoint(IConnectionPoint *iface)
540 return CONTAINING_RECORD(iface, ConnectionPoint, IConnectionPoint_iface);
543 static inline ScriptHost *impl_from_IActiveScriptSite(IActiveScriptSite *iface)
545 return CONTAINING_RECORD(iface, ScriptHost, IActiveScriptSite_iface);
548 static inline ScriptHost *impl_from_IActiveScriptSiteWindow(IActiveScriptSiteWindow *iface)
550 return CONTAINING_RECORD(iface, ScriptHost, IActiveScriptSiteWindow_iface);
553 static inline ScriptHost *impl_from_IServiceProvider(IServiceProvider *iface)
555 return CONTAINING_RECORD(iface, ScriptHost, IServiceProvider_iface);
558 static inline struct module_enum *module_enum_from_IEnumVARIANT(IEnumVARIANT *iface)
560 return CONTAINING_RECORD(iface, struct module_enum, IEnumVARIANT_iface);
563 static inline struct procedure_enum *procedure_enum_from_IEnumVARIANT(IEnumVARIANT *iface)
565 return CONTAINING_RECORD(iface, struct procedure_enum, IEnumVARIANT_iface);
568 /* IActiveScriptSite */
569 static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
571 ScriptHost *This = impl_from_IActiveScriptSite(iface);
573 if(IsEqualGUID(&IID_IUnknown, riid)) {
574 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
575 *ppv = &This->IActiveScriptSite_iface;
576 }else if(IsEqualGUID(&IID_IActiveScriptSite, riid)) {
577 TRACE("(%p)->(IID_IActiveScriptSite %p)\n", This, ppv);
578 *ppv = &This->IActiveScriptSite_iface;
579 }else if(IsEqualGUID(&IID_IActiveScriptSiteWindow, riid)) {
580 TRACE("(%p)->(IID_IActiveScriptSiteWindow %p)\n", This, ppv);
581 *ppv = &This->IActiveScriptSiteWindow_iface;
582 }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
583 TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
584 *ppv = &This->IServiceProvider_iface;
585 }else {
586 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
587 *ppv = NULL;
588 return E_NOINTERFACE;
591 IUnknown_AddRef((IUnknown*)*ppv);
592 return S_OK;
595 static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
597 ScriptHost *This = impl_from_IActiveScriptSite(iface);
598 LONG ref = InterlockedIncrement(&This->ref);
600 TRACE("(%p) ref=%d\n", This, ref);
602 return ref;
605 static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
607 ScriptHost *This = impl_from_IActiveScriptSite(iface);
608 LONG ref = InterlockedDecrement(&This->ref);
610 TRACE("(%p) ref=%d\n", This, ref);
612 if(!ref) {
613 clear_named_items(This);
614 heap_free(This);
617 return ref;
620 static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *lcid)
622 ScriptHost *This = impl_from_IActiveScriptSite(iface);
624 TRACE("(%p, %p)\n", This, lcid);
626 *lcid = GetUserDefaultLCID();
627 return S_OK;
630 static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR name, DWORD mask,
631 IUnknown **unk, ITypeInfo **ti)
633 ScriptHost *This = impl_from_IActiveScriptSite(iface);
634 struct named_item *item;
636 TRACE("(%p, %s, %#x, %p, %p)\n", This, debugstr_w(name), mask, unk, ti);
638 item = host_get_named_item(This, name);
639 if (!item)
640 return TYPE_E_ELEMENTNOTFOUND;
642 if (mask != SCRIPTINFO_IUNKNOWN) {
643 FIXME("mask %#x is not supported\n", mask);
644 return E_NOTIMPL;
647 *unk = (IUnknown*)item->disp;
648 IUnknown_AddRef(*unk);
650 return S_OK;
653 static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *version)
655 ScriptHost *This = impl_from_IActiveScriptSite(iface);
657 FIXME("(%p, %p)\n", This, version);
659 return E_NOTIMPL;
662 static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface, const VARIANT *result,
663 const EXCEPINFO *ei)
665 ScriptHost *This = impl_from_IActiveScriptSite(iface);
667 FIXME("(%p, %s, %p)\n", This, debugstr_variant(result), ei);
669 return E_NOTIMPL;
672 static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE state)
674 ScriptHost *This = impl_from_IActiveScriptSite(iface);
676 FIXME("(%p, %d)\n", This, state);
678 return E_NOTIMPL;
681 static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *script_error)
683 ScriptHost *This = impl_from_IActiveScriptSite(iface);
685 TRACE("(%p, %p)\n", This, script_error);
687 if (This->error)
689 IScriptError_Clear(&This->error->IScriptError_iface);
690 IActiveScriptError_AddRef(script_error);
691 This->error->object = script_error;
693 return S_FALSE;
696 static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
698 ScriptHost *This = impl_from_IActiveScriptSite(iface);
700 FIXME("(%p)\n", This);
702 return E_NOTIMPL;
705 static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
707 ScriptHost *This = impl_from_IActiveScriptSite(iface);
709 FIXME("(%p)\n", This);
711 return E_NOTIMPL;
714 static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
715 ActiveScriptSite_QueryInterface,
716 ActiveScriptSite_AddRef,
717 ActiveScriptSite_Release,
718 ActiveScriptSite_GetLCID,
719 ActiveScriptSite_GetItemInfo,
720 ActiveScriptSite_GetDocVersionString,
721 ActiveScriptSite_OnScriptTerminate,
722 ActiveScriptSite_OnStateChange,
723 ActiveScriptSite_OnScriptError,
724 ActiveScriptSite_OnEnterScript,
725 ActiveScriptSite_OnLeaveScript
728 /* IActiveScriptSiteWindow */
729 static HRESULT WINAPI ActiveScriptSiteWindow_QueryInterface(IActiveScriptSiteWindow *iface, REFIID riid, void **obj)
731 ScriptHost *This = impl_from_IActiveScriptSiteWindow(iface);
732 return IActiveScriptSite_QueryInterface(&This->IActiveScriptSite_iface, riid, obj);
735 static ULONG WINAPI ActiveScriptSiteWindow_AddRef(IActiveScriptSiteWindow *iface)
737 ScriptHost *This = impl_from_IActiveScriptSiteWindow(iface);
738 return IActiveScriptSite_AddRef(&This->IActiveScriptSite_iface);
741 static ULONG WINAPI ActiveScriptSiteWindow_Release(IActiveScriptSiteWindow *iface)
743 ScriptHost *This = impl_from_IActiveScriptSiteWindow(iface);
744 return IActiveScriptSite_Release(&This->IActiveScriptSite_iface);
747 static HRESULT WINAPI ActiveScriptSiteWindow_GetWindow(IActiveScriptSiteWindow *iface, HWND *hwnd)
749 ScriptHost *This = impl_from_IActiveScriptSiteWindow(iface);
751 FIXME("(%p, %p)\n", This, hwnd);
753 return E_NOTIMPL;
756 static HRESULT WINAPI ActiveScriptSiteWindow_EnableModeless(IActiveScriptSiteWindow *iface, BOOL enable)
758 ScriptHost *This = impl_from_IActiveScriptSiteWindow(iface);
760 FIXME("(%p, %d)\n", This, enable);
762 return E_NOTIMPL;
765 static const IActiveScriptSiteWindowVtbl ActiveScriptSiteWindowVtbl = {
766 ActiveScriptSiteWindow_QueryInterface,
767 ActiveScriptSiteWindow_AddRef,
768 ActiveScriptSiteWindow_Release,
769 ActiveScriptSiteWindow_GetWindow,
770 ActiveScriptSiteWindow_EnableModeless
773 /* IServiceProvider */
774 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **obj)
776 ScriptHost *This = impl_from_IServiceProvider(iface);
777 return IActiveScriptSite_QueryInterface(&This->IActiveScriptSite_iface, riid, obj);
780 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
782 ScriptHost *This = impl_from_IServiceProvider(iface);
783 return IActiveScriptSite_AddRef(&This->IActiveScriptSite_iface);
786 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
788 ScriptHost *This = impl_from_IServiceProvider(iface);
789 return IActiveScriptSite_Release(&This->IActiveScriptSite_iface);
792 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface, REFGUID service,
793 REFIID riid, void **obj)
795 ScriptHost *This = impl_from_IServiceProvider(iface);
797 FIXME("(%p)->(%s %s %p)\n", This, debugstr_guid(service), debugstr_guid(riid), obj);
799 return E_NOTIMPL;
802 static const IServiceProviderVtbl ServiceProviderVtbl = {
803 ServiceProvider_QueryInterface,
804 ServiceProvider_AddRef,
805 ServiceProvider_Release,
806 ServiceProvider_QueryService
809 static HRESULT WINAPI ScriptProcedure_QueryInterface(IScriptProcedure *iface, REFIID riid, void **ppv)
811 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
813 if (IsEqualGUID(&IID_IDispatch, riid) || IsEqualGUID(&IID_IUnknown, riid) ||
814 IsEqualGUID(&IID_IScriptProcedure, riid))
816 *ppv = &This->IScriptProcedure_iface;
818 else
820 WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
821 *ppv = NULL;
822 return E_NOINTERFACE;
825 IUnknown_AddRef((IUnknown*)*ppv);
826 return S_OK;
829 static ULONG WINAPI ScriptProcedure_AddRef(IScriptProcedure *iface)
831 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
832 LONG ref = InterlockedIncrement(&This->ref);
834 TRACE("(%p) ref=%d\n", This, ref);
836 return ref;
839 static ULONG WINAPI ScriptProcedure_Release(IScriptProcedure *iface)
841 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
842 LONG ref = InterlockedDecrement(&This->ref);
844 TRACE("(%p) ref=%d\n", This, ref);
846 if (!ref)
848 list_remove(&This->entry);
849 SysFreeString(This->name);
850 heap_free(This);
852 return ref;
855 static HRESULT WINAPI ScriptProcedure_GetTypeInfoCount(IScriptProcedure *iface, UINT *pctinfo)
857 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
859 TRACE("(%p)->(%p)\n", This, pctinfo);
861 *pctinfo = 1;
862 return S_OK;
865 static HRESULT WINAPI ScriptProcedure_GetTypeInfo(IScriptProcedure *iface, UINT iTInfo,
866 LCID lcid, ITypeInfo **ppTInfo)
868 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
870 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
872 return get_typeinfo(IScriptProcedure_tid, ppTInfo);
875 static HRESULT WINAPI ScriptProcedure_GetIDsOfNames(IScriptProcedure *iface, REFIID riid,
876 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
878 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
879 ITypeInfo *typeinfo;
880 HRESULT hr;
882 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
884 hr = get_typeinfo(IScriptProcedure_tid, &typeinfo);
885 if (SUCCEEDED(hr))
887 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
888 ITypeInfo_Release(typeinfo);
891 return hr;
894 static HRESULT WINAPI ScriptProcedure_Invoke(IScriptProcedure *iface, DISPID dispIdMember,
895 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
896 EXCEPINFO *pExcepInfo, UINT *puArgErr)
898 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
899 ITypeInfo *typeinfo;
900 HRESULT hr;
902 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
903 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
905 hr = get_typeinfo(IScriptProcedure_tid, &typeinfo);
906 if(SUCCEEDED(hr))
908 hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
909 pDispParams, pVarResult, pExcepInfo, puArgErr);
910 ITypeInfo_Release(typeinfo);
913 return hr;
916 static HRESULT WINAPI ScriptProcedure_get_Name(IScriptProcedure *iface, BSTR *pbstrName)
918 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
920 TRACE("(%p)->(%p)\n", This, pbstrName);
922 if (!pbstrName) return E_POINTER;
924 *pbstrName = SysAllocString(This->name);
925 return *pbstrName ? S_OK : E_OUTOFMEMORY;
928 static HRESULT WINAPI ScriptProcedure_get_NumArgs(IScriptProcedure *iface, LONG *pcArgs)
930 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
932 TRACE("(%p)->(%p)\n", This, pcArgs);
934 if (!pcArgs) return E_POINTER;
936 *pcArgs = This->num_args;
937 return S_OK;
940 static HRESULT WINAPI ScriptProcedure_get_HasReturnValue(IScriptProcedure *iface, VARIANT_BOOL *pfHasReturnValue)
942 ScriptProcedure *This = impl_from_IScriptProcedure(iface);
944 TRACE("(%p)->(%p)\n", This, pfHasReturnValue);
946 if (!pfHasReturnValue) return E_POINTER;
948 *pfHasReturnValue = (This->ret_type == VT_VOID) ? VARIANT_FALSE : VARIANT_TRUE;
949 return S_OK;
952 static const IScriptProcedureVtbl ScriptProcedureVtbl = {
953 ScriptProcedure_QueryInterface,
954 ScriptProcedure_AddRef,
955 ScriptProcedure_Release,
956 ScriptProcedure_GetTypeInfoCount,
957 ScriptProcedure_GetTypeInfo,
958 ScriptProcedure_GetIDsOfNames,
959 ScriptProcedure_Invoke,
960 ScriptProcedure_get_Name,
961 ScriptProcedure_get_NumArgs,
962 ScriptProcedure_get_HasReturnValue
965 /* This function always releases the FUNCDESC passed in */
966 static HRESULT get_script_procedure(ScriptProcedureCollection *procedures, ITypeInfo *typeinfo,
967 FUNCDESC *desc, IScriptProcedure **procedure)
969 struct list *proc_list;
970 ScriptProcedure *proc;
971 ULONG hash;
972 HRESULT hr;
973 BSTR str;
974 UINT len;
976 hr = ITypeInfo_GetNames(typeinfo, desc->memid, &str, 1, &len);
977 if (FAILED(hr)) goto done;
979 len = SysStringLen(str);
980 hash = LHashValOfNameSys(sizeof(void*) == 8 ? SYS_WIN64 : SYS_WIN32, LOCALE_USER_DEFAULT, str);
981 proc_list = &procedures->hash_table[hash % ARRAY_SIZE(procedures->hash_table)];
983 /* Try to find it in the hash table */
984 LIST_FOR_EACH_ENTRY(proc, proc_list, ScriptProcedure, entry)
986 if (proc->hash == hash && SysStringLen(proc->name) == len &&
987 !memcmp(proc->name, str, len * sizeof(*str)))
989 SysFreeString(str);
990 IScriptProcedure_AddRef(&proc->IScriptProcedure_iface);
991 *procedure = &proc->IScriptProcedure_iface;
992 goto done;
996 if (!(proc = heap_alloc(sizeof(*proc))))
998 hr = E_OUTOFMEMORY;
999 SysFreeString(str);
1000 goto done;
1003 proc->IScriptProcedure_iface.lpVtbl = &ScriptProcedureVtbl;
1004 proc->ref = 1;
1005 proc->hash = hash;
1006 proc->name = str;
1007 proc->num_args = desc->cParams + desc->cParamsOpt;
1008 proc->ret_type = desc->elemdescFunc.tdesc.vt;
1009 list_add_tail(proc_list, &proc->entry);
1011 *procedure = &proc->IScriptProcedure_iface;
1013 done:
1014 ITypeInfo_ReleaseFuncDesc(typeinfo, desc);
1015 return hr;
1018 static HRESULT WINAPI procedure_enum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv)
1020 struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
1022 if (IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IEnumVARIANT, riid))
1024 *ppv = &This->IEnumVARIANT_iface;
1026 else
1028 WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
1029 *ppv = NULL;
1030 return E_NOINTERFACE;
1033 IUnknown_AddRef((IUnknown*)*ppv);
1034 return S_OK;
1037 static ULONG WINAPI procedure_enum_AddRef(IEnumVARIANT *iface)
1039 struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
1040 LONG ref = InterlockedIncrement(&This->ref);
1042 TRACE("(%p) ref=%d\n", This, ref);
1044 return ref;
1047 static ULONG WINAPI procedure_enum_Release(IEnumVARIANT *iface)
1049 struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
1050 LONG ref = InterlockedDecrement(&This->ref);
1052 TRACE("(%p) ref=%d\n", This, ref);
1054 if (!ref)
1056 IScriptProcedureCollection_Release(&This->procedures->IScriptProcedureCollection_iface);
1057 heap_free(This);
1060 return ref;
1063 static HRESULT WINAPI procedure_enum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
1065 struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
1066 FUNCDESC *desc;
1067 ITypeInfo *ti;
1068 UINT i, num;
1069 HRESULT hr;
1071 TRACE("(%p)->(%u %p %p)\n", This, celt, rgVar, pCeltFetched);
1073 if (!rgVar) return E_POINTER;
1074 if (!This->procedures->module->host) return E_FAIL;
1076 hr = start_script(This->procedures->module->host);
1077 if (FAILED(hr)) return hr;
1079 hr = get_script_typeinfo(This->procedures->module, &ti);
1080 if (FAILED(hr)) return hr;
1082 num = min(celt, This->count - This->pos);
1083 for (i = 0; i < num; i++)
1085 hr = ITypeInfo_GetFuncDesc(ti, This->pos + i, &desc);
1086 if (FAILED(hr)) break;
1088 hr = get_script_procedure(This->procedures, ti, desc, (IScriptProcedure**)&V_DISPATCH(rgVar + i));
1089 if (FAILED(hr)) break;
1091 V_VT(rgVar + i) = VT_DISPATCH;
1094 if (FAILED(hr))
1096 while (i--)
1097 VariantClear(rgVar + i);
1098 if (pCeltFetched) *pCeltFetched = 0;
1099 return hr;
1102 This->pos += i;
1104 if (pCeltFetched) *pCeltFetched = i;
1105 return i == celt ? S_OK : S_FALSE;
1108 static HRESULT WINAPI procedure_enum_Skip(IEnumVARIANT *iface, ULONG celt)
1110 struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
1112 TRACE("(%p)->(%u)\n", This, celt);
1114 if (This->count - This->pos < celt)
1116 This->pos = This->count;
1117 return S_FALSE;
1119 This->pos += celt;
1120 return S_OK;
1123 static HRESULT WINAPI procedure_enum_Reset(IEnumVARIANT *iface)
1125 struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
1127 TRACE("(%p)\n", This);
1129 This->pos = 0;
1130 return S_OK;
1133 static HRESULT WINAPI procedure_enum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
1135 struct procedure_enum *This = procedure_enum_from_IEnumVARIANT(iface);
1136 struct procedure_enum *clone;
1138 TRACE("(%p)->(%p)\n", This, ppEnum);
1140 if (!ppEnum) return E_POINTER;
1142 if (!(clone = heap_alloc(sizeof(*clone))))
1143 return E_OUTOFMEMORY;
1145 *clone = *This;
1146 clone->ref = 1;
1147 IScriptProcedureCollection_AddRef(&This->procedures->IScriptProcedureCollection_iface);
1149 *ppEnum = &clone->IEnumVARIANT_iface;
1150 return S_OK;
1153 static const IEnumVARIANTVtbl procedure_enum_vtbl = {
1154 procedure_enum_QueryInterface,
1155 procedure_enum_AddRef,
1156 procedure_enum_Release,
1157 procedure_enum_Next,
1158 procedure_enum_Skip,
1159 procedure_enum_Reset,
1160 procedure_enum_Clone
1163 static HRESULT WINAPI ScriptProcedureCollection_QueryInterface(IScriptProcedureCollection *iface, REFIID riid, void **ppv)
1165 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1167 if (IsEqualGUID(&IID_IDispatch, riid) || IsEqualGUID(&IID_IUnknown, riid) ||
1168 IsEqualGUID(&IID_IScriptProcedureCollection, riid))
1170 *ppv = &This->IScriptProcedureCollection_iface;
1172 else
1174 WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
1175 *ppv = NULL;
1176 return E_NOINTERFACE;
1179 IUnknown_AddRef((IUnknown*)*ppv);
1180 return S_OK;
1183 static ULONG WINAPI ScriptProcedureCollection_AddRef(IScriptProcedureCollection *iface)
1185 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1186 LONG ref = InterlockedIncrement(&This->ref);
1188 TRACE("(%p) ref=%d\n", This, ref);
1190 return ref;
1193 static ULONG WINAPI ScriptProcedureCollection_Release(IScriptProcedureCollection *iface)
1195 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1196 LONG ref = InterlockedDecrement(&This->ref);
1197 UINT i;
1199 TRACE("(%p) ref=%d\n", This, ref);
1201 if (!ref)
1203 /* Unlink any dangling items from the hash table */
1204 for (i = 0; i < ARRAY_SIZE(This->hash_table); i++)
1205 list_remove(&This->hash_table[i]);
1207 This->module->procedures = NULL;
1208 IScriptModule_Release(&This->module->IScriptModule_iface);
1209 heap_free(This);
1211 return ref;
1214 static HRESULT WINAPI ScriptProcedureCollection_GetTypeInfoCount(IScriptProcedureCollection *iface, UINT *pctinfo)
1216 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1218 TRACE("(%p)->(%p)\n", This, pctinfo);
1220 *pctinfo = 1;
1221 return S_OK;
1224 static HRESULT WINAPI ScriptProcedureCollection_GetTypeInfo(IScriptProcedureCollection *iface, UINT iTInfo,
1225 LCID lcid, ITypeInfo **ppTInfo)
1227 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1229 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
1231 return get_typeinfo(IScriptProcedureCollection_tid, ppTInfo);
1234 static HRESULT WINAPI ScriptProcedureCollection_GetIDsOfNames(IScriptProcedureCollection *iface, REFIID riid,
1235 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1237 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1238 ITypeInfo *typeinfo;
1239 HRESULT hr;
1241 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
1243 hr = get_typeinfo(IScriptProcedureCollection_tid, &typeinfo);
1244 if (SUCCEEDED(hr))
1246 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
1247 ITypeInfo_Release(typeinfo);
1250 return hr;
1253 static HRESULT WINAPI ScriptProcedureCollection_Invoke(IScriptProcedureCollection *iface, DISPID dispIdMember,
1254 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
1255 EXCEPINFO *pExcepInfo, UINT *puArgErr)
1257 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1258 ITypeInfo *typeinfo;
1259 HRESULT hr;
1261 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1262 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1264 hr = get_typeinfo(IScriptProcedureCollection_tid, &typeinfo);
1265 if(SUCCEEDED(hr))
1267 hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
1268 pDispParams, pVarResult, pExcepInfo, puArgErr);
1269 ITypeInfo_Release(typeinfo);
1272 return hr;
1275 static HRESULT WINAPI ScriptProcedureCollection_get__NewEnum(IScriptProcedureCollection *iface, IUnknown **ppenumProcedures)
1277 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1278 struct procedure_enum *proc_enum;
1279 TYPEATTR *attr;
1280 ITypeInfo *ti;
1281 UINT count;
1282 HRESULT hr;
1284 TRACE("(%p)->(%p)\n", This, ppenumProcedures);
1286 if (!ppenumProcedures) return E_POINTER;
1287 if (!This->module->host) return E_FAIL;
1289 hr = start_script(This->module->host);
1290 if (FAILED(hr)) return hr;
1292 hr = get_script_typeinfo(This->module, &ti);
1293 if (FAILED(hr)) return hr;
1295 hr = ITypeInfo_GetTypeAttr(ti, &attr);
1296 if (FAILED(hr)) return hr;
1298 count = attr->cFuncs;
1299 ITypeInfo_ReleaseTypeAttr(ti, attr);
1301 if (!(proc_enum = heap_alloc(sizeof(*proc_enum))))
1302 return E_OUTOFMEMORY;
1304 proc_enum->IEnumVARIANT_iface.lpVtbl = &procedure_enum_vtbl;
1305 proc_enum->ref = 1;
1306 proc_enum->pos = 0;
1307 proc_enum->count = count;
1308 proc_enum->procedures = This;
1309 IScriptProcedureCollection_AddRef(&This->IScriptProcedureCollection_iface);
1311 *ppenumProcedures = (IUnknown*)&proc_enum->IEnumVARIANT_iface;
1312 return S_OK;
1315 static HRESULT WINAPI ScriptProcedureCollection_get_Item(IScriptProcedureCollection *iface, VARIANT index,
1316 IScriptProcedure **ppdispProcedure)
1318 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1319 ITypeInfo *typeinfo;
1320 FUNCDESC *desc;
1321 HRESULT hr;
1323 TRACE("(%p)->(%s %p)\n", This, wine_dbgstr_variant(&index), ppdispProcedure);
1325 if (!ppdispProcedure) return E_POINTER;
1326 if (!This->module->host) return E_FAIL;
1328 hr = start_script(This->module->host);
1329 if (FAILED(hr)) return hr;
1331 hr = get_script_typeinfo(This->module, &typeinfo);
1332 if (FAILED(hr)) return hr;
1334 if (V_VT(&index) == VT_BSTR)
1336 struct list *proc_list;
1337 ScriptProcedure *proc;
1338 ITypeComp *comp;
1339 BINDPTR bindptr;
1340 DESCKIND kind;
1341 ULONG hash;
1342 UINT len;
1344 len = SysStringLen(V_BSTR(&index));
1345 hash = LHashValOfNameSys(sizeof(void*) == 8 ? SYS_WIN64 : SYS_WIN32, LOCALE_USER_DEFAULT, V_BSTR(&index));
1346 proc_list = &This->hash_table[hash % ARRAY_SIZE(This->hash_table)];
1348 /* Try to find it in the hash table */
1349 LIST_FOR_EACH_ENTRY(proc, proc_list, ScriptProcedure, entry)
1351 if (proc->hash == hash && SysStringLen(proc->name) == len &&
1352 !memcmp(proc->name, V_BSTR(&index), len * sizeof(WCHAR)))
1354 IScriptProcedure_AddRef(&proc->IScriptProcedure_iface);
1355 *ppdispProcedure = &proc->IScriptProcedure_iface;
1356 return S_OK;
1360 hr = get_script_typecomp(This->module, typeinfo, &comp);
1361 if (FAILED(hr)) return hr;
1363 hr = ITypeComp_Bind(comp, V_BSTR(&index), hash, INVOKE_FUNC, &typeinfo, &kind, &bindptr);
1364 if (FAILED(hr)) return hr;
1366 switch (kind)
1368 case DESCKIND_FUNCDESC:
1369 hr = get_script_procedure(This, typeinfo, bindptr.lpfuncdesc, ppdispProcedure);
1370 ITypeInfo_Release(typeinfo);
1371 return hr;
1372 case DESCKIND_IMPLICITAPPOBJ:
1373 case DESCKIND_VARDESC:
1374 ITypeInfo_ReleaseVarDesc(typeinfo, bindptr.lpvardesc);
1375 ITypeInfo_Release(typeinfo);
1376 break;
1377 case DESCKIND_TYPECOMP:
1378 ITypeComp_Release(bindptr.lptcomp);
1379 break;
1380 default:
1381 break;
1383 return CTL_E_ILLEGALFUNCTIONCALL;
1386 hr = VariantChangeType(&index, &index, 0, VT_INT);
1387 if (FAILED(hr)) return hr;
1388 if (V_INT(&index) <= 0) return 0x800a0009;
1390 hr = ITypeInfo_GetFuncDesc(typeinfo, V_INT(&index) - 1, &desc);
1391 if (FAILED(hr)) return hr;
1393 return get_script_procedure(This, typeinfo, desc, ppdispProcedure);
1396 static HRESULT WINAPI ScriptProcedureCollection_get_Count(IScriptProcedureCollection *iface, LONG *plCount)
1398 ScriptProcedureCollection *This = impl_from_IScriptProcedureCollection(iface);
1399 TYPEATTR *attr;
1400 ITypeInfo *ti;
1401 HRESULT hr;
1403 TRACE("(%p)->(%p)\n", This, plCount);
1405 if (!plCount) return E_POINTER;
1406 if (!This->module->host) return E_FAIL;
1408 hr = start_script(This->module->host);
1409 if (FAILED(hr)) return hr;
1411 if (This->count == -1)
1413 hr = get_script_typeinfo(This->module, &ti);
1414 if (FAILED(hr)) return hr;
1416 hr = ITypeInfo_GetTypeAttr(ti, &attr);
1417 if (FAILED(hr)) return hr;
1419 This->count = attr->cFuncs;
1420 ITypeInfo_ReleaseTypeAttr(ti, attr);
1423 *plCount = This->count;
1424 return S_OK;
1427 static const IScriptProcedureCollectionVtbl ScriptProcedureCollectionVtbl = {
1428 ScriptProcedureCollection_QueryInterface,
1429 ScriptProcedureCollection_AddRef,
1430 ScriptProcedureCollection_Release,
1431 ScriptProcedureCollection_GetTypeInfoCount,
1432 ScriptProcedureCollection_GetTypeInfo,
1433 ScriptProcedureCollection_GetIDsOfNames,
1434 ScriptProcedureCollection_Invoke,
1435 ScriptProcedureCollection_get__NewEnum,
1436 ScriptProcedureCollection_get_Item,
1437 ScriptProcedureCollection_get_Count
1440 static void detach_script_host(ScriptHost *host)
1442 if (--host->module_count)
1443 return;
1445 if (host->script) {
1446 IActiveScript_Close(host->script);
1447 IActiveScript_Release(host->script);
1450 if (host->parse)
1451 IActiveScriptParse_Release(host->parse);
1453 if (host->error)
1454 IScriptError_Release(&host->error->IScriptError_iface);
1456 host->parse = NULL;
1457 host->error = NULL;
1458 host->script = NULL;
1461 static void detach_module(ScriptModule *module)
1463 ScriptHost *host = module->host;
1465 if (host) {
1466 module->host = NULL;
1467 detach_script_host(host);
1468 IActiveScriptSite_Release(&host->IActiveScriptSite_iface);
1472 static HRESULT WINAPI ScriptModule_QueryInterface(IScriptModule *iface, REFIID riid, void **ppv)
1474 ScriptModule *This = impl_from_IScriptModule(iface);
1476 if (IsEqualGUID(&IID_IDispatch, riid) || IsEqualGUID(&IID_IUnknown, riid) ||
1477 IsEqualGUID(&IID_IScriptModule, riid))
1479 *ppv = &This->IScriptModule_iface;
1481 else
1483 WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
1484 *ppv = NULL;
1485 return E_NOINTERFACE;
1488 IUnknown_AddRef((IUnknown*)*ppv);
1489 return S_OK;
1492 static ULONG WINAPI ScriptModule_AddRef(IScriptModule *iface)
1494 ScriptModule *This = impl_from_IScriptModule(iface);
1495 LONG ref = InterlockedIncrement(&This->ref);
1497 TRACE("(%p) ref=%d\n", This, ref);
1499 return ref;
1502 static ULONG WINAPI ScriptModule_Release(IScriptModule *iface)
1504 ScriptModule *This = impl_from_IScriptModule(iface);
1505 LONG ref = InterlockedDecrement(&This->ref);
1507 TRACE("(%p) ref=%d\n", This, ref);
1509 if (!ref)
1511 detach_module(This);
1512 SysFreeString(This->name);
1513 uncache_module_objects(This);
1514 heap_free(This);
1517 return ref;
1520 static HRESULT WINAPI ScriptModule_GetTypeInfoCount(IScriptModule *iface, UINT *pctinfo)
1522 ScriptModule *This = impl_from_IScriptModule(iface);
1524 TRACE("(%p)->(%p)\n", This, pctinfo);
1526 *pctinfo = 1;
1527 return S_OK;
1530 static HRESULT WINAPI ScriptModule_GetTypeInfo(IScriptModule *iface, UINT iTInfo,
1531 LCID lcid, ITypeInfo **ppTInfo)
1533 ScriptModule *This = impl_from_IScriptModule(iface);
1535 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
1537 return get_typeinfo(IScriptModule_tid, ppTInfo);
1540 static HRESULT WINAPI ScriptModule_GetIDsOfNames(IScriptModule *iface, REFIID riid,
1541 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1543 ScriptModule *This = impl_from_IScriptModule(iface);
1544 ITypeInfo *typeinfo;
1545 HRESULT hr;
1547 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
1549 hr = get_typeinfo(IScriptModule_tid, &typeinfo);
1550 if (SUCCEEDED(hr))
1552 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
1553 ITypeInfo_Release(typeinfo);
1556 return hr;
1559 static HRESULT WINAPI ScriptModule_Invoke(IScriptModule *iface, DISPID dispIdMember,
1560 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
1561 EXCEPINFO *pExcepInfo, UINT *puArgErr)
1563 ScriptModule *This = impl_from_IScriptModule(iface);
1564 ITypeInfo *typeinfo;
1565 HRESULT hr;
1567 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1568 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1570 hr = get_typeinfo(IScriptModule_tid, &typeinfo);
1571 if(SUCCEEDED(hr))
1573 hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
1574 pDispParams, pVarResult, pExcepInfo, puArgErr);
1575 ITypeInfo_Release(typeinfo);
1578 return hr;
1581 static HRESULT WINAPI ScriptModule_get_Name(IScriptModule *iface, BSTR *pbstrName)
1583 ScriptModule *This = impl_from_IScriptModule(iface);
1585 TRACE("(%p)->(%p)\n", This, pbstrName);
1587 if (!pbstrName) return E_POINTER;
1588 if (!This->host) return E_FAIL;
1590 *pbstrName = SysAllocString(This->name ? This->name : L"Global");
1591 return *pbstrName ? S_OK : E_OUTOFMEMORY;
1594 static HRESULT WINAPI ScriptModule_get_CodeObject(IScriptModule *iface, IDispatch **ppdispObject)
1596 ScriptModule *This = impl_from_IScriptModule(iface);
1597 HRESULT hr;
1599 TRACE("(%p)->(%p)\n", This, ppdispObject);
1601 if (!This->host) return E_FAIL;
1603 hr = start_script(This->host);
1604 if (FAILED(hr)) return hr;
1606 hr = get_script_dispatch(This, ppdispObject);
1607 if (FAILED(hr)) return hr;
1609 IDispatch_AddRef(*ppdispObject);
1610 return hr;
1613 static HRESULT WINAPI ScriptModule_get_Procedures(IScriptModule *iface, IScriptProcedureCollection **ppdispProcedures)
1615 ScriptModule *This = impl_from_IScriptModule(iface);
1617 TRACE("(%p)->(%p)\n", This, ppdispProcedures);
1619 if (!This->host)
1620 return E_FAIL;
1622 if (This->procedures)
1623 IScriptProcedureCollection_AddRef(&This->procedures->IScriptProcedureCollection_iface);
1624 else
1626 ScriptProcedureCollection *procs;
1627 UINT i;
1629 if (!(procs = heap_alloc(sizeof(*procs))))
1630 return E_OUTOFMEMORY;
1632 procs->IScriptProcedureCollection_iface.lpVtbl = &ScriptProcedureCollectionVtbl;
1633 procs->ref = 1;
1634 procs->count = -1;
1635 procs->module = This;
1636 for (i = 0; i < ARRAY_SIZE(procs->hash_table); i++)
1637 list_init(&procs->hash_table[i]);
1639 This->procedures = procs;
1640 IScriptModule_AddRef(&This->IScriptModule_iface);
1643 *ppdispProcedures = &This->procedures->IScriptProcedureCollection_iface;
1644 return S_OK;
1647 static HRESULT WINAPI ScriptModule_AddCode(IScriptModule *iface, BSTR code)
1649 ScriptModule *This = impl_from_IScriptModule(iface);
1651 TRACE("(%p)->(%s)\n", This, debugstr_w(code));
1653 if (!This->host)
1654 return E_FAIL;
1656 return parse_script_text(This, code, SCRIPTTEXT_ISVISIBLE, NULL);
1659 static HRESULT WINAPI ScriptModule_Eval(IScriptModule *iface, BSTR expression, VARIANT *res)
1661 ScriptModule *This = impl_from_IScriptModule(iface);
1663 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(expression), res);
1665 if (!res)
1666 return E_POINTER;
1667 V_VT(res) = VT_EMPTY;
1668 if (!This->host)
1669 return E_FAIL;
1671 return parse_script_text(This, expression, SCRIPTTEXT_ISEXPRESSION, res);
1674 static HRESULT WINAPI ScriptModule_ExecuteStatement(IScriptModule *iface, BSTR statement)
1676 ScriptModule *This = impl_from_IScriptModule(iface);
1678 TRACE("(%p)->(%s)\n", This, debugstr_w(statement));
1680 if (!This->host)
1681 return E_FAIL;
1683 return parse_script_text(This, statement, 0, NULL);
1686 static HRESULT WINAPI ScriptModule_Run(IScriptModule *iface, BSTR procedure_name, SAFEARRAY **parameters, VARIANT *res)
1688 ScriptModule *This = impl_from_IScriptModule(iface);
1689 SAFEARRAY *sa;
1691 TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(procedure_name), parameters, res);
1693 if (!parameters || !res) return E_POINTER;
1694 if (!(sa = *parameters)) return E_POINTER;
1696 V_VT(res) = VT_EMPTY;
1697 if (sa->cDims == 0) return DISP_E_BADINDEX;
1698 if (!(sa->fFeatures & FADF_VARIANT)) return DISP_E_BADVARTYPE;
1699 if (!This->host) return E_FAIL;
1701 return run_procedure(This, procedure_name, sa, res);
1704 static const IScriptModuleVtbl ScriptModuleVtbl = {
1705 ScriptModule_QueryInterface,
1706 ScriptModule_AddRef,
1707 ScriptModule_Release,
1708 ScriptModule_GetTypeInfoCount,
1709 ScriptModule_GetTypeInfo,
1710 ScriptModule_GetIDsOfNames,
1711 ScriptModule_Invoke,
1712 ScriptModule_get_Name,
1713 ScriptModule_get_CodeObject,
1714 ScriptModule_get_Procedures,
1715 ScriptModule_AddCode,
1716 ScriptModule_Eval,
1717 ScriptModule_ExecuteStatement,
1718 ScriptModule_Run
1721 static HRESULT WINAPI module_enum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv)
1723 struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
1725 if (IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IEnumVARIANT, riid))
1727 *ppv = &This->IEnumVARIANT_iface;
1729 else
1731 WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
1732 *ppv = NULL;
1733 return E_NOINTERFACE;
1736 IUnknown_AddRef((IUnknown*)*ppv);
1737 return S_OK;
1740 static ULONG WINAPI module_enum_AddRef(IEnumVARIANT *iface)
1742 struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
1743 LONG ref = InterlockedIncrement(&This->ref);
1745 TRACE("(%p) ref=%d\n", This, ref);
1747 return ref;
1750 static ULONG WINAPI module_enum_Release(IEnumVARIANT *iface)
1752 struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
1753 LONG ref = InterlockedDecrement(&This->ref);
1755 TRACE("(%p) ref=%d\n", This, ref);
1757 if (!ref)
1759 IActiveScriptSite_Release(&This->host->IActiveScriptSite_iface);
1760 IScriptControl_Release(&This->control->IScriptControl_iface);
1761 heap_free(This);
1764 return ref;
1767 static HRESULT WINAPI module_enum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
1769 struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
1770 unsigned int i, num;
1772 TRACE("(%p)->(%u %p %p)\n", This, celt, rgVar, pCeltFetched);
1774 if (!rgVar) return E_POINTER;
1775 if (This->host != This->control->host) return E_FAIL;
1777 num = min(celt, This->host->module_count - This->pos);
1778 for (i = 0; i < num; i++)
1780 V_VT(rgVar + i) = VT_DISPATCH;
1781 V_DISPATCH(rgVar + i) = (IDispatch*)(&This->control->modules[This->pos++]->IScriptModule_iface);
1782 IDispatch_AddRef(V_DISPATCH(rgVar + i));
1785 if (pCeltFetched) *pCeltFetched = i;
1786 return i == celt ? S_OK : S_FALSE;
1789 static HRESULT WINAPI module_enum_Skip(IEnumVARIANT *iface, ULONG celt)
1791 struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
1793 TRACE("(%p)->(%u)\n", This, celt);
1795 if (This->host != This->control->host) return E_FAIL;
1797 if (This->host->module_count - This->pos < celt)
1799 This->pos = This->host->module_count;
1800 return S_FALSE;
1802 This->pos += celt;
1803 return S_OK;
1806 static HRESULT WINAPI module_enum_Reset(IEnumVARIANT *iface)
1808 struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
1810 TRACE("(%p)\n", This);
1812 if (This->host != This->control->host) return E_FAIL;
1814 This->pos = 0;
1815 return S_OK;
1818 static HRESULT WINAPI module_enum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
1820 struct module_enum *This = module_enum_from_IEnumVARIANT(iface);
1821 struct module_enum *clone;
1823 TRACE("(%p)->(%p)\n", This, ppEnum);
1825 if (!ppEnum) return E_POINTER;
1826 if (This->host != This->control->host) return E_FAIL;
1828 if (!(clone = heap_alloc(sizeof(*clone))))
1829 return E_OUTOFMEMORY;
1831 *clone = *This;
1832 clone->ref = 1;
1833 IActiveScriptSite_AddRef(&This->host->IActiveScriptSite_iface);
1834 IScriptControl_AddRef(&This->control->IScriptControl_iface);
1836 *ppEnum = &clone->IEnumVARIANT_iface;
1837 return S_OK;
1840 static const IEnumVARIANTVtbl module_enum_vtbl = {
1841 module_enum_QueryInterface,
1842 module_enum_AddRef,
1843 module_enum_Release,
1844 module_enum_Next,
1845 module_enum_Skip,
1846 module_enum_Reset,
1847 module_enum_Clone
1850 static ScriptModule *create_module(ScriptHost *host, BSTR name)
1852 ScriptModule *module;
1854 if (!(module = heap_alloc_zero(sizeof(*module)))) return NULL;
1856 module->IScriptModule_iface.lpVtbl = &ScriptModuleVtbl;
1857 module->ref = 1;
1858 if (name && !(module->name = SysAllocString(name)))
1860 heap_free(module);
1861 return NULL;
1863 module->host = host;
1864 IActiveScriptSite_AddRef(&host->IActiveScriptSite_iface);
1865 return module;
1868 static void release_modules(ScriptControl *control, BOOL force_detach)
1870 unsigned int i, module_count = control->host->module_count;
1872 for (i = 0; i < module_count; i++) {
1873 if (force_detach) detach_module(control->modules[i]);
1874 IScriptModule_Release(&control->modules[i]->IScriptModule_iface);
1877 heap_free(control->modules);
1880 static ScriptModule *find_module(ScriptControl *control, BSTR name)
1882 unsigned int i;
1884 if (!wcsicmp(name, L"Global"))
1885 return control->modules[0];
1887 for (i = 1; i < control->host->module_count; i++)
1889 if (!wcsicmp(name, control->modules[i]->name))
1890 return control->modules[i];
1892 return NULL;
1895 static HRESULT WINAPI ScriptModuleCollection_QueryInterface(IScriptModuleCollection *iface, REFIID riid, void **ppv)
1897 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
1899 if (IsEqualGUID(&IID_IDispatch, riid) || IsEqualGUID(&IID_IUnknown, riid) ||
1900 IsEqualGUID(&IID_IScriptModuleCollection, riid))
1902 *ppv = &This->IScriptModuleCollection_iface;
1904 else
1906 WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
1907 *ppv = NULL;
1908 return E_NOINTERFACE;
1911 IUnknown_AddRef((IUnknown*)*ppv);
1912 return S_OK;
1915 static ULONG WINAPI ScriptModuleCollection_AddRef(IScriptModuleCollection *iface)
1917 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
1918 return IScriptControl_AddRef(&This->IScriptControl_iface);
1921 static ULONG WINAPI ScriptModuleCollection_Release(IScriptModuleCollection *iface)
1923 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
1924 return IScriptControl_Release(&This->IScriptControl_iface);
1927 static HRESULT WINAPI ScriptModuleCollection_GetTypeInfoCount(IScriptModuleCollection *iface, UINT *pctinfo)
1929 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
1931 TRACE("(%p)->(%p)\n", This, pctinfo);
1933 *pctinfo = 1;
1934 return S_OK;
1937 static HRESULT WINAPI ScriptModuleCollection_GetTypeInfo(IScriptModuleCollection *iface, UINT iTInfo,
1938 LCID lcid, ITypeInfo **ppTInfo)
1940 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
1942 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
1944 return get_typeinfo(IScriptModuleCollection_tid, ppTInfo);
1947 static HRESULT WINAPI ScriptModuleCollection_GetIDsOfNames(IScriptModuleCollection *iface, REFIID riid,
1948 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1950 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
1951 ITypeInfo *typeinfo;
1952 HRESULT hr;
1954 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
1956 hr = get_typeinfo(IScriptModuleCollection_tid, &typeinfo);
1957 if (SUCCEEDED(hr))
1959 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
1960 ITypeInfo_Release(typeinfo);
1963 return hr;
1966 static HRESULT WINAPI ScriptModuleCollection_Invoke(IScriptModuleCollection *iface, DISPID dispIdMember,
1967 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
1968 EXCEPINFO *pExcepInfo, UINT *puArgErr)
1970 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
1971 ITypeInfo *typeinfo;
1972 HRESULT hr;
1974 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1975 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1977 hr = get_typeinfo(IScriptModuleCollection_tid, &typeinfo);
1978 if(SUCCEEDED(hr))
1980 hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
1981 pDispParams, pVarResult, pExcepInfo, puArgErr);
1982 ITypeInfo_Release(typeinfo);
1985 return hr;
1988 static HRESULT WINAPI ScriptModuleCollection_get__NewEnum(IScriptModuleCollection *iface, IUnknown **ppenumContexts)
1990 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
1991 struct module_enum *module_enum;
1993 TRACE("(%p)->(%p)\n", This, ppenumContexts);
1995 if (!ppenumContexts) return E_POINTER;
1996 if (!This->host) return E_FAIL;
1998 if (!(module_enum = heap_alloc(sizeof(*module_enum))))
1999 return E_OUTOFMEMORY;
2001 module_enum->IEnumVARIANT_iface.lpVtbl = &module_enum_vtbl;
2002 module_enum->ref = 1;
2003 module_enum->pos = 0;
2004 module_enum->host = This->host;
2005 module_enum->control = This;
2006 IActiveScriptSite_AddRef(&This->host->IActiveScriptSite_iface);
2007 IScriptControl_AddRef(&This->IScriptControl_iface);
2009 *ppenumContexts = (IUnknown*)&module_enum->IEnumVARIANT_iface;
2010 return S_OK;
2013 static HRESULT WINAPI ScriptModuleCollection_get_Item(IScriptModuleCollection *iface, VARIANT index,
2014 IScriptModule **ppmod)
2016 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
2017 ScriptModule *module;
2018 unsigned int i;
2019 HRESULT hr;
2021 TRACE("(%p)->(%s %p)\n", This, wine_dbgstr_variant(&index), ppmod);
2023 if (!ppmod) return E_POINTER;
2024 if (!This->host) return E_FAIL;
2026 if (V_VT(&index) == VT_BSTR)
2028 module = find_module(This, V_BSTR(&index));
2029 if (!module) return CTL_E_ILLEGALFUNCTIONCALL;
2031 else
2033 hr = VariantChangeType(&index, &index, 0, VT_INT);
2034 if (FAILED(hr)) return hr;
2036 i = V_INT(&index) - 1;
2037 if (i >= This->host->module_count) return 0x800a0009;
2039 module = This->modules[i];
2042 *ppmod = &module->IScriptModule_iface;
2043 IScriptModule_AddRef(*ppmod);
2044 return S_OK;
2047 static HRESULT WINAPI ScriptModuleCollection_get_Count(IScriptModuleCollection *iface, LONG *plCount)
2049 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
2051 TRACE("(%p)->(%p)\n", This, plCount);
2053 if (!plCount) return E_POINTER;
2054 if (!This->host) return E_FAIL;
2056 *plCount = This->host->module_count;
2057 return S_OK;
2060 static HRESULT WINAPI ScriptModuleCollection_Add(IScriptModuleCollection *iface, BSTR name,
2061 VARIANT *object, IScriptModule **ppmod)
2063 ScriptControl *This = impl_from_IScriptModuleCollection(iface);
2064 ScriptModule *module, **modules;
2065 ScriptHost *host = This->host;
2066 HRESULT hr;
2068 TRACE("(%p)->(%s %s %p)\n", This, wine_dbgstr_w(name), wine_dbgstr_variant(object), ppmod);
2070 if (!ppmod) return E_POINTER;
2071 if (!name || V_VT(object) != VT_DISPATCH) return E_INVALIDARG;
2072 if (!host) return E_FAIL;
2073 if (find_module(This, name)) return E_INVALIDARG;
2075 /* See if we need to grow the array */
2076 if (is_power_of_2(host->module_count))
2078 modules = heap_realloc(This->modules, host->module_count * 2 * sizeof(*This->modules));
2079 if (!modules) return E_OUTOFMEMORY;
2080 This->modules = modules;
2083 if (!(module = create_module(host, name)))
2084 return E_OUTOFMEMORY;
2086 /* If no object, Windows only calls AddNamedItem without adding a NULL object */
2087 if (V_DISPATCH(object))
2088 hr = add_script_object(host, name, V_DISPATCH(object), 0);
2089 else
2090 hr = IActiveScript_AddNamedItem(host->script, name, SCRIPTITEM_CODEONLY);
2092 if (FAILED(hr))
2094 IScriptModule_Release(&module->IScriptModule_iface);
2095 return hr;
2097 This->modules[host->module_count++] = module;
2099 *ppmod = &module->IScriptModule_iface;
2100 IScriptModule_AddRef(*ppmod);
2101 return S_OK;
2104 static const IScriptModuleCollectionVtbl ScriptModuleCollectionVtbl = {
2105 ScriptModuleCollection_QueryInterface,
2106 ScriptModuleCollection_AddRef,
2107 ScriptModuleCollection_Release,
2108 ScriptModuleCollection_GetTypeInfoCount,
2109 ScriptModuleCollection_GetTypeInfo,
2110 ScriptModuleCollection_GetIDsOfNames,
2111 ScriptModuleCollection_Invoke,
2112 ScriptModuleCollection_get__NewEnum,
2113 ScriptModuleCollection_get_Item,
2114 ScriptModuleCollection_get_Count,
2115 ScriptModuleCollection_Add
2118 static void fill_error_info(ScriptError *error)
2120 EXCEPINFO info;
2122 if (error->info_filled) return;
2123 error->info_filled = TRUE;
2125 if (!error->object)
2126 return;
2127 if (FAILED(IActiveScriptError_GetExceptionInfo(error->object, &info)))
2128 return;
2129 if (info.pfnDeferredFillIn)
2130 info.pfnDeferredFillIn(&info);
2132 error->number = info.scode;
2135 static HRESULT WINAPI ScriptError_QueryInterface(IScriptError *iface, REFIID riid, void **ppv)
2137 ScriptError *This = impl_from_IScriptError(iface);
2139 if (IsEqualGUID(&IID_IDispatch, riid) || IsEqualGUID(&IID_IUnknown, riid) ||
2140 IsEqualGUID(&IID_IScriptError, riid))
2142 *ppv = &This->IScriptError_iface;
2144 else
2146 WARN("unsupported interface: (%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
2147 *ppv = NULL;
2148 return E_NOINTERFACE;
2151 IUnknown_AddRef((IUnknown*)*ppv);
2152 return S_OK;
2155 static ULONG WINAPI ScriptError_AddRef(IScriptError *iface)
2157 ScriptError *This = impl_from_IScriptError(iface);
2158 LONG ref = InterlockedIncrement(&This->ref);
2160 TRACE("(%p) ref=%d\n", This, ref);
2162 return ref;
2165 static ULONG WINAPI ScriptError_Release(IScriptError *iface)
2167 ScriptError *This = impl_from_IScriptError(iface);
2168 LONG ref = InterlockedDecrement(&This->ref);
2170 TRACE("(%p) ref=%d\n", This, ref);
2172 if (!ref)
2174 IScriptError_Clear(&This->IScriptError_iface);
2175 heap_free(This);
2178 return ref;
2181 static HRESULT WINAPI ScriptError_GetTypeInfoCount(IScriptError *iface, UINT *pctinfo)
2183 ScriptError *This = impl_from_IScriptError(iface);
2185 TRACE("(%p)->(%p)\n", This, pctinfo);
2187 *pctinfo = 1;
2188 return S_OK;
2191 static HRESULT WINAPI ScriptError_GetTypeInfo(IScriptError *iface, UINT iTInfo,
2192 LCID lcid, ITypeInfo **ppTInfo)
2194 ScriptError *This = impl_from_IScriptError(iface);
2196 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
2198 return get_typeinfo(IScriptError_tid, ppTInfo);
2201 static HRESULT WINAPI ScriptError_GetIDsOfNames(IScriptError *iface, REFIID riid,
2202 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
2204 ScriptError *This = impl_from_IScriptError(iface);
2205 ITypeInfo *typeinfo;
2206 HRESULT hr;
2208 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
2210 hr = get_typeinfo(IScriptError_tid, &typeinfo);
2211 if (SUCCEEDED(hr))
2213 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
2214 ITypeInfo_Release(typeinfo);
2217 return hr;
2220 static HRESULT WINAPI ScriptError_Invoke(IScriptError *iface, DISPID dispIdMember,
2221 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
2222 EXCEPINFO *pExcepInfo, UINT *puArgErr)
2224 ScriptError *This = impl_from_IScriptError(iface);
2225 ITypeInfo *typeinfo;
2226 HRESULT hr;
2228 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
2229 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2231 hr = get_typeinfo(IScriptError_tid, &typeinfo);
2232 if(SUCCEEDED(hr))
2234 hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
2235 pDispParams, pVarResult, pExcepInfo, puArgErr);
2236 ITypeInfo_Release(typeinfo);
2239 return hr;
2242 static HRESULT WINAPI ScriptError_get_Number(IScriptError *iface, LONG *plNumber)
2244 ScriptError *This = impl_from_IScriptError(iface);
2246 TRACE("(%p)->(%p)\n", This, plNumber);
2248 fill_error_info(This);
2249 *plNumber = This->number;
2250 return S_OK;
2253 static HRESULT WINAPI ScriptError_get_Source(IScriptError *iface, BSTR *pbstrSource)
2255 ScriptError *This = impl_from_IScriptError(iface);
2257 FIXME("(%p)->(%p)\n", This, pbstrSource);
2259 return E_NOTIMPL;
2262 static HRESULT WINAPI ScriptError_get_Description(IScriptError *iface, BSTR *pbstrDescription)
2264 ScriptError *This = impl_from_IScriptError(iface);
2266 FIXME("(%p)->(%p)\n", This, pbstrDescription);
2268 return E_NOTIMPL;
2271 static HRESULT WINAPI ScriptError_get_HelpFile(IScriptError *iface, BSTR *pbstrHelpFile)
2273 ScriptError *This = impl_from_IScriptError(iface);
2275 FIXME("(%p)->(%p)\n", This, pbstrHelpFile);
2277 return E_NOTIMPL;
2280 static HRESULT WINAPI ScriptError_get_HelpContext(IScriptError *iface, LONG *plHelpContext)
2282 ScriptError *This = impl_from_IScriptError(iface);
2284 FIXME("(%p)->(%p)\n", This, plHelpContext);
2286 return E_NOTIMPL;
2289 static HRESULT WINAPI ScriptError_get_Text(IScriptError *iface, BSTR *pbstrText)
2291 ScriptError *This = impl_from_IScriptError(iface);
2293 FIXME("(%p)->(%p)\n", This, pbstrText);
2295 return E_NOTIMPL;
2298 static HRESULT WINAPI ScriptError_get_Line(IScriptError *iface, LONG *plLine)
2300 ScriptError *This = impl_from_IScriptError(iface);
2302 FIXME("(%p)->(%p)\n", This, plLine);
2304 return E_NOTIMPL;
2307 static HRESULT WINAPI ScriptError_get_Column(IScriptError *iface, LONG *plColumn)
2309 ScriptError *This = impl_from_IScriptError(iface);
2311 FIXME("(%p)->(%p)\n", This, plColumn);
2313 return E_NOTIMPL;
2316 static HRESULT WINAPI ScriptError_Clear(IScriptError *iface)
2318 ScriptError *This = impl_from_IScriptError(iface);
2320 TRACE("(%p)->()\n", This);
2322 if (This->object)
2324 IActiveScriptError_Release(This->object);
2325 This->object = NULL;
2328 This->number = 0;
2330 This->info_filled = FALSE;
2331 return S_OK;
2334 static const IScriptErrorVtbl ScriptErrorVtbl = {
2335 ScriptError_QueryInterface,
2336 ScriptError_AddRef,
2337 ScriptError_Release,
2338 ScriptError_GetTypeInfoCount,
2339 ScriptError_GetTypeInfo,
2340 ScriptError_GetIDsOfNames,
2341 ScriptError_Invoke,
2342 ScriptError_get_Number,
2343 ScriptError_get_Source,
2344 ScriptError_get_Description,
2345 ScriptError_get_HelpFile,
2346 ScriptError_get_HelpContext,
2347 ScriptError_get_Text,
2348 ScriptError_get_Line,
2349 ScriptError_get_Column,
2350 ScriptError_Clear
2353 static HRESULT init_script_host(ScriptControl *control, const CLSID *clsid, ScriptHost **ret)
2355 IObjectSafety *objsafety;
2356 ScriptHost *host;
2357 HRESULT hr;
2359 *ret = NULL;
2361 host = heap_alloc(sizeof(*host));
2362 if (!host)
2363 return E_OUTOFMEMORY;
2365 host->IActiveScriptSite_iface.lpVtbl = &ActiveScriptSiteVtbl;
2366 host->IActiveScriptSiteWindow_iface.lpVtbl = &ActiveScriptSiteWindowVtbl;
2367 host->IServiceProvider_iface.lpVtbl = &ServiceProviderVtbl;
2368 host->ref = 1;
2369 host->script = NULL;
2370 host->parse = NULL;
2371 host->clsid = *clsid;
2372 host->module_count = 1;
2373 list_init(&host->named_items);
2375 hr = CoCreateInstance(&host->clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
2376 &IID_IActiveScript, (void**)&host->script);
2377 if (FAILED(hr)) {
2378 WARN("Failed to create an instance for %s, %#x\n", debugstr_guid(clsid), hr);
2379 goto failed;
2382 hr = IActiveScript_QueryInterface(host->script, &IID_IObjectSafety, (void**)&objsafety);
2383 if (FAILED(hr)) {
2384 FIXME("Could not get IObjectSafety, %#x\n", hr);
2385 goto failed;
2388 hr = IObjectSafety_SetInterfaceSafetyOptions(objsafety, &IID_IActiveScriptParse, INTERFACESAFE_FOR_UNTRUSTED_DATA, 0);
2389 IObjectSafety_Release(objsafety);
2390 if (FAILED(hr)) {
2391 FIXME("SetInterfaceSafetyOptions failed, %#x\n", hr);
2392 goto failed;
2395 hr = IActiveScript_SetScriptSite(host->script, &host->IActiveScriptSite_iface);
2396 if (FAILED(hr)) {
2397 WARN("SetScriptSite failed, %#x\n", hr);
2398 goto failed;
2401 hr = IActiveScript_QueryInterface(host->script, &IID_IActiveScriptParse, (void**)&host->parse);
2402 if (FAILED(hr)) {
2403 WARN("Failed to get IActiveScriptParse, %#x\n", hr);
2404 goto failed;
2407 hr = IActiveScriptParse_InitNew(host->parse);
2408 if (FAILED(hr)) {
2409 WARN("InitNew failed, %#x\n", hr);
2410 goto failed;
2412 host->script_state = SCRIPTSTATE_INITIALIZED;
2413 host->error = control->error;
2414 IScriptError_AddRef(&host->error->IScriptError_iface);
2416 *ret = host;
2417 return S_OK;
2419 failed:
2420 detach_script_host(host);
2421 return hr;
2424 static HRESULT WINAPI ScriptControl_QueryInterface(IScriptControl *iface, REFIID riid, void **ppv)
2426 ScriptControl *This = impl_from_IScriptControl(iface);
2428 if(IsEqualGUID(&IID_IUnknown, riid)) {
2429 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
2430 *ppv = &This->IScriptControl_iface;
2431 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
2432 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
2433 *ppv = &This->IScriptControl_iface;
2434 }else if(IsEqualGUID(&IID_IScriptControl, riid)) {
2435 TRACE("(%p)->(IID_IScriptControl %p)\n", This, ppv);
2436 *ppv = &This->IScriptControl_iface;
2437 }else if(IsEqualGUID(&IID_IOleObject, riid)) {
2438 TRACE("(%p)->(IID_IOleObject %p)\n", This, ppv);
2439 *ppv = &This->IOleObject_iface;
2440 }else if(IsEqualGUID(&IID_IPersistStreamInit, riid)) {
2441 TRACE("(%p)->(IID_IPersistStreamInit %p)\n", This, ppv);
2442 *ppv = &This->IPersistStreamInit_iface;
2443 }else if(IsEqualGUID(&IID_IPersist, riid)) {
2444 TRACE("(%p)->(IID_IPersist %p)\n", This, ppv);
2445 *ppv = &This->IPersistStreamInit_iface;
2446 }else if(IsEqualGUID(&IID_IOleControl, riid)) {
2447 TRACE("(%p)->(IID_IOleControl %p)\n", This, ppv);
2448 *ppv = &This->IOleControl_iface;
2449 }else if(IsEqualGUID(&IID_IQuickActivate, riid)) {
2450 TRACE("(%p)->(IID_IQuickActivate %p)\n", This, ppv);
2451 *ppv = &This->IQuickActivate_iface;
2452 }else if(IsEqualGUID(&IID_IViewObject, riid)) {
2453 TRACE("(%p)->(IID_IViewObject %p)\n", This, ppv);
2454 *ppv = &This->IViewObjectEx_iface;
2455 }else if(IsEqualGUID(&IID_IViewObject2, riid)) {
2456 TRACE("(%p)->(IID_IViewObject2 %p)\n", This, ppv);
2457 *ppv = &This->IViewObjectEx_iface;
2458 }else if(IsEqualGUID(&IID_IViewObjectEx, riid)) {
2459 TRACE("(%p)->(IID_IViewObjectEx %p)\n", This, ppv);
2460 *ppv = &This->IViewObjectEx_iface;
2461 }else if(IsEqualGUID(&IID_IPointerInactive, riid)) {
2462 TRACE("(%p)->(IID_IPointerInactive %p)\n", This, ppv);
2463 *ppv = &This->IPointerInactive_iface;
2464 }else if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) {
2465 TRACE("(%p)->(IID_IConnectionPointContainer %p)\n", This, ppv);
2466 *ppv = &This->IConnectionPointContainer_iface;
2467 }else {
2468 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
2469 *ppv = NULL;
2470 return E_NOINTERFACE;
2473 IUnknown_AddRef((IUnknown*)*ppv);
2474 return S_OK;
2477 static ULONG WINAPI ScriptControl_AddRef(IScriptControl *iface)
2479 ScriptControl *This = impl_from_IScriptControl(iface);
2480 LONG ref = InterlockedIncrement(&This->ref);
2482 TRACE("(%p) ref=%d\n", This, ref);
2484 return ref;
2487 static ULONG WINAPI ScriptControl_Release(IScriptControl *iface)
2489 ScriptControl *This = impl_from_IScriptControl(iface);
2490 LONG ref = InterlockedDecrement(&This->ref);
2492 TRACE("(%p) ref=%d\n", This, ref);
2494 if(!ref) {
2495 if (This->site)
2496 IOleClientSite_Release(This->site);
2497 if (This->host)
2499 release_modules(This, FALSE);
2500 IActiveScriptSite_Release(&This->host->IActiveScriptSite_iface);
2502 IScriptError_Release(&This->error->IScriptError_iface);
2503 heap_free(This);
2506 return ref;
2509 static HRESULT WINAPI ScriptControl_GetTypeInfoCount(IScriptControl *iface, UINT *pctinfo)
2511 ScriptControl *This = impl_from_IScriptControl(iface);
2512 TRACE("(%p)->(%p)\n", This, pctinfo);
2513 *pctinfo = 1;
2514 return S_OK;
2517 static HRESULT WINAPI ScriptControl_GetTypeInfo(IScriptControl *iface, UINT iTInfo,
2518 LCID lcid, ITypeInfo **ppTInfo)
2520 ScriptControl *This = impl_from_IScriptControl(iface);
2521 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
2522 return get_typeinfo(IScriptControl_tid, ppTInfo);
2525 static HRESULT WINAPI ScriptControl_GetIDsOfNames(IScriptControl *iface, REFIID riid,
2526 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
2528 ScriptControl *This = impl_from_IScriptControl(iface);
2529 ITypeInfo *typeinfo;
2530 HRESULT hres;
2532 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId);
2534 hres = get_typeinfo(IScriptControl_tid, &typeinfo);
2535 if(SUCCEEDED(hres)) {
2536 hres = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
2537 ITypeInfo_Release(typeinfo);
2540 return hres;
2543 static HRESULT WINAPI ScriptControl_Invoke(IScriptControl *iface, DISPID dispIdMember,
2544 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
2545 EXCEPINFO *pExcepInfo, UINT *puArgErr)
2547 ScriptControl *This = impl_from_IScriptControl(iface);
2548 ITypeInfo *typeinfo;
2549 HRESULT hres;
2551 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
2552 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2554 hres = get_typeinfo(IScriptControl_tid, &typeinfo);
2555 if(SUCCEEDED(hres)) {
2556 hres = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags,
2557 pDispParams, pVarResult, pExcepInfo, puArgErr);
2558 ITypeInfo_Release(typeinfo);
2561 return hres;
2564 static HRESULT WINAPI ScriptControl_get_Language(IScriptControl *iface, BSTR *p)
2566 ScriptControl *This = impl_from_IScriptControl(iface);
2567 LPOLESTR progidW;
2568 HRESULT hr;
2570 TRACE("(%p)->(%p)\n", This, p);
2572 if (!p)
2573 return E_POINTER;
2575 *p = NULL;
2577 if (!This->host)
2578 return S_OK;
2580 hr = ProgIDFromCLSID(&This->host->clsid, &progidW);
2581 if (FAILED(hr))
2582 return hr;
2584 *p = SysAllocString(progidW);
2585 CoTaskMemFree(progidW);
2586 return *p ? S_OK : E_OUTOFMEMORY;
2589 static HRESULT WINAPI ScriptControl_put_Language(IScriptControl *iface, BSTR language)
2591 ScriptControl *This = impl_from_IScriptControl(iface);
2592 CLSID clsid;
2593 HRESULT hres;
2595 TRACE("(%p)->(%s)\n", This, debugstr_w(language));
2597 if (language && FAILED(CLSIDFromProgID(language, &clsid)))
2598 return CTL_E_INVALIDPROPERTYVALUE;
2600 if (This->host) {
2601 release_modules(This, TRUE);
2602 IActiveScriptSite_Release(&This->host->IActiveScriptSite_iface);
2603 This->host = NULL;
2606 if (!language)
2607 return S_OK;
2609 hres = init_script_host(This, &clsid, &This->host);
2610 if (FAILED(hres))
2611 return hres;
2613 /* Alloc global module */
2614 This->modules = heap_alloc_zero(sizeof(*This->modules));
2615 if (This->modules) {
2616 This->modules[0] = create_module(This->host, NULL);
2617 if (!This->modules[0]) {
2618 heap_free(This->modules);
2619 This->modules = NULL;
2620 hres = E_OUTOFMEMORY;
2623 else
2624 hres = E_OUTOFMEMORY;
2626 if (FAILED(hres)) {
2627 detach_script_host(This->host);
2628 This->host = NULL;
2630 return hres;
2633 static HRESULT WINAPI ScriptControl_get_State(IScriptControl *iface, ScriptControlStates *p)
2635 ScriptControl *This = impl_from_IScriptControl(iface);
2636 SCRIPTSTATE state;
2637 HRESULT hres;
2639 TRACE("(%p)->(%p)\n", This, p);
2641 if(!p)
2642 return E_POINTER;
2644 if(!This->host)
2645 return E_FAIL;
2647 hres = IActiveScript_GetScriptState(This->host->script, &state);
2648 if (FAILED(hres)) return hres;
2650 switch (state)
2652 case SCRIPTSTATE_INITIALIZED:
2653 case SCRIPTSTATE_STARTED:
2654 *p = Initialized;
2655 break;
2656 case SCRIPTSTATE_CONNECTED:
2657 *p = Connected;
2658 break;
2659 default:
2660 WARN("unexpected state %d\n", state);
2661 return E_FAIL;
2663 return S_OK;
2666 static HRESULT WINAPI ScriptControl_put_State(IScriptControl *iface, ScriptControlStates state)
2668 ScriptControl *This = impl_from_IScriptControl(iface);
2669 TRACE("(%p)->(%x)\n", This, state);
2671 if(!This->host)
2672 return E_FAIL;
2674 if(state != Initialized && state != Connected)
2675 return CTL_E_INVALIDPROPERTYVALUE;
2677 return IActiveScript_SetScriptState(This->host->script, state == Connected ? SCRIPTSTATE_CONNECTED : SCRIPTSTATE_STARTED);
2680 static HRESULT WINAPI ScriptControl_put_SitehWnd(IScriptControl *iface, LONG hwnd)
2682 ScriptControl *This = impl_from_IScriptControl(iface);
2684 FIXME("(%p)->(%x)\n", This, hwnd);
2686 return S_OK;
2689 static HRESULT WINAPI ScriptControl_get_SitehWnd(IScriptControl *iface, LONG *p)
2691 ScriptControl *This = impl_from_IScriptControl(iface);
2692 FIXME("(%p)->(%p)\n", This, p);
2693 return E_NOTIMPL;
2696 static HRESULT WINAPI ScriptControl_get_Timeout(IScriptControl *iface, LONG *p)
2698 ScriptControl *This = impl_from_IScriptControl(iface);
2700 TRACE("(%p)->(%p)\n", This, p);
2702 if (!p)
2703 return E_POINTER;
2705 *p = This->timeout;
2706 return S_OK;
2709 static HRESULT WINAPI ScriptControl_put_Timeout(IScriptControl *iface, LONG timeout)
2711 ScriptControl *This = impl_from_IScriptControl(iface);
2713 TRACE("(%p)->(%d)\n", This, timeout);
2715 if (timeout < -1)
2716 return CTL_E_INVALIDPROPERTYVALUE;
2718 if (timeout != -1)
2719 FIXME("execution timeout ignored\n");
2721 This->timeout = timeout;
2722 return S_OK;
2725 static HRESULT WINAPI ScriptControl_get_AllowUI(IScriptControl *iface, VARIANT_BOOL *p)
2727 ScriptControl *This = impl_from_IScriptControl(iface);
2728 TRACE("(%p)->(%p)\n", This, p);
2730 if(!p)
2731 return E_POINTER;
2733 *p = This->allow_ui;
2734 return S_OK;
2737 static HRESULT WINAPI ScriptControl_put_AllowUI(IScriptControl *iface, VARIANT_BOOL allow_ui)
2739 ScriptControl *This = impl_from_IScriptControl(iface);
2740 TRACE("(%p)->(%x)\n", This, allow_ui);
2742 This->allow_ui = allow_ui;
2743 return S_OK;
2746 static HRESULT WINAPI ScriptControl_get_UseSafeSubset(IScriptControl *iface, VARIANT_BOOL *p)
2748 ScriptControl *This = impl_from_IScriptControl(iface);
2749 TRACE("(%p)->(%p)\n", This, p);
2751 if(!p)
2752 return E_POINTER;
2754 *p = This->use_safe_subset;
2755 return S_OK;
2758 static HRESULT WINAPI ScriptControl_put_UseSafeSubset(IScriptControl *iface, VARIANT_BOOL use_safe_subset)
2760 ScriptControl *This = impl_from_IScriptControl(iface);
2761 TRACE("(%p)->(%x)\n", This, use_safe_subset);
2763 This->use_safe_subset = use_safe_subset;
2764 return S_OK;
2767 static HRESULT WINAPI ScriptControl_get_Modules(IScriptControl *iface, IScriptModuleCollection **p)
2769 ScriptControl *This = impl_from_IScriptControl(iface);
2771 TRACE("(%p)->(%p)\n", This, p);
2773 if (!This->host) return E_FAIL;
2775 *p = &This->IScriptModuleCollection_iface;
2776 IScriptControl_AddRef(iface);
2777 return S_OK;
2780 static HRESULT WINAPI ScriptControl_get_Error(IScriptControl *iface, IScriptError **p)
2782 ScriptControl *This = impl_from_IScriptControl(iface);
2784 TRACE("(%p)->(%p)\n", This, p);
2786 if (!p) return E_POINTER;
2788 *p = &This->error->IScriptError_iface;
2789 IScriptError_AddRef(*p);
2790 return S_OK;
2793 static HRESULT WINAPI ScriptControl_get_CodeObject(IScriptControl *iface, IDispatch **p)
2795 ScriptControl *This = impl_from_IScriptControl(iface);
2797 TRACE("(%p)->(%p)\n", This, p);
2799 if (!This->host) return E_FAIL;
2801 return IScriptModule_get_CodeObject(&This->modules[0]->IScriptModule_iface, p);
2804 static HRESULT WINAPI ScriptControl_get_Procedures(IScriptControl *iface, IScriptProcedureCollection **p)
2806 ScriptControl *This = impl_from_IScriptControl(iface);
2808 TRACE("(%p)->(%p)\n", This, p);
2810 if (!This->host) return E_FAIL;
2812 return IScriptModule_get_Procedures(&This->modules[0]->IScriptModule_iface, p);
2815 static HRESULT WINAPI ScriptControl__AboutBox(IScriptControl *iface)
2817 ScriptControl *This = impl_from_IScriptControl(iface);
2818 FIXME("(%p)\n", This);
2819 return E_NOTIMPL;
2822 static HRESULT WINAPI ScriptControl_AddObject(IScriptControl *iface, BSTR name, IDispatch *object, VARIANT_BOOL add_members)
2824 ScriptControl *This = impl_from_IScriptControl(iface);
2825 DWORD flags = SCRIPTITEM_ISVISIBLE | SCRIPTITEM_ISSOURCE;
2827 TRACE("(%p)->(%s %p %x)\n", This, debugstr_w(name), object, add_members);
2829 if (!object)
2830 return E_INVALIDARG;
2832 if (!This->host)
2833 return E_FAIL;
2835 if (add_members)
2836 flags |= SCRIPTITEM_GLOBALMEMBERS;
2837 return add_script_object(This->host, name, object, flags);
2840 static HRESULT WINAPI ScriptControl_Reset(IScriptControl *iface)
2842 ScriptControl *This = impl_from_IScriptControl(iface);
2844 TRACE("(%p)\n", This);
2846 if (!This->host)
2847 return E_FAIL;
2849 clear_named_items(This->host);
2850 return set_script_state(This->host, SCRIPTSTATE_INITIALIZED);
2853 static HRESULT WINAPI ScriptControl_AddCode(IScriptControl *iface, BSTR code)
2855 ScriptControl *This = impl_from_IScriptControl(iface);
2857 TRACE("(%p)->(%s).\n", This, debugstr_w(code));
2859 if (!This->host)
2860 return E_FAIL;
2862 return parse_script_text(This->modules[0], code, SCRIPTTEXT_ISVISIBLE, NULL);
2865 static HRESULT WINAPI ScriptControl_Eval(IScriptControl *iface, BSTR expression, VARIANT *res)
2867 ScriptControl *This = impl_from_IScriptControl(iface);
2869 TRACE("(%p)->(%s, %p).\n", This, debugstr_w(expression), res);
2871 if (!res)
2872 return E_POINTER;
2873 V_VT(res) = VT_EMPTY;
2874 if (!This->host)
2875 return E_FAIL;
2877 return parse_script_text(This->modules[0], expression, SCRIPTTEXT_ISEXPRESSION, res);
2880 static HRESULT WINAPI ScriptControl_ExecuteStatement(IScriptControl *iface, BSTR statement)
2882 ScriptControl *This = impl_from_IScriptControl(iface);
2884 TRACE("(%p)->(%s)\n", This, debugstr_w(statement));
2886 if (!This->host)
2887 return E_FAIL;
2889 return parse_script_text(This->modules[0], statement, 0, NULL);
2892 static HRESULT WINAPI ScriptControl_Run(IScriptControl *iface, BSTR procedure_name, SAFEARRAY **parameters, VARIANT *res)
2894 ScriptControl *This = impl_from_IScriptControl(iface);
2895 SAFEARRAY *sa;
2897 TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(procedure_name), parameters, res);
2899 if (!parameters || !res) return E_POINTER;
2900 if (!(sa = *parameters)) return E_POINTER;
2902 V_VT(res) = VT_EMPTY;
2903 if (sa->cDims == 0) return DISP_E_BADINDEX;
2904 if (!(sa->fFeatures & FADF_VARIANT)) return DISP_E_BADVARTYPE;
2905 if (!This->host) return E_FAIL;
2907 return run_procedure(This->modules[0], procedure_name, sa, res);
2910 static const IScriptControlVtbl ScriptControlVtbl = {
2911 ScriptControl_QueryInterface,
2912 ScriptControl_AddRef,
2913 ScriptControl_Release,
2914 ScriptControl_GetTypeInfoCount,
2915 ScriptControl_GetTypeInfo,
2916 ScriptControl_GetIDsOfNames,
2917 ScriptControl_Invoke,
2918 ScriptControl_get_Language,
2919 ScriptControl_put_Language,
2920 ScriptControl_get_State,
2921 ScriptControl_put_State,
2922 ScriptControl_put_SitehWnd,
2923 ScriptControl_get_SitehWnd,
2924 ScriptControl_get_Timeout,
2925 ScriptControl_put_Timeout,
2926 ScriptControl_get_AllowUI,
2927 ScriptControl_put_AllowUI,
2928 ScriptControl_get_UseSafeSubset,
2929 ScriptControl_put_UseSafeSubset,
2930 ScriptControl_get_Modules,
2931 ScriptControl_get_Error,
2932 ScriptControl_get_CodeObject,
2933 ScriptControl_get_Procedures,
2934 ScriptControl__AboutBox,
2935 ScriptControl_AddObject,
2936 ScriptControl_Reset,
2937 ScriptControl_AddCode,
2938 ScriptControl_Eval,
2939 ScriptControl_ExecuteStatement,
2940 ScriptControl_Run
2943 static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **obj)
2945 ScriptControl *This = impl_from_IOleObject(iface);
2946 return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
2949 static ULONG WINAPI OleObject_AddRef(IOleObject *iface)
2951 ScriptControl *This = impl_from_IOleObject(iface);
2952 return IScriptControl_AddRef(&This->IScriptControl_iface);
2955 static ULONG WINAPI OleObject_Release(IOleObject *iface)
2957 ScriptControl *This = impl_from_IOleObject(iface);
2958 return IScriptControl_Release(&This->IScriptControl_iface);
2961 static HRESULT WINAPI OleObject_SetClientSite(IOleObject *iface, IOleClientSite *site)
2963 ScriptControl *This = impl_from_IOleObject(iface);
2965 TRACE("(%p)->(%p)\n", This, site);
2967 if (This->site)
2968 IOleClientSite_Release(This->site);
2970 if ((This->site = site))
2971 IOleClientSite_AddRef(site);
2973 return S_OK;
2976 static HRESULT WINAPI OleObject_GetClientSite(IOleObject *iface, IOleClientSite **site)
2978 ScriptControl *This = impl_from_IOleObject(iface);
2980 TRACE("(%p)->(%p)\n", This, site);
2982 if (!site)
2983 return E_POINTER;
2985 if ((*site = This->site))
2986 IOleClientSite_AddRef(*site);
2988 return S_OK;
2991 static HRESULT WINAPI OleObject_SetHostNames(IOleObject *iface, LPCOLESTR containerapp, LPCOLESTR containerobj)
2993 ScriptControl *This = impl_from_IOleObject(iface);
2995 FIXME("(%p)->(%s %s)\n", This, debugstr_w(containerapp), debugstr_w(containerobj));
2997 return E_NOTIMPL;
3000 static HRESULT WINAPI OleObject_Close(IOleObject *iface, DWORD save)
3002 ScriptControl *This = impl_from_IOleObject(iface);
3004 FIXME("(%p)->(%d)\n", This, save);
3006 return E_NOTIMPL;
3009 static HRESULT WINAPI OleObject_SetMoniker(IOleObject *iface, DWORD which, IMoniker *moniker)
3011 ScriptControl *This = impl_from_IOleObject(iface);
3013 FIXME("(%p)->(%d %p)\n", This, which, moniker);
3015 return E_NOTIMPL;
3018 static HRESULT WINAPI OleObject_GetMoniker(IOleObject *iface, DWORD assign, DWORD which, IMoniker **moniker)
3020 ScriptControl *This = impl_from_IOleObject(iface);
3022 FIXME("(%p)->(%d %d %p)\n", This, assign, which, moniker);
3024 return E_NOTIMPL;
3027 static HRESULT WINAPI OleObject_InitFromData(IOleObject *iface, IDataObject *dataobj, BOOL creation,
3028 DWORD reserved)
3030 ScriptControl *This = impl_from_IOleObject(iface);
3032 FIXME("(%p)->(%p %d %d)\n", This, dataobj, creation, reserved);
3034 return E_NOTIMPL;
3037 static HRESULT WINAPI OleObject_GetClipboardData(IOleObject *iface, DWORD reserved, IDataObject **dataobj)
3039 ScriptControl *This = impl_from_IOleObject(iface);
3041 FIXME("(%p)->(%d %p)\n", This, reserved, dataobj);
3043 return E_NOTIMPL;
3046 static HRESULT WINAPI OleObject_DoVerb(IOleObject *iface, LONG verb, LPMSG msg, IOleClientSite *active_site,
3047 LONG index, HWND hwndParent, LPCRECT rect)
3049 ScriptControl *This = impl_from_IOleObject(iface);
3051 FIXME("(%p)->(%d %p %p %d %p %p)\n", This, verb, msg, active_site, index, hwndParent, rect);
3053 return E_NOTIMPL;
3056 static HRESULT WINAPI OleObject_EnumVerbs(IOleObject *iface, IEnumOLEVERB **enumoleverb)
3058 ScriptControl *This = impl_from_IOleObject(iface);
3060 FIXME("(%p)->(%p)\n", This, enumoleverb);
3062 return E_NOTIMPL;
3065 static HRESULT WINAPI OleObject_Update(IOleObject *iface)
3067 ScriptControl *This = impl_from_IOleObject(iface);
3069 FIXME("(%p)\n", This);
3071 return E_NOTIMPL;
3074 static HRESULT WINAPI OleObject_IsUpToDate(IOleObject *iface)
3076 ScriptControl *This = impl_from_IOleObject(iface);
3078 FIXME("(%p)\n", This);
3080 return E_NOTIMPL;
3083 static HRESULT WINAPI OleObject_GetUserClassID(IOleObject *iface, CLSID *clsid)
3085 ScriptControl *This = impl_from_IOleObject(iface);
3087 FIXME("(%p)->(%p)\n", This, clsid);
3089 return E_NOTIMPL;
3092 static HRESULT WINAPI OleObject_GetUserType(IOleObject *iface, DWORD form_of_type, LPOLESTR *usertype)
3094 ScriptControl *This = impl_from_IOleObject(iface);
3096 FIXME("(%p)->(%d %p)\n", This, form_of_type, usertype);
3098 return E_NOTIMPL;
3101 static HRESULT WINAPI OleObject_SetExtent(IOleObject *iface, DWORD aspect, SIZEL *size)
3103 ScriptControl *This = impl_from_IOleObject(iface);
3105 FIXME("(%p)->(%d %p)\n", This, aspect, size);
3107 return E_NOTIMPL;
3110 static HRESULT WINAPI OleObject_GetExtent(IOleObject *iface, DWORD aspect, SIZEL *size)
3112 ScriptControl *This = impl_from_IOleObject(iface);
3114 TRACE("(%p)->(%d %p)\n", This, aspect, size);
3116 if (aspect != DVASPECT_CONTENT)
3117 return DV_E_DVASPECT;
3119 *size = This->extent;
3120 return S_OK;
3123 static HRESULT WINAPI OleObject_Advise(IOleObject *iface, IAdviseSink *sink, DWORD *connection)
3125 ScriptControl *This = impl_from_IOleObject(iface);
3127 FIXME("(%p)->(%p %p)\n", This, sink, connection);
3129 return E_NOTIMPL;
3132 static HRESULT WINAPI OleObject_Unadvise(IOleObject *iface, DWORD connection)
3134 ScriptControl *This = impl_from_IOleObject(iface);
3136 FIXME("(%p)->(%d)\n", This, connection);
3138 return E_NOTIMPL;
3141 static HRESULT WINAPI OleObject_EnumAdvise(IOleObject *iface, IEnumSTATDATA **enumadvise)
3143 ScriptControl *This = impl_from_IOleObject(iface);
3145 FIXME("(%p)->(%p)\n", This, enumadvise);
3147 return E_NOTIMPL;
3150 static HRESULT WINAPI OleObject_GetMiscStatus(IOleObject *iface, DWORD aspect, DWORD *status)
3152 ScriptControl *This = impl_from_IOleObject(iface);
3154 TRACE("(%p)->(%d %p)\n", This, aspect, status);
3156 return OleRegGetMiscStatus(&CLSID_ScriptControl, aspect, status);
3159 static HRESULT WINAPI OleObject_SetColorScheme(IOleObject *iface, LOGPALETTE *logpal)
3161 ScriptControl *This = impl_from_IOleObject(iface);
3163 FIXME("(%p)->(%p)\n", This, logpal);
3165 return E_NOTIMPL;
3168 static const IOleObjectVtbl OleObjectVtbl = {
3169 OleObject_QueryInterface,
3170 OleObject_AddRef,
3171 OleObject_Release,
3172 OleObject_SetClientSite,
3173 OleObject_GetClientSite,
3174 OleObject_SetHostNames,
3175 OleObject_Close,
3176 OleObject_SetMoniker,
3177 OleObject_GetMoniker,
3178 OleObject_InitFromData,
3179 OleObject_GetClipboardData,
3180 OleObject_DoVerb,
3181 OleObject_EnumVerbs,
3182 OleObject_Update,
3183 OleObject_IsUpToDate,
3184 OleObject_GetUserClassID,
3185 OleObject_GetUserType,
3186 OleObject_SetExtent,
3187 OleObject_GetExtent,
3188 OleObject_Advise,
3189 OleObject_Unadvise,
3190 OleObject_EnumAdvise,
3191 OleObject_GetMiscStatus,
3192 OleObject_SetColorScheme
3195 static HRESULT WINAPI PersistStreamInit_QueryInterface(IPersistStreamInit *iface, REFIID riid, void **obj)
3197 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3198 return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
3201 static ULONG WINAPI PersistStreamInit_AddRef(IPersistStreamInit *iface)
3203 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3204 return IScriptControl_AddRef(&This->IScriptControl_iface);
3207 static ULONG WINAPI PersistStreamInit_Release(IPersistStreamInit *iface)
3209 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3210 return IScriptControl_Release(&This->IScriptControl_iface);
3213 static HRESULT WINAPI PersistStreamInit_GetClassID(IPersistStreamInit *iface, CLSID *clsid)
3215 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3217 FIXME("(%p)->(%p)\n", This, clsid);
3219 return E_NOTIMPL;
3222 static HRESULT WINAPI PersistStreamInit_IsDirty(IPersistStreamInit *iface)
3224 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3226 FIXME("(%p)\n", This);
3228 return E_NOTIMPL;
3231 static HRESULT WINAPI PersistStreamInit_Load(IPersistStreamInit *iface, IStream *stream)
3233 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3235 FIXME("(%p)->(%p)\n", This, stream);
3237 return E_NOTIMPL;
3240 static HRESULT WINAPI PersistStreamInit_Save(IPersistStreamInit *iface, IStream *stream, BOOL clear_dirty)
3242 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3244 FIXME("(%p)->(%p %d)\n", This, stream, clear_dirty);
3246 return E_NOTIMPL;
3249 static HRESULT WINAPI PersistStreamInit_GetSizeMax(IPersistStreamInit *iface, ULARGE_INTEGER *size)
3251 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3253 FIXME("(%p)->(%p)\n", This, size);
3255 return E_NOTIMPL;
3258 static HRESULT WINAPI PersistStreamInit_InitNew(IPersistStreamInit *iface)
3260 ScriptControl *This = impl_from_IPersistStreamInit(iface);
3262 FIXME("(%p)\n", This);
3264 return S_OK;
3267 static const IPersistStreamInitVtbl PersistStreamInitVtbl = {
3268 PersistStreamInit_QueryInterface,
3269 PersistStreamInit_AddRef,
3270 PersistStreamInit_Release,
3271 PersistStreamInit_GetClassID,
3272 PersistStreamInit_IsDirty,
3273 PersistStreamInit_Load,
3274 PersistStreamInit_Save,
3275 PersistStreamInit_GetSizeMax,
3276 PersistStreamInit_InitNew
3279 static HRESULT WINAPI OleControl_QueryInterface(IOleControl *iface, REFIID riid, void **obj)
3281 ScriptControl *This = impl_from_IOleControl(iface);
3282 return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
3285 static ULONG WINAPI OleControl_AddRef(IOleControl *iface)
3287 ScriptControl *This = impl_from_IOleControl(iface);
3288 return IScriptControl_AddRef(&This->IScriptControl_iface);
3291 static ULONG WINAPI OleControl_Release(IOleControl *iface)
3293 ScriptControl *This = impl_from_IOleControl(iface);
3294 return IScriptControl_Release(&This->IScriptControl_iface);
3297 static HRESULT WINAPI OleControl_GetControlInfo(IOleControl *iface, CONTROLINFO *info)
3299 ScriptControl *This = impl_from_IOleControl(iface);
3301 TRACE("(%p)->(%p)\n", This, info);
3303 if (!info)
3304 return E_POINTER;
3306 info->hAccel = NULL;
3307 info->cAccel = 0;
3309 return S_OK;
3312 static HRESULT WINAPI OleControl_OnMnemonic(IOleControl *iface, MSG *msg)
3314 ScriptControl *This = impl_from_IOleControl(iface);
3316 FIXME("(%p)->(%p)\n", This, msg);
3318 return E_NOTIMPL;
3321 static HRESULT WINAPI OleControl_OnAmbientPropertyChange(IOleControl *iface, DISPID dispid)
3323 ScriptControl *This = impl_from_IOleControl(iface);
3325 FIXME("(%p)->(%#x)\n", This, dispid);
3327 return E_NOTIMPL;
3330 static HRESULT WINAPI OleControl_FreezeEvents(IOleControl *iface, BOOL freeze)
3332 ScriptControl *This = impl_from_IOleControl(iface);
3334 FIXME("(%p)->(%d)\n", This, freeze);
3336 return E_NOTIMPL;
3339 static const IOleControlVtbl OleControlVtbl = {
3340 OleControl_QueryInterface,
3341 OleControl_AddRef,
3342 OleControl_Release,
3343 OleControl_GetControlInfo,
3344 OleControl_OnMnemonic,
3345 OleControl_OnAmbientPropertyChange,
3346 OleControl_FreezeEvents
3349 static HRESULT WINAPI QuickActivate_QueryInterface(IQuickActivate *iface, REFIID riid, void **obj)
3351 ScriptControl *This = impl_from_IQuickActivate(iface);
3352 return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
3355 static ULONG WINAPI QuickActivate_AddRef(IQuickActivate *iface)
3357 ScriptControl *This = impl_from_IQuickActivate(iface);
3358 return IScriptControl_AddRef(&This->IScriptControl_iface);
3361 static ULONG WINAPI QuickActivate_Release(IQuickActivate *iface)
3363 ScriptControl *This = impl_from_IQuickActivate(iface);
3364 return IScriptControl_Release(&This->IScriptControl_iface);
3367 static HRESULT WINAPI QuickActivate_QuickActivate(IQuickActivate *iface, QACONTAINER *container, QACONTROL *control)
3369 ScriptControl *This = impl_from_IQuickActivate(iface);
3371 FIXME("(%p)->(%p %p)\n", This, container, control);
3373 return E_NOTIMPL;
3376 static HRESULT WINAPI QuickActivate_SetContentExtent(IQuickActivate *iface, SIZEL *size)
3378 ScriptControl *This = impl_from_IQuickActivate(iface);
3380 FIXME("(%p)->(%p)\n", This, size);
3382 return E_NOTIMPL;
3385 static HRESULT WINAPI QuickActivate_GetContentExtent(IQuickActivate *iface, SIZEL *size)
3387 ScriptControl *This = impl_from_IQuickActivate(iface);
3389 FIXME("(%p)->(%p)\n", This, size);
3391 return E_NOTIMPL;
3394 static const IQuickActivateVtbl QuickActivateVtbl = {
3395 QuickActivate_QueryInterface,
3396 QuickActivate_AddRef,
3397 QuickActivate_Release,
3398 QuickActivate_QuickActivate,
3399 QuickActivate_SetContentExtent,
3400 QuickActivate_GetContentExtent
3403 static HRESULT WINAPI ViewObject_QueryInterface(IViewObjectEx *iface, REFIID riid, void **obj)
3405 ScriptControl *This = impl_from_IViewObjectEx(iface);
3406 return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
3409 static ULONG WINAPI ViewObject_AddRef(IViewObjectEx *iface)
3411 ScriptControl *This = impl_from_IViewObjectEx(iface);
3412 return IScriptControl_AddRef(&This->IScriptControl_iface);
3415 static ULONG WINAPI ViewObject_Release(IViewObjectEx *iface)
3417 ScriptControl *This = impl_from_IViewObjectEx(iface);
3418 return IScriptControl_Release(&This->IScriptControl_iface);
3421 static HRESULT WINAPI ViewObject_Draw(IViewObjectEx *iface, DWORD drawaspect, LONG index, void *aspect,
3422 DVTARGETDEVICE *device, HDC target_dev, HDC hdc_draw, const RECTL *bounds, const RECTL *win_bounds,
3423 BOOL (STDMETHODCALLTYPE *fn_continue)(ULONG_PTR cont), ULONG_PTR cont)
3425 ScriptControl *This = impl_from_IViewObjectEx(iface);
3427 FIXME("(%p)->(%d %d %p %p %p %p %p %p %p %lu)\n", This, drawaspect, index, aspect, device, target_dev,
3428 hdc_draw, bounds, win_bounds, fn_continue, cont);
3430 return E_NOTIMPL;
3433 static HRESULT WINAPI ViewObject_GetColorSet(IViewObjectEx *iface, DWORD drawaspect, LONG index, void *aspect,
3434 DVTARGETDEVICE *device, HDC hic_target, LOGPALETTE **colorset)
3436 ScriptControl *This = impl_from_IViewObjectEx(iface);
3438 FIXME("(%p)->(%d %d %p %p %p %p)\n", This, drawaspect, index, aspect, device, hic_target,
3439 colorset);
3441 return E_NOTIMPL;
3444 static HRESULT WINAPI ViewObject_Freeze(IViewObjectEx *iface, DWORD drawaspect, LONG index, void *aspect,
3445 DWORD *freeze)
3447 ScriptControl *This = impl_from_IViewObjectEx(iface);
3449 FIXME("(%p)->(%d %d %p %p)\n", This, drawaspect, index, aspect, freeze);
3451 return E_NOTIMPL;
3454 static HRESULT WINAPI ViewObject_Unfreeze(IViewObjectEx *iface, DWORD freeze)
3456 ScriptControl *This = impl_from_IViewObjectEx(iface);
3458 FIXME("(%p)->(%d)\n", This, freeze);
3460 return E_NOTIMPL;
3463 static HRESULT WINAPI ViewObject_SetAdvise(IViewObjectEx *iface, DWORD aspects, DWORD flags, IAdviseSink *sink)
3465 ScriptControl *This = impl_from_IViewObjectEx(iface);
3467 TRACE("(%p)->(%d %#x %p)\n", This, aspects, flags, sink);
3469 if (aspects != DVASPECT_CONTENT)
3470 return DV_E_DVASPECT;
3472 This->view_sink_flags = flags;
3473 if (This->view_sink)
3474 IAdviseSink_Release(This->view_sink);
3475 This->view_sink = sink;
3476 if (This->view_sink)
3477 IAdviseSink_AddRef(This->view_sink);
3479 return S_OK;
3482 static HRESULT WINAPI ViewObject_GetAdvise(IViewObjectEx *iface, DWORD *aspects, DWORD *flags, IAdviseSink **sink)
3484 ScriptControl *This = impl_from_IViewObjectEx(iface);
3486 TRACE("(%p)->(%p %p %p)\n", This, aspects, flags, sink);
3488 if (aspects)
3489 *aspects = DVASPECT_CONTENT;
3490 if (flags)
3491 *flags = This->view_sink_flags;
3492 if (sink) {
3493 *sink = This->view_sink;
3494 if (*sink)
3495 IAdviseSink_AddRef(*sink);
3498 return S_OK;
3501 static HRESULT WINAPI ViewObject_GetExtent(IViewObjectEx *iface, DWORD draw_aspect, LONG index,
3502 DVTARGETDEVICE *device, SIZEL *size)
3504 ScriptControl *This = impl_from_IViewObjectEx(iface);
3506 FIXME("(%p)->(%d %d %p %p)\n", This, draw_aspect, index, device, size);
3508 return E_NOTIMPL;
3511 static HRESULT WINAPI ViewObject_GetRect(IViewObjectEx *iface, DWORD aspect, RECTL *rect)
3513 ScriptControl *This = impl_from_IViewObjectEx(iface);
3515 FIXME("(%p)->(%d %p)\n", This, aspect, rect);
3517 return E_NOTIMPL;
3520 static HRESULT WINAPI ViewObject_GetViewStatus(IViewObjectEx *iface, DWORD *status)
3522 ScriptControl *This = impl_from_IViewObjectEx(iface);
3524 TRACE("(%p)->(%p)\n", This, status);
3526 *status = VIEWSTATUS_OPAQUE;
3527 return S_OK;
3530 static HRESULT WINAPI ViewObject_QueryHitPoint(IViewObjectEx *iface, DWORD aspect, const RECT *bounds,
3531 POINT pt, LONG close_hint, DWORD *hit_result)
3533 ScriptControl *This = impl_from_IViewObjectEx(iface);
3535 FIXME("(%p)->(%d %s %s %d %p)\n", This, aspect, wine_dbgstr_rect(bounds), wine_dbgstr_point(&pt), close_hint, hit_result);
3537 return E_NOTIMPL;
3540 static HRESULT WINAPI ViewObject_QueryHitRect(IViewObjectEx *iface, DWORD aspect, const RECT *bounds,
3541 const RECT *loc, LONG close_hint, DWORD *hit_result)
3543 ScriptControl *This = impl_from_IViewObjectEx(iface);
3545 FIXME("(%p)->(%d %s %s %d %p)\n", This, aspect, wine_dbgstr_rect(bounds), wine_dbgstr_rect(loc), close_hint, hit_result);
3547 return E_NOTIMPL;
3550 static HRESULT WINAPI ViewObject_GetNaturalExtent(IViewObjectEx *iface, DWORD aspect, LONG index,
3551 DVTARGETDEVICE *device, HDC target_hdc, DVEXTENTINFO *extent_info, SIZEL *size)
3553 ScriptControl *This = impl_from_IViewObjectEx(iface);
3555 FIXME("(%p)->(%d %d %p %p %p %p)\n", This, aspect, index, device, target_hdc, extent_info, size);
3557 return E_NOTIMPL;
3560 static const IViewObjectExVtbl ViewObjectExVtbl = {
3561 ViewObject_QueryInterface,
3562 ViewObject_AddRef,
3563 ViewObject_Release,
3564 ViewObject_Draw,
3565 ViewObject_GetColorSet,
3566 ViewObject_Freeze,
3567 ViewObject_Unfreeze,
3568 ViewObject_SetAdvise,
3569 ViewObject_GetAdvise,
3570 ViewObject_GetExtent,
3571 ViewObject_GetRect,
3572 ViewObject_GetViewStatus,
3573 ViewObject_QueryHitPoint,
3574 ViewObject_QueryHitRect,
3575 ViewObject_GetNaturalExtent
3578 static HRESULT WINAPI PointerInactive_QueryInterface(IPointerInactive *iface, REFIID riid, void **obj)
3580 ScriptControl *This = impl_from_IPointerInactive(iface);
3581 return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
3584 static ULONG WINAPI PointerInactive_AddRef(IPointerInactive *iface)
3586 ScriptControl *This = impl_from_IPointerInactive(iface);
3587 return IScriptControl_AddRef(&This->IScriptControl_iface);
3590 static ULONG WINAPI PointerInactive_Release(IPointerInactive *iface)
3592 ScriptControl *This = impl_from_IPointerInactive(iface);
3593 return IScriptControl_Release(&This->IScriptControl_iface);
3596 static HRESULT WINAPI PointerInactive_GetActivationPolicy(IPointerInactive *iface, DWORD *policy)
3598 ScriptControl *This = impl_from_IPointerInactive(iface);
3600 TRACE("(%p)->(%p)\n", This, policy);
3602 if (!policy)
3603 return E_POINTER;
3605 *policy = 0;
3606 return S_OK;
3609 static HRESULT WINAPI PointerInactive_OnInactiveMouseMove(IPointerInactive *iface, const RECT *bounds,
3610 LONG x, LONG y, DWORD key_state)
3612 ScriptControl *This = impl_from_IPointerInactive(iface);
3614 FIXME("(%p)->(%s %d %d %#x)\n", This, wine_dbgstr_rect(bounds), x, y, key_state);
3616 return E_NOTIMPL;
3619 static HRESULT WINAPI PointerInactive_OnInactiveSetCursor(IPointerInactive *iface, const RECT *bounds,
3620 LONG x, LONG y, DWORD msg, BOOL set_always)
3622 ScriptControl *This = impl_from_IPointerInactive(iface);
3624 FIXME("(%p)->(%s %d %d %#x %d)\n", This, wine_dbgstr_rect(bounds), x, y, msg, set_always);
3626 return E_NOTIMPL;
3629 static const IPointerInactiveVtbl PointerInactiveVtbl = {
3630 PointerInactive_QueryInterface,
3631 PointerInactive_AddRef,
3632 PointerInactive_Release,
3633 PointerInactive_GetActivationPolicy,
3634 PointerInactive_OnInactiveMouseMove,
3635 PointerInactive_OnInactiveSetCursor
3638 static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface, REFIID riid, void **obj)
3640 ScriptControl *This = impl_from_IConnectionPointContainer(iface);
3641 return IScriptControl_QueryInterface(&This->IScriptControl_iface, riid, obj);
3644 static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface)
3646 ScriptControl *This = impl_from_IConnectionPointContainer(iface);
3647 return IScriptControl_AddRef(&This->IScriptControl_iface);
3650 static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface)
3652 ScriptControl *This = impl_from_IConnectionPointContainer(iface);
3653 return IScriptControl_Release(&This->IScriptControl_iface);
3656 static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface, IEnumConnectionPoints **enum_points)
3658 ScriptControl *This = impl_from_IConnectionPointContainer(iface);
3660 FIXME("(%p)->(%p)\n", This, enum_points);
3662 return E_NOTIMPL;
3665 static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface, REFIID riid, IConnectionPoint **cp)
3667 ScriptControl *This = impl_from_IConnectionPointContainer(iface);
3668 ConnectionPoint *iter;
3670 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), cp);
3672 *cp = NULL;
3674 for (iter = This->cp_list; iter; iter = iter->next) {
3675 if (IsEqualIID(iter->riid, riid))
3676 *cp = &iter->IConnectionPoint_iface;
3679 if (*cp) {
3680 IConnectionPoint_AddRef(*cp);
3681 return S_OK;
3684 FIXME("unsupported connection point %s\n", debugstr_guid(riid));
3685 return CONNECT_E_NOCONNECTION;
3688 static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl = {
3689 ConnectionPointContainer_QueryInterface,
3690 ConnectionPointContainer_AddRef,
3691 ConnectionPointContainer_Release,
3692 ConnectionPointContainer_EnumConnectionPoints,
3693 ConnectionPointContainer_FindConnectionPoint
3696 static HRESULT WINAPI ConnectionPoint_QueryInterface(IConnectionPoint *iface,
3697 REFIID riid, void **ppv)
3699 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
3701 if(IsEqualGUID(&IID_IUnknown, riid)) {
3702 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
3703 *ppv = &This->IConnectionPoint_iface;
3704 }else if(IsEqualGUID(&IID_IConnectionPoint, riid)) {
3705 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
3706 *ppv = &This->IConnectionPoint_iface;
3707 }else {
3708 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
3709 *ppv = NULL;
3710 return E_NOINTERFACE;
3713 IUnknown_AddRef((IUnknown*)*ppv);
3714 return S_OK;
3717 static ULONG WINAPI ConnectionPoint_AddRef(IConnectionPoint *iface)
3719 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
3720 return IConnectionPointContainer_AddRef(&This->control->IConnectionPointContainer_iface);
3723 static ULONG WINAPI ConnectionPoint_Release(IConnectionPoint *iface)
3725 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
3726 return IConnectionPointContainer_Release(&This->control->IConnectionPointContainer_iface);
3729 static HRESULT WINAPI ConnectionPoint_GetConnectionInterface(IConnectionPoint *iface, IID *iid)
3731 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
3733 TRACE("(%p)->(%p)\n", This, iid);
3735 *iid = *This->riid;
3736 return S_OK;
3739 static HRESULT WINAPI ConnectionPoint_GetConnectionPointContainer(IConnectionPoint *iface,
3740 IConnectionPointContainer **container)
3742 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
3744 TRACE("(%p)->(%p)\n", This, container);
3746 if (!container)
3747 return E_POINTER;
3749 *container = &This->control->IConnectionPointContainer_iface;
3750 IConnectionPointContainer_AddRef(*container);
3752 return S_OK;
3755 static HRESULT WINAPI ConnectionPoint_Advise(IConnectionPoint *iface, IUnknown *unk_sink,
3756 DWORD *cookie)
3758 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
3760 FIXME("(%p)->(%p %p)\n", This, unk_sink, cookie);
3762 return E_NOTIMPL;
3765 static HRESULT WINAPI ConnectionPoint_Unadvise(IConnectionPoint *iface, DWORD cookie)
3767 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
3769 FIXME("(%p)->(%d)\n", This, cookie);
3771 return E_NOTIMPL;
3774 static HRESULT WINAPI ConnectionPoint_EnumConnections(IConnectionPoint *iface,
3775 IEnumConnections **ppEnum)
3777 ConnectionPoint *This = impl_from_IConnectionPoint(iface);
3779 FIXME("(%p)->(%p): stub\n", This, ppEnum);
3781 return E_NOTIMPL;
3784 static const IConnectionPointVtbl ConnectionPointVtbl =
3786 ConnectionPoint_QueryInterface,
3787 ConnectionPoint_AddRef,
3788 ConnectionPoint_Release,
3789 ConnectionPoint_GetConnectionInterface,
3790 ConnectionPoint_GetConnectionPointContainer,
3791 ConnectionPoint_Advise,
3792 ConnectionPoint_Unadvise,
3793 ConnectionPoint_EnumConnections
3796 static void ConnectionPoint_Init(ConnectionPoint *cp, ScriptControl *sc, REFIID riid)
3798 cp->IConnectionPoint_iface.lpVtbl = &ConnectionPointVtbl;
3799 cp->control = sc;
3800 cp->riid = riid;
3802 cp->next = sc->cp_list;
3803 sc->cp_list = cp;
3806 static HRESULT WINAPI ScriptControl_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
3808 ScriptControl *script_control;
3809 DWORD dpi_x, dpi_y;
3810 HRESULT hres;
3811 HDC hdc;
3813 TRACE("(%p %s %p)\n", outer, debugstr_guid(riid), ppv);
3815 script_control = heap_alloc_zero(sizeof(*script_control));
3816 if(!script_control)
3817 return E_OUTOFMEMORY;
3819 script_control->error = heap_alloc_zero(sizeof(*script_control->error));
3820 if(!script_control->error)
3822 heap_free(script_control);
3823 return E_OUTOFMEMORY;
3826 script_control->IScriptControl_iface.lpVtbl = &ScriptControlVtbl;
3827 script_control->IPersistStreamInit_iface.lpVtbl = &PersistStreamInitVtbl;
3828 script_control->IOleObject_iface.lpVtbl = &OleObjectVtbl;
3829 script_control->IOleControl_iface.lpVtbl = &OleControlVtbl;
3830 script_control->IQuickActivate_iface.lpVtbl = &QuickActivateVtbl;
3831 script_control->IViewObjectEx_iface.lpVtbl = &ViewObjectExVtbl;
3832 script_control->IPointerInactive_iface.lpVtbl = &PointerInactiveVtbl;
3833 script_control->IConnectionPointContainer_iface.lpVtbl = &ConnectionPointContainerVtbl;
3834 script_control->IScriptModuleCollection_iface.lpVtbl = &ScriptModuleCollectionVtbl;
3835 script_control->ref = 1;
3836 script_control->timeout = 10000;
3837 script_control->allow_ui = VARIANT_TRUE;
3838 script_control->use_safe_subset = VARIANT_FALSE;
3840 script_control->error->IScriptError_iface.lpVtbl = &ScriptErrorVtbl;
3841 script_control->error->ref = 1;
3843 ConnectionPoint_Init(&script_control->cp_scsource, script_control, &DIID_DScriptControlSource);
3844 ConnectionPoint_Init(&script_control->cp_propnotif, script_control, &IID_IPropertyNotifySink);
3846 hdc = GetDC(0);
3847 dpi_x = GetDeviceCaps(hdc, LOGPIXELSX);
3848 dpi_y = GetDeviceCaps(hdc, LOGPIXELSY);
3849 ReleaseDC(0, hdc);
3851 script_control->extent.cx = MulDiv(38, 2540, dpi_x);
3852 script_control->extent.cy = MulDiv(38, 2540, dpi_y);
3854 hres = IScriptControl_QueryInterface(&script_control->IScriptControl_iface, riid, ppv);
3855 IScriptControl_Release(&script_control->IScriptControl_iface);
3856 return hres;
3859 /******************************************************************
3860 * DllMain (msscript.ocx.@)
3862 BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
3864 TRACE("(%p %d %p)\n", instance, reason, reserved);
3866 switch(reason) {
3867 case DLL_WINE_PREATTACH:
3868 return FALSE; /* prefer native version */
3869 case DLL_PROCESS_ATTACH:
3870 msscript_instance = instance;
3871 DisableThreadLibraryCalls(instance);
3872 break;
3873 case DLL_PROCESS_DETACH:
3874 if(!reserved)
3875 release_typelib();
3876 break;
3879 return TRUE;
3882 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
3884 *ppv = NULL;
3886 if(IsEqualGUID(&IID_IUnknown, riid)) {
3887 TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
3888 *ppv = iface;
3889 }else if(IsEqualGUID(&IID_IClassFactory, riid)) {
3890 TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv);
3891 *ppv = iface;
3894 if(*ppv) {
3895 IUnknown_AddRef((IUnknown*)*ppv);
3896 return S_OK;
3899 WARN("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
3900 return E_NOINTERFACE;
3903 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
3905 TRACE("(%p)\n", iface);
3906 return 2;
3909 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
3911 TRACE("(%p)\n", iface);
3912 return 1;
3915 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock)
3917 TRACE("(%p)->(%x)\n", iface, fLock);
3918 return S_OK;
3921 static const IClassFactoryVtbl ScriptControlFactoryVtbl = {
3922 ClassFactory_QueryInterface,
3923 ClassFactory_AddRef,
3924 ClassFactory_Release,
3925 ScriptControl_CreateInstance,
3926 ClassFactory_LockServer
3929 static IClassFactory ScriptControlFactory = { &ScriptControlFactoryVtbl };
3931 /***********************************************************************
3932 * DllGetClassObject (msscript.ocx.@)
3934 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
3936 if(IsEqualGUID(&CLSID_ScriptControl, rclsid)) {
3937 TRACE("(CLSID_ScriptControl %s %p)\n", debugstr_guid(riid), ppv);
3938 return IClassFactory_QueryInterface(&ScriptControlFactory, riid, ppv);
3941 FIXME("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
3942 return CLASS_E_CLASSNOTAVAILABLE;
3945 /***********************************************************************
3946 * DllCanUnloadNow (msscript.ocx.@)
3948 HRESULT WINAPI DllCanUnloadNow(void)
3950 TRACE("\n");
3951 return S_FALSE;
3954 /***********************************************************************
3955 * DllRegisterServer (msscript.ocx.@)
3957 HRESULT WINAPI DllRegisterServer(void)
3959 TRACE("()\n");
3960 return __wine_register_resources(msscript_instance);
3963 /***********************************************************************
3964 * DllUnregisterServer (msscript.ocx.@)
3966 HRESULT WINAPI DllUnregisterServer(void)
3968 TRACE("()\n");
3969 return __wine_unregister_resources(msscript_instance);