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