jscript: Added IActiveScript::GetScriptState implementation.
[wine] / dlls / jscript / jscript.c
1 /*
2  * Copyright 2008 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include "jscript.h"
20 #include "objsafe.h"
21
22 #include "wine/debug.h"
23
24 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
25
26 typedef struct {
27     const IActiveScriptVtbl                 *lpIActiveScriptVtbl;
28     const IActiveScriptParseVtbl            *lpIActiveScriptParseVtbl;
29     const IActiveScriptParseProcedure2Vtbl  *lpIActiveScriptParseProcedure2Vtbl;
30     const IActiveScriptPropertyVtbl         *lpIActiveScriptPropertyVtbl;
31     const IObjectSafetyVtbl                 *lpIObjectSafetyVtbl;
32
33     LONG ref;
34
35     DWORD safeopt;
36     script_ctx_t *ctx;
37     LONG thread_id;
38
39     IActiveScriptSite *site;
40 } JScript;
41
42 #define ACTSCRIPT(x)    ((IActiveScript*)                 &(x)->lpIActiveScriptVtbl)
43 #define ASPARSE(x)      ((IActiveScriptParse*)            &(x)->lpIActiveScriptParseVtbl)
44 #define ASPARSEPROC(x)  ((IActiveScriptParseProcedure2*)  &(x)->lpIActiveScriptParseProcedure2Vtbl)
45 #define ACTSCPPROP(x)   ((IActiveScriptProperty*)         &(x)->lpIActiveScriptPropertyVtbl)
46 #define OBJSAFETY(x)    ((IObjectSafety*)                 &(x)->lpIObjectSafetyVtbl)
47
48 void script_release(script_ctx_t *ctx)
49 {
50     if(--ctx->ref)
51         return;
52
53     heap_free(ctx);
54 }
55
56 static void change_state(JScript *This, SCRIPTSTATE state)
57 {
58     if(This->ctx->state == state)
59         return;
60
61     This->ctx->state = state;
62     IActiveScriptSite_OnStateChange(This->site, state);
63 }
64
65 #define ACTSCRIPT_THIS(iface) DEFINE_THIS(JScript, IActiveScript, iface)
66
67 static HRESULT WINAPI JScript_QueryInterface(IActiveScript *iface, REFIID riid, void **ppv)
68 {
69     JScript *This = ACTSCRIPT_THIS(iface);
70
71     *ppv = NULL;
72
73     if(IsEqualGUID(riid, &IID_IUnknown)) {
74         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
75         *ppv = ACTSCRIPT(This);
76     }else if(IsEqualGUID(riid, &IID_IActiveScript)) {
77         TRACE("(%p)->(IID_IActiveScript %p)\n", This, ppv);
78         *ppv = ACTSCRIPT(This);
79     }else if(IsEqualGUID(riid, &IID_IActiveScriptParse)) {
80         TRACE("(%p)->(IID_IActiveScriptParse %p)\n", This, ppv);
81         *ppv = ASPARSE(This);
82     }else if(IsEqualGUID(riid, &IID_IActiveScriptParseProcedure)) {
83         TRACE("(%p)->(IID_IActiveScriptParseProcedure %p)\n", This, ppv);
84         *ppv = ASPARSEPROC(This);
85     }else if(IsEqualGUID(riid, &IID_IActiveScriptParseProcedure2)) {
86         TRACE("(%p)->(IID_IActiveScriptParseProcedure2 %p)\n", This, ppv);
87         *ppv = ASPARSEPROC(This);
88     }else if(IsEqualGUID(riid, &IID_IActiveScriptProperty)) {
89         TRACE("(%p)->(IID_IActiveScriptProperty %p)\n", This, ppv);
90         *ppv = ACTSCPPROP(This);
91     }else if(IsEqualGUID(riid, &IID_IObjectSafety)) {
92         TRACE("(%p)->(IID_IObjectSafety %p)\n", This, ppv);
93         *ppv = OBJSAFETY(This);
94     }
95
96     if(*ppv) {
97         IUnknown_AddRef((IUnknown*)*ppv);
98         return S_OK;
99     }
100
101     FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
102     return E_NOINTERFACE;
103 }
104
105 static ULONG WINAPI JScript_AddRef(IActiveScript *iface)
106 {
107     JScript *This = ACTSCRIPT_THIS(iface);
108     LONG ref = InterlockedIncrement(&This->ref);
109
110     TRACE("(%p) ref=%d\n", This, ref);
111
112     return ref;
113 }
114
115 static ULONG WINAPI JScript_Release(IActiveScript *iface)
116 {
117     JScript *This = ACTSCRIPT_THIS(iface);
118     LONG ref = InterlockedDecrement(&This->ref);
119
120     TRACE("(%p) ref=%d\n", iface, ref);
121
122     if(!ref) {
123         if(This->ctx && This->ctx->state != SCRIPTSTATE_CLOSED)
124             IActiveScript_Close(ACTSCRIPT(This));
125         if(This->ctx)
126             script_release(This->ctx);
127         heap_free(This);
128         unlock_module();
129     }
130
131     return ref;
132 }
133
134 static HRESULT WINAPI JScript_SetScriptSite(IActiveScript *iface,
135                                             IActiveScriptSite *pass)
136 {
137     JScript *This = ACTSCRIPT_THIS(iface);
138     LCID lcid;
139     HRESULT hres;
140
141     TRACE("(%p)->(%p)\n", This, pass);
142
143     if(!pass)
144         return E_POINTER;
145
146     if(This->site)
147         return E_UNEXPECTED;
148
149     if(!This->ctx) {
150         hres = IActiveScriptParse_InitNew(ASPARSE(This));
151         if(FAILED(hres))
152             return hres;
153     }
154
155     hres = create_dispex(This->ctx, &This->ctx->script_disp);
156     if(FAILED(hres))
157         return hres;
158
159     if(InterlockedCompareExchange(&This->thread_id, GetCurrentThreadId(), 0))
160         return E_UNEXPECTED;
161
162     This->site = pass;
163     IActiveScriptSite_AddRef(This->site);
164
165     hres = IActiveScriptSite_GetLCID(This->site, &lcid);
166     if(hres == S_OK)
167         This->ctx->lcid = lcid;
168
169     change_state(This, SCRIPTSTATE_INITIALIZED);
170     return S_OK;
171 }
172
173 static HRESULT WINAPI JScript_GetScriptSite(IActiveScript *iface, REFIID riid,
174                                             void **ppvObject)
175 {
176     JScript *This = ACTSCRIPT_THIS(iface);
177     FIXME("(%p)->()\n", This);
178     return E_NOTIMPL;
179 }
180
181 static HRESULT WINAPI JScript_SetScriptState(IActiveScript *iface, SCRIPTSTATE ss)
182 {
183     JScript *This = ACTSCRIPT_THIS(iface);
184     FIXME("(%p)->(%d)\n", This, ss);
185     return E_NOTIMPL;
186 }
187
188 static HRESULT WINAPI JScript_GetScriptState(IActiveScript *iface, SCRIPTSTATE *pssState)
189 {
190     JScript *This = ACTSCRIPT_THIS(iface);
191
192     TRACE("(%p)->(%p)\n", This, pssState);
193
194     if(!pssState)
195         return E_POINTER;
196
197     if(!This->thread_id) {
198         *pssState = SCRIPTSTATE_UNINITIALIZED;
199         return S_OK;
200     }
201
202     if(This->thread_id != GetCurrentThreadId())
203         return E_UNEXPECTED;
204
205     *pssState = This->ctx ? This->ctx->state : SCRIPTSTATE_UNINITIALIZED;
206     return S_OK;
207 }
208
209 static HRESULT WINAPI JScript_Close(IActiveScript *iface)
210 {
211     JScript *This = ACTSCRIPT_THIS(iface);
212
213     TRACE("(%p)->()\n", This);
214
215     if(This->thread_id != GetCurrentThreadId())
216         return E_UNEXPECTED;
217
218     if(This->ctx) {
219         change_state(This, SCRIPTSTATE_CLOSED);
220
221         if(This->ctx->script_disp) {
222             IDispatchEx_Release(_IDispatchEx_(This->ctx->script_disp));
223             This->ctx->script_disp = NULL;
224         }
225     }
226
227     if(This->site) {
228         IActiveScriptSite_Release(This->site);
229         This->site = NULL;
230     }
231
232     return S_OK;
233 }
234
235 static HRESULT WINAPI JScript_AddNamedItem(IActiveScript *iface,
236                                            LPCOLESTR pstrName, DWORD dwFlags)
237 {
238     JScript *This = ACTSCRIPT_THIS(iface);
239     FIXME("(%p)->(%s %x)\n", This, debugstr_w(pstrName), dwFlags);
240     return E_NOTIMPL;
241 }
242
243 static HRESULT WINAPI JScript_AddTypeLib(IActiveScript *iface, REFGUID rguidTypeLib,
244                                          DWORD dwMajor, DWORD dwMinor, DWORD dwFlags)
245 {
246     JScript *This = ACTSCRIPT_THIS(iface);
247     FIXME("(%p)->()\n", This);
248     return E_NOTIMPL;
249 }
250
251 static HRESULT WINAPI JScript_GetScriptDispatch(IActiveScript *iface, LPCOLESTR pstrItemName,
252                                                 IDispatch **ppdisp)
253 {
254     JScript *This = ACTSCRIPT_THIS(iface);
255
256     TRACE("(%p)->(%p)\n", This, ppdisp);
257
258     if(!ppdisp)
259         return E_POINTER;
260
261     if(This->thread_id != GetCurrentThreadId() || !This->ctx->script_disp) {
262         *ppdisp = NULL;
263         return E_UNEXPECTED;
264     }
265
266     *ppdisp = (IDispatch*)_IDispatchEx_(This->ctx->script_disp);
267     IDispatch_AddRef(*ppdisp);
268     return S_OK;
269 }
270
271 static HRESULT WINAPI JScript_GetCurrentScriptThreadID(IActiveScript *iface,
272                                                        SCRIPTTHREADID *pstridThread)
273 {
274     JScript *This = ACTSCRIPT_THIS(iface);
275     FIXME("(%p)->()\n", This);
276     return E_NOTIMPL;
277 }
278
279 static HRESULT WINAPI JScript_GetScriptThreadID(IActiveScript *iface,
280                                                 DWORD dwWin32ThreadId, SCRIPTTHREADID *pstidThread)
281 {
282     JScript *This = ACTSCRIPT_THIS(iface);
283     FIXME("(%p)->()\n", This);
284     return E_NOTIMPL;
285 }
286
287 static HRESULT WINAPI JScript_GetScriptThreadState(IActiveScript *iface,
288         SCRIPTTHREADID stidThread, SCRIPTTHREADSTATE *pstsState)
289 {
290     JScript *This = ACTSCRIPT_THIS(iface);
291     FIXME("(%p)->()\n", This);
292     return E_NOTIMPL;
293 }
294
295 static HRESULT WINAPI JScript_InterruptScriptThread(IActiveScript *iface,
296         SCRIPTTHREADID stidThread, const EXCEPINFO *pexcepinfo, DWORD dwFlags)
297 {
298     JScript *This = ACTSCRIPT_THIS(iface);
299     FIXME("(%p)->()\n", This);
300     return E_NOTIMPL;
301 }
302
303 static HRESULT WINAPI JScript_Clone(IActiveScript *iface, IActiveScript **ppscript)
304 {
305     JScript *This = ACTSCRIPT_THIS(iface);
306     FIXME("(%p)->()\n", This);
307     return E_NOTIMPL;
308 }
309
310 #undef ACTSCRIPT_THIS
311
312 static const IActiveScriptVtbl JScriptVtbl = {
313     JScript_QueryInterface,
314     JScript_AddRef,
315     JScript_Release,
316     JScript_SetScriptSite,
317     JScript_GetScriptSite,
318     JScript_SetScriptState,
319     JScript_GetScriptState,
320     JScript_Close,
321     JScript_AddNamedItem,
322     JScript_AddTypeLib,
323     JScript_GetScriptDispatch,
324     JScript_GetCurrentScriptThreadID,
325     JScript_GetScriptThreadID,
326     JScript_GetScriptThreadState,
327     JScript_InterruptScriptThread,
328     JScript_Clone
329 };
330
331 #define ASPARSE_THIS(iface) DEFINE_THIS(JScript, IActiveScriptParse, iface)
332
333 static HRESULT WINAPI JScriptParse_QueryInterface(IActiveScriptParse *iface, REFIID riid, void **ppv)
334 {
335     JScript *This = ASPARSE_THIS(iface);
336     return IActiveScript_QueryInterface(ACTSCRIPT(This), riid, ppv);
337 }
338
339 static ULONG WINAPI JScriptParse_AddRef(IActiveScriptParse *iface)
340 {
341     JScript *This = ASPARSE_THIS(iface);
342     return IActiveScript_AddRef(ACTSCRIPT(This));
343 }
344
345 static ULONG WINAPI JScriptParse_Release(IActiveScriptParse *iface)
346 {
347     JScript *This = ASPARSE_THIS(iface);
348     return IActiveScript_Release(ACTSCRIPT(This));
349 }
350
351 static HRESULT WINAPI JScriptParse_InitNew(IActiveScriptParse *iface)
352 {
353     JScript *This = ASPARSE_THIS(iface);
354     script_ctx_t *ctx;
355
356     TRACE("(%p)\n", This);
357
358     if(This->ctx)
359         return E_UNEXPECTED;
360
361     ctx = heap_alloc_zero(sizeof(script_ctx_t));
362     if(!ctx)
363         return E_OUTOFMEMORY;
364
365     ctx->ref = 1;
366     ctx->state = SCRIPTSTATE_UNINITIALIZED;
367
368     ctx = InterlockedCompareExchangePointer((void**)&This->ctx, ctx, NULL);
369     if(ctx) {
370         script_release(ctx);
371         return E_UNEXPECTED;
372     }
373
374     return S_OK;
375 }
376
377 static HRESULT WINAPI JScriptParse_AddScriptlet(IActiveScriptParse *iface,
378         LPCOLESTR pstrDefaultName, LPCOLESTR pstrCode, LPCOLESTR pstrItemName,
379         LPCOLESTR pstrSubItemName, LPCOLESTR pstrEventName, LPCOLESTR pstrDelimiter,
380         DWORD dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags,
381         BSTR *pbstrName, EXCEPINFO *pexcepinfo)
382 {
383     JScript *This = ASPARSE_THIS(iface);
384     FIXME("(%p)->(%s %s %s %s %s %s %x %u %x %p %p)\n", This, debugstr_w(pstrDefaultName),
385           debugstr_w(pstrCode), debugstr_w(pstrItemName), debugstr_w(pstrSubItemName),
386           debugstr_w(pstrEventName), debugstr_w(pstrDelimiter), dwSourceContextCookie,
387           ulStartingLineNumber, dwFlags, pbstrName, pexcepinfo);
388     return E_NOTIMPL;
389 }
390
391 static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface,
392         LPCOLESTR pstrCode, LPCOLESTR pstrItemName, IUnknown *punkContext,
393         LPCOLESTR pstrDelimiter, DWORD dwSourceContextCookie, ULONG ulStartingLine,
394         DWORD dwFlags, VARIANT *pvarResult, EXCEPINFO *pexcepinfo)
395 {
396     JScript *This = ASPARSE_THIS(iface);
397     FIXME("(%p)->(%s %s %p %s %x %u %x %p %p)\n", This, debugstr_w(pstrCode),
398           debugstr_w(pstrItemName), punkContext, debugstr_w(pstrDelimiter),
399           dwSourceContextCookie, ulStartingLine, dwFlags, pvarResult, pexcepinfo);
400     return E_NOTIMPL;
401 }
402
403 #undef ASPARSE_THIS
404
405 static const IActiveScriptParseVtbl JScriptParseVtbl = {
406     JScriptParse_QueryInterface,
407     JScriptParse_AddRef,
408     JScriptParse_Release,
409     JScriptParse_InitNew,
410     JScriptParse_AddScriptlet,
411     JScriptParse_ParseScriptText
412 };
413
414 #define ASPARSEPROC_THIS(iface) DEFINE_THIS(JScript, IActiveScriptParse, iface)
415
416 static HRESULT WINAPI JScriptParseProcedure_QueryInterface(IActiveScriptParseProcedure2 *iface, REFIID riid, void **ppv)
417 {
418     JScript *This = ASPARSEPROC_THIS(iface);
419     return IActiveScript_QueryInterface(ACTSCRIPT(This), riid, ppv);
420 }
421
422 static ULONG WINAPI JScriptParseProcedure_AddRef(IActiveScriptParseProcedure2 *iface)
423 {
424     JScript *This = ASPARSEPROC_THIS(iface);
425     return IActiveScript_AddRef(ACTSCRIPT(This));
426 }
427
428 static ULONG WINAPI JScriptParseProcedure_Release(IActiveScriptParseProcedure2 *iface)
429 {
430     JScript *This = ASPARSEPROC_THIS(iface);
431     return IActiveScript_Release(ACTSCRIPT(This));
432 }
433
434 static HRESULT WINAPI JScriptParseProcedure_ParseProcedureText(IActiveScriptParseProcedure2 *iface,
435         LPCOLESTR pstrCode, LPCOLESTR pstrFormalParams, LPCOLESTR pstrProcedureName,
436         LPCOLESTR pstrItemName, IUnknown *punkContext, LPCOLESTR pstrDelimiter,
437         DWORD dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags, IDispatch **ppdisp)
438 {
439     JScript *This = ASPARSEPROC_THIS(iface);
440     FIXME("(%p)->()\n", This);
441     return E_NOTIMPL;
442 }
443
444 #undef ASPARSEPROC_THIS
445
446 static const IActiveScriptParseProcedure2Vtbl JScriptParseProcedureVtbl = {
447     JScriptParseProcedure_QueryInterface,
448     JScriptParseProcedure_AddRef,
449     JScriptParseProcedure_Release,
450     JScriptParseProcedure_ParseProcedureText,
451 };
452
453 #define ACTSCPPROP_THIS(iface) DEFINE_THIS(JScript, IActiveScriptProperty, iface)
454
455 static HRESULT WINAPI JScriptProperty_QueryInterface(IActiveScriptProperty *iface, REFIID riid, void **ppv)
456 {
457     JScript *This = ACTSCPPROP_THIS(iface);
458     return IActiveScript_QueryInterface(ACTSCRIPT(This), riid, ppv);
459 }
460
461 static ULONG WINAPI JScriptProperty_AddRef(IActiveScriptProperty *iface)
462 {
463     JScript *This = ACTSCPPROP_THIS(iface);
464     return IActiveScript_AddRef(ACTSCRIPT(This));
465 }
466
467 static ULONG WINAPI JScriptProperty_Release(IActiveScriptProperty *iface)
468 {
469     JScript *This = ACTSCPPROP_THIS(iface);
470     return IActiveScript_Release(ACTSCRIPT(This));
471 }
472
473 static HRESULT WINAPI JScriptProperty_GetProperty(IActiveScriptProperty *iface, DWORD dwProperty,
474         VARIANT *pvarIndex, VARIANT *pvarValue)
475 {
476     JScript *This = ACTSCPPROP_THIS(iface);
477     FIXME("(%p)->(%x %p %p)\n", This, dwProperty, pvarIndex, pvarValue);
478     return E_NOTIMPL;
479 }
480
481 static HRESULT WINAPI JScriptProperty_SetProperty(IActiveScriptProperty *iface, DWORD dwProperty,
482         VARIANT *pvarIndex, VARIANT *pvarValue)
483 {
484     JScript *This = ACTSCPPROP_THIS(iface);
485     FIXME("(%p)->(%x %p %p)\n", This, dwProperty, pvarIndex, pvarValue);
486     return E_NOTIMPL;
487 }
488
489 #undef ACTSCPPROP_THIS
490
491 static const IActiveScriptPropertyVtbl JScriptPropertyVtbl = {
492     JScriptProperty_QueryInterface,
493     JScriptProperty_AddRef,
494     JScriptProperty_Release,
495     JScriptProperty_GetProperty,
496     JScriptProperty_SetProperty
497 };
498
499 #define OBJSAFETY_THIS(iface) DEFINE_THIS(JScript, IObjectSafety, iface)
500
501 static HRESULT WINAPI JScriptSafety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
502 {
503     JScript *This = OBJSAFETY_THIS(iface);
504     return IActiveScript_QueryInterface(ACTSCRIPT(This), riid, ppv);
505 }
506
507 static ULONG WINAPI JScriptSafety_AddRef(IObjectSafety *iface)
508 {
509     JScript *This = OBJSAFETY_THIS(iface);
510     return IActiveScript_AddRef(ACTSCRIPT(This));
511 }
512
513 static ULONG WINAPI JScriptSafety_Release(IObjectSafety *iface)
514 {
515     JScript *This = OBJSAFETY_THIS(iface);
516     return IActiveScript_Release(ACTSCRIPT(This));
517 }
518
519 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER)
520
521 static HRESULT WINAPI JScriptSafety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
522         DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
523 {
524     JScript *This = OBJSAFETY_THIS(iface);
525
526     TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
527
528     if(!pdwSupportedOptions || !pdwEnabledOptions)
529         return E_POINTER;
530
531     *pdwSupportedOptions = SUPPORTED_OPTIONS;
532     *pdwEnabledOptions = This->safeopt;
533
534     return S_OK;
535 }
536
537 static HRESULT WINAPI JScriptSafety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
538         DWORD dwOptionSetMask, DWORD dwEnabledOptions)
539 {
540     JScript *This = OBJSAFETY_THIS(iface);
541
542     TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
543
544     if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
545         return E_FAIL;
546
547     This->safeopt = dwEnabledOptions & dwEnabledOptions;
548     return S_OK;
549 }
550
551 #undef OBJSAFETY_THIS
552
553 static const IObjectSafetyVtbl JScriptSafetyVtbl = {
554     JScriptSafety_QueryInterface,
555     JScriptSafety_AddRef,
556     JScriptSafety_Release,
557     JScriptSafety_GetInterfaceSafetyOptions,
558     JScriptSafety_SetInterfaceSafetyOptions
559 };
560
561 HRESULT WINAPI JScriptFactory_CreateInstance(IClassFactory *iface, IUnknown *pUnkOuter,
562                                              REFIID riid, void **ppv)
563 {
564     JScript *ret;
565     HRESULT hres;
566
567     TRACE("(%p %s %p)\n", pUnkOuter, debugstr_guid(riid), ppv);
568
569     lock_module();
570
571     ret = heap_alloc_zero(sizeof(*ret));
572
573     ret->lpIActiveScriptVtbl                 = &JScriptVtbl;
574     ret->lpIActiveScriptParseVtbl            = &JScriptParseVtbl;
575     ret->lpIActiveScriptParseProcedure2Vtbl  = &JScriptParseProcedureVtbl;
576     ret->lpIActiveScriptPropertyVtbl         = &JScriptPropertyVtbl;
577     ret->lpIObjectSafetyVtbl                 = &JScriptSafetyVtbl;
578     ret->ref = 1;
579     ret->safeopt = INTERFACE_USES_DISPEX;
580
581     hres = IActiveScript_QueryInterface(ACTSCRIPT(ret), riid, ppv);
582     IActiveScript_Release(ACTSCRIPT(ret));
583     return hres;
584 }