1c2c66affSColin Finck /*
2c2c66affSColin Finck * Copyright 2011 Jacek Caban for CodeWeavers
3c2c66affSColin Finck *
4c2c66affSColin Finck * This library is free software; you can redistribute it and/or
5c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
6c2c66affSColin Finck * License as published by the Free Software Foundation; either
7c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
8c2c66affSColin Finck *
9c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
10c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
11c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12c2c66affSColin Finck * Lesser General Public License for more details.
13c2c66affSColin Finck *
14c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
15c2c66affSColin Finck * License along with this library; if not, write to the Free Software
16c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17c2c66affSColin Finck */
18c2c66affSColin Finck
19c2c66affSColin Finck #include <stdio.h>
20c2c66affSColin Finck
21c2c66affSColin Finck #define COBJMACROS
22c2c66affSColin Finck #define CONST_VTABLE
23c2c66affSColin Finck
243c774903SAmine Khaldi #define PSAPI_VERSION 1
253c774903SAmine Khaldi #include <initguid.h>
263c774903SAmine Khaldi #include <windows.h>
27c2c66affSColin Finck #include <psapi.h>
283c774903SAmine Khaldi #include <oaidl.h>
29c2c66affSColin Finck
303c774903SAmine Khaldi #include "wine/test.h"
31c2c66affSColin Finck
32c2c66affSColin Finck #define DEFINE_EXPECT(func) \
33c2c66affSColin Finck static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
34c2c66affSColin Finck
35c2c66affSColin Finck #define SET_EXPECT(func) \
36c2c66affSColin Finck expect_ ## func = TRUE
37c2c66affSColin Finck
38c2c66affSColin Finck #define CLEAR_CALLED(func) \
39c2c66affSColin Finck expect_ ## func = called_ ## func = FALSE
40c2c66affSColin Finck
41c2c66affSColin Finck #define CHECK_EXPECT2(func) \
42c2c66affSColin Finck do { \
43c2c66affSColin Finck ok(expect_ ##func, "unexpected call " #func "\n"); \
44c2c66affSColin Finck called_ ## func = TRUE; \
45c2c66affSColin Finck }while(0)
46c2c66affSColin Finck
47c2c66affSColin Finck #define CHECK_EXPECT(func) \
48c2c66affSColin Finck do { \
49c2c66affSColin Finck CHECK_EXPECT2(func); \
50c2c66affSColin Finck expect_ ## func = FALSE; \
51c2c66affSColin Finck }while(0)
52c2c66affSColin Finck
53c2c66affSColin Finck #define CHECK_CALLED(func) \
54c2c66affSColin Finck do { \
55c2c66affSColin Finck ok(called_ ## func, "expected " #func "\n"); \
56c2c66affSColin Finck expect_ ## func = called_ ## func = FALSE; \
57c2c66affSColin Finck }while(0)
58c2c66affSColin Finck
59c2c66affSColin Finck DEFINE_EXPECT(reportSuccess);
60c2c66affSColin Finck
61c2c66affSColin Finck #define DISPID_TESTOBJ_OK 10000
62c2c66affSColin Finck #define DISPID_TESTOBJ_TRACE 10001
63c2c66affSColin Finck #define DISPID_TESTOBJ_REPORTSUCCESS 10002
64c2c66affSColin Finck #define DISPID_TESTOBJ_WSCRIPTFULLNAME 10003
65c2c66affSColin Finck #define DISPID_TESTOBJ_WSCRIPTPATH 10004
66c2c66affSColin Finck #define DISPID_TESTOBJ_WSCRIPTSCRIPTNAME 10005
67c2c66affSColin Finck #define DISPID_TESTOBJ_WSCRIPTSCRIPTFULLNAME 10006
68c2c66affSColin Finck
69c2c66affSColin Finck #define TESTOBJ_CLSID "{178fc166-f585-4e24-9c13-4bb7faf80646}"
70c2c66affSColin Finck
71c2c66affSColin Finck static const GUID CLSID_TestObj =
72c2c66affSColin Finck {0x178fc166,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x06,0x46}};
73c2c66affSColin Finck
74c2c66affSColin Finck static const char *script_name;
75c2c66affSColin Finck static HANDLE wscript_process;
76c2c66affSColin Finck
strcmp_wa(LPCWSTR strw,const char * stra)77c2c66affSColin Finck static int strcmp_wa(LPCWSTR strw, const char *stra)
78c2c66affSColin Finck {
79c2c66affSColin Finck WCHAR buf[512];
80*f2df3bf0SAmine Khaldi MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, ARRAY_SIZE(buf));
81c2c66affSColin Finck return lstrcmpW(strw, buf);
82c2c66affSColin Finck }
83c2c66affSColin Finck
mystrrchr(const WCHAR * str,WCHAR ch)84c2c66affSColin Finck static const WCHAR* mystrrchr(const WCHAR *str, WCHAR ch)
85c2c66affSColin Finck {
86c2c66affSColin Finck const WCHAR *pos = NULL, *current = str;
87c2c66affSColin Finck while(*current != 0) {
88c2c66affSColin Finck if(*current == ch)
89c2c66affSColin Finck pos = current;
90c2c66affSColin Finck ++current;
91c2c66affSColin Finck }
92c2c66affSColin Finck return pos;
93c2c66affSColin Finck }
94c2c66affSColin Finck
a2bstr(const char * str)95c2c66affSColin Finck static BSTR a2bstr(const char *str)
96c2c66affSColin Finck {
97c2c66affSColin Finck BSTR ret;
98c2c66affSColin Finck int len;
99c2c66affSColin Finck
100c2c66affSColin Finck len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
101c2c66affSColin Finck ret = SysAllocStringLen(NULL, len-1);
102c2c66affSColin Finck MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
103c2c66affSColin Finck
104c2c66affSColin Finck return ret;
105c2c66affSColin Finck }
106c2c66affSColin Finck
Dispatch_QueryInterface(IDispatch * iface,REFIID riid,void ** ppv)107c2c66affSColin Finck static HRESULT WINAPI Dispatch_QueryInterface(IDispatch *iface, REFIID riid, void **ppv)
108c2c66affSColin Finck {
109c2c66affSColin Finck if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDispatch)) {
110c2c66affSColin Finck *ppv = iface;
111c2c66affSColin Finck return S_OK;
112c2c66affSColin Finck }
113c2c66affSColin Finck
114c2c66affSColin Finck *ppv = NULL;
115c2c66affSColin Finck return E_NOINTERFACE;
116c2c66affSColin Finck }
117c2c66affSColin Finck
Dispatch_AddRef(IDispatch * iface)118c2c66affSColin Finck static ULONG WINAPI Dispatch_AddRef(IDispatch *iface)
119c2c66affSColin Finck {
120c2c66affSColin Finck return 2;
121c2c66affSColin Finck }
122c2c66affSColin Finck
Dispatch_Release(IDispatch * iface)123c2c66affSColin Finck static ULONG WINAPI Dispatch_Release(IDispatch *iface)
124c2c66affSColin Finck {
125c2c66affSColin Finck return 1;
126c2c66affSColin Finck }
127c2c66affSColin Finck
Dispatch_GetTypeInfoCount(IDispatch * iface,UINT * pctinfo)128c2c66affSColin Finck static HRESULT WINAPI Dispatch_GetTypeInfoCount(IDispatch *iface, UINT *pctinfo)
129c2c66affSColin Finck {
130c2c66affSColin Finck ok(0, "unexpected call\n");
131c2c66affSColin Finck return E_NOTIMPL;
132c2c66affSColin Finck }
133c2c66affSColin Finck
Dispatch_GetTypeInfo(IDispatch * iface,UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)134c2c66affSColin Finck static HRESULT WINAPI Dispatch_GetTypeInfo(IDispatch *iface, UINT iTInfo,
135c2c66affSColin Finck LCID lcid, ITypeInfo **ppTInfo)
136c2c66affSColin Finck {
137c2c66affSColin Finck ok(0, "unexpected call\n");
138c2c66affSColin Finck return E_NOTIMPL;
139c2c66affSColin Finck }
140c2c66affSColin Finck
Dispatch_GetIDsOfNames(IDispatch * iface,REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)141c2c66affSColin Finck static HRESULT WINAPI Dispatch_GetIDsOfNames(IDispatch *iface, REFIID riid,
142c2c66affSColin Finck LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
143c2c66affSColin Finck {
144c2c66affSColin Finck unsigned i;
145c2c66affSColin Finck
146c2c66affSColin Finck for(i=0; i<cNames; i++) {
147c2c66affSColin Finck if(!strcmp_wa(rgszNames[i], "ok")) {
148c2c66affSColin Finck rgDispId[i] = DISPID_TESTOBJ_OK;
149c2c66affSColin Finck }else if(!strcmp_wa(rgszNames[i], "trace")) {
150c2c66affSColin Finck rgDispId[i] = DISPID_TESTOBJ_TRACE;
151c2c66affSColin Finck }else if(!strcmp_wa(rgszNames[i], "reportSuccess")) {
152c2c66affSColin Finck rgDispId[i] = DISPID_TESTOBJ_REPORTSUCCESS;
153c2c66affSColin Finck }else if(!strcmp_wa(rgszNames[i], "wscriptFullName")) {
154c2c66affSColin Finck rgDispId[i] = DISPID_TESTOBJ_WSCRIPTFULLNAME;
155c2c66affSColin Finck }else if(!strcmp_wa(rgszNames[i], "wscriptPath")) {
156c2c66affSColin Finck rgDispId[i] = DISPID_TESTOBJ_WSCRIPTPATH;
157c2c66affSColin Finck }else if(!strcmp_wa(rgszNames[i], "wscriptScriptName")) {
158c2c66affSColin Finck rgDispId[i] = DISPID_TESTOBJ_WSCRIPTSCRIPTNAME;
159c2c66affSColin Finck }else if(!strcmp_wa(rgszNames[i], "wscriptScriptFullName")) {
160c2c66affSColin Finck rgDispId[i] = DISPID_TESTOBJ_WSCRIPTSCRIPTFULLNAME;
161c2c66affSColin Finck }else {
162c2c66affSColin Finck ok(0, "unexpected name %s\n", wine_dbgstr_w(rgszNames[i]));
163c2c66affSColin Finck return DISP_E_UNKNOWNNAME;
164c2c66affSColin Finck }
165c2c66affSColin Finck }
166c2c66affSColin Finck
167c2c66affSColin Finck return S_OK;
168c2c66affSColin Finck }
169c2c66affSColin Finck
Dispatch_Invoke(IDispatch * iface,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pdp,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)170c2c66affSColin Finck static HRESULT WINAPI Dispatch_Invoke(IDispatch *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
171c2c66affSColin Finck WORD wFlags, DISPPARAMS *pdp, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
172c2c66affSColin Finck {
173c2c66affSColin Finck switch(dispIdMember) {
174c2c66affSColin Finck case DISPID_TESTOBJ_OK: {
175c2c66affSColin Finck VARIANT *expr, *msg;
176c2c66affSColin Finck
177c2c66affSColin Finck ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
178c2c66affSColin Finck ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
179c2c66affSColin Finck ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
180c2c66affSColin Finck
181c2c66affSColin Finck expr = pdp->rgvarg+1;
182c2c66affSColin Finck if(V_VT(expr) == (VT_VARIANT|VT_BYREF))
183c2c66affSColin Finck expr = V_VARIANTREF(expr);
184c2c66affSColin Finck
185c2c66affSColin Finck msg = pdp->rgvarg;
186c2c66affSColin Finck if(V_VT(msg) == (VT_VARIANT|VT_BYREF))
187c2c66affSColin Finck msg = V_VARIANTREF(msg);
188c2c66affSColin Finck
189c2c66affSColin Finck ok(V_VT(msg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(msg));
190c2c66affSColin Finck ok(V_VT(expr) == VT_BOOL, "V_VT(psp->rgvargs+1) = %d\n", V_VT(expr));
191c2c66affSColin Finck ok(V_BOOL(expr), "%s: %s\n", script_name, wine_dbgstr_w(V_BSTR(msg)));
192c2c66affSColin Finck if(pVarResult)
193c2c66affSColin Finck V_VT(pVarResult) = VT_EMPTY;
194c2c66affSColin Finck break;
195c2c66affSColin Finck }
196c2c66affSColin Finck case DISPID_TESTOBJ_TRACE:
197c2c66affSColin Finck ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
198c2c66affSColin Finck ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
199c2c66affSColin Finck ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
200c2c66affSColin Finck ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
201c2c66affSColin Finck trace("%s: %s\n", script_name, wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
202c2c66affSColin Finck if(pVarResult)
203c2c66affSColin Finck V_VT(pVarResult) = VT_EMPTY;
204c2c66affSColin Finck break;
205c2c66affSColin Finck case DISPID_TESTOBJ_REPORTSUCCESS:
206c2c66affSColin Finck CHECK_EXPECT(reportSuccess);
207c2c66affSColin Finck
208c2c66affSColin Finck ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
209c2c66affSColin Finck ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
210c2c66affSColin Finck ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
211c2c66affSColin Finck if(pVarResult)
212c2c66affSColin Finck V_VT(pVarResult) = VT_EMPTY;
213c2c66affSColin Finck break;
214c2c66affSColin Finck case DISPID_TESTOBJ_WSCRIPTFULLNAME:
215c2c66affSColin Finck {
216c2c66affSColin Finck WCHAR fullName[MAX_PATH];
217c2c66affSColin Finck DWORD res;
218c2c66affSColin Finck
219c2c66affSColin Finck ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
220c2c66affSColin Finck ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
221c2c66affSColin Finck ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
222c2c66affSColin Finck V_VT(pVarResult) = VT_BSTR;
223*f2df3bf0SAmine Khaldi res = GetModuleFileNameExW(wscript_process, NULL, fullName, ARRAY_SIZE(fullName));
224c2c66affSColin Finck if(res == 0)
225c2c66affSColin Finck return E_FAIL;
226c2c66affSColin Finck if(!(V_BSTR(pVarResult) = SysAllocString(fullName)))
227c2c66affSColin Finck return E_OUTOFMEMORY;
228c2c66affSColin Finck break;
229c2c66affSColin Finck }
230c2c66affSColin Finck case DISPID_TESTOBJ_WSCRIPTPATH:
231c2c66affSColin Finck {
232c2c66affSColin Finck WCHAR fullPath[MAX_PATH];
233c2c66affSColin Finck DWORD res;
234c2c66affSColin Finck const WCHAR *pos;
235c2c66affSColin Finck
236c2c66affSColin Finck ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
237c2c66affSColin Finck ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
238c2c66affSColin Finck ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
239c2c66affSColin Finck V_VT(pVarResult) = VT_BSTR;
240*f2df3bf0SAmine Khaldi res = GetModuleFileNameExW(wscript_process, NULL, fullPath, ARRAY_SIZE(fullPath));
241c2c66affSColin Finck if(res == 0)
242c2c66affSColin Finck return E_FAIL;
243c2c66affSColin Finck pos = mystrrchr(fullPath, '\\');
244c2c66affSColin Finck if(!(V_BSTR(pVarResult) = SysAllocStringLen(fullPath, pos-fullPath)))
245c2c66affSColin Finck return E_OUTOFMEMORY;
246c2c66affSColin Finck break;
247c2c66affSColin Finck }
248c2c66affSColin Finck case DISPID_TESTOBJ_WSCRIPTSCRIPTNAME:
249c2c66affSColin Finck {
250c2c66affSColin Finck char fullPath[MAX_PATH];
251c2c66affSColin Finck char *pos;
252c2c66affSColin Finck long res;
253c2c66affSColin Finck
254c2c66affSColin Finck ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
255c2c66affSColin Finck ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
256c2c66affSColin Finck ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
257c2c66affSColin Finck V_VT(pVarResult) = VT_BSTR;
258c2c66affSColin Finck res = GetFullPathNameA(script_name, sizeof(fullPath), fullPath, &pos);
259c2c66affSColin Finck if(!res || res > sizeof(fullPath))
260c2c66affSColin Finck return E_FAIL;
261c2c66affSColin Finck if(!(V_BSTR(pVarResult) = a2bstr(pos)))
262c2c66affSColin Finck return E_OUTOFMEMORY;
263c2c66affSColin Finck break;
264c2c66affSColin Finck }
265c2c66affSColin Finck case DISPID_TESTOBJ_WSCRIPTSCRIPTFULLNAME:
266c2c66affSColin Finck {
267c2c66affSColin Finck char fullPath[MAX_PATH];
268c2c66affSColin Finck long res;
269c2c66affSColin Finck
270c2c66affSColin Finck ok(wFlags == INVOKE_PROPERTYGET, "wFlags = %x\n", wFlags);
271c2c66affSColin Finck ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
272c2c66affSColin Finck ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
273c2c66affSColin Finck V_VT(pVarResult) = VT_BSTR;
274c2c66affSColin Finck res = GetFullPathNameA(script_name, sizeof(fullPath), fullPath, NULL);
275c2c66affSColin Finck if(!res || res > sizeof(fullPath))
276c2c66affSColin Finck return E_FAIL;
277c2c66affSColin Finck if(!(V_BSTR(pVarResult) = a2bstr(fullPath)))
278c2c66affSColin Finck return E_OUTOFMEMORY;
279c2c66affSColin Finck break;
280c2c66affSColin Finck }
281c2c66affSColin Finck default:
282c2c66affSColin Finck ok(0, "unexpected dispIdMember %d\n", dispIdMember);
283c2c66affSColin Finck return E_NOTIMPL;
284c2c66affSColin Finck }
285c2c66affSColin Finck
286c2c66affSColin Finck return S_OK;
287c2c66affSColin Finck }
288c2c66affSColin Finck
289c2c66affSColin Finck static IDispatchVtbl testobj_vtbl = {
290c2c66affSColin Finck Dispatch_QueryInterface,
291c2c66affSColin Finck Dispatch_AddRef,
292c2c66affSColin Finck Dispatch_Release,
293c2c66affSColin Finck Dispatch_GetTypeInfoCount,
294c2c66affSColin Finck Dispatch_GetTypeInfo,
295c2c66affSColin Finck Dispatch_GetIDsOfNames,
296c2c66affSColin Finck Dispatch_Invoke
297c2c66affSColin Finck };
298c2c66affSColin Finck
299c2c66affSColin Finck static IDispatch testobj = { &testobj_vtbl };
300c2c66affSColin Finck
ClassFactory_QueryInterface(IClassFactory * iface,REFIID riid,void ** ppv)301c2c66affSColin Finck static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
302c2c66affSColin Finck {
303c2c66affSColin Finck if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) {
304c2c66affSColin Finck *ppv = iface;
305c2c66affSColin Finck return S_OK;
306c2c66affSColin Finck }
307c2c66affSColin Finck
308c2c66affSColin Finck *ppv = NULL;
309c2c66affSColin Finck return E_NOINTERFACE;
310c2c66affSColin Finck }
311c2c66affSColin Finck
ClassFactory_AddRef(IClassFactory * iface)312c2c66affSColin Finck static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
313c2c66affSColin Finck {
314c2c66affSColin Finck return 2;
315c2c66affSColin Finck }
316c2c66affSColin Finck
ClassFactory_Release(IClassFactory * iface)317c2c66affSColin Finck static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
318c2c66affSColin Finck {
319c2c66affSColin Finck return 1;
320c2c66affSColin Finck }
321c2c66affSColin Finck
ClassFactory_CreateInstance(IClassFactory * iface,IUnknown * outer,REFIID riid,void ** ppv)322c2c66affSColin Finck static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
323c2c66affSColin Finck {
324c2c66affSColin Finck ok(!outer, "outer = %p\n", outer);
325c2c66affSColin Finck return IDispatch_QueryInterface(&testobj, riid, ppv);
326c2c66affSColin Finck }
327c2c66affSColin Finck
ClassFactory_LockServer(IClassFactory * iface,BOOL dolock)328c2c66affSColin Finck static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
329c2c66affSColin Finck {
330c2c66affSColin Finck return S_OK;
331c2c66affSColin Finck }
332c2c66affSColin Finck
333c2c66affSColin Finck static const IClassFactoryVtbl ClassFactoryVtbl = {
334c2c66affSColin Finck ClassFactory_QueryInterface,
335c2c66affSColin Finck ClassFactory_AddRef,
336c2c66affSColin Finck ClassFactory_Release,
337c2c66affSColin Finck ClassFactory_CreateInstance,
338c2c66affSColin Finck ClassFactory_LockServer
339c2c66affSColin Finck };
340c2c66affSColin Finck
341c2c66affSColin Finck static IClassFactory testobj_cf = { &ClassFactoryVtbl };
342c2c66affSColin Finck
run_script_file(const char * file_name,DWORD expected_exit_code)343c2c66affSColin Finck static void run_script_file(const char *file_name, DWORD expected_exit_code)
344c2c66affSColin Finck {
345c2c66affSColin Finck char command[MAX_PATH];
346c2c66affSColin Finck STARTUPINFOA si = {sizeof(si)};
347c2c66affSColin Finck PROCESS_INFORMATION pi;
348c2c66affSColin Finck DWORD exit_code;
349c2c66affSColin Finck BOOL bres;
350c2c66affSColin Finck
351c2c66affSColin Finck script_name = file_name;
352c2c66affSColin Finck sprintf(command, "wscript.exe %s arg1 2 ar3", file_name);
353c2c66affSColin Finck
354c2c66affSColin Finck SET_EXPECT(reportSuccess);
355c2c66affSColin Finck
356c2c66affSColin Finck bres = CreateProcessA(NULL, command, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
357c2c66affSColin Finck if(!bres) {
358c2c66affSColin Finck win_skip("script.exe is not available\n");
359c2c66affSColin Finck CLEAR_CALLED(reportSuccess);
360c2c66affSColin Finck return;
361c2c66affSColin Finck }
362c2c66affSColin Finck
363c2c66affSColin Finck wscript_process = pi.hProcess;
364c2c66affSColin Finck WaitForSingleObject(pi.hProcess, INFINITE);
365c2c66affSColin Finck
366c2c66affSColin Finck bres = GetExitCodeProcess(pi.hProcess, &exit_code);
367c2c66affSColin Finck ok(bres, "GetExitCodeProcess failed: %u\n", GetLastError());
368c2c66affSColin Finck ok(exit_code == expected_exit_code, "exit_code = %u, expected %u\n", exit_code, expected_exit_code);
369c2c66affSColin Finck
370c2c66affSColin Finck CloseHandle(pi.hThread);
371c2c66affSColin Finck CloseHandle(pi.hProcess);
372c2c66affSColin Finck
373c2c66affSColin Finck CHECK_CALLED(reportSuccess);
374c2c66affSColin Finck }
375c2c66affSColin Finck
run_script(const char * name,const char * script_data,size_t script_size,DWORD expected_exit_code)376c2c66affSColin Finck static void run_script(const char *name, const char *script_data, size_t script_size, DWORD expected_exit_code)
377c2c66affSColin Finck {
378c2c66affSColin Finck char file_name[MAX_PATH];
379c2c66affSColin Finck const char *ext;
380c2c66affSColin Finck HANDLE file;
381c2c66affSColin Finck DWORD size;
382c2c66affSColin Finck BOOL res;
383c2c66affSColin Finck
384c2c66affSColin Finck ext = strrchr(name, '.');
385c2c66affSColin Finck ok(ext != NULL, "no script extension\n");
386c2c66affSColin Finck if(!ext)
387c2c66affSColin Finck return;
388c2c66affSColin Finck
389c2c66affSColin Finck sprintf(file_name, "test%s", ext);
390c2c66affSColin Finck
391c2c66affSColin Finck file = CreateFileA(file_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
392c2c66affSColin Finck FILE_ATTRIBUTE_NORMAL, NULL);
393c2c66affSColin Finck ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError());
394c2c66affSColin Finck if(file == INVALID_HANDLE_VALUE)
395c2c66affSColin Finck return;
396c2c66affSColin Finck
397c2c66affSColin Finck res = WriteFile(file, script_data, script_size, &size, NULL);
398c2c66affSColin Finck CloseHandle(file);
399c2c66affSColin Finck ok(res, "Could not write to file: %u\n", GetLastError());
400c2c66affSColin Finck if(!res)
401c2c66affSColin Finck return;
402c2c66affSColin Finck
403c2c66affSColin Finck run_script_file(file_name, expected_exit_code);
404c2c66affSColin Finck
405c2c66affSColin Finck DeleteFileA(file_name);
406c2c66affSColin Finck }
407c2c66affSColin Finck
run_simple_script(const char * script,DWORD expected_exit_code)408c2c66affSColin Finck static void run_simple_script(const char *script, DWORD expected_exit_code)
409c2c66affSColin Finck {
410c2c66affSColin Finck run_script("simple.js", script, strlen(script), expected_exit_code);
411c2c66affSColin Finck }
412c2c66affSColin Finck
test_enum_proc(HMODULE module,LPCSTR type,LPSTR name,LONG_PTR param)413c2c66affSColin Finck static BOOL WINAPI test_enum_proc(HMODULE module, LPCSTR type, LPSTR name, LONG_PTR param)
414c2c66affSColin Finck {
415c2c66affSColin Finck const char *script_data;
416c2c66affSColin Finck DWORD script_size;
417c2c66affSColin Finck HRSRC src;
418c2c66affSColin Finck
419c2c66affSColin Finck trace("running %s test...\n", name);
420c2c66affSColin Finck
421c2c66affSColin Finck src = FindResourceA(NULL, name, type);
422c2c66affSColin Finck ok(src != NULL, "Could not find resource %s: %u\n", name, GetLastError());
423c2c66affSColin Finck if(!src)
424c2c66affSColin Finck return TRUE;
425c2c66affSColin Finck
426c2c66affSColin Finck script_data = LoadResource(NULL, src);
427c2c66affSColin Finck script_size = SizeofResource(NULL, src);
428c2c66affSColin Finck while(script_size && !script_data[script_size-1])
429c2c66affSColin Finck script_size--;
430c2c66affSColin Finck
431c2c66affSColin Finck run_script(name, script_data, script_size, 0);
432c2c66affSColin Finck return TRUE;
433c2c66affSColin Finck }
434c2c66affSColin Finck
init_key(const char * key_name,const char * def_value,BOOL init)435c2c66affSColin Finck static BOOL init_key(const char *key_name, const char *def_value, BOOL init)
436c2c66affSColin Finck {
437c2c66affSColin Finck HKEY hkey;
438c2c66affSColin Finck DWORD res;
439c2c66affSColin Finck
440c2c66affSColin Finck if(!init) {
441c2c66affSColin Finck RegDeleteKeyA(HKEY_CLASSES_ROOT, key_name);
442c2c66affSColin Finck return TRUE;
443c2c66affSColin Finck }
444c2c66affSColin Finck
445c2c66affSColin Finck res = RegCreateKeyA(HKEY_CLASSES_ROOT, key_name, &hkey);
446c2c66affSColin Finck if(res != ERROR_SUCCESS)
447c2c66affSColin Finck return FALSE;
448c2c66affSColin Finck
449c2c66affSColin Finck if(def_value)
450c2c66affSColin Finck res = RegSetValueA(hkey, NULL, REG_SZ, def_value, strlen(def_value));
451c2c66affSColin Finck
452c2c66affSColin Finck RegCloseKey(hkey);
453c2c66affSColin Finck return res == ERROR_SUCCESS;
454c2c66affSColin Finck }
455c2c66affSColin Finck
init_registry(BOOL init)456c2c66affSColin Finck static BOOL init_registry(BOOL init)
457c2c66affSColin Finck {
458c2c66affSColin Finck return init_key("Wine.Test\\CLSID", TESTOBJ_CLSID, init);
459c2c66affSColin Finck }
460c2c66affSColin Finck
register_activex(void)461c2c66affSColin Finck static BOOL register_activex(void)
462c2c66affSColin Finck {
463c2c66affSColin Finck DWORD regid;
464c2c66affSColin Finck HRESULT hres;
465c2c66affSColin Finck
466c2c66affSColin Finck if(!init_registry(TRUE)) {
467c2c66affSColin Finck init_registry(FALSE);
468c2c66affSColin Finck return FALSE;
469c2c66affSColin Finck }
470c2c66affSColin Finck
471c2c66affSColin Finck hres = CoRegisterClassObject(&CLSID_TestObj, (IUnknown *)&testobj_cf,
472c2c66affSColin Finck CLSCTX_SERVER, REGCLS_MULTIPLEUSE, ®id);
473c2c66affSColin Finck ok(hres == S_OK, "Could not register script engine: %08x\n", hres);
474c2c66affSColin Finck return TRUE;
475c2c66affSColin Finck }
476c2c66affSColin Finck
START_TEST(run)477c2c66affSColin Finck START_TEST(run)
478c2c66affSColin Finck {
479c2c66affSColin Finck char **argv;
480c2c66affSColin Finck int argc;
481c2c66affSColin Finck
482c2c66affSColin Finck CoInitializeEx(NULL, COINIT_MULTITHREADED);
483c2c66affSColin Finck
484c2c66affSColin Finck if(!register_activex()) {
485c2c66affSColin Finck skip("Could not register ActiveX object.\n");
486c2c66affSColin Finck CoUninitialize();
487c2c66affSColin Finck return;
488c2c66affSColin Finck }
489c2c66affSColin Finck
490c2c66affSColin Finck argc = winetest_get_mainargs(&argv);
491c2c66affSColin Finck if(argc > 2) {
492c2c66affSColin Finck run_script_file(argv[2], 0);
493c2c66affSColin Finck }else {
494c2c66affSColin Finck EnumResourceNamesA(NULL, "TESTSCRIPT", test_enum_proc, 0);
495c2c66affSColin Finck
496c2c66affSColin Finck run_simple_script("var winetest = new ActiveXObject('Wine.Test');\n"
497c2c66affSColin Finck "winetest.reportSuccess();\n"
498c2c66affSColin Finck "WScript.Quit(3);\n"
499c2c66affSColin Finck "winetest.ok(false, 'not quit?');\n", 3);
500c2c66affSColin Finck }
501c2c66affSColin Finck
502c2c66affSColin Finck init_registry(FALSE);
503c2c66affSColin Finck CoUninitialize();
504c2c66affSColin Finck }
505