jscript: Added IActiveScriptParse::InitNew 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 } JScript;
38
39 #define ACTSCRIPT(x)    ((IActiveScript*)                 &(x)->lpIActiveScriptVtbl)
40 #define ASPARSE(x)      ((IActiveScriptParse*)            &(x)->lpIActiveScriptParseVtbl)
41 #define ASPARSEPROC(x)  ((IActiveScriptParseProcedure2*)  &(x)->lpIActiveScriptParseProcedure2Vtbl)
42 #define ACTSCPPROP(x)   ((IActiveScriptProperty*)         &(x)->lpIActiveScriptPropertyVtbl)
43 #define OBJSAFETY(x)    ((IObjectSafety*)                 &(x)->lpIObjectSafetyVtbl)
44
45 void script_release(script_ctx_t *ctx)
46 {
47     if(--ctx->ref)
48         return;
49
50     heap_free(ctx);
51 }
52
53 #define ACTSCRIPT_THIS(iface) DEFINE_THIS(JScript, IActiveScript, iface)
54
55 static HRESULT WINAPI JScript_QueryInterface(IActiveScript *iface, REFIID riid, void **ppv)
56 {
57     JScript *This = ACTSCRIPT_THIS(iface);
58
59     *ppv = NULL;
60
61     if(IsEqualGUID(riid, &IID_IUnknown)) {
62         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
63         *ppv = ACTSCRIPT(This);
64     }else if(IsEqualGUID(riid, &IID_IActiveScript)) {
65         TRACE("(%p)->(IID_IActiveScript %p)\n", This, ppv);
66         *ppv = ACTSCRIPT(This);
67     }else if(IsEqualGUID(riid, &IID_IActiveScriptParse)) {
68         TRACE("(%p)->(IID_IActiveScriptParse %p)\n", This, ppv);
69         *ppv = ASPARSE(This);
70     }else if(IsEqualGUID(riid, &IID_IActiveScriptParseProcedure)) {
71         TRACE("(%p)->(IID_IActiveScriptParseProcedure %p)\n", This, ppv);
72         *ppv = ASPARSEPROC(This);
73     }else if(IsEqualGUID(riid, &IID_IActiveScriptParseProcedure2)) {
74         TRACE("(%p)->(IID_IActiveScriptParseProcedure2 %p)\n", This, ppv);
75         *ppv = ASPARSEPROC(This);
76     }else if(IsEqualGUID(riid, &IID_IActiveScriptProperty)) {
77         TRACE("(%p)->(IID_IActiveScriptProperty %p)\n", This, ppv);
78         *ppv = ACTSCPPROP(This);
79     }else if(IsEqualGUID(riid, &IID_IObjectSafety)) {
80         TRACE("(%p)->(IID_IObjectSafety %p)\n", This, ppv);
81         *ppv = OBJSAFETY(This);
82     }
83
84     if(*ppv) {
85         IUnknown_AddRef((IUnknown*)*ppv);
86         return S_OK;
87     }
88
89     FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
90     return E_NOINTERFACE;
91 }
92
93 static ULONG WINAPI JScript_AddRef(IActiveScript *iface)
94 {
95     JScript *This = ACTSCRIPT_THIS(iface);
96     LONG ref = InterlockedIncrement(&This->ref);
97
98     TRACE("(%p) ref=%d\n", This, ref);
99
100     return ref;
101 }
102
103 static ULONG WINAPI JScript_Release(IActiveScript *iface)
104 {
105     JScript *This = ACTSCRIPT_THIS(iface);
106     LONG ref = InterlockedDecrement(&This->ref);
107
108     TRACE("(%p) ref=%d\n", iface, ref);
109
110     if(!ref) {
111         if(This->ctx)
112             script_release(This->ctx);
113         heap_free(This);
114         unlock_module();
115     }
116
117     return ref;
118 }
119
120 static HRESULT WINAPI JScript_SetScriptSite(IActiveScript *iface,
121                                             IActiveScriptSite *pass)
122 {
123     JScript *This = ACTSCRIPT_THIS(iface);
124     FIXME("(%p)->(%p)\n", This, pass);
125     return E_NOTIMPL;
126 }
127
128 static HRESULT WINAPI JScript_GetScriptSite(IActiveScript *iface, REFIID riid,
129                                             void **ppvObject)
130 {
131     JScript *This = ACTSCRIPT_THIS(iface);
132     FIXME("(%p)->()\n", This);
133     return E_NOTIMPL;
134 }
135
136 static HRESULT WINAPI JScript_SetScriptState(IActiveScript *iface, SCRIPTSTATE ss)
137 {
138     JScript *This = ACTSCRIPT_THIS(iface);
139     FIXME("(%p)->(%d)\n", This, ss);
140     return E_NOTIMPL;
141 }
142
143 static HRESULT WINAPI JScript_GetScriptState(IActiveScript *iface, SCRIPTSTATE *pssState)
144 {
145     JScript *This = ACTSCRIPT_THIS(iface);
146     FIXME("(%p)->(%p)\n", This, pssState);
147     return E_NOTIMPL;
148 }
149
150 static HRESULT WINAPI JScript_Close(IActiveScript *iface)
151 {
152     JScript *This = ACTSCRIPT_THIS(iface);
153     FIXME("(%p)->()\n", This);
154     return E_NOTIMPL;
155 }
156
157 static HRESULT WINAPI JScript_AddNamedItem(IActiveScript *iface,
158                                            LPCOLESTR pstrName, DWORD dwFlags)
159 {
160     JScript *This = ACTSCRIPT_THIS(iface);
161     FIXME("(%p)->(%s %x)\n", This, debugstr_w(pstrName), dwFlags);
162     return E_NOTIMPL;
163 }
164
165 static HRESULT WINAPI JScript_AddTypeLib(IActiveScript *iface, REFGUID rguidTypeLib,
166                                          DWORD dwMajor, DWORD dwMinor, DWORD dwFlags)
167 {
168     JScript *This = ACTSCRIPT_THIS(iface);
169     FIXME("(%p)->()\n", This);
170     return E_NOTIMPL;
171 }
172
173 static HRESULT WINAPI JScript_GetScriptDispatch(IActiveScript *iface, LPCOLESTR pstrItemName,
174                                                 IDispatch **ppdisp)
175 {
176     JScript *This = ACTSCRIPT_THIS(iface);
177     FIXME("(%p)->()\n", This);
178     return E_NOTIMPL;
179 }
180
181 static HRESULT WINAPI JScript_GetCurrentScriptThreadID(IActiveScript *iface,
182                                                        SCRIPTTHREADID *pstridThread)
183 {
184     JScript *This = ACTSCRIPT_THIS(iface);
185     FIXME("(%p)->()\n", This);
186     return E_NOTIMPL;
187 }
188
189 static HRESULT WINAPI JScript_GetScriptThreadID(IActiveScript *iface,
190                                                 DWORD dwWin32ThreadId, SCRIPTTHREADID *pstidThread)
191 {
192     JScript *This = ACTSCRIPT_THIS(iface);
193     FIXME("(%p)->()\n", This);
194     return E_NOTIMPL;
195 }
196
197 static HRESULT WINAPI JScript_GetScriptThreadState(IActiveScript *iface,
198         SCRIPTTHREADID stidThread, SCRIPTTHREADSTATE *pstsState)
199 {
200     JScript *This = ACTSCRIPT_THIS(iface);
201     FIXME("(%p)->()\n", This);
202     return E_NOTIMPL;
203 }
204
205 static HRESULT WINAPI JScript_InterruptScriptThread(IActiveScript *iface,
206         SCRIPTTHREADID stidThread, const EXCEPINFO *pexcepinfo, DWORD dwFlags)
207 {
208     JScript *This = ACTSCRIPT_THIS(iface);
209     FIXME("(%p)->()\n", This);
210     return E_NOTIMPL;
211 }
212
213 static HRESULT WINAPI JScript_Clone(IActiveScript *iface, IActiveScript **ppscript)
214 {
215     JScript *This = ACTSCRIPT_THIS(iface);
216     FIXME("(%p)->()\n", This);
217     return E_NOTIMPL;
218 }
219
220 #undef ACTSCRIPT_THIS
221
222 static const IActiveScriptVtbl JScriptVtbl = {
223     JScript_QueryInterface,
224     JScript_AddRef,
225     JScript_Release,
226     JScript_SetScriptSite,
227     JScript_GetScriptSite,
228     JScript_SetScriptState,
229     JScript_GetScriptState,
230     JScript_Close,
231     JScript_AddNamedItem,
232     JScript_AddTypeLib,
233     JScript_GetScriptDispatch,
234     JScript_GetCurrentScriptThreadID,
235     JScript_GetScriptThreadID,
236     JScript_GetScriptThreadState,
237     JScript_InterruptScriptThread,
238     JScript_Clone
239 };
240
241 #define ASPARSE_THIS(iface) DEFINE_THIS(JScript, IActiveScriptParse, iface)
242
243 static HRESULT WINAPI JScriptParse_QueryInterface(IActiveScriptParse *iface, REFIID riid, void **ppv)
244 {
245     JScript *This = ASPARSE_THIS(iface);
246     return IActiveScript_QueryInterface(ACTSCRIPT(This), riid, ppv);
247 }
248
249 static ULONG WINAPI JScriptParse_AddRef(IActiveScriptParse *iface)
250 {
251     JScript *This = ASPARSE_THIS(iface);
252     return IActiveScript_AddRef(ACTSCRIPT(This));
253 }
254
255 static ULONG WINAPI JScriptParse_Release(IActiveScriptParse *iface)
256 {
257     JScript *This = ASPARSE_THIS(iface);
258     return IActiveScript_Release(ACTSCRIPT(This));
259 }
260
261 static HRESULT WINAPI JScriptParse_InitNew(IActiveScriptParse *iface)
262 {
263     JScript *This = ASPARSE_THIS(iface);
264     script_ctx_t *ctx;
265
266     TRACE("(%p)\n", This);
267
268     if(This->ctx)
269         return E_UNEXPECTED;
270
271     ctx = heap_alloc_zero(sizeof(script_ctx_t));
272     if(!ctx)
273         return E_OUTOFMEMORY;
274
275     ctx->ref = 1;
276     ctx->state = SCRIPTSTATE_UNINITIALIZED;
277
278     ctx = InterlockedCompareExchangePointer((void**)&This->ctx, ctx, NULL);
279     if(ctx) {
280         script_release(ctx);
281         return E_UNEXPECTED;
282     }
283
284     return S_OK;
285 }
286
287 static HRESULT WINAPI JScriptParse_AddScriptlet(IActiveScriptParse *iface,
288         LPCOLESTR pstrDefaultName, LPCOLESTR pstrCode, LPCOLESTR pstrItemName,
289         LPCOLESTR pstrSubItemName, LPCOLESTR pstrEventName, LPCOLESTR pstrDelimiter,
290         DWORD dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags,
291         BSTR *pbstrName, EXCEPINFO *pexcepinfo)
292 {
293     JScript *This = ASPARSE_THIS(iface);
294     FIXME("(%p)->(%s %s %s %s %s %s %x %u %x %p %p)\n", This, debugstr_w(pstrDefaultName),
295           debugstr_w(pstrCode), debugstr_w(pstrItemName), debugstr_w(pstrSubItemName),
296           debugstr_w(pstrEventName), debugstr_w(pstrDelimiter), dwSourceContextCookie,
297           ulStartingLineNumber, dwFlags, pbstrName, pexcepinfo);
298     return E_NOTIMPL;
299 }
300
301 static HRESULT WINAPI JScriptParse_ParseScriptText(IActiveScriptParse *iface,
302         LPCOLESTR pstrCode, LPCOLESTR pstrItemName, IUnknown *punkContext,
303         LPCOLESTR pstrDelimiter, DWORD dwSourceContextCookie, ULONG ulStartingLine,
304         DWORD dwFlags, VARIANT *pvarResult, EXCEPINFO *pexcepinfo)
305 {
306     JScript *This = ASPARSE_THIS(iface);
307     FIXME("(%p)->(%s %s %p %s %x %u %x %p %p)\n", This, debugstr_w(pstrCode),
308           debugstr_w(pstrItemName), punkContext, debugstr_w(pstrDelimiter),
309           dwSourceContextCookie, ulStartingLine, dwFlags, pvarResult, pexcepinfo);
310     return E_NOTIMPL;
311 }
312
313 #undef ASPARSE_THIS
314
315 static const IActiveScriptParseVtbl JScriptParseVtbl = {
316     JScriptParse_QueryInterface,
317     JScriptParse_AddRef,
318     JScriptParse_Release,
319     JScriptParse_InitNew,
320     JScriptParse_AddScriptlet,
321     JScriptParse_ParseScriptText
322 };
323
324 #define ASPARSEPROC_THIS(iface) DEFINE_THIS(JScript, IActiveScriptParse, iface)
325
326 static HRESULT WINAPI JScriptParseProcedure_QueryInterface(IActiveScriptParseProcedure2 *iface, REFIID riid, void **ppv)
327 {
328     JScript *This = ASPARSEPROC_THIS(iface);
329     return IActiveScript_QueryInterface(ACTSCRIPT(This), riid, ppv);
330 }
331
332 static ULONG WINAPI JScriptParseProcedure_AddRef(IActiveScriptParseProcedure2 *iface)
333 {
334     JScript *This = ASPARSEPROC_THIS(iface);
335     return IActiveScript_AddRef(ACTSCRIPT(This));
336 }
337
338 static ULONG WINAPI JScriptParseProcedure_Release(IActiveScriptParseProcedure2 *iface)
339 {
340     JScript *This = ASPARSEPROC_THIS(iface);
341     return IActiveScript_Release(ACTSCRIPT(This));
342 }
343
344 static HRESULT WINAPI JScriptParseProcedure_ParseProcedureText(IActiveScriptParseProcedure2 *iface,
345         LPCOLESTR pstrCode, LPCOLESTR pstrFormalParams, LPCOLESTR pstrProcedureName,
346         LPCOLESTR pstrItemName, IUnknown *punkContext, LPCOLESTR pstrDelimiter,
347         DWORD dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags, IDispatch **ppdisp)
348 {
349     JScript *This = ASPARSEPROC_THIS(iface);
350     FIXME("(%p)->()\n", This);
351     return E_NOTIMPL;
352 }
353
354 #undef ASPARSEPROC_THIS
355
356 static const IActiveScriptParseProcedure2Vtbl JScriptParseProcedureVtbl = {
357     JScriptParseProcedure_QueryInterface,
358     JScriptParseProcedure_AddRef,
359     JScriptParseProcedure_Release,
360     JScriptParseProcedure_ParseProcedureText,
361 };
362
363 #define ACTSCPPROP_THIS(iface) DEFINE_THIS(JScript, IActiveScriptProperty, iface)
364
365 static HRESULT WINAPI JScriptProperty_QueryInterface(IActiveScriptProperty *iface, REFIID riid, void **ppv)
366 {
367     JScript *This = ACTSCPPROP_THIS(iface);
368     return IActiveScript_QueryInterface(ACTSCRIPT(This), riid, ppv);
369 }
370
371 static ULONG WINAPI JScriptProperty_AddRef(IActiveScriptProperty *iface)
372 {
373     JScript *This = ACTSCPPROP_THIS(iface);
374     return IActiveScript_AddRef(ACTSCRIPT(This));
375 }
376
377 static ULONG WINAPI JScriptProperty_Release(IActiveScriptProperty *iface)
378 {
379     JScript *This = ACTSCPPROP_THIS(iface);
380     return IActiveScript_Release(ACTSCRIPT(This));
381 }
382
383 static HRESULT WINAPI JScriptProperty_GetProperty(IActiveScriptProperty *iface, DWORD dwProperty,
384         VARIANT *pvarIndex, VARIANT *pvarValue)
385 {
386     JScript *This = ACTSCPPROP_THIS(iface);
387     FIXME("(%p)->(%x %p %p)\n", This, dwProperty, pvarIndex, pvarValue);
388     return E_NOTIMPL;
389 }
390
391 static HRESULT WINAPI JScriptProperty_SetProperty(IActiveScriptProperty *iface, DWORD dwProperty,
392         VARIANT *pvarIndex, VARIANT *pvarValue)
393 {
394     JScript *This = ACTSCPPROP_THIS(iface);
395     FIXME("(%p)->(%x %p %p)\n", This, dwProperty, pvarIndex, pvarValue);
396     return E_NOTIMPL;
397 }
398
399 #undef ACTSCPPROP_THIS
400
401 static const IActiveScriptPropertyVtbl JScriptPropertyVtbl = {
402     JScriptProperty_QueryInterface,
403     JScriptProperty_AddRef,
404     JScriptProperty_Release,
405     JScriptProperty_GetProperty,
406     JScriptProperty_SetProperty
407 };
408
409 #define OBJSAFETY_THIS(iface) DEFINE_THIS(JScript, IObjectSafety, iface)
410
411 static HRESULT WINAPI JScriptSafety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
412 {
413     JScript *This = OBJSAFETY_THIS(iface);
414     return IActiveScript_QueryInterface(ACTSCRIPT(This), riid, ppv);
415 }
416
417 static ULONG WINAPI JScriptSafety_AddRef(IObjectSafety *iface)
418 {
419     JScript *This = OBJSAFETY_THIS(iface);
420     return IActiveScript_AddRef(ACTSCRIPT(This));
421 }
422
423 static ULONG WINAPI JScriptSafety_Release(IObjectSafety *iface)
424 {
425     JScript *This = OBJSAFETY_THIS(iface);
426     return IActiveScript_Release(ACTSCRIPT(This));
427 }
428
429 #define SUPPORTED_OPTIONS (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER)
430
431 static HRESULT WINAPI JScriptSafety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
432         DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
433 {
434     JScript *This = OBJSAFETY_THIS(iface);
435
436     TRACE("(%p)->(%s %p %p)\n", This, debugstr_guid(riid), pdwSupportedOptions, pdwEnabledOptions);
437
438     if(!pdwSupportedOptions || !pdwEnabledOptions)
439         return E_POINTER;
440
441     *pdwSupportedOptions = SUPPORTED_OPTIONS;
442     *pdwEnabledOptions = This->safeopt;
443
444     return S_OK;
445 }
446
447 static HRESULT WINAPI JScriptSafety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
448         DWORD dwOptionSetMask, DWORD dwEnabledOptions)
449 {
450     JScript *This = OBJSAFETY_THIS(iface);
451
452     TRACE("(%p)->(%s %x %x)\n", This, debugstr_guid(riid), dwOptionSetMask, dwEnabledOptions);
453
454     if(dwOptionSetMask & ~SUPPORTED_OPTIONS)
455         return E_FAIL;
456
457     This->safeopt = dwEnabledOptions & dwEnabledOptions;
458     return S_OK;
459 }
460
461 #undef OBJSAFETY_THIS
462
463 static const IObjectSafetyVtbl JScriptSafetyVtbl = {
464     JScriptSafety_QueryInterface,
465     JScriptSafety_AddRef,
466     JScriptSafety_Release,
467     JScriptSafety_GetInterfaceSafetyOptions,
468     JScriptSafety_SetInterfaceSafetyOptions
469 };
470
471 HRESULT WINAPI JScriptFactory_CreateInstance(IClassFactory *iface, IUnknown *pUnkOuter,
472                                              REFIID riid, void **ppv)
473 {
474     JScript *ret;
475     HRESULT hres;
476
477     TRACE("(%p %s %p)\n", pUnkOuter, debugstr_guid(riid), ppv);
478
479     lock_module();
480
481     ret = heap_alloc_zero(sizeof(*ret));
482
483     ret->lpIActiveScriptVtbl                 = &JScriptVtbl;
484     ret->lpIActiveScriptParseVtbl            = &JScriptParseVtbl;
485     ret->lpIActiveScriptParseProcedure2Vtbl  = &JScriptParseProcedureVtbl;
486     ret->lpIActiveScriptPropertyVtbl         = &JScriptPropertyVtbl;
487     ret->lpIObjectSafetyVtbl                 = &JScriptSafetyVtbl;
488     ret->ref = 1;
489     ret->safeopt = INTERFACE_USES_DISPEX;
490
491     hres = IActiveScript_QueryInterface(ACTSCRIPT(ret), riid, ppv);
492     IActiveScript_Release(ACTSCRIPT(ret));
493     return hres;
494 }