mshtml: Implement HTMLCurrentStyle_get_borderLeftWidth.
[wine] / dlls / mshtml / tests / script.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 #define COBJMACROS
20 #define CONST_VTABLE
21
22 #include <wine/test.h>
23 #include <stdarg.h>
24 #include <stdio.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "ole2.h"
29 #include "dispex.h"
30 #include "mshtml.h"
31 #include "initguid.h"
32 #include "activscp.h"
33 #include "activdbg.h"
34 #include "objsafe.h"
35 #include "mshtmdid.h"
36
37 DEFINE_GUID(CLSID_IdentityUnmarshal,0x0000001b,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
38
39 #ifdef _WIN64
40
41 #define CTXARG_T DWORDLONG
42 #define IActiveScriptParseVtbl IActiveScriptParse64Vtbl
43 #define IActiveScriptParseProcedure2Vtbl IActiveScriptParseProcedure2_64Vtbl
44
45 #else
46
47 #define CTXARG_T DWORD
48 #define IActiveScriptParseVtbl IActiveScriptParse32Vtbl
49 #define IActiveScriptParseProcedure2Vtbl IActiveScriptParseProcedure2_32Vtbl
50
51 #endif
52
53 #define DEFINE_EXPECT(func) \
54     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
55
56 #define SET_EXPECT(func) \
57     do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0)
58
59 #define CHECK_EXPECT2(func) \
60     do { \
61         ok(expect_ ##func, "unexpected call " #func "\n"); \
62         called_ ## func = TRUE; \
63     }while(0)
64
65 #define CHECK_EXPECT(func) \
66     do { \
67         CHECK_EXPECT2(func); \
68         expect_ ## func = FALSE; \
69     }while(0)
70
71 #define CHECK_CALLED(func) \
72     do { \
73         ok(called_ ## func, "expected " #func "\n"); \
74         expect_ ## func = called_ ## func = FALSE; \
75     }while(0)
76
77 #define CHECK_NOT_CALLED(func) \
78     do { \
79         ok(!called_ ## func, "unexpected " #func "\n"); \
80         expect_ ## func = called_ ## func = FALSE; \
81     }while(0)
82
83 #define CLEAR_CALLED(func) \
84     expect_ ## func = called_ ## func = FALSE
85
86
87 DEFINE_EXPECT(CreateInstance);
88 DEFINE_EXPECT(GetInterfaceSafetyOptions);
89 DEFINE_EXPECT(SetInterfaceSafetyOptions);
90 DEFINE_EXPECT(InitNew);
91 DEFINE_EXPECT(Close);
92 DEFINE_EXPECT(SetProperty);
93 DEFINE_EXPECT(SetScriptSite);
94 DEFINE_EXPECT(GetScriptState);
95 DEFINE_EXPECT(SetScriptState_STARTED);
96 DEFINE_EXPECT(SetScriptState_CONNECTED);
97 DEFINE_EXPECT(SetScriptState_DISCONNECTED);
98 DEFINE_EXPECT(AddNamedItem);
99 DEFINE_EXPECT(ParseScriptText);
100 DEFINE_EXPECT(GetScriptDispatch);
101 DEFINE_EXPECT(funcDisp);
102
103 #define TESTSCRIPT_CLSID "{178fc163-f585-4e24-9c13-4bb7faf80746}"
104
105 static const GUID CLSID_TestScript =
106     {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x07,0x46}};
107
108 static IHTMLDocument2 *notif_doc;
109 static IDispatchEx *window_dispex;
110 static BOOL doc_complete;
111
112 static const char *debugstr_guid(REFIID riid)
113 {
114     static char buf[50];
115
116     sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
117             riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
118             riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
119             riid->Data4[5], riid->Data4[6], riid->Data4[7]);
120
121     return buf;
122 }
123
124 static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface,
125         REFIID riid, void**ppv)
126 {
127     if(IsEqualGUID(&IID_IPropertyNotifySink, riid)) {
128         *ppv = iface;
129         return S_OK;
130     }
131
132     return E_NOINTERFACE;
133 }
134
135 static ULONG WINAPI PropertyNotifySink_AddRef(IPropertyNotifySink *iface)
136 {
137     return 2;
138 }
139
140 static ULONG WINAPI PropertyNotifySink_Release(IPropertyNotifySink *iface)
141 {
142     return 1;
143 }
144
145 static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, DISPID dispID)
146 {
147     if(dispID == DISPID_READYSTATE){
148         BSTR state;
149         HRESULT hres;
150
151         static const WCHAR completeW[] = {'c','o','m','p','l','e','t','e',0};
152
153         hres = IHTMLDocument2_get_readyState(notif_doc, &state);
154         ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
155
156         if(!lstrcmpW(state, completeW))
157             doc_complete = TRUE;
158
159         SysFreeString(state);
160     }
161
162     return S_OK;
163 }
164
165 static HRESULT WINAPI PropertyNotifySink_OnRequestEdit(IPropertyNotifySink *iface, DISPID dispID)
166 {
167     ok(0, "unexpected call\n");
168     return E_NOTIMPL;
169 }
170
171 static IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = {
172     PropertyNotifySink_QueryInterface,
173     PropertyNotifySink_AddRef,
174     PropertyNotifySink_Release,
175     PropertyNotifySink_OnChanged,
176     PropertyNotifySink_OnRequestEdit
177 };
178
179 static IPropertyNotifySink PropertyNotifySink = { &PropertyNotifySinkVtbl };
180
181 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
182 {
183     *ppv = NULL;
184
185     if(IsEqualGUID(riid, &IID_IUnknown)
186        || IsEqualGUID(riid, &IID_IDispatch)
187        || IsEqualGUID(riid, &IID_IDispatchEx))
188         *ppv = iface;
189     else
190         return E_NOINTERFACE;
191
192     return S_OK;
193 }
194
195 static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
196 {
197     return 2;
198 }
199
200 static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
201 {
202     return 1;
203 }
204
205 static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
206 {
207     ok(0, "unexpected call\n");
208     return E_NOTIMPL;
209 }
210
211 static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
212                                               LCID lcid, ITypeInfo **ppTInfo)
213 {
214     ok(0, "unexpected call\n");
215     return E_NOTIMPL;
216 }
217
218 static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
219                                                 LPOLESTR *rgszNames, UINT cNames,
220                                                 LCID lcid, DISPID *rgDispId)
221 {
222     ok(0, "unexpected call\n");
223     return E_NOTIMPL;
224 }
225
226 static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
227                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
228                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
229 {
230     ok(0, "unexpected call\n");
231     return E_NOTIMPL;
232 }
233
234 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
235 {
236     ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
237     return E_NOTIMPL;
238 }
239
240 static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
241 {
242     ok(0, "unexpected call\n");
243     return E_NOTIMPL;
244 }
245
246 static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
247 {
248     ok(0, "unexpected call\n");
249     return E_NOTIMPL;
250 }
251
252 static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
253 {
254     ok(0, "unexpected call\n");
255     return E_NOTIMPL;
256 }
257
258 static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
259 {
260     ok(0, "unexpected call\n");
261     return E_NOTIMPL;
262 }
263
264 static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
265 {
266     ok(0, "unexpected call\n");
267     return E_NOTIMPL;
268 }
269
270 static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
271 {
272     ok(0, "unexpected call\n");
273     return E_NOTIMPL;
274 }
275
276 static HRESULT WINAPI funcDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
277         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
278 {
279     CHECK_EXPECT(funcDisp);
280
281     ok(id == DISPID_VALUE, "id = %d\n", id);
282     ok(lcid == 0, "lcid = %x\n", lcid);
283     ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
284     ok(pdp != NULL, "pdp == NULL\n");
285     ok(pdp->cArgs == 2, "pdp->cArgs = %d\n", pdp->cArgs);
286     ok(pdp->cNamedArgs == 1, "pdp->cNamedArgs = %d\n", pdp->cNamedArgs);
287     ok(pdp->rgdispidNamedArgs[0] == DISPID_THIS, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
288     ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(rgvarg) = %d\n", V_VT(pdp->rgvarg));
289     ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(rgvarg[1]) = %d\n", V_VT(pdp->rgvarg));
290     ok(V_BOOL(pdp->rgvarg+1) == VARIANT_TRUE, "V_BOOL(rgvarg[1]) = %x\n", V_BOOL(pdp->rgvarg));
291     ok(pvarRes != NULL, "pvarRes == NULL\n");
292     ok(pei != NULL, "pei == NULL\n");
293     ok(!pspCaller, "pspCaller != NULL\n");
294
295     V_VT(pvarRes) = VT_I4;
296     V_I4(pvarRes) = 100;
297     return S_OK;
298 }
299
300 static IDispatchExVtbl testObjVtbl = {
301     DispatchEx_QueryInterface,
302     DispatchEx_AddRef,
303     DispatchEx_Release,
304     DispatchEx_GetTypeInfoCount,
305     DispatchEx_GetTypeInfo,
306     DispatchEx_GetIDsOfNames,
307     DispatchEx_Invoke,
308     DispatchEx_GetDispID,
309     funcDisp_InvokeEx,
310     DispatchEx_DeleteMemberByName,
311     DispatchEx_DeleteMemberByDispID,
312     DispatchEx_GetMemberProperties,
313     DispatchEx_GetMemberName,
314     DispatchEx_GetNextDispID,
315     DispatchEx_GetNameSpaceParent
316 };
317
318 static IDispatchEx funcDisp = { &testObjVtbl };
319
320 static IHTMLDocument2 *create_document(void)
321 {
322     IHTMLDocument2 *doc;
323     HRESULT hres;
324
325     hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
326             &IID_IHTMLDocument2, (void**)&doc);
327     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
328
329     return doc;
330 }
331
332 static IHTMLDocument2 *create_doc_with_string(const char *str)
333 {
334     IPersistStreamInit *init;
335     IStream *stream;
336     IHTMLDocument2 *doc;
337     HGLOBAL mem;
338     SIZE_T len;
339
340     notif_doc = doc = create_document();
341     if(!doc)
342         return NULL;
343
344     doc_complete = FALSE;
345     len = strlen(str);
346     mem = GlobalAlloc(0, len);
347     memcpy(mem, str, len);
348     CreateStreamOnHGlobal(mem, TRUE, &stream);
349
350     IHTMLDocument2_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&init);
351
352     IPersistStreamInit_Load(init, stream);
353     IPersistStreamInit_Release(init);
354     IStream_Release(stream);
355
356     return doc;
357 }
358
359 static void do_advise(IUnknown *unk, REFIID riid, IUnknown *unk_advise)
360 {
361     IConnectionPointContainer *container;
362     IConnectionPoint *cp;
363     DWORD cookie;
364     HRESULT hres;
365
366     hres = IUnknown_QueryInterface(unk, &IID_IConnectionPointContainer, (void**)&container);
367     ok(hres == S_OK, "QueryInterface(IID_IConnectionPointContainer) failed: %08x\n", hres);
368
369     hres = IConnectionPointContainer_FindConnectionPoint(container, riid, &cp);
370     IConnectionPointContainer_Release(container);
371     ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres);
372
373     hres = IConnectionPoint_Advise(cp, unk_advise, &cookie);
374     IConnectionPoint_Release(cp);
375     ok(hres == S_OK, "Advise failed: %08x\n", hres);
376 }
377
378 typedef void (*domtest_t)(IHTMLDocument2*);
379
380 static IHTMLDocument2 *create_and_load_doc(const char *str)
381 {
382     IHTMLDocument2 *doc;
383     IHTMLElement *body = NULL;
384     ULONG ref;
385     MSG msg;
386     HRESULT hres;
387     static const WCHAR ucPtr[] = {'b','a','c','k','g','r','o','u','n','d',0};
388     DISPID dispID = -1;
389     OLECHAR *name;
390
391
392     doc = create_doc_with_string(str);
393     do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
394
395     while(!doc_complete && GetMessage(&msg, NULL, 0, 0)) {
396         TranslateMessage(&msg);
397         DispatchMessage(&msg);
398     }
399
400     hres = IHTMLDocument2_get_body(doc, &body);
401     ok(hres == S_OK, "get_body failed: %08x\n", hres);
402
403     if(!body) {
404         skip("Could not get document body. Assuming no Gecko installed.\n");
405         ref = IHTMLDocument2_Release(doc);
406         ok(!ref, "ref = %d\n", ref);
407         return NULL;
408     }
409
410     /* Check we can query for function on the IHTMLElementBody interface */
411     name = (WCHAR*)ucPtr;
412     hres = IHTMLElement_GetIDsOfNames(body, &IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispID);
413     ok(hres == S_OK, "GetIDsOfNames(background) failed %08x\n", hres);
414     ok(dispID == DISPID_IHTMLBODYELEMENT_BACKGROUND, "Incorrect dispID got (%d)\n", dispID);
415
416     IHTMLElement_Release(body);
417     return doc;
418 }
419
420 static IActiveScriptSite *site;
421 static SCRIPTSTATE state;
422
423 static HRESULT WINAPI ObjectSafety_QueryInterface(IObjectSafety *iface, REFIID riid, void **ppv)
424 {
425     *ppv = NULL;
426     ok(0, "unexpected call\n");
427     return E_NOINTERFACE;
428 }
429
430 static ULONG WINAPI ObjectSafety_AddRef(IObjectSafety *iface)
431 {
432     return 2;
433 }
434
435 static ULONG WINAPI ObjectSafety_Release(IObjectSafety *iface)
436 {
437     return 1;
438 }
439
440 static HRESULT WINAPI ObjectSafety_GetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
441         DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
442 {
443     CHECK_EXPECT(GetInterfaceSafetyOptions);
444
445     ok(IsEqualGUID(&IID_IActiveScriptParse, riid), "unexpected riid %s\n", debugstr_guid(riid));
446     ok(pdwSupportedOptions != NULL, "pdwSupportedOptions == NULL\n");
447     ok(pdwEnabledOptions != NULL, "pdwEnabledOptions == NULL\n");
448
449     *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER;
450     *pdwEnabledOptions = INTERFACE_USES_DISPEX;
451
452     return S_OK;
453 }
454
455 static HRESULT WINAPI ObjectSafety_SetInterfaceSafetyOptions(IObjectSafety *iface, REFIID riid,
456         DWORD dwOptionSetMask, DWORD dwEnabledOptions)
457 {
458     CHECK_EXPECT(SetInterfaceSafetyOptions);
459
460     ok(IsEqualGUID(&IID_IActiveScriptParse, riid), "unexpected riid %s\n", debugstr_guid(riid));
461
462     ok(dwOptionSetMask == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
463        "dwOptionSetMask=%x\n", dwOptionSetMask);
464     ok(dwEnabledOptions == (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER),
465        "dwEnabledOptions=%x\n", dwOptionSetMask);
466
467     return S_OK;
468 }
469
470 static const IObjectSafetyVtbl ObjectSafetyVtbl = {
471     ObjectSafety_QueryInterface,
472     ObjectSafety_AddRef,
473     ObjectSafety_Release,
474     ObjectSafety_GetInterfaceSafetyOptions,
475     ObjectSafety_SetInterfaceSafetyOptions
476 };
477
478 static IObjectSafety ObjectSafety = { &ObjectSafetyVtbl };
479
480 static HRESULT WINAPI ActiveScriptProperty_QueryInterface(IActiveScriptProperty *iface, REFIID riid, void **ppv)
481 {
482     *ppv = NULL;
483     ok(0, "unexpected call\n");
484     return E_NOINTERFACE;
485 }
486
487 static ULONG WINAPI ActiveScriptProperty_AddRef(IActiveScriptProperty *iface)
488 {
489     return 2;
490 }
491
492 static ULONG WINAPI ActiveScriptProperty_Release(IActiveScriptProperty *iface)
493 {
494     return 1;
495 }
496
497 static HRESULT WINAPI ActiveScriptProperty_GetProperty(IActiveScriptProperty *iface, DWORD dwProperty,
498         VARIANT *pvarIndex, VARIANT *pvarValue)
499 {
500     ok(0, "unexpected call\n");
501     return E_NOTIMPL;
502 }
503
504 static HRESULT WINAPI ActiveScriptProperty_SetProperty(IActiveScriptProperty *iface, DWORD dwProperty,
505         VARIANT *pvarIndex, VARIANT *pvarValue)
506 {
507     CHECK_EXPECT(SetProperty);
508
509     ok(dwProperty == SCRIPTPROP_HACK_TRIDENTEVENTSINK, "unexpected property %d\n", dwProperty);
510     ok(!pvarIndex, "pvarIndex != NULL\n");
511     ok(pvarValue != NULL, "pvarValue == NULL\n");
512     ok(V_VT(pvarValue) == VT_BOOL, "V_VT(pvarValue)=%d\n", V_VT(pvarValue));
513     ok(V_BOOL(pvarValue) == VARIANT_TRUE, "V_BOOL(pvarValue)=%x\n", V_BOOL(pvarValue));
514
515     return E_NOTIMPL;
516 }
517
518 static const IActiveScriptPropertyVtbl ActiveScriptPropertyVtbl = {
519     ActiveScriptProperty_QueryInterface,
520     ActiveScriptProperty_AddRef,
521     ActiveScriptProperty_Release,
522     ActiveScriptProperty_GetProperty,
523     ActiveScriptProperty_SetProperty
524 };
525
526 static IActiveScriptProperty ActiveScriptProperty = { &ActiveScriptPropertyVtbl };
527
528 static HRESULT WINAPI ActiveScriptParseProcedure_QueryInterface(IActiveScriptParseProcedure2 *iface, REFIID riid, void **ppv)
529 {
530     *ppv = NULL;
531     ok(0, "unexpected call\n");
532     return E_NOINTERFACE;
533 }
534
535 static ULONG WINAPI ActiveScriptParseProcedure_AddRef(IActiveScriptParseProcedure2 *iface)
536 {
537     return 2;
538 }
539
540 static ULONG WINAPI ActiveScriptParseProcedure_Release(IActiveScriptParseProcedure2 *iface)
541 {
542     return 1;
543 }
544
545 static HRESULT WINAPI ActiveScriptParseProcedure_ParseProcedureText(IActiveScriptParseProcedure2 *iface,
546         LPCOLESTR pstrCode, LPCOLESTR pstrFormalParams, LPCOLESTR pstrProcedureName,
547         LPCOLESTR pstrItemName, IUnknown *punkContext, LPCOLESTR pstrDelimiter,
548         CTXARG_T dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags, IDispatch **ppdisp)
549 {
550     ok(0, "unexpected call\n");
551     return E_NOTIMPL;
552 }
553
554 static const IActiveScriptParseProcedure2Vtbl ActiveScriptParseProcedureVtbl = {
555     ActiveScriptParseProcedure_QueryInterface,
556     ActiveScriptParseProcedure_AddRef,
557     ActiveScriptParseProcedure_Release,
558     ActiveScriptParseProcedure_ParseProcedureText
559 };
560
561 static IActiveScriptParseProcedure2 ActiveScriptParseProcedure = { &ActiveScriptParseProcedureVtbl };
562
563 static HRESULT WINAPI ActiveScriptParse_QueryInterface(IActiveScriptParse *iface, REFIID riid, void **ppv)
564 {
565     *ppv = NULL;
566     ok(0, "unexpected call\n");
567     return E_NOINTERFACE;
568 }
569
570 static ULONG WINAPI ActiveScriptParse_AddRef(IActiveScriptParse *iface)
571 {
572     return 2;
573 }
574
575 static ULONG WINAPI ActiveScriptParse_Release(IActiveScriptParse *iface)
576 {
577     return 1;
578 }
579
580 static HRESULT WINAPI ActiveScriptParse_InitNew(IActiveScriptParse *iface)
581 {
582     CHECK_EXPECT(InitNew);
583     return S_OK;
584 }
585
586 static HRESULT WINAPI ActiveScriptParse_AddScriptlet(IActiveScriptParse *iface,
587         LPCOLESTR pstrDefaultName, LPCOLESTR pstrCode, LPCOLESTR pstrItemName,
588         LPCOLESTR pstrSubItemName, LPCOLESTR pstrEventName, LPCOLESTR pstrDelimiter,
589         CTXARG_T dwSourceContextCookie, ULONG ulStartingLineNumber, DWORD dwFlags,
590         BSTR *pbstrName, EXCEPINFO *pexcepinfo)
591 {
592     ok(0, "unexpected call\n");
593     return E_NOTIMPL;
594 }
595
596 static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *iface,
597         LPCOLESTR pstrCode, LPCOLESTR pstrItemName, IUnknown *punkContext,
598         LPCOLESTR pstrDelimiter, CTXARG_T dwSourceContextCookie, ULONG ulStartingLine,
599         DWORD dwFlags, VARIANT *pvarResult, EXCEPINFO *pexcepinfo)
600 {
601     IDispatchEx *document;
602     IUnknown *unk;
603     VARIANT var, arg;
604     DISPPARAMS dp;
605     EXCEPINFO ei;
606     DISPID id, named_arg = DISPID_PROPERTYPUT;
607     BSTR tmp;
608     HRESULT hres;
609
610     static const WCHAR documentW[] = {'d','o','c','u','m','e','n','t',0};
611     static const WCHAR testW[] = {'t','e','s','t',0};
612     static const WCHAR funcW[] = {'f','u','n','c',0};
613
614     CHECK_EXPECT(ParseScriptText);
615
616     SET_EXPECT(GetScriptDispatch);
617
618     tmp = SysAllocString(documentW);
619     hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive, &id);
620     SysFreeString(tmp);
621     ok(hres == S_OK, "GetDispID(document) failed: %08x\n", hres);
622     ok(id == DISPID_IHTMLWINDOW2_DOCUMENT, "id=%x\n", id);
623
624     todo_wine CHECK_CALLED(GetScriptDispatch);
625
626     VariantInit(&var);
627     memset(&dp, 0, sizeof(dp));
628     memset(&ei, 0, sizeof(ei));
629
630     hres = IDispatchEx_InvokeEx(window_dispex, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
631     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
632     ok(V_VT(&var) == VT_DISPATCH, "V_VT(var)=%d\n", V_VT(&var));
633     ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(&var) == NULL\n");
634
635     hres = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IDispatchEx, (void**)&document);
636     VariantClear(&var);
637     ok(hres == S_OK, "Could not get DispatchEx: %08x\n", hres);
638
639     tmp = SysAllocString(testW);
640     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive, &id);
641     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(document) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
642     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive | fdexNameImplicit, &id);
643     ok(hres == DISP_E_UNKNOWNNAME, "GetDispID(document) failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
644     SysFreeString(tmp);
645
646     id = 0;
647     tmp = SysAllocString(testW);
648     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive|fdexNameEnsure, &id);
649     SysFreeString(tmp);
650     ok(hres == S_OK, "GetDispID(document) failed: %08x\n", hres);
651     ok(id, "id == 0\n");
652
653     dp.cArgs = 1;
654     dp.rgvarg = &var;
655     dp.cNamedArgs = 1;
656     dp.rgdispidNamedArgs = &named_arg;
657     V_VT(&var) = VT_I4;
658     V_I4(&var) = 100;
659
660     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYPUT, &dp, NULL, &ei, NULL);
661     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
662
663     tmp = SysAllocString(testW);
664     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive, &id);
665     SysFreeString(tmp);
666     ok(hres == S_OK, "GetDispID(document) failed: %08x\n", hres);
667
668     VariantInit(&var);
669     memset(&dp, 0, sizeof(dp));
670     memset(&ei, 0, sizeof(ei));
671     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
672     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
673     ok(V_VT(&var) == VT_I4, "V_VT(var)=%d\n", V_VT(&var));
674     ok(V_I4(&var) == 100, "V_I4(&var) == NULL\n");
675
676     unk = (void*)0xdeadbeef;
677     hres = IDispatchEx_GetNameSpaceParent(window_dispex, &unk);
678     ok(hres == S_OK, "GetNameSpaceParent failed: %08x\n", hres);
679     ok(!unk, "unk=%p, expected NULL\n", unk);
680
681     id = 0;
682     tmp = SysAllocString(funcW);
683     hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive|fdexNameEnsure, &id);
684     SysFreeString(tmp);
685     ok(hres == S_OK, "GetDispID(func) failed: %08x\n", hres);
686     ok(id, "id == 0\n");
687
688     dp.cArgs = 1;
689     dp.rgvarg = &var;
690     dp.cNamedArgs = 0;
691     dp.rgdispidNamedArgs = NULL;
692     V_VT(&var) = VT_DISPATCH;
693     V_DISPATCH(&var) = (IDispatch*)&funcDisp;
694
695     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYPUT, &dp, NULL, &ei, NULL);
696     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
697
698     VariantInit(&var);
699     memset(&dp, 0, sizeof(dp));
700     memset(&ei, 0, sizeof(ei));
701     V_VT(&arg) = VT_BOOL;
702     V_BOOL(&arg) = VARIANT_TRUE;
703     dp.cArgs = 1;
704     dp.rgvarg = &arg;
705
706     SET_EXPECT(funcDisp);
707     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_FUNC, &dp, &var, &ei, NULL);
708     CHECK_CALLED(funcDisp);
709
710     ok(hres == S_OK, "InvokeEx(INVOKE_FUNC) failed: %08x\n", hres);
711     ok(V_VT(&var) == VT_I4, "V_VT(var)=%d\n", V_VT(&var));
712     ok(V_I4(&var) == 100, "V_I4(&var) == NULL\n");
713
714     IDispatchEx_Release(document);
715
716     return S_OK;
717 }
718
719 static const IActiveScriptParseVtbl ActiveScriptParseVtbl = {
720     ActiveScriptParse_QueryInterface,
721     ActiveScriptParse_AddRef,
722     ActiveScriptParse_Release,
723     ActiveScriptParse_InitNew,
724     ActiveScriptParse_AddScriptlet,
725     ActiveScriptParse_ParseScriptText
726 };
727
728 static IActiveScriptParse ActiveScriptParse = { &ActiveScriptParseVtbl };
729
730 static HRESULT WINAPI ActiveScript_QueryInterface(IActiveScript *iface, REFIID riid, void **ppv)
731 {
732     *ppv = NULL;
733
734     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IActiveScript, riid)) {
735         *ppv = iface;
736         return S_OK;
737     }
738
739     if(IsEqualGUID(&IID_IActiveScriptParse, riid)) {
740         *ppv = &ActiveScriptParse;
741         return S_OK;
742     }
743
744     if(IsEqualGUID(&IID_IActiveScriptParseProcedure2, riid)) {
745         *ppv = &ActiveScriptParseProcedure;
746         return S_OK;
747     }
748
749     if(IsEqualGUID(&IID_IActiveScriptProperty, riid)) {
750         *ppv = &ActiveScriptProperty;
751         return S_OK;
752     }
753
754     if(IsEqualGUID(&IID_IObjectSafety, riid)) {
755         *ppv = &ObjectSafety;
756         return S_OK;
757     }
758
759     ok(0, "unexpected riid %s\n", debugstr_guid(riid));
760     return E_NOINTERFACE;
761 }
762
763 static ULONG WINAPI ActiveScript_AddRef(IActiveScript *iface)
764 {
765     return 2;
766 }
767
768 static ULONG WINAPI ActiveScript_Release(IActiveScript *iface)
769 {
770     return 1;
771 }
772
773 static HRESULT WINAPI ActiveScript_SetScriptSite(IActiveScript *iface, IActiveScriptSite *pass)
774 {
775     IActiveScriptSiteInterruptPoll *poll;
776     IActiveScriptSiteDebug *debug;
777     IServiceProvider *service;
778     ICanHandleException *canexpection;
779     LCID lcid;
780     HRESULT hres;
781
782     CHECK_EXPECT(SetScriptSite);
783
784     ok(pass != NULL, "pass == NULL\n");
785
786     hres = IActiveScriptSite_QueryInterface(pass, &IID_IActiveScriptSiteInterruptPoll, (void**)&poll);
787     ok(hres == S_OK, "Could not get IActiveScriptSiteInterruptPoll interface: %08x\n", hres);
788     if(FAILED(hres))
789         IActiveScriptSiteInterruptPoll_Release(poll);
790
791     hres = IActiveScriptSite_GetLCID(pass, &lcid);
792     ok(hres == S_OK, "GetLCID failed: %08x\n", hres);
793
794     hres = IActiveScriptSite_OnStateChange(pass, (state = SCRIPTSTATE_INITIALIZED));
795     ok(hres == S_OK, "OnStateChange failed: %08x\n", hres);
796
797     hres = IActiveScriptSite_QueryInterface(pass, &IID_IActiveScriptSiteDebug, (void**)&debug);
798     ok(hres == S_OK, "Could not get IActiveScriptSiteDebug interface: %08x\n", hres);
799     if(SUCCEEDED(hres))
800         IActiveScriptSiteDebug32_Release(debug);
801
802     hres = IActiveScriptSite_QueryInterface(pass, &IID_ICanHandleException, (void**)&canexpection);
803     ok(hres == E_NOINTERFACE, "Could not get IID_ICanHandleException interface: %08x\n", hres);
804
805     hres = IActiveScriptSite_QueryInterface(pass, &IID_IServiceProvider, (void**)&service);
806     todo_wine ok(hres == S_OK, "Could not get IServiceProvider interface: %08x\n", hres);
807     if(SUCCEEDED(hres))
808         IServiceProvider_Release(service);
809
810     site = pass;
811     IActiveScriptSite_AddRef(site);
812     return S_OK;
813 }
814
815 static HRESULT WINAPI ActiveScript_GetScriptSite(IActiveScript *iface, REFIID riid,
816                                             void **ppvObject)
817 {
818     ok(0, "unexpected call\n");
819     return E_NOTIMPL;
820 }
821
822 static HRESULT WINAPI ActiveScript_SetScriptState(IActiveScript *iface, SCRIPTSTATE ss)
823 {
824     HRESULT hres;
825
826     switch(ss) {
827     case SCRIPTSTATE_STARTED:
828         CHECK_EXPECT(SetScriptState_STARTED);
829         break;
830     case SCRIPTSTATE_CONNECTED:
831         CHECK_EXPECT(SetScriptState_CONNECTED);
832         break;
833     case SCRIPTSTATE_DISCONNECTED:
834         CHECK_EXPECT(SetScriptState_DISCONNECTED);
835         break;
836     default:
837         ok(0, "unexpected state %d\n", ss);
838         return E_NOTIMPL;
839     }
840
841     hres = IActiveScriptSite_OnStateChange(site, (state = ss));
842     return S_OK;
843 }
844
845 static HRESULT WINAPI ActiveScript_GetScriptState(IActiveScript *iface, SCRIPTSTATE *pssState)
846 {
847     CHECK_EXPECT(GetScriptState);
848
849     *pssState = state;
850     return S_OK;
851 }
852
853 static HRESULT WINAPI ActiveScript_Close(IActiveScript *iface)
854 {
855     CHECK_EXPECT(Close);
856     return E_NOTIMPL;
857 }
858
859 static HRESULT WINAPI ActiveScript_AddNamedItem(IActiveScript *iface,
860         LPCOLESTR pstrName, DWORD dwFlags)
861 {
862     IDispatch *disp;
863     IUnknown *unk = NULL, *unk2;
864     HRESULT hres;
865
866     static const WCHAR windowW[] = {'w','i','n','d','o','w',0};
867
868     static const IID unknown_iid = {0x719C3050,0xF9D3,0x11CF,{0xA4,0x93,0x00,0x40,0x05,0x23,0xA8,0xA0}};
869
870     CHECK_EXPECT(AddNamedItem);
871
872     ok(!lstrcmpW(pstrName, windowW), "pstrName=%s\n", wine_dbgstr_w(pstrName));
873     ok(dwFlags == (SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS), "dwFlags=%x\n", dwFlags);
874
875     hres = IActiveScriptSite_GetItemInfo(site, windowW, SCRIPTINFO_IUNKNOWN, &unk, NULL);
876     ok(hres == S_OK, "GetItemInfo failed: %08x\n", hres);
877     ok(unk != NULL, "unk == NULL\n");
878
879     hres = IUnknown_QueryInterface(unk, &IID_IDispatch, (void**)&disp);
880     ok(hres == S_OK, "Could not get IDispatch interface: %08x\n", hres);
881     if(SUCCEEDED(hres))
882         IDispatch_Release(disp);
883
884     hres = IUnknown_QueryInterface(unk, &unknown_iid, (void**)&unk2);
885     ok(hres == E_NOINTERFACE, "Got ?? interface: %p\n", unk2);
886     if(SUCCEEDED(hres))
887         IUnknown_Release(unk2);
888
889     hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&window_dispex);
890     ok(hres == S_OK, "Could not get IDispatchEx interface: %08x\n", hres);
891
892     IUnknown_Release(unk);
893     return S_OK;
894 }
895
896 static HRESULT WINAPI ActiveScript_AddTypeLib(IActiveScript *iface, REFGUID rguidTypeLib,
897                                          DWORD dwMajor, DWORD dwMinor, DWORD dwFlags)
898 {
899     ok(0, "unexpected call\n");
900     return E_NOTIMPL;
901 }
902
903 static HRESULT WINAPI ActiveScript_GetScriptDispatch(IActiveScript *iface, LPCOLESTR pstrItemName,
904                                                 IDispatch **ppdisp)
905 {
906     CHECK_EXPECT(GetScriptDispatch);
907     return E_NOTIMPL;
908 }
909
910 static HRESULT WINAPI ActiveScript_GetCurrentScriptThreadID(IActiveScript *iface,
911                                                        SCRIPTTHREADID *pstridThread)
912 {
913     ok(0, "unexpected call\n");
914     return E_NOTIMPL;
915 }
916
917 static HRESULT WINAPI ActiveScript_GetScriptThreadID(IActiveScript *iface,
918                                                 DWORD dwWin32ThreadId, SCRIPTTHREADID *pstidThread)
919 {
920     ok(0, "unexpected call\n");
921     return E_NOTIMPL;
922 }
923
924 static HRESULT WINAPI ActiveScript_GetScriptThreadState(IActiveScript *iface,
925         SCRIPTTHREADID stidThread, SCRIPTTHREADSTATE *pstsState)
926 {
927     ok(0, "unexpected call\n");
928     return E_NOTIMPL;
929 }
930
931 static HRESULT WINAPI ActiveScript_InterruptScriptThread(IActiveScript *iface,
932         SCRIPTTHREADID stidThread, const EXCEPINFO *pexcepinfo, DWORD dwFlags)
933 {
934     ok(0, "unexpected call\n");
935     return E_NOTIMPL;
936 }
937
938 static HRESULT WINAPI ActiveScript_Clone(IActiveScript *iface, IActiveScript **ppscript)
939 {
940     ok(0, "unexpected call\n");
941     return E_NOTIMPL;
942 }
943
944 static const IActiveScriptVtbl ActiveScriptVtbl = {
945     ActiveScript_QueryInterface,
946     ActiveScript_AddRef,
947     ActiveScript_Release,
948     ActiveScript_SetScriptSite,
949     ActiveScript_GetScriptSite,
950     ActiveScript_SetScriptState,
951     ActiveScript_GetScriptState,
952     ActiveScript_Close,
953     ActiveScript_AddNamedItem,
954     ActiveScript_AddTypeLib,
955     ActiveScript_GetScriptDispatch,
956     ActiveScript_GetCurrentScriptThreadID,
957     ActiveScript_GetScriptThreadID,
958     ActiveScript_GetScriptThreadState,
959     ActiveScript_InterruptScriptThread,
960     ActiveScript_Clone
961 };
962
963 static IActiveScript ActiveScript = { &ActiveScriptVtbl };
964
965 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
966 {
967     *ppv = NULL;
968
969     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) {
970         *ppv = iface;
971         return S_OK;
972     }
973
974     if(IsEqualGUID(&IID_IMarshal, riid))
975         return E_NOINTERFACE;
976     if(IsEqualGUID(&CLSID_IdentityUnmarshal, riid))
977         return E_NOINTERFACE;
978
979     ok(0, "unexpected riid %s\n", debugstr_guid(riid));
980     return E_NOTIMPL;
981 }
982
983 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
984 {
985     return 2;
986 }
987
988 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
989 {
990     return 1;
991 }
992
993 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
994 {
995     CHECK_EXPECT(CreateInstance);
996
997     ok(!outer, "outer = %p\n", outer);
998     ok(IsEqualGUID(&IID_IActiveScript, riid), "unexpected riid %s\n", debugstr_guid(riid));
999     *ppv = &ActiveScript;
1000     return S_OK;
1001 }
1002
1003 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
1004 {
1005     ok(0, "unexpected call\n");
1006     return S_OK;
1007 }
1008
1009 static const IClassFactoryVtbl ClassFactoryVtbl = {
1010     ClassFactory_QueryInterface,
1011     ClassFactory_AddRef,
1012     ClassFactory_Release,
1013     ClassFactory_CreateInstance,
1014     ClassFactory_LockServer
1015 };
1016
1017 static IClassFactory script_cf = { &ClassFactoryVtbl };
1018
1019 static const char simple_script_str[] =
1020     "<html><head></head><body>"
1021     "<script language=\"TestScript\">simple script</script>"
1022     "</body></html>";
1023
1024 static void test_simple_script(void)
1025 {
1026     IHTMLDocument2 *doc;
1027
1028     SET_EXPECT(CreateInstance);
1029     SET_EXPECT(GetInterfaceSafetyOptions);
1030     SET_EXPECT(SetInterfaceSafetyOptions);
1031     SET_EXPECT(SetProperty);
1032     SET_EXPECT(InitNew);
1033     SET_EXPECT(SetScriptSite);
1034     SET_EXPECT(GetScriptState);
1035     SET_EXPECT(SetScriptState_STARTED);
1036     SET_EXPECT(AddNamedItem);
1037     SET_EXPECT(ParseScriptText);
1038     SET_EXPECT(SetScriptState_CONNECTED);
1039
1040     doc = create_and_load_doc(simple_script_str);
1041     if(!doc) return;
1042
1043     CHECK_CALLED(CreateInstance);
1044     CHECK_CALLED(GetInterfaceSafetyOptions);
1045     CHECK_CALLED(SetInterfaceSafetyOptions);
1046     CHECK_CALLED(SetProperty);
1047     CHECK_CALLED(InitNew);
1048     CHECK_CALLED(SetScriptSite);
1049     CHECK_CALLED(GetScriptState);
1050     CHECK_CALLED(SetScriptState_STARTED);
1051     CHECK_CALLED(AddNamedItem);
1052     CHECK_CALLED(ParseScriptText);
1053     CHECK_CALLED(SetScriptState_CONNECTED);
1054
1055     if(site)
1056         IActiveScriptSite_Release(site);
1057     if(window_dispex)
1058         IDispatchEx_Release(window_dispex);
1059
1060     SET_EXPECT(SetScriptState_DISCONNECTED);
1061     SET_EXPECT(Close);
1062
1063     IHTMLDocument2_Release(doc);
1064
1065     CHECK_CALLED(SetScriptState_DISCONNECTED);
1066     CHECK_CALLED(Close);
1067 }
1068
1069 static BOOL init_key(const char *key_name, const char *def_value, BOOL init)
1070 {
1071     HKEY hkey;
1072     DWORD res;
1073
1074     if(!init) {
1075         RegDeleteKey(HKEY_CLASSES_ROOT, key_name);
1076         return TRUE;
1077     }
1078
1079     res = RegCreateKeyA(HKEY_CLASSES_ROOT, key_name, &hkey);
1080     if(res != ERROR_SUCCESS)
1081         return FALSE;
1082
1083     if(def_value)
1084         res = RegSetValueA(hkey, NULL, REG_SZ, def_value, strlen(def_value));
1085
1086     RegCloseKey(hkey);
1087
1088     return res == ERROR_SUCCESS;
1089 }
1090
1091 static BOOL init_registry(BOOL init)
1092 {
1093     return init_key("TestScript\\CLSID", TESTSCRIPT_CLSID, init)
1094         && init_key("CLSID\\"TESTSCRIPT_CLSID"\\Implemented Categories\\{F0B7A1A1-9847-11CF-8F20-00805F2CD064}",
1095                     NULL, init)
1096         && init_key("CLSID\\"TESTSCRIPT_CLSID"\\Implemented Categories\\{F0B7A1A2-9847-11CF-8F20-00805F2CD064}",
1097                     NULL, init);
1098 }
1099
1100 static BOOL register_script_engine(void)
1101 {
1102     DWORD regid;
1103     HRESULT hres;
1104
1105     if(!init_registry(TRUE)) {
1106         init_registry(FALSE);
1107         return FALSE;
1108     }
1109
1110     hres = CoRegisterClassObject(&CLSID_TestScript, (IUnknown *)&script_cf,
1111                                  CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &regid);
1112     ok(hres == S_OK, "Could not register screipt engine: %08x\n", hres);
1113
1114     return TRUE;
1115 }
1116
1117 static void gecko_installer_workaround(BOOL disable)
1118 {
1119     HKEY hkey;
1120     DWORD res;
1121
1122     static BOOL has_url = FALSE;
1123     static char url[2048];
1124
1125     if(!disable && !has_url)
1126         return;
1127
1128     res = RegOpenKey(HKEY_CURRENT_USER, "Software\\Wine\\MSHTML", &hkey);
1129     if(res != ERROR_SUCCESS)
1130         return;
1131
1132     if(disable) {
1133         DWORD type, size = sizeof(url);
1134
1135         res = RegQueryValueEx(hkey, "GeckoUrl", NULL, &type, (PVOID)url, &size);
1136         if(res == ERROR_SUCCESS && type == REG_SZ)
1137             has_url = TRUE;
1138
1139         RegDeleteValue(hkey, "GeckoUrl");
1140     }else {
1141         RegSetValueEx(hkey, "GeckoUrl", 0, REG_SZ, (PVOID)url, lstrlenA(url)+1);
1142     }
1143
1144     RegCloseKey(hkey);
1145 }
1146
1147 /* Check if Internet Explorer is configured to run in "Enhanced Security Configuration" (aka hardened mode) */
1148 /* Note: this code is duplicated in dlls/mshtml/tests/dom.c, dlls/mshtml/tests/script.c and dlls/urlmon/tests/sec_mgr.c */
1149 static BOOL is_ie_hardened(void)
1150 {
1151     HKEY zone_map;
1152     DWORD ie_harden, type, size;
1153
1154     ie_harden = 0;
1155     if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ZoneMap",
1156                     0, KEY_QUERY_VALUE, &zone_map) == ERROR_SUCCESS) {
1157         size = sizeof(DWORD);
1158         if (RegQueryValueEx(zone_map, "IEHarden", NULL, &type, (LPBYTE) &ie_harden, &size) != ERROR_SUCCESS ||
1159             type != REG_DWORD) {
1160             ie_harden = 0;
1161         }
1162     RegCloseKey(zone_map);
1163     }
1164
1165     return ie_harden != 0;
1166 }
1167
1168 START_TEST(script)
1169 {
1170     gecko_installer_workaround(TRUE);
1171     CoInitialize(NULL);
1172
1173     if(winetest_interactive || ! is_ie_hardened()) {
1174         if(register_script_engine()) {
1175             test_simple_script();
1176             init_registry(FALSE);
1177         }else {
1178             skip("Could not register TestScript engine\n");
1179         }
1180     }else {
1181         skip("IE running in Enhanced Security Configuration\n");
1182     }
1183
1184     CoUninitialize();
1185     gecko_installer_workaround(FALSE);
1186 }