2 * Copyright 2011 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
25 #include "wine/debug.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(vbscript
);
31 #define CTXARG_T DWORDLONG
32 #define IActiveScriptDebugVtbl IActiveScriptDebug64Vtbl
33 #define IActiveScriptParseVtbl IActiveScriptParse64Vtbl
34 #define IActiveScriptParseProcedure2Vtbl IActiveScriptParseProcedure2_64Vtbl
38 #define CTXARG_T DWORD
39 #define IActiveScriptDebugVtbl IActiveScriptDebug32Vtbl
40 #define IActiveScriptParseVtbl IActiveScriptParse32Vtbl
41 #define IActiveScriptParseProcedure2Vtbl IActiveScriptParseProcedure2_32Vtbl
46 IActiveScript IActiveScript_iface
;
47 IActiveScriptDebug IActiveScriptDebug_iface
;
48 IActiveScriptParse IActiveScriptParse_iface
;
49 IActiveScriptParseProcedure2 IActiveScriptParseProcedure2_iface
;
50 IObjectSafety IObjectSafety_iface
;
61 IActiveScriptError IActiveScriptError_iface
;
69 static inline WCHAR
*heap_pool_strdup(heap_pool_t
*heap
, const WCHAR
*str
)
71 size_t size
= (lstrlenW(str
) + 1) * sizeof(WCHAR
);
72 WCHAR
*ret
= heap_pool_alloc(heap
, size
);
73 if (ret
) memcpy(ret
, str
, size
);
77 static void change_state(VBScript
*This
, SCRIPTSTATE state
)
79 if(This
->state
== state
)
84 IActiveScriptSite_OnStateChange(This
->ctx
->site
, state
);
87 static inline BOOL
is_started(VBScript
*This
)
89 return This
->state
== SCRIPTSTATE_STARTED
90 || This
->state
== SCRIPTSTATE_CONNECTED
91 || This
->state
== SCRIPTSTATE_DISCONNECTED
;
94 static HRESULT
exec_global_code(script_ctx_t
*ctx
, vbscode_t
*code
, VARIANT
*res
)
96 ScriptDisp
*obj
= ctx
->script_obj
;
97 function_t
*func_iter
, **new_funcs
;
98 dynamic_var_t
*var
, **new_vars
;
99 IServiceProvider
*prev_caller
;
103 if(code
->named_item
) {
104 if(!code
->named_item
->script_obj
) {
105 hres
= create_script_disp(ctx
, &code
->named_item
->script_obj
);
106 if(FAILED(hres
)) return hres
;
108 obj
= code
->named_item
->script_obj
;
111 cnt
= obj
->global_vars_cnt
+ code
->main_code
.var_cnt
;
112 if (cnt
> obj
->global_vars_size
)
114 if (obj
->global_vars
)
115 new_vars
= realloc(obj
->global_vars
, cnt
* sizeof(*new_vars
));
117 new_vars
= malloc(cnt
* sizeof(*new_vars
));
119 return E_OUTOFMEMORY
;
120 obj
->global_vars
= new_vars
;
121 obj
->global_vars_size
= cnt
;
124 cnt
= obj
->global_funcs_cnt
;
125 for (func_iter
= code
->funcs
; func_iter
; func_iter
= func_iter
->next
)
127 if (cnt
> obj
->global_funcs_size
)
129 if (obj
->global_funcs
)
130 new_funcs
= realloc(obj
->global_funcs
, cnt
* sizeof(*new_funcs
));
132 new_funcs
= malloc(cnt
* sizeof(*new_funcs
));
134 return E_OUTOFMEMORY
;
135 obj
->global_funcs
= new_funcs
;
136 obj
->global_funcs_size
= cnt
;
139 for (i
= 0; i
< code
->main_code
.var_cnt
; i
++)
141 if (!(var
= heap_pool_alloc(&obj
->heap
, sizeof(*var
))))
142 return E_OUTOFMEMORY
;
144 var
->name
= heap_pool_strdup(&obj
->heap
, code
->main_code
.vars
[i
].name
);
146 return E_OUTOFMEMORY
;
147 V_VT(&var
->v
) = VT_EMPTY
;
148 var
->is_const
= FALSE
;
151 obj
->global_vars
[obj
->global_vars_cnt
+ i
] = var
;
154 obj
->global_vars_cnt
+= code
->main_code
.var_cnt
;
156 for (func_iter
= code
->funcs
; func_iter
; func_iter
= func_iter
->next
)
158 for (i
= 0; i
< obj
->global_funcs_cnt
; i
++)
160 if (!wcsicmp(obj
->global_funcs
[i
]->name
, func_iter
->name
))
162 /* global function already exists, replace it */
163 obj
->global_funcs
[i
] = func_iter
;
167 if (i
== obj
->global_funcs_cnt
)
168 obj
->global_funcs
[obj
->global_funcs_cnt
++] = func_iter
;
173 class_desc_t
*class = code
->classes
;
183 class->next
= obj
->classes
;
184 obj
->classes
= code
->classes
;
185 code
->last_class
= class;
188 code
->pending_exec
= FALSE
;
190 prev_caller
= ctx
->vbcaller
->caller
;
191 ctx
->vbcaller
->caller
= SP_CALLER_UNINITIALIZED
;
192 hres
= exec_script(ctx
, TRUE
, &code
->main_code
, NULL
, NULL
, res
);
193 ctx
->vbcaller
->caller
= prev_caller
;
197 static void exec_queued_code(script_ctx_t
*ctx
)
201 LIST_FOR_EACH_ENTRY(iter
, &ctx
->code_list
, vbscode_t
, entry
) {
202 if(iter
->pending_exec
)
203 exec_global_code(ctx
, iter
, NULL
);
207 static HRESULT
retrieve_named_item_disp(IActiveScriptSite
*site
, named_item_t
*item
)
212 hres
= IActiveScriptSite_GetItemInfo(site
, item
->name
, SCRIPTINFO_IUNKNOWN
, &unk
, NULL
);
214 WARN("GetItemInfo failed: %08lx\n", hres
);
218 hres
= IUnknown_QueryInterface(unk
, &IID_IDispatch
, (void**)&item
->disp
);
219 IUnknown_Release(unk
);
221 WARN("object does not implement IDispatch\n");
228 named_item_t
*lookup_named_item(script_ctx_t
*ctx
, const WCHAR
*name
, unsigned flags
)
233 LIST_FOR_EACH_ENTRY(item
, &ctx
->named_items
, named_item_t
, entry
) {
234 if((item
->flags
& flags
) == flags
&& !wcsicmp(item
->name
, name
)) {
235 if(!item
->script_obj
&& !(item
->flags
& SCRIPTITEM_GLOBALMEMBERS
)) {
236 hres
= create_script_disp(ctx
, &item
->script_obj
);
237 if(FAILED(hres
)) return NULL
;
240 if(!item
->disp
&& (flags
|| !(item
->flags
& SCRIPTITEM_CODEONLY
))) {
241 hres
= retrieve_named_item_disp(ctx
->site
, item
);
242 if(FAILED(hres
)) continue;
252 static void release_named_item_script_obj(named_item_t
*item
)
254 if(!item
->script_obj
) return;
256 item
->script_obj
->ctx
= NULL
;
257 IDispatchEx_Release(&item
->script_obj
->IDispatchEx_iface
);
258 item
->script_obj
= NULL
;
261 void release_named_item(named_item_t
*item
)
263 if(--item
->ref
) return;
269 static void release_script(script_ctx_t
*ctx
)
271 named_item_t
*item
, *item_next
;
272 vbscode_t
*code
, *code_next
;
274 collect_objects(ctx
);
277 LIST_FOR_EACH_ENTRY_SAFE(code
, code_next
, &ctx
->code_list
, vbscode_t
, entry
)
279 if(code
->is_persistent
)
281 code
->pending_exec
= TRUE
;
282 if(code
->last_class
) code
->last_class
->next
= NULL
;
283 if(code
->named_item
) release_named_item_script_obj(code
->named_item
);
287 list_remove(&code
->entry
);
288 release_vbscode(code
);
292 LIST_FOR_EACH_ENTRY_SAFE(item
, item_next
, &ctx
->named_items
, named_item_t
, entry
)
296 IDispatch_Release(item
->disp
);
299 release_named_item_script_obj(item
);
300 if(!(item
->flags
& SCRIPTITEM_ISPERSISTENT
))
302 list_remove(&item
->entry
);
303 release_named_item(item
);
308 IInternetHostSecurityManager_Release(ctx
->secmgr
);
313 IActiveScriptSite_Release(ctx
->site
);
317 if(ctx
->script_obj
) {
318 ScriptDisp
*script_obj
= ctx
->script_obj
;
320 ctx
->script_obj
= NULL
;
321 script_obj
->ctx
= NULL
;
322 IDispatchEx_Release(&script_obj
->IDispatchEx_iface
);
326 static void release_code_list(script_ctx_t
*ctx
)
328 while(!list_empty(&ctx
->code_list
)) {
329 vbscode_t
*iter
= LIST_ENTRY(list_head(&ctx
->code_list
), vbscode_t
, entry
);
331 list_remove(&iter
->entry
);
332 release_vbscode(iter
);
336 static void release_named_item_list(script_ctx_t
*ctx
)
338 while(!list_empty(&ctx
->named_items
)) {
339 named_item_t
*iter
= LIST_ENTRY(list_head(&ctx
->named_items
), named_item_t
, entry
);
340 list_remove(&iter
->entry
);
341 release_named_item(iter
);
345 static void decrease_state(VBScript
*This
, SCRIPTSTATE state
)
347 switch(This
->state
) {
348 case SCRIPTSTATE_CONNECTED
:
349 change_state(This
, SCRIPTSTATE_DISCONNECTED
);
350 if(state
== SCRIPTSTATE_DISCONNECTED
)
353 case SCRIPTSTATE_STARTED
:
354 case SCRIPTSTATE_DISCONNECTED
:
355 change_state(This
, SCRIPTSTATE_INITIALIZED
);
357 case SCRIPTSTATE_INITIALIZED
:
358 case SCRIPTSTATE_UNINITIALIZED
:
359 change_state(This
, state
);
360 if(state
== SCRIPTSTATE_INITIALIZED
)
362 release_script(This
->ctx
);
364 if(state
== SCRIPTSTATE_CLOSED
) {
365 release_code_list(This
->ctx
);
366 release_named_item_list(This
->ctx
);
369 case SCRIPTSTATE_CLOSED
:
375 static inline struct vbcaller
*vbcaller_from_IServiceProvider(IServiceProvider
*iface
)
377 return CONTAINING_RECORD(iface
, struct vbcaller
, IServiceProvider_iface
);
380 static HRESULT WINAPI
vbcaller_QueryInterface(IServiceProvider
*iface
, REFIID riid
, void **ppv
)
382 struct vbcaller
*This
= vbcaller_from_IServiceProvider(iface
);
384 if(IsEqualGUID(&IID_IUnknown
, riid
) || IsEqualGUID(&IID_IServiceProvider
, riid
)) {
385 *ppv
= &This
->IServiceProvider_iface
;
387 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
389 return E_NOINTERFACE
;
392 IUnknown_AddRef((IUnknown
*)*ppv
);
396 static ULONG WINAPI
vbcaller_AddRef(IServiceProvider
*iface
)
398 struct vbcaller
*This
= vbcaller_from_IServiceProvider(iface
);
399 LONG ref
= InterlockedIncrement(&This
->ref
);
401 TRACE("(%p) ref=%ld\n", This
, ref
);
406 static ULONG WINAPI
vbcaller_Release(IServiceProvider
*iface
)
408 struct vbcaller
*This
= vbcaller_from_IServiceProvider(iface
);
409 LONG ref
= InterlockedDecrement(&This
->ref
);
411 TRACE("(%p) ref=%ld\n", This
, ref
);
419 static HRESULT WINAPI
vbcaller_QueryService(IServiceProvider
*iface
, REFGUID guidService
,
420 REFIID riid
, void **ppv
)
422 struct vbcaller
*This
= vbcaller_from_IServiceProvider(iface
);
424 if(IsEqualGUID(guidService
, &SID_GetCaller
)) {
425 TRACE("(%p)->(SID_GetCaller)\n", This
);
429 return (This
->caller
== SP_CALLER_UNINITIALIZED
) ? E_NOINTERFACE
: IServiceProvider_QueryInterface(This
->caller
, riid
, ppv
);
432 FIXME("(%p)->(%s %s %p)\n", This
, debugstr_guid(guidService
), debugstr_guid(riid
), ppv
);
435 return E_NOINTERFACE
;
438 static const IServiceProviderVtbl ServiceProviderVtbl
= {
439 vbcaller_QueryInterface
,
442 vbcaller_QueryService
445 static struct vbcaller
*create_vbcaller(void)
447 struct vbcaller
*ret
;
449 ret
= malloc(sizeof(*ret
));
451 ret
->IServiceProvider_iface
.lpVtbl
= &ServiceProviderVtbl
;
453 ret
->caller
= SP_CALLER_UNINITIALIZED
;
458 static inline VBScriptError
*impl_from_IActiveScriptError(IActiveScriptError
*iface
)
460 return CONTAINING_RECORD(iface
, VBScriptError
, IActiveScriptError_iface
);
463 static HRESULT WINAPI
VBScriptError_QueryInterface(IActiveScriptError
*iface
, REFIID riid
, void **ppv
)
465 VBScriptError
*This
= impl_from_IActiveScriptError(iface
);
467 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
468 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
469 *ppv
= &This
->IActiveScriptError_iface
;
470 }else if(IsEqualGUID(riid
, &IID_IActiveScriptError
)) {
471 TRACE("(%p)->(IID_IActiveScriptError %p)\n", This
, ppv
);
472 *ppv
= &This
->IActiveScriptError_iface
;
474 FIXME("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
476 return E_NOINTERFACE
;
479 IUnknown_AddRef((IUnknown
*)*ppv
);
483 static ULONG WINAPI
VBScriptError_AddRef(IActiveScriptError
*iface
)
485 VBScriptError
*This
= impl_from_IActiveScriptError(iface
);
486 LONG ref
= InterlockedIncrement(&This
->ref
);
488 TRACE("(%p) ref=%ld\n", This
, ref
);
493 static ULONG WINAPI
VBScriptError_Release(IActiveScriptError
*iface
)
495 VBScriptError
*This
= impl_from_IActiveScriptError(iface
);
496 LONG ref
= InterlockedDecrement(&This
->ref
);
498 TRACE("(%p) ref=%ld\n", This
, ref
);
506 static HRESULT WINAPI
VBScriptError_GetExceptionInfo(IActiveScriptError
*iface
, EXCEPINFO
*excepinfo
)
508 VBScriptError
*This
= impl_from_IActiveScriptError(iface
);
510 TRACE("(%p)->(%p)\n", This
, excepinfo
);
512 *excepinfo
= This
->ei
;
513 excepinfo
->bstrSource
= SysAllocString(This
->ei
.bstrSource
);
514 excepinfo
->bstrDescription
= SysAllocString(This
->ei
.bstrDescription
);
515 excepinfo
->bstrHelpFile
= SysAllocString(This
->ei
.bstrHelpFile
);
519 static HRESULT WINAPI
VBScriptError_GetSourcePosition(IActiveScriptError
*iface
, DWORD
*source_context
, ULONG
*line
, LONG
*character
)
521 VBScriptError
*This
= impl_from_IActiveScriptError(iface
);
523 TRACE("(%p)->(%p %p %p)\n", This
, source_context
, line
, character
);
526 *source_context
= This
->cookie
;
530 *character
= This
->character
;
534 static HRESULT WINAPI
VBScriptError_GetSourceLineText(IActiveScriptError
*iface
, BSTR
*source
)
536 VBScriptError
*This
= impl_from_IActiveScriptError(iface
);
537 FIXME("(%p)->(%p)\n", This
, source
);
541 static const IActiveScriptErrorVtbl VBScriptErrorVtbl
= {
542 VBScriptError_QueryInterface
,
543 VBScriptError_AddRef
,
544 VBScriptError_Release
,
545 VBScriptError_GetExceptionInfo
,
546 VBScriptError_GetSourcePosition
,
547 VBScriptError_GetSourceLineText
550 HRESULT
report_script_error(script_ctx_t
*ctx
, const vbscode_t
*code
, unsigned loc
)
552 VBScriptError
*error
;
554 HRESULT hres
, result
;
556 if(!(error
= malloc(sizeof(*error
))))
557 return E_OUTOFMEMORY
;
558 error
->IActiveScriptError_iface
.lpVtbl
= &VBScriptErrorVtbl
;
562 memset(&ctx
->ei
, 0, sizeof(ctx
->ei
));
563 result
= error
->ei
.scode
;
566 error
->cookie
= code
->cookie
;
567 error
->line
= code
->start_line
;
568 for(nl
= p
= code
->source
; p
< code
->source
+ loc
; p
++) {
569 if(*p
!= '\n') continue;
573 error
->character
= code
->source
+ loc
- nl
;
575 hres
= IActiveScriptSite_OnScriptError(ctx
->site
, &error
->IActiveScriptError_iface
);
576 IActiveScriptError_Release(&error
->IActiveScriptError_iface
);
577 return hres
== S_OK
? SCRIPT_E_REPORTED
: result
;
580 static inline VBScript
*impl_from_IActiveScript(IActiveScript
*iface
)
582 return CONTAINING_RECORD(iface
, VBScript
, IActiveScript_iface
);
585 static HRESULT WINAPI
VBScript_QueryInterface(IActiveScript
*iface
, REFIID riid
, void **ppv
)
587 VBScript
*This
= impl_from_IActiveScript(iface
);
589 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
590 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
591 *ppv
= &This
->IActiveScript_iface
;
592 }else if(IsEqualGUID(riid
, &IID_IActiveScript
)) {
593 TRACE("(%p)->(IID_IActiveScript %p)\n", This
, ppv
);
594 *ppv
= &This
->IActiveScript_iface
;
595 }else if(IsEqualGUID(riid
, &IID_IActiveScriptDebug
)) {
596 TRACE("(%p)->(IID_IActiveScriptDebug %p)\n", This
, ppv
);
597 *ppv
= &This
->IActiveScriptDebug_iface
;
598 }else if(IsEqualGUID(riid
, &IID_IActiveScriptParse
)) {
599 TRACE("(%p)->(IID_IActiveScriptParse %p)\n", This
, ppv
);
600 *ppv
= &This
->IActiveScriptParse_iface
;
601 }else if(IsEqualGUID(riid
, &IID_IActiveScriptParseProcedure2
)) {
602 TRACE("(%p)->(IID_IActiveScriptParseProcedure2 %p)\n", This
, ppv
);
603 *ppv
= &This
->IActiveScriptParseProcedure2_iface
;
604 }else if(IsEqualGUID(riid
, &IID_IObjectSafety
)) {
605 TRACE("(%p)->(IID_IObjectSafety %p)\n", This
, ppv
);
606 *ppv
= &This
->IObjectSafety_iface
;
608 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
610 return E_NOINTERFACE
;
613 IUnknown_AddRef((IUnknown
*)*ppv
);
617 static ULONG WINAPI
VBScript_AddRef(IActiveScript
*iface
)
619 VBScript
*This
= impl_from_IActiveScript(iface
);
620 LONG ref
= InterlockedIncrement(&This
->ref
);
622 TRACE("(%p) ref=%ld\n", This
, ref
);
627 static ULONG WINAPI
VBScript_Release(IActiveScript
*iface
)
629 VBScript
*This
= impl_from_IActiveScript(iface
);
630 LONG ref
= InterlockedDecrement(&This
->ref
);
632 TRACE("(%p) ref=%ld\n", iface
, ref
);
635 decrease_state(This
, SCRIPTSTATE_CLOSED
);
636 detach_global_objects(This
->ctx
);
637 IServiceProvider_Release(&This
->ctx
->vbcaller
->IServiceProvider_iface
);
645 static HRESULT WINAPI
VBScript_SetScriptSite(IActiveScript
*iface
, IActiveScriptSite
*pass
)
647 VBScript
*This
= impl_from_IActiveScript(iface
);
648 LCID lcid
= LOCALE_USER_DEFAULT
;
652 TRACE("(%p)->(%p)\n", This
, pass
);
660 if(InterlockedCompareExchange(&This
->thread_id
, GetCurrentThreadId(), 0))
663 /* Retrieve new dispatches for persistent named items */
664 LIST_FOR_EACH_ENTRY(item
, &This
->ctx
->named_items
, named_item_t
, entry
)
668 hres
= retrieve_named_item_disp(pass
, item
);
669 if(FAILED(hres
)) return hres
;
672 /* For some reason, CODEONLY flag is lost in re-initialized scripts */
673 item
->flags
&= ~SCRIPTITEM_CODEONLY
;
676 hres
= create_script_disp(This
->ctx
, &This
->ctx
->script_obj
);
680 This
->ctx
->site
= pass
;
681 IActiveScriptSite_AddRef(This
->ctx
->site
);
683 IActiveScriptSite_GetLCID(This
->ctx
->site
, &lcid
);
684 This
->ctx
->lcid
= IsValidLocale(lcid
, 0) ? lcid
: GetUserDefaultLCID();
685 GetLocaleInfoW(lcid
, LOCALE_IDEFAULTANSICODEPAGE
| LOCALE_RETURN_NUMBER
, (WCHAR
*)&This
->ctx
->codepage
,
686 sizeof(This
->ctx
->codepage
)/sizeof(WCHAR
));
687 if (!This
->ctx
->codepage
)
688 This
->ctx
->codepage
= CP_UTF8
;
690 if(This
->is_initialized
)
691 change_state(This
, SCRIPTSTATE_INITIALIZED
);
695 static HRESULT WINAPI
VBScript_GetScriptSite(IActiveScript
*iface
, REFIID riid
,
698 VBScript
*This
= impl_from_IActiveScript(iface
);
699 FIXME("(%p)->()\n", This
);
703 static HRESULT WINAPI
VBScript_SetScriptState(IActiveScript
*iface
, SCRIPTSTATE ss
)
705 VBScript
*This
= impl_from_IActiveScript(iface
);
707 TRACE("(%p)->(%d)\n", This
, ss
);
709 if(This
->thread_id
&& GetCurrentThreadId() != This
->thread_id
)
712 if(ss
== SCRIPTSTATE_UNINITIALIZED
) {
713 if(This
->state
== SCRIPTSTATE_CLOSED
)
716 decrease_state(This
, SCRIPTSTATE_UNINITIALIZED
);
720 if(!This
->is_initialized
|| (!This
->ctx
->site
&& ss
!= SCRIPTSTATE_CLOSED
))
724 case SCRIPTSTATE_STARTED
:
725 case SCRIPTSTATE_CONNECTED
: /* FIXME */
726 if(This
->state
== SCRIPTSTATE_CLOSED
)
729 exec_queued_code(This
->ctx
);
731 case SCRIPTSTATE_INITIALIZED
:
732 decrease_state(This
, SCRIPTSTATE_INITIALIZED
);
734 case SCRIPTSTATE_CLOSED
:
735 decrease_state(This
, SCRIPTSTATE_CLOSED
);
737 case SCRIPTSTATE_DISCONNECTED
:
738 FIXME("unimplemented SCRIPTSTATE_DISCONNECTED\n");
741 FIXME("unimplemented state %d\n", ss
);
745 change_state(This
, ss
);
749 static HRESULT WINAPI
VBScript_GetScriptState(IActiveScript
*iface
, SCRIPTSTATE
*pssState
)
751 VBScript
*This
= impl_from_IActiveScript(iface
);
753 TRACE("(%p)->(%p)\n", This
, pssState
);
758 if(This
->thread_id
&& This
->thread_id
!= GetCurrentThreadId())
761 *pssState
= This
->state
;
765 static HRESULT WINAPI
VBScript_Close(IActiveScript
*iface
)
767 VBScript
*This
= impl_from_IActiveScript(iface
);
769 TRACE("(%p)->()\n", This
);
771 if(This
->thread_id
&& This
->thread_id
!= GetCurrentThreadId())
774 decrease_state(This
, SCRIPTSTATE_CLOSED
);
778 static HRESULT WINAPI
VBScript_AddNamedItem(IActiveScript
*iface
, LPCOLESTR pstrName
, DWORD dwFlags
)
780 VBScript
*This
= impl_from_IActiveScript(iface
);
782 IDispatch
*disp
= NULL
;
785 TRACE("(%p)->(%s %lx)\n", This
, debugstr_w(pstrName
), dwFlags
);
787 if(This
->thread_id
!= GetCurrentThreadId() || !This
->ctx
->site
)
790 if(dwFlags
& SCRIPTITEM_GLOBALMEMBERS
) {
793 hres
= IActiveScriptSite_GetItemInfo(This
->ctx
->site
, pstrName
, SCRIPTINFO_IUNKNOWN
, &unk
, NULL
);
795 WARN("GetItemInfo failed: %08lx\n", hres
);
799 hres
= IUnknown_QueryInterface(unk
, &IID_IDispatch
, (void**)&disp
);
800 IUnknown_Release(unk
);
802 WARN("object does not implement IDispatch\n");
807 item
= malloc(sizeof(*item
));
810 IDispatch_Release(disp
);
811 return E_OUTOFMEMORY
;
816 item
->flags
= dwFlags
;
817 item
->script_obj
= NULL
;
818 item
->name
= wcsdup(pstrName
);
821 IDispatch_Release(disp
);
823 return E_OUTOFMEMORY
;
826 list_add_tail(&This
->ctx
->named_items
, &item
->entry
);
830 static HRESULT WINAPI
VBScript_AddTypeLib(IActiveScript
*iface
, REFGUID rguidTypeLib
,
831 DWORD dwMajor
, DWORD dwMinor
, DWORD dwFlags
)
833 VBScript
*This
= impl_from_IActiveScript(iface
);
834 FIXME("(%p)->(%s %ld %ld %ld)\n", This
, debugstr_guid(rguidTypeLib
), dwMajor
, dwMinor
, dwFlags
);
838 static HRESULT WINAPI
VBScript_GetScriptDispatch(IActiveScript
*iface
, LPCOLESTR pstrItemName
, IDispatch
**ppdisp
)
840 VBScript
*This
= impl_from_IActiveScript(iface
);
841 ScriptDisp
*script_obj
;
843 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(pstrItemName
), ppdisp
);
848 if(This
->thread_id
!= GetCurrentThreadId() || !This
->ctx
->script_obj
) {
853 script_obj
= This
->ctx
->script_obj
;
855 named_item_t
*item
= lookup_named_item(This
->ctx
, pstrItemName
, 0);
856 if(!item
) return E_INVALIDARG
;
857 if(item
->script_obj
) script_obj
= item
->script_obj
;
860 *ppdisp
= (IDispatch
*)&script_obj
->IDispatchEx_iface
;
861 IDispatch_AddRef(*ppdisp
);
865 static HRESULT WINAPI
VBScript_GetCurrentScriptThreadID(IActiveScript
*iface
,
866 SCRIPTTHREADID
*pstridThread
)
868 VBScript
*This
= impl_from_IActiveScript(iface
);
869 FIXME("(%p)->()\n", This
);
873 static HRESULT WINAPI
VBScript_GetScriptThreadID(IActiveScript
*iface
,
874 DWORD dwWin32ThreadId
, SCRIPTTHREADID
*pstidThread
)
876 VBScript
*This
= impl_from_IActiveScript(iface
);
877 FIXME("(%p)->()\n", This
);
881 static HRESULT WINAPI
VBScript_GetScriptThreadState(IActiveScript
*iface
,
882 SCRIPTTHREADID stidThread
, SCRIPTTHREADSTATE
*pstsState
)
884 VBScript
*This
= impl_from_IActiveScript(iface
);
885 FIXME("(%p)->()\n", This
);
889 static HRESULT WINAPI
VBScript_InterruptScriptThread(IActiveScript
*iface
,
890 SCRIPTTHREADID stidThread
, const EXCEPINFO
*pexcepinfo
, DWORD dwFlags
)
892 VBScript
*This
= impl_from_IActiveScript(iface
);
893 FIXME("(%p)->()\n", This
);
897 static HRESULT WINAPI
VBScript_Clone(IActiveScript
*iface
, IActiveScript
**ppscript
)
899 VBScript
*This
= impl_from_IActiveScript(iface
);
900 FIXME("(%p)->()\n", This
);
904 static const IActiveScriptVtbl VBScriptVtbl
= {
905 VBScript_QueryInterface
,
908 VBScript_SetScriptSite
,
909 VBScript_GetScriptSite
,
910 VBScript_SetScriptState
,
911 VBScript_GetScriptState
,
913 VBScript_AddNamedItem
,
915 VBScript_GetScriptDispatch
,
916 VBScript_GetCurrentScriptThreadID
,
917 VBScript_GetScriptThreadID
,
918 VBScript_GetScriptThreadState
,
919 VBScript_InterruptScriptThread
,
923 static inline VBScript
*impl_from_IActiveScriptDebug(IActiveScriptDebug
*iface
)
925 return CONTAINING_RECORD(iface
, VBScript
, IActiveScriptDebug_iface
);
928 static HRESULT WINAPI
VBScriptDebug_QueryInterface(IActiveScriptDebug
*iface
, REFIID riid
, void **ppv
)
930 VBScript
*This
= impl_from_IActiveScriptDebug(iface
);
931 return IActiveScript_QueryInterface(&This
->IActiveScript_iface
, riid
, ppv
);
934 static ULONG WINAPI
VBScriptDebug_AddRef(IActiveScriptDebug
*iface
)
936 VBScript
*This
= impl_from_IActiveScriptDebug(iface
);
937 return IActiveScript_AddRef(&This
->IActiveScript_iface
);
940 static ULONG WINAPI
VBScriptDebug_Release(IActiveScriptDebug
*iface
)
942 VBScript
*This
= impl_from_IActiveScriptDebug(iface
);
943 return IActiveScript_Release(&This
->IActiveScript_iface
);
946 static HRESULT WINAPI
VBScriptDebug_GetScriptTextAttributes(IActiveScriptDebug
*iface
,
947 LPCOLESTR code
, ULONG len
, LPCOLESTR delimiter
, DWORD flags
, SOURCE_TEXT_ATTR
*attr
)
949 VBScript
*This
= impl_from_IActiveScriptDebug(iface
);
950 FIXME("(%p)->(%s %lu %s %#lx %p)\n", This
, debugstr_w(code
), len
,
951 debugstr_w(delimiter
), flags
, attr
);
955 static HRESULT WINAPI
VBScriptDebug_GetScriptletTextAttributes(IActiveScriptDebug
*iface
,
956 LPCOLESTR code
, ULONG len
, LPCOLESTR delimiter
, DWORD flags
, SOURCE_TEXT_ATTR
*attr
)
958 VBScript
*This
= impl_from_IActiveScriptDebug(iface
);
959 FIXME("(%p)->(%s %lu %s %#lx %p)\n", This
, debugstr_w(code
), len
,
960 debugstr_w(delimiter
), flags
, attr
);
964 static HRESULT WINAPI
VBScriptDebug_EnumCodeContextsOfPosition(IActiveScriptDebug
*iface
,
965 CTXARG_T source
, ULONG offset
, ULONG len
, IEnumDebugCodeContexts
**ret
)
967 VBScript
*This
= impl_from_IActiveScriptDebug(iface
);
968 FIXME("(%p)->(%s %lu %lu %p)\n", This
, wine_dbgstr_longlong(source
), offset
, len
, ret
);
972 static const IActiveScriptDebugVtbl VBScriptDebugVtbl
= {
973 VBScriptDebug_QueryInterface
,
974 VBScriptDebug_AddRef
,
975 VBScriptDebug_Release
,
976 VBScriptDebug_GetScriptTextAttributes
,
977 VBScriptDebug_GetScriptletTextAttributes
,
978 VBScriptDebug_EnumCodeContextsOfPosition
,
981 static inline VBScript
*impl_from_IActiveScriptParse(IActiveScriptParse
*iface
)
983 return CONTAINING_RECORD(iface
, VBScript
, IActiveScriptParse_iface
);
986 static HRESULT WINAPI
VBScriptParse_QueryInterface(IActiveScriptParse
*iface
, REFIID riid
, void **ppv
)
988 VBScript
*This
= impl_from_IActiveScriptParse(iface
);
989 return IActiveScript_QueryInterface(&This
->IActiveScript_iface
, riid
, ppv
);
992 static ULONG WINAPI
VBScriptParse_AddRef(IActiveScriptParse
*iface
)
994 VBScript
*This
= impl_from_IActiveScriptParse(iface
);
995 return IActiveScript_AddRef(&This
->IActiveScript_iface
);
998 static ULONG WINAPI
VBScriptParse_Release(IActiveScriptParse
*iface
)
1000 VBScript
*This
= impl_from_IActiveScriptParse(iface
);
1001 return IActiveScript_Release(&This
->IActiveScript_iface
);
1004 static HRESULT WINAPI
VBScriptParse_InitNew(IActiveScriptParse
*iface
)
1006 VBScript
*This
= impl_from_IActiveScriptParse(iface
);
1008 TRACE("(%p)\n", This
);
1010 if(This
->is_initialized
)
1011 return E_UNEXPECTED
;
1012 This
->is_initialized
= TRUE
;
1015 change_state(This
, SCRIPTSTATE_INITIALIZED
);
1019 static HRESULT WINAPI
VBScriptParse_AddScriptlet(IActiveScriptParse
*iface
,
1020 LPCOLESTR pstrDefaultName
, LPCOLESTR pstrCode
, LPCOLESTR pstrItemName
,
1021 LPCOLESTR pstrSubItemName
, LPCOLESTR pstrEventName
, LPCOLESTR pstrDelimiter
,
1022 CTXARG_T dwSourceContextCookie
, ULONG ulStartingLineNumber
, DWORD dwFlags
,
1023 BSTR
*pbstrName
, EXCEPINFO
*pexcepinfo
)
1025 VBScript
*This
= impl_from_IActiveScriptParse(iface
);
1026 FIXME("(%p)->(%s %s %s %s %s %s %s %lu %lx %p %p)\n", This
, debugstr_w(pstrDefaultName
),
1027 debugstr_w(pstrCode
), debugstr_w(pstrItemName
), debugstr_w(pstrSubItemName
),
1028 debugstr_w(pstrEventName
), debugstr_w(pstrDelimiter
), wine_dbgstr_longlong(dwSourceContextCookie
),
1029 ulStartingLineNumber
, dwFlags
, pbstrName
, pexcepinfo
);
1033 static HRESULT WINAPI
VBScriptParse_ParseScriptText(IActiveScriptParse
*iface
,
1034 LPCOLESTR pstrCode
, LPCOLESTR pstrItemName
, IUnknown
*punkContext
,
1035 LPCOLESTR pstrDelimiter
, CTXARG_T dwSourceContextCookie
, ULONG ulStartingLine
,
1036 DWORD dwFlags
, VARIANT
*pvarResult
, EXCEPINFO
*pexcepinfo
)
1038 VBScript
*This
= impl_from_IActiveScriptParse(iface
);
1042 TRACE("(%p)->(%s %s %p %s %s %lu %lx %p %p)\n", This
, debugstr_w(pstrCode
),
1043 debugstr_w(pstrItemName
), punkContext
, debugstr_w(pstrDelimiter
),
1044 wine_dbgstr_longlong(dwSourceContextCookie
), ulStartingLine
, dwFlags
, pvarResult
, pexcepinfo
);
1046 if(This
->thread_id
!= GetCurrentThreadId() || This
->state
== SCRIPTSTATE_CLOSED
)
1047 return E_UNEXPECTED
;
1049 hres
= compile_script(This
->ctx
, pstrCode
, pstrItemName
, pstrDelimiter
, dwSourceContextCookie
,
1050 ulStartingLine
, dwFlags
, &code
);
1054 if(!(dwFlags
& SCRIPTTEXT_ISEXPRESSION
) && !is_started(This
)) {
1055 code
->pending_exec
= TRUE
;
1059 return exec_global_code(This
->ctx
, code
, pvarResult
);
1062 static const IActiveScriptParseVtbl VBScriptParseVtbl
= {
1063 VBScriptParse_QueryInterface
,
1064 VBScriptParse_AddRef
,
1065 VBScriptParse_Release
,
1066 VBScriptParse_InitNew
,
1067 VBScriptParse_AddScriptlet
,
1068 VBScriptParse_ParseScriptText
1071 static inline VBScript
*impl_from_IActiveScriptParseProcedure2(IActiveScriptParseProcedure2
*iface
)
1073 return CONTAINING_RECORD(iface
, VBScript
, IActiveScriptParseProcedure2_iface
);
1076 static HRESULT WINAPI
VBScriptParseProcedure_QueryInterface(IActiveScriptParseProcedure2
*iface
, REFIID riid
, void **ppv
)
1078 VBScript
*This
= impl_from_IActiveScriptParseProcedure2(iface
);
1079 return IActiveScript_QueryInterface(&This
->IActiveScript_iface
, riid
, ppv
);
1082 static ULONG WINAPI
VBScriptParseProcedure_AddRef(IActiveScriptParseProcedure2
*iface
)
1084 VBScript
*This
= impl_from_IActiveScriptParseProcedure2(iface
);
1085 return IActiveScript_AddRef(&This
->IActiveScript_iface
);
1088 static ULONG WINAPI
VBScriptParseProcedure_Release(IActiveScriptParseProcedure2
*iface
)
1090 VBScript
*This
= impl_from_IActiveScriptParseProcedure2(iface
);
1091 return IActiveScript_Release(&This
->IActiveScript_iface
);
1094 static HRESULT WINAPI
VBScriptParseProcedure_ParseProcedureText(IActiveScriptParseProcedure2
*iface
,
1095 LPCOLESTR pstrCode
, LPCOLESTR pstrFormalParams
, LPCOLESTR pstrProcedureName
,
1096 LPCOLESTR pstrItemName
, IUnknown
*punkContext
, LPCOLESTR pstrDelimiter
,
1097 CTXARG_T dwSourceContextCookie
, ULONG ulStartingLineNumber
, DWORD dwFlags
, IDispatch
**ppdisp
)
1099 VBScript
*This
= impl_from_IActiveScriptParseProcedure2(iface
);
1104 TRACE("(%p)->(%s %s %s %s %p %s %s %lu %lx %p)\n", This
, debugstr_w(pstrCode
), debugstr_w(pstrFormalParams
),
1105 debugstr_w(pstrProcedureName
), debugstr_w(pstrItemName
), punkContext
, debugstr_w(pstrDelimiter
),
1106 wine_dbgstr_longlong(dwSourceContextCookie
), ulStartingLineNumber
, dwFlags
, ppdisp
);
1108 if(This
->thread_id
!= GetCurrentThreadId() || This
->state
== SCRIPTSTATE_CLOSED
)
1109 return E_UNEXPECTED
;
1111 hres
= compile_procedure(This
->ctx
, pstrCode
, pstrItemName
, pstrDelimiter
, dwSourceContextCookie
,
1112 ulStartingLineNumber
, dwFlags
, &desc
);
1116 hres
= create_vbdisp(desc
, &vbdisp
);
1120 *ppdisp
= (IDispatch
*)&vbdisp
->IDispatchEx_iface
;
1124 static const IActiveScriptParseProcedure2Vtbl VBScriptParseProcedureVtbl
= {
1125 VBScriptParseProcedure_QueryInterface
,
1126 VBScriptParseProcedure_AddRef
,
1127 VBScriptParseProcedure_Release
,
1128 VBScriptParseProcedure_ParseProcedureText
,
1131 static inline VBScript
*impl_from_IObjectSafety(IObjectSafety
*iface
)
1133 return CONTAINING_RECORD(iface
, VBScript
, IObjectSafety_iface
);
1136 static HRESULT WINAPI
VBScriptSafety_QueryInterface(IObjectSafety
*iface
, REFIID riid
, void **ppv
)
1138 VBScript
*This
= impl_from_IObjectSafety(iface
);
1139 return IActiveScript_QueryInterface(&This
->IActiveScript_iface
, riid
, ppv
);
1142 static ULONG WINAPI
VBScriptSafety_AddRef(IObjectSafety
*iface
)
1144 VBScript
*This
= impl_from_IObjectSafety(iface
);
1145 return IActiveScript_AddRef(&This
->IActiveScript_iface
);
1148 static ULONG WINAPI
VBScriptSafety_Release(IObjectSafety
*iface
)
1150 VBScript
*This
= impl_from_IObjectSafety(iface
);
1151 return IActiveScript_Release(&This
->IActiveScript_iface
);
1154 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER)
1156 static HRESULT WINAPI
VBScriptSafety_GetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
1157 DWORD
*pdwSupportedOptions
, DWORD
*pdwEnabledOptions
)
1159 VBScript
*This
= impl_from_IObjectSafety(iface
);
1161 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_guid(riid
), pdwSupportedOptions
, pdwEnabledOptions
);
1163 if(!pdwSupportedOptions
|| !pdwEnabledOptions
)
1166 *pdwSupportedOptions
= SUPPORTED_OPTIONS
;
1167 *pdwEnabledOptions
= This
->ctx
->safeopt
;
1171 static HRESULT WINAPI
VBScriptSafety_SetInterfaceSafetyOptions(IObjectSafety
*iface
, REFIID riid
,
1172 DWORD dwOptionSetMask
, DWORD dwEnabledOptions
)
1174 VBScript
*This
= impl_from_IObjectSafety(iface
);
1176 TRACE("(%p)->(%s %lx %lx)\n", This
, debugstr_guid(riid
), dwOptionSetMask
, dwEnabledOptions
);
1178 if(dwOptionSetMask
& ~SUPPORTED_OPTIONS
)
1181 This
->ctx
->safeopt
= (dwEnabledOptions
& dwOptionSetMask
) | (This
->ctx
->safeopt
& ~dwOptionSetMask
) | INTERFACE_USES_DISPEX
;
1185 static const IObjectSafetyVtbl VBScriptSafetyVtbl
= {
1186 VBScriptSafety_QueryInterface
,
1187 VBScriptSafety_AddRef
,
1188 VBScriptSafety_Release
,
1189 VBScriptSafety_GetInterfaceSafetyOptions
,
1190 VBScriptSafety_SetInterfaceSafetyOptions
1193 HRESULT WINAPI
VBScriptFactory_CreateInstance(IClassFactory
*iface
, IUnknown
*pUnkOuter
, REFIID riid
, void **ppv
)
1195 struct vbcaller
*vbcaller
;
1200 TRACE("(%p %s %p)\n", pUnkOuter
, debugstr_guid(riid
), ppv
);
1202 ret
= calloc(1, sizeof(*ret
));
1204 return E_OUTOFMEMORY
;
1206 if(!(vbcaller
= create_vbcaller())) {
1208 return E_OUTOFMEMORY
;
1211 ret
->IActiveScript_iface
.lpVtbl
= &VBScriptVtbl
;
1212 ret
->IActiveScriptDebug_iface
.lpVtbl
= &VBScriptDebugVtbl
;
1213 ret
->IActiveScriptParse_iface
.lpVtbl
= &VBScriptParseVtbl
;
1214 ret
->IActiveScriptParseProcedure2_iface
.lpVtbl
= &VBScriptParseProcedureVtbl
;
1215 ret
->IObjectSafety_iface
.lpVtbl
= &VBScriptSafetyVtbl
;
1218 ret
->state
= SCRIPTSTATE_UNINITIALIZED
;
1220 ctx
= ret
->ctx
= calloc(1, sizeof(*ctx
));
1222 IServiceProvider_Release(&vbcaller
->IServiceProvider_iface
);
1224 return E_OUTOFMEMORY
;
1227 ctx
->vbcaller
= vbcaller
;
1228 ctx
->safeopt
= INTERFACE_USES_DISPEX
;
1229 list_init(&ctx
->objects
);
1230 list_init(&ctx
->code_list
);
1231 list_init(&ctx
->named_items
);
1233 hres
= init_global(ctx
);
1235 IActiveScript_Release(&ret
->IActiveScript_iface
);
1239 hres
= IActiveScript_QueryInterface(&ret
->IActiveScript_iface
, riid
, ppv
);
1240 IActiveScript_Release(&ret
->IActiveScript_iface
);
1245 IServiceProvider IServiceProvider_iface
;
1249 IServiceProvider
*sp
;
1252 static inline AXSite
*impl_from_IServiceProvider(IServiceProvider
*iface
)
1254 return CONTAINING_RECORD(iface
, AXSite
, IServiceProvider_iface
);
1257 static HRESULT WINAPI
AXSite_QueryInterface(IServiceProvider
*iface
, REFIID riid
, void **ppv
)
1259 AXSite
*This
= impl_from_IServiceProvider(iface
);
1261 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
1262 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
1263 *ppv
= &This
->IServiceProvider_iface
;
1264 }else if(IsEqualGUID(&IID_IServiceProvider
, riid
)) {
1265 TRACE("(%p)->(IID_IServiceProvider %p)\n", This
, ppv
);
1266 *ppv
= &This
->IServiceProvider_iface
;
1268 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
1270 return E_NOINTERFACE
;
1273 IUnknown_AddRef((IUnknown
*)*ppv
);
1277 static ULONG WINAPI
AXSite_AddRef(IServiceProvider
*iface
)
1279 AXSite
*This
= impl_from_IServiceProvider(iface
);
1280 LONG ref
= InterlockedIncrement(&This
->ref
);
1282 TRACE("(%p) ref=%ld\n", This
, ref
);
1287 static ULONG WINAPI
AXSite_Release(IServiceProvider
*iface
)
1289 AXSite
*This
= impl_from_IServiceProvider(iface
);
1290 LONG ref
= InterlockedDecrement(&This
->ref
);
1292 TRACE("(%p) ref=%ld\n", This
, ref
);
1300 static HRESULT WINAPI
AXSite_QueryService(IServiceProvider
*iface
,
1301 REFGUID guidService
, REFIID riid
, void **ppv
)
1303 AXSite
*This
= impl_from_IServiceProvider(iface
);
1305 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_guid(guidService
), debugstr_guid(riid
), ppv
);
1307 return IServiceProvider_QueryService(This
->sp
, guidService
, riid
, ppv
);
1310 static IServiceProviderVtbl AXSiteVtbl
= {
1311 AXSite_QueryInterface
,
1317 IUnknown
*create_ax_site(script_ctx_t
*ctx
)
1319 IServiceProvider
*sp
;
1323 hres
= IActiveScriptSite_QueryInterface(ctx
->site
, &IID_IServiceProvider
, (void**)&sp
);
1325 ERR("Could not get IServiceProvider iface: %08lx\n", hres
);
1329 ret
= malloc(sizeof(*ret
));
1331 IServiceProvider_Release(sp
);
1335 ret
->IServiceProvider_iface
.lpVtbl
= &AXSiteVtbl
;
1339 return (IUnknown
*)&ret
->IServiceProvider_iface
;