1 /*
2  * Copyright 2009,2011 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 <stdio.h>
20 
21 #define COBJMACROS
22 #define CONST_VTABLE
23 
24 #include <ole2.h>
25 #include <dispex.h>
26 #include <activscp.h>
27 #include <objsafe.h>
28 #include <urlmon.h>
29 #include <mshtmhst.h>
30 
31 #include "wine/test.h"
32 
33 #ifdef _WIN64
34 
35 #define IActiveScriptParse_QueryInterface IActiveScriptParse64_QueryInterface
36 #define IActiveScriptParse_Release IActiveScriptParse64_Release
37 #define IActiveScriptParse_InitNew IActiveScriptParse64_InitNew
38 #define IActiveScriptParse_ParseScriptText IActiveScriptParse64_ParseScriptText
39 #define IActiveScriptParseProcedure2_Release IActiveScriptParseProcedure2_64_Release
40 
41 #else
42 
43 #define IActiveScriptParse_QueryInterface IActiveScriptParse32_QueryInterface
44 #define IActiveScriptParse_Release IActiveScriptParse32_Release
45 #define IActiveScriptParse_InitNew IActiveScriptParse32_InitNew
46 #define IActiveScriptParse_ParseScriptText IActiveScriptParse32_ParseScriptText
47 #define IActiveScriptParseProcedure2_Release IActiveScriptParseProcedure2_32_Release
48 
49 #endif
50 
51 extern const CLSID CLSID_VBScript;
52 
53 #define VB_E_ACCESS_DENIED      0x800a0046
54 
55 #define DEFINE_EXPECT(func) \
56     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
57 
58 #define SET_EXPECT(func) \
59     expect_ ## func = TRUE
60 
61 #define CHECK_EXPECT2(func) \
62     do { \
63         ok(expect_ ##func, "unexpected call " #func "\n"); \
64         called_ ## func = TRUE; \
65     }while(0)
66 
67 #define CHECK_EXPECT(func) \
68     do { \
69         CHECK_EXPECT2(func); \
70         expect_ ## func = FALSE; \
71     }while(0)
72 
73 #define CHECK_CALLED(func) \
74     do { \
75         ok(called_ ## func, "expected " #func "\n"); \
76         expect_ ## func = called_ ## func = FALSE; \
77     }while(0)
78 
79 #define CLEAR_CALLED(func) \
80     expect_ ## func = called_ ## func = FALSE
81 
82 DEFINE_EXPECT(CreateInstance);
83 DEFINE_EXPECT(ProcessUrlAction);
84 DEFINE_EXPECT(QueryCustomPolicy);
85 DEFINE_EXPECT(reportSuccess);
86 DEFINE_EXPECT(Host_QS_SecMgr);
87 DEFINE_EXPECT(Caller_QS_SecMgr);
88 DEFINE_EXPECT(QI_IObjectWithSite);
89 DEFINE_EXPECT(SetSite);
90 
91 static const WCHAR testW[] = {'t','e','s','t',0};
92 
93 static HRESULT QS_SecMgr_hres;
94 static HRESULT ProcessUrlAction_hres;
95 static DWORD ProcessUrlAction_policy;
96 static HRESULT CreateInstance_hres;
97 static HRESULT QueryCustomPolicy_hres;
98 static DWORD QueryCustomPolicy_psize;
99 static DWORD QueryCustomPolicy_policy;
100 static HRESULT QI_IDispatch_hres;
101 static HRESULT QI_IObjectWithSite_hres;
102 static HRESULT SetSite_hres;
103 
104 #define TESTOBJ_CLSID     "{178fc163-f585-4e24-9c13-4bb7faf80646}"
105 #define TESTOBJINST_CLSID "{178fc163-f585-4e24-9c13-4bb7faf80647}"
106 
107 static const GUID CLSID_TestObj =
108     {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x06,0x46}};
109 static const GUID CLSID_TestObjInst =
110     {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x06,0x47}};
111 
112 /* Defined as extern in urlmon.idl, but not exported by uuid.lib */
113 const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY =
114     {0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}};
115 
116 #define DISPID_TEST_REPORTSUCCESS    0x1000
117 
118 #define DISPID_GLOBAL_OK             0x2000
119 
120 #define VB_E_CANNOT_CREATE_OBJ 0x800a01ad
121 
122 static BSTR a2bstr(const char *str)
123 {
124     BSTR ret;
125     int len;
126 
127     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
128     ret = SysAllocStringLen(NULL, len-1);
129     MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
130 
131     return ret;
132 }
133 
134 static int strcmp_wa(LPCWSTR strw, const char *stra)
135 {
136     CHAR buf[512];
137     WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), 0, 0);
138     return lstrcmpA(buf, stra);
139 }
140 
141 static HRESULT WINAPI ObjectWithSite_QueryInterface(IObjectWithSite *iface, REFIID riid, void **ppv)
142 {
143     ok(0, "unexpected call\n");
144     return E_NOTIMPL;
145 }
146 
147 static ULONG WINAPI ObjectWithSite_AddRef(IObjectWithSite *iface)
148 {
149     return 2;
150 }
151 
152 static ULONG WINAPI ObjectWithSite_Release(IObjectWithSite *iface)
153 {
154     return 1;
155 }
156 
157 static HRESULT WINAPI ObjectWithSite_SetSite(IObjectWithSite *iface, IUnknown *pUnkSite)
158 {
159     IServiceProvider *sp;
160     HRESULT hres;
161 
162 
163     CHECK_EXPECT(SetSite);
164     ok(pUnkSite != NULL, "pUnkSite == NULL\n");
165 
166     hres = IUnknown_QueryInterface(pUnkSite, &IID_IServiceProvider, (void**)&sp);
167     ok(hres == S_OK, "Could not get IServiceProvider iface: %08x\n", hres);
168     IServiceProvider_Release(sp);
169 
170     return SetSite_hres;
171 }
172 
173 static HRESULT WINAPI ObjectWithSite_GetSite(IObjectWithSite *iface, REFIID riid, void **ppvSite)
174 {
175     ok(0, "unexpected call\n");
176     return E_NOTIMPL;
177 }
178 
179 static const IObjectWithSiteVtbl ObjectWithSiteVtbl = {
180     ObjectWithSite_QueryInterface,
181     ObjectWithSite_AddRef,
182     ObjectWithSite_Release,
183     ObjectWithSite_SetSite,
184     ObjectWithSite_GetSite
185 };
186 
187 static IObjectWithSite ObjectWithSite = { &ObjectWithSiteVtbl };
188 
189 static IObjectWithSite *object_with_site;
190 
191 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
192 {
193     *ppv = NULL;
194 
195     if(IsEqualGUID(riid, &IID_IUnknown)) {
196        *ppv = iface;
197     }else if(IsEqualGUID(riid, &IID_IDispatch) || IsEqualGUID(riid, &IID_IDispatchEx)) {
198         if(FAILED(QI_IDispatch_hres))
199             return QI_IDispatch_hres;
200         *ppv = iface;
201     }else if(IsEqualGUID(&IID_IObjectWithSite, riid)) {
202         CHECK_EXPECT(QI_IObjectWithSite);
203         if(FAILED(QI_IObjectWithSite_hres))
204             return QI_IObjectWithSite_hres;
205         *ppv = object_with_site;
206     }else if(IsEqualGUID(&IID_IObjectSafety, riid)) {
207         ok(0, "Unexpected IID_IObjectSafety query\n");
208     }
209 
210     return *ppv ? S_OK : E_NOINTERFACE;
211 }
212 
213 static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
214 {
215     return 2;
216 }
217 
218 static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
219 {
220     return 1;
221 }
222 
223 static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
224 {
225     ok(0, "unexpected call\n");
226     return E_NOTIMPL;
227 }
228 
229 static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
230                                               LCID lcid, ITypeInfo **ppTInfo)
231 {
232     ok(0, "unexpected call\n");
233     return E_NOTIMPL;
234 }
235 
236 static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
237                                                 LPOLESTR *rgszNames, UINT cNames,
238                                                 LCID lcid, DISPID *rgDispId)
239 {
240     ok(0, "unexpected call\n");
241     return E_NOTIMPL;
242 }
243 
244 static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
245                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
246                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
247 {
248     ok(0, "unexpected call\n");
249     return E_NOTIMPL;
250 }
251 
252 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
253 {
254     ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
255     return E_NOTIMPL;
256 }
257 
258 static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
259 {
260     ok(0, "unexpected call\n");
261     return E_NOTIMPL;
262 }
263 
264 static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
265 {
266     ok(0, "unexpected call\n");
267     return E_NOTIMPL;
268 }
269 
270 static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
271 {
272     ok(0, "unexpected call\n");
273     return E_NOTIMPL;
274 }
275 
276 static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
277 {
278     ok(0, "unexpected call\n");
279     return E_NOTIMPL;
280 }
281 
282 static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
283 {
284     ok(0, "unexpected call\n");
285     return E_NOTIMPL;
286 }
287 
288 static HRESULT WINAPI Test_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
289 {
290     if(!strcmp_wa(bstrName, "reportSuccess")) {
291         ok(grfdex == fdexNameCaseInsensitive, "grfdex = %x\n", grfdex);
292         *pid = DISPID_TEST_REPORTSUCCESS;
293         return S_OK;
294     }
295 
296     ok(0, "unexpected name %s\n", wine_dbgstr_w(bstrName));
297     return E_NOTIMPL;
298 }
299 
300 static HRESULT WINAPI Test_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
301         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
302 {
303     switch(id) {
304     case DISPID_TEST_REPORTSUCCESS:
305         CHECK_EXPECT(reportSuccess);
306 
307         ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
308         ok(pdp != NULL, "pdp == NULL\n");
309         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
310         ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
311         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
312         ok(!pvarRes, "pvarRes != NULL\n");
313         ok(pei != NULL, "pei == NULL\n");
314         break;
315 
316     default:
317         ok(0, "unexpected call\n");
318         return E_NOTIMPL;
319     }
320 
321     return S_OK;
322 }
323 
324 static IDispatchExVtbl testObjVtbl = {
325     DispatchEx_QueryInterface,
326     DispatchEx_AddRef,
327     DispatchEx_Release,
328     DispatchEx_GetTypeInfoCount,
329     DispatchEx_GetTypeInfo,
330     DispatchEx_GetIDsOfNames,
331     DispatchEx_Invoke,
332     Test_GetDispID,
333     Test_InvokeEx,
334     DispatchEx_DeleteMemberByName,
335     DispatchEx_DeleteMemberByDispID,
336     DispatchEx_GetMemberProperties,
337     DispatchEx_GetMemberName,
338     DispatchEx_GetNextDispID,
339     DispatchEx_GetNameSpaceParent
340 };
341 
342 static IDispatchEx testObj = { &testObjVtbl };
343 
344 static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
345 {
346     if(!strcmp_wa(bstrName, "ok")) {
347         ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
348         *pid = DISPID_GLOBAL_OK;
349         return S_OK;
350     }
351 
352     ok(0, "unexpected name %s\n", wine_dbgstr_w(bstrName));
353     return E_NOTIMPL;
354 }
355 
356 static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
357         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
358 {
359     switch(id) {
360     case DISPID_GLOBAL_OK:
361         ok(wFlags == INVOKE_FUNC || wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
362         ok(pdp != NULL, "pdp == NULL\n");
363         ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
364         ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
365         ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
366         ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
367         ok(pei != NULL, "pei == NULL\n");
368 
369         ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
370         ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg));
371         ok(V_BOOL(pdp->rgvarg+1), "%s\n", wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
372         break;
373 
374     default:
375         ok(0, "unexpected call\n");
376         return E_NOTIMPL;
377     }
378 
379     return S_OK;
380 }
381 
382 static IDispatchExVtbl globalObjVtbl = {
383     DispatchEx_QueryInterface,
384     DispatchEx_AddRef,
385     DispatchEx_Release,
386     DispatchEx_GetTypeInfoCount,
387     DispatchEx_GetTypeInfo,
388     DispatchEx_GetIDsOfNames,
389     DispatchEx_Invoke,
390     Global_GetDispID,
391     Global_InvokeEx,
392     DispatchEx_DeleteMemberByName,
393     DispatchEx_DeleteMemberByDispID,
394     DispatchEx_GetMemberProperties,
395     DispatchEx_GetMemberName,
396     DispatchEx_GetNextDispID,
397     DispatchEx_GetNameSpaceParent
398 };
399 
400 static IDispatchEx globalObj = { &globalObjVtbl };
401 
402 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
403 {
404     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) {
405         *ppv = iface;
406         return S_OK;
407     }
408 
409     /* TODO: IClassFactoryEx */
410     *ppv = NULL;
411     return E_NOINTERFACE;
412 }
413 
414 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
415 {
416     return 2;
417 }
418 
419 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
420 {
421     return 1;
422 }
423 
424 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
425 {
426     CHECK_EXPECT(CreateInstance);
427 
428     ok(!outer, "outer = %p\n", outer);
429     ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
430 
431     if(SUCCEEDED(CreateInstance_hres))
432         *ppv = &testObj;
433     return CreateInstance_hres;
434 }
435 
436 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
437 {
438     ok(0, "unexpected call\n");
439     return S_OK;
440 }
441 
442 static const IClassFactoryVtbl ClassFactoryVtbl = {
443     ClassFactory_QueryInterface,
444     ClassFactory_AddRef,
445     ClassFactory_Release,
446     ClassFactory_CreateInstance,
447     ClassFactory_LockServer
448 };
449 
450 static IClassFactory activex_cf = { &ClassFactoryVtbl };
451 
452 static HRESULT WINAPI InternetHostSecurityManager_QueryInterface(IInternetHostSecurityManager *iface, REFIID riid, void **ppv)
453 {
454     ok(0, "unexpected call\n");
455     return E_NOINTERFACE;
456 }
457 
458 static ULONG WINAPI InternetHostSecurityManager_AddRef(IInternetHostSecurityManager *iface)
459 {
460     return 2;
461 }
462 
463 static ULONG WINAPI InternetHostSecurityManager_Release(IInternetHostSecurityManager *iface)
464 {
465     return 1;
466 }
467 
468 static HRESULT WINAPI InternetHostSecurityManager_GetSecurityId(IInternetHostSecurityManager *iface,  BYTE *pbSecurityId,
469         DWORD *pcbSecurityId, DWORD_PTR dwReserved)
470 {
471     ok(0, "unexpected call\n");
472     return E_NOTIMPL;
473 }
474 
475 static HRESULT WINAPI InternetHostSecurityManager_ProcessUrlAction(IInternetHostSecurityManager *iface, DWORD dwAction,
476         BYTE *pPolicy, DWORD cbPolicy, BYTE *pContext, DWORD cbContext, DWORD dwFlags, DWORD dwReserved)
477 {
478     CHECK_EXPECT(ProcessUrlAction);
479 
480     ok(dwAction == URLACTION_ACTIVEX_RUN, "dwAction = %x\n", dwAction);
481     ok(pPolicy != NULL, "pPolicy == NULL\n");
482     ok(cbPolicy == sizeof(DWORD), "cbPolicy = %d\n", cbPolicy);
483     ok(pContext != NULL, "pContext == NULL\n");
484     ok(cbContext == sizeof(GUID), "cbContext = %d\n", cbContext);
485     ok(IsEqualGUID(pContext, &CLSID_TestObj), "pContext = %s\n", wine_dbgstr_guid((const IID*)pContext));
486     ok(!dwFlags, "dwFlags = %x\n", dwFlags);
487     ok(!dwReserved, "dwReserved = %x\n", dwReserved);
488 
489     if(SUCCEEDED(ProcessUrlAction_hres))
490         *(DWORD*)pPolicy = ProcessUrlAction_policy;
491     return ProcessUrlAction_hres;
492 }
493 
494 static HRESULT WINAPI InternetHostSecurityManager_QueryCustomPolicy(IInternetHostSecurityManager *iface, REFGUID guidKey,
495         BYTE **ppPolicy, DWORD *pcbPolicy, BYTE *pContext, DWORD cbContext, DWORD dwReserved)
496 {
497     const struct CONFIRMSAFETY *cs = (const struct CONFIRMSAFETY*)pContext;
498     DWORD *ret;
499 
500     CHECK_EXPECT(QueryCustomPolicy);
501 
502     ok(IsEqualGUID(&GUID_CUSTOM_CONFIRMOBJECTSAFETY, guidKey), "guidKey = %s\n", wine_dbgstr_guid(guidKey));
503 
504     ok(ppPolicy != NULL, "ppPolicy == NULL\n");
505     ok(pcbPolicy != NULL, "pcbPolicy == NULL\n");
506     ok(pContext != NULL, "pContext == NULL\n");
507     ok(cbContext == sizeof(struct CONFIRMSAFETY), "cbContext = %d\n", cbContext);
508     ok(!dwReserved, "dwReserved = %x\n", dwReserved);
509 
510     /* TODO: CLSID */
511     ok(cs->pUnk != NULL, "cs->pUnk == NULL\n");
512     ok(!cs->dwFlags, "dwFlags = %x\n", cs->dwFlags);
513 
514     if(FAILED(QueryCustomPolicy_hres))
515         return QueryCustomPolicy_hres;
516 
517     ret = CoTaskMemAlloc(QueryCustomPolicy_psize);
518     *ppPolicy = (BYTE*)ret;
519     *pcbPolicy = QueryCustomPolicy_psize;
520     memset(ret, 0, QueryCustomPolicy_psize);
521     if(QueryCustomPolicy_psize >= sizeof(DWORD))
522         *ret = QueryCustomPolicy_policy;
523 
524     return QueryCustomPolicy_hres;
525 }
526 
527 static const IInternetHostSecurityManagerVtbl InternetHostSecurityManagerVtbl = {
528     InternetHostSecurityManager_QueryInterface,
529     InternetHostSecurityManager_AddRef,
530     InternetHostSecurityManager_Release,
531     InternetHostSecurityManager_GetSecurityId,
532     InternetHostSecurityManager_ProcessUrlAction,
533     InternetHostSecurityManager_QueryCustomPolicy
534 };
535 
536 static IInternetHostSecurityManager InternetHostSecurityManager = { &InternetHostSecurityManagerVtbl };
537 
538 static IServiceProvider ServiceProvider;
539 
540 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
541 {
542     ok(0, "unexpected call\n");
543     return E_NOINTERFACE;
544 }
545 
546 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
547 {
548     return 2;
549 }
550 
551 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
552 {
553     return 1;
554 }
555 
556 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface,
557         REFGUID guidService, REFIID riid, void **ppv)
558 {
559     if(IsEqualGUID(&SID_GetCaller, guidService))
560         return E_NOINTERFACE;
561 
562     if(IsEqualGUID(&SID_SInternetHostSecurityManager, guidService)) {
563         if(iface == &ServiceProvider)
564             CHECK_EXPECT(Host_QS_SecMgr);
565         else
566             CHECK_EXPECT(Caller_QS_SecMgr);
567         ok(IsEqualGUID(&IID_IInternetHostSecurityManager, riid), "unexpected riid %s\n", wine_dbgstr_guid(riid));
568         if(SUCCEEDED(QS_SecMgr_hres))
569             *ppv = &InternetHostSecurityManager;
570         return QS_SecMgr_hres;
571     }
572 
573     ok(0, "unexpected service %s\n", wine_dbgstr_guid(guidService));
574     return E_NOINTERFACE;
575 }
576 
577 static IServiceProviderVtbl ServiceProviderVtbl = {
578     ServiceProvider_QueryInterface,
579     ServiceProvider_AddRef,
580     ServiceProvider_Release,
581     ServiceProvider_QueryService
582 };
583 
584 static IServiceProvider ServiceProvider = { &ServiceProviderVtbl };
585 
586 static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
587 {
588     if(IsEqualGUID(&IID_IUnknown, riid)) {
589         *ppv = iface;
590     }else if(IsEqualGUID(&IID_IActiveScriptSite, riid)) {
591         *ppv = iface;
592     }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
593         *ppv = &ServiceProvider;
594     }else {
595         *ppv = NULL;
596         return E_NOINTERFACE;
597     }
598 
599     IUnknown_AddRef((IUnknown*)*ppv);
600     return S_OK;
601 }
602 
603 static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
604 {
605     return 2;
606 }
607 
608 static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
609 {
610     return 1;
611 }
612 
613 static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *plcid)
614 {
615     *plcid = GetUserDefaultLCID();
616     return S_OK;
617 }
618 
619 static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR pstrName,
620         DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti)
621 {
622     ok(dwReturnMask == SCRIPTINFO_IUNKNOWN, "unexpected dwReturnMask %x\n", dwReturnMask);
623     ok(!ppti, "ppti != NULL\n");
624     ok(!strcmp_wa(pstrName, "test"), "pstrName = %s\n", wine_dbgstr_w(pstrName));
625 
626     *ppiunkItem = (IUnknown*)&globalObj;
627     return S_OK;
628 }
629 
630 static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *pbstrVersion)
631 {
632     return E_NOTIMPL;
633 }
634 
635 static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface,
636         const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo)
637 {
638     return E_NOTIMPL;
639 }
640 
641 static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE ssScriptState)
642 {
643     return E_NOTIMPL;
644 }
645 
646 static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror)
647 {
648     return E_NOTIMPL;
649 }
650 
651 static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
652 {
653     return E_NOTIMPL;
654 }
655 
656 static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
657 {
658     return E_NOTIMPL;
659 }
660 
661 static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
662     ActiveScriptSite_QueryInterface,
663     ActiveScriptSite_AddRef,
664     ActiveScriptSite_Release,
665     ActiveScriptSite_GetLCID,
666     ActiveScriptSite_GetItemInfo,
667     ActiveScriptSite_GetDocVersionString,
668     ActiveScriptSite_OnScriptTerminate,
669     ActiveScriptSite_OnStateChange,
670     ActiveScriptSite_OnScriptError,
671     ActiveScriptSite_OnEnterScript,
672     ActiveScriptSite_OnLeaveScript
673 };
674 
675 static IActiveScriptSite ActiveScriptSite = { &ActiveScriptSiteVtbl };
676 
677 static void set_safety_options(IUnknown *unk, BOOL use_sec_mgr)
678 {
679     IObjectSafety *safety;
680     DWORD supported, enabled, options_all, options_set;
681     HRESULT hres;
682 
683     hres = IUnknown_QueryInterface(unk, &IID_IObjectSafety, (void**)&safety);
684     ok(hres == S_OK, "Could not get IObjectSafety: %08x\n", hres);
685     if(FAILED(hres))
686         return;
687 
688     options_all = INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER;
689     if(use_sec_mgr)
690         options_set = options_all;
691     else
692         options_set = INTERFACE_USES_DISPEX;
693 
694     hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, options_all, options_set);
695     ok(hres == S_OK, "SetInterfaceSafetyOptions failed: %08x\n", hres);
696 
697     supported = enabled = 0xdeadbeef;
698     hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported, &enabled);
699     ok(hres == S_OK, "GetInterfaceSafetyOptions failed: %08x\n", hres);
700     ok(supported == options_all, "supported=%x, expected %x\n", supported, options_all);
701     ok(enabled == options_set, "enabled=%x, expected %x\n", enabled, options_set);
702 
703     IObjectSafety_Release(safety);
704 }
705 
706 #define parse_script_a(p,s) _parse_script_a(__LINE__,p,s)
707 static void _parse_script_a(unsigned line, IActiveScriptParse *parser, const char *script)
708 {
709     BSTR str;
710     HRESULT hres;
711 
712     str = a2bstr(script);
713     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
714     SysFreeString(str);
715     ok_(__FILE__,line)(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
716 }
717 
718 static HRESULT parse_script_ae(IActiveScriptParse *parser, const char *script)
719 {
720     BSTR str;
721     HRESULT hres;
722 
723     str = a2bstr(script);
724     hres = IActiveScriptParse_ParseScriptText(parser, str, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
725     SysFreeString(str);
726 
727     return hres;
728 }
729 
730 static IActiveScriptParse *create_script(BOOL use_sec_mgr)
731 {
732     IActiveScriptParse *parser;
733     IActiveScript *script;
734     HRESULT hres;
735 
736     QS_SecMgr_hres = S_OK;
737     ProcessUrlAction_hres = S_OK;
738     ProcessUrlAction_policy = URLPOLICY_ALLOW;
739     CreateInstance_hres = S_OK;
740     QueryCustomPolicy_hres = S_OK;
741     QueryCustomPolicy_psize = sizeof(DWORD);
742     QueryCustomPolicy_policy = URLPOLICY_ALLOW;
743     QI_IDispatch_hres = S_OK;
744     QI_IObjectWithSite_hres = S_OK;
745     SetSite_hres = S_OK;
746 
747     hres = CoCreateInstance(&CLSID_VBScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
748             &IID_IActiveScript, (void**)&script);
749     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
750     if(FAILED(hres))
751         return NULL;
752 
753     set_safety_options((IUnknown*)script, use_sec_mgr);
754 
755     hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParse, (void**)&parser);
756     ok(hres == S_OK, "Could not get IActiveScriptParse: %08x\n", hres);
757 
758     hres = IActiveScriptParse_InitNew(parser);
759     ok(hres == S_OK, "InitNew failed: %08x\n", hres);
760 
761     hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
762     ok(hres == S_OK, "SetScriptSite failed: %08x\n", hres);
763 
764     hres = IActiveScript_AddNamedItem(script, testW,
765             SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
766     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
767 
768     hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_STARTED);
769     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_STARTED) failed: %08x\n", hres);
770 
771     IActiveScript_Release(script);
772 
773     return parser;
774 }
775 
776 static void test_CreateObject(void)
777 {
778     IActiveScriptParse *parser;
779     HRESULT hres;
780 
781     parser = create_script(TRUE);
782 
783     SET_EXPECT(Host_QS_SecMgr);
784     SET_EXPECT(ProcessUrlAction);
785     SET_EXPECT(CreateInstance);
786     SET_EXPECT(QueryCustomPolicy);
787     SET_EXPECT(QI_IObjectWithSite);
788     SET_EXPECT(reportSuccess);
789     parse_script_a(parser, "Call CreateObject(\"Wine.Test\").reportSuccess()");
790     CHECK_CALLED(Host_QS_SecMgr);
791     CHECK_CALLED(ProcessUrlAction);
792     CHECK_CALLED(CreateInstance);
793     CHECK_CALLED(QueryCustomPolicy);
794     CHECK_CALLED(QI_IObjectWithSite);
795     CHECK_CALLED(reportSuccess);
796 
797     IActiveScriptParse_Release(parser);
798 
799     parser = create_script(TRUE);
800 
801     hres = parse_script_ae(parser, "Call CreateObject(\"Wine.TestABC\")");
802     ok(hres == VB_E_CANNOT_CREATE_OBJ, "hres = %08x\n", hres);
803 
804     IActiveScriptParse_Release(parser);
805 
806     parser = create_script(TRUE);
807     QS_SecMgr_hres = E_NOINTERFACE;
808 
809     SET_EXPECT(Host_QS_SecMgr);
810     hres = parse_script_ae(parser, "Call CreateObject(\"Wine.Test\")");
811     ok(hres == VB_E_CANNOT_CREATE_OBJ, "hres = %08x\n", hres);
812     CHECK_CALLED(Host_QS_SecMgr);
813 
814     IActiveScriptParse_Release(parser);
815 
816     parser = create_script(TRUE);
817     ProcessUrlAction_hres = E_FAIL;
818 
819     SET_EXPECT(Host_QS_SecMgr);
820     SET_EXPECT(ProcessUrlAction);
821     hres = parse_script_ae(parser, "Call CreateObject(\"Wine.Test\")");
822     ok(hres == VB_E_CANNOT_CREATE_OBJ, "hres = %08x\n", hres);
823     CHECK_CALLED(Host_QS_SecMgr);
824     CHECK_CALLED(ProcessUrlAction);
825 
826     IActiveScriptParse_Release(parser);
827 
828     parser = create_script(TRUE);
829     ProcessUrlAction_policy = URLPOLICY_DISALLOW;
830 
831     SET_EXPECT(Host_QS_SecMgr);
832     SET_EXPECT(ProcessUrlAction);
833     hres = parse_script_ae(parser, "Call CreateObject(\"Wine.Test\")");
834     ok(hres == VB_E_CANNOT_CREATE_OBJ, "hres = %08x\n", hres);
835     CHECK_CALLED(Host_QS_SecMgr);
836     CHECK_CALLED(ProcessUrlAction);
837 
838     IActiveScriptParse_Release(parser);
839 
840     parser = create_script(TRUE);
841     CreateInstance_hres = E_FAIL;
842 
843     SET_EXPECT(Host_QS_SecMgr);
844     SET_EXPECT(ProcessUrlAction);
845     SET_EXPECT(CreateInstance);
846     hres = parse_script_ae(parser, "Call CreateObject(\"Wine.Test\")");
847     ok(hres == VB_E_CANNOT_CREATE_OBJ, "hres = %08x\n", hres);
848     CHECK_CALLED(Host_QS_SecMgr);
849     CHECK_CALLED(ProcessUrlAction);
850     CHECK_CALLED(CreateInstance);
851 
852     IActiveScriptParse_Release(parser);
853 
854     parser = create_script(TRUE);
855     QueryCustomPolicy_hres = E_FAIL;
856 
857     SET_EXPECT(Host_QS_SecMgr);
858     SET_EXPECT(ProcessUrlAction);
859     SET_EXPECT(CreateInstance);
860     SET_EXPECT(QueryCustomPolicy);
861     hres = parse_script_ae(parser, "Call CreateObject(\"Wine.Test\")");
862     ok(hres == VB_E_CANNOT_CREATE_OBJ, "hres = %08x\n", hres);
863     CHECK_CALLED(Host_QS_SecMgr);
864     CHECK_CALLED(ProcessUrlAction);
865     CHECK_CALLED(CreateInstance);
866     CHECK_CALLED(QueryCustomPolicy);
867 
868     IActiveScriptParse_Release(parser);
869 
870     parser = create_script(TRUE);
871     QueryCustomPolicy_psize = 6;
872 
873     SET_EXPECT(Host_QS_SecMgr);
874     SET_EXPECT(ProcessUrlAction);
875     SET_EXPECT(CreateInstance);
876     SET_EXPECT(QueryCustomPolicy);
877     SET_EXPECT(QI_IObjectWithSite);
878     SET_EXPECT(reportSuccess);
879     parse_script_a(parser, "Call CreateObject(\"Wine.Test\").reportSuccess()");
880     CHECK_CALLED(Host_QS_SecMgr);
881     CHECK_CALLED(ProcessUrlAction);
882     CHECK_CALLED(CreateInstance);
883     CHECK_CALLED(QueryCustomPolicy);
884     CHECK_CALLED(QI_IObjectWithSite);
885     CHECK_CALLED(reportSuccess);
886 
887     IActiveScriptParse_Release(parser);
888 
889     parser = create_script(TRUE);
890     QueryCustomPolicy_policy = URLPOLICY_DISALLOW;
891 
892     SET_EXPECT(Host_QS_SecMgr);
893     SET_EXPECT(ProcessUrlAction);
894     SET_EXPECT(CreateInstance);
895     SET_EXPECT(QueryCustomPolicy);
896     hres = parse_script_ae(parser, "Call CreateObject(\"Wine.Test\")");
897     ok(hres == VB_E_CANNOT_CREATE_OBJ, "hres = %08x\n", hres);
898     CHECK_CALLED(Host_QS_SecMgr);
899     CHECK_CALLED(ProcessUrlAction);
900     CHECK_CALLED(CreateInstance);
901     CHECK_CALLED(QueryCustomPolicy);
902 
903     QueryCustomPolicy_psize = 6;
904 
905     SET_EXPECT(ProcessUrlAction);
906     SET_EXPECT(CreateInstance);
907     SET_EXPECT(QueryCustomPolicy);
908     hres = parse_script_ae(parser, "Call CreateObject(\"Wine.Test\")");
909     ok(hres == VB_E_CANNOT_CREATE_OBJ, "hres = %08x\n", hres);
910     CHECK_CALLED(ProcessUrlAction);
911     CHECK_CALLED(CreateInstance);
912     CHECK_CALLED(QueryCustomPolicy);
913 
914     QueryCustomPolicy_policy = URLPOLICY_ALLOW;
915     QueryCustomPolicy_psize = 3;
916 
917     SET_EXPECT(ProcessUrlAction);
918     SET_EXPECT(CreateInstance);
919     SET_EXPECT(QueryCustomPolicy);
920     hres = parse_script_ae(parser, "Call CreateObject(\"Wine.Test\")");
921     ok(hres == VB_E_CANNOT_CREATE_OBJ, "hres = %08x\n", hres);
922     CHECK_CALLED(ProcessUrlAction);
923     CHECK_CALLED(CreateInstance);
924     CHECK_CALLED(QueryCustomPolicy);
925 
926     IActiveScriptParse_Release(parser);
927 
928     parser = create_script(FALSE);
929 
930     SET_EXPECT(CreateInstance);
931     SET_EXPECT(QI_IObjectWithSite);
932     SET_EXPECT(reportSuccess);
933     parse_script_a(parser, "Call CreateObject(\"Wine.Test\").reportSuccess()");
934     CHECK_CALLED(CreateInstance);
935     CHECK_CALLED(QI_IObjectWithSite);
936     CHECK_CALLED(reportSuccess);
937 
938     IActiveScriptParse_Release(parser);
939 
940     parser = create_script(TRUE);
941     object_with_site = &ObjectWithSite;
942 
943     SET_EXPECT(Host_QS_SecMgr);
944     SET_EXPECT(ProcessUrlAction);
945     SET_EXPECT(CreateInstance);
946     SET_EXPECT(QueryCustomPolicy);
947     SET_EXPECT(QI_IObjectWithSite);
948     SET_EXPECT(SetSite);
949     SET_EXPECT(reportSuccess);
950     parse_script_a(parser, "Call CreateObject(\"Wine.Test\").reportSuccess()");
951     CHECK_CALLED(Host_QS_SecMgr);
952     CHECK_CALLED(ProcessUrlAction);
953     CHECK_CALLED(CreateInstance);
954     CHECK_CALLED(QueryCustomPolicy);
955     CHECK_CALLED(QI_IObjectWithSite);
956     CHECK_CALLED(SetSite);
957     CHECK_CALLED(reportSuccess);
958 
959     SetSite_hres = E_FAIL;
960     SET_EXPECT(ProcessUrlAction);
961     SET_EXPECT(CreateInstance);
962     SET_EXPECT(QueryCustomPolicy);
963     SET_EXPECT(QI_IObjectWithSite);
964     SET_EXPECT(SetSite);
965     hres = parse_script_ae(parser, "Call CreateObject(\"Wine.Test\")");
966     ok(hres == VB_E_CANNOT_CREATE_OBJ, "hres = %08x\n", hres);
967     CHECK_CALLED(ProcessUrlAction);
968     CHECK_CALLED(CreateInstance);
969     CHECK_CALLED(QueryCustomPolicy);
970     CHECK_CALLED(QI_IObjectWithSite);
971     CHECK_CALLED(SetSite);
972 
973     IActiveScriptParse_Release(parser);
974 }
975 
976 static void test_GetObject(void)
977 {
978     IActiveScriptParse *parser;
979     HRESULT hres;
980 
981     /* Never allowed with security manager */
982     parser = create_script(TRUE);
983     hres = parse_script_ae(parser, "Call GetObject(\"clsid:" TESTOBJINST_CLSID "\").reportSuccess()");
984     ok(hres == VB_E_CANNOT_CREATE_OBJ, "hres = %08x\n", hres);
985     IActiveScriptParse_Release(parser);
986 
987     parser = create_script(FALSE);
988 
989     SET_EXPECT(QI_IObjectWithSite);
990     SET_EXPECT(SetSite);
991     SET_EXPECT(reportSuccess);
992     hres = parse_script_ae(parser, "Call GetObject(\"clsid:" TESTOBJINST_CLSID "\").reportSuccess()");
993     if(broken(hres == VB_E_ACCESS_DENIED)) /* 64-bit win8 fails on the first try */
994         hres = parse_script_ae(parser, "Call GetObject(\"clsid:" TESTOBJINST_CLSID "\").reportSuccess()");
995     if(hres == HRESULT_FROM_WIN32(ERROR_MOD_NOT_FOUND)) { /* Workaround for broken win2k */
996         win_skip("got unexpected error %08x\n", hres);
997         CLEAR_CALLED(QI_IObjectWithSite);
998         CLEAR_CALLED(SetSite);
999         CLEAR_CALLED(reportSuccess);
1000         IActiveScriptParse_Release(parser);
1001         return;
1002     }
1003     ok(hres == S_OK, "hres = %08x\n", hres);
1004     CHECK_CALLED(QI_IObjectWithSite);
1005     CHECK_CALLED(SetSite);
1006     CHECK_CALLED(reportSuccess);
1007 
1008     SetSite_hres = E_FAIL;
1009     SET_EXPECT(QI_IObjectWithSite);
1010     SET_EXPECT(SetSite);
1011     hres = parse_script_ae(parser, "Call GetObject(\"clsid:" TESTOBJINST_CLSID "\").reportSuccess()");
1012     ok(hres == E_FAIL, "hres = %08x\n", hres);
1013     CHECK_CALLED(QI_IObjectWithSite);
1014     CHECK_CALLED(SetSite);
1015 
1016     QI_IObjectWithSite_hres = E_NOINTERFACE;
1017     SET_EXPECT(QI_IObjectWithSite);
1018     SET_EXPECT(reportSuccess);
1019     parse_script_a(parser, "Call GetObject(\"clsid:" TESTOBJINST_CLSID "\").reportSuccess()");
1020     CHECK_CALLED(QI_IObjectWithSite);
1021     CHECK_CALLED(reportSuccess);
1022 
1023     IActiveScriptParse_Release(parser);
1024 
1025     /* Invalid moniker */
1026     parser = create_script(FALSE);
1027     hres = parse_script_ae(parser, "Call GetObject(\"nonexistent:test\").reportSuccess()");
1028     ok(hres == MK_E_SYNTAX, "hres = %08x\n", hres);
1029     IActiveScriptParse_Release(parser);
1030 }
1031 
1032 static BOOL init_key(const char *key_name, const char *def_value, BOOL init)
1033 {
1034     HKEY hkey;
1035     DWORD res;
1036 
1037     if(!init) {
1038         RegDeleteKeyA(HKEY_CLASSES_ROOT, key_name);
1039         return TRUE;
1040     }
1041 
1042     res = RegCreateKeyA(HKEY_CLASSES_ROOT, key_name, &hkey);
1043     if(res != ERROR_SUCCESS)
1044         return FALSE;
1045 
1046     if(def_value)
1047         res = RegSetValueA(hkey, NULL, REG_SZ, def_value, strlen(def_value));
1048 
1049     RegCloseKey(hkey);
1050 
1051     return res == ERROR_SUCCESS;
1052 }
1053 
1054 static BOOL init_registry(BOOL init)
1055 {
1056     return init_key("Wine.Test\\CLSID", TESTOBJ_CLSID, init);
1057 }
1058 
1059 static BOOL register_activex(void)
1060 {
1061     DWORD regid;
1062     HRESULT hres;
1063 
1064     if(!init_registry(TRUE)) {
1065         init_registry(FALSE);
1066         return FALSE;
1067     }
1068 
1069     hres = CoRegisterClassObject(&CLSID_TestObj, (IUnknown *)&activex_cf,
1070                                  CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &regid);
1071     ok(hres == S_OK, "Could not register script engine: %08x\n", hres);
1072 
1073     hres = CoRegisterClassObject(&CLSID_TestObjInst, (IUnknown *)&testObj,
1074                                  CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &regid);
1075     ok(hres == S_OK, "Could not register script engine: %08x\n", hres);
1076 
1077     return TRUE;
1078 }
1079 
1080 static BOOL check_vbscript(void)
1081 {
1082     IActiveScriptParseProcedure2 *vbscript;
1083     HRESULT hres;
1084 
1085     hres = CoCreateInstance(&CLSID_VBScript, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1086             &IID_IActiveScriptParseProcedure2, (void**)&vbscript);
1087     if(SUCCEEDED(hres))
1088         IActiveScriptParseProcedure2_Release(vbscript);
1089 
1090     return hres == S_OK;
1091 }
1092 
1093 
1094 START_TEST(createobj)
1095 {
1096     CoInitialize(NULL);
1097 
1098     if(check_vbscript()) {
1099         if(register_activex()) {
1100             test_CreateObject();
1101             test_GetObject();
1102             init_registry(FALSE);
1103         }else {
1104             skip("Could not register ActiveX object.\n");
1105         }
1106     }else {
1107         win_skip("Broken engine, probably too old\n");
1108     }
1109 
1110     CoUninitialize();
1111 }
1112