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