2 * Copyright 2011 Jacek Caban for CodeWeavers
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.
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.
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
27 #include "wine/test.h"
29 DEFINE_GUID(GUID_NULL
,0,0,0,0,0,0,0,0,0,0,0);
31 #define EXPECT_HR(hr,hr_exp) \
32 ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
34 static void test_wshshell(void)
36 static const WCHAR notepadW
[] = {'n','o','t','e','p','a','d','.','e','x','e',0};
37 static const WCHAR desktopW
[] = {'D','e','s','k','t','o','p',0};
38 static const WCHAR lnk1W
[] = {'f','i','l','e','.','l','n','k',0};
39 static const WCHAR pathW
[] = {'%','P','A','T','H','%',0};
40 static const WCHAR sysW
[] = {'S','Y','S','T','E','M',0};
41 static const WCHAR path2W
[] = {'P','A','T','H',0};
46 IDispatch
*disp
, *shortcut
;
48 IFolderCollection
*folders
;
55 VARIANT arg
, res
, arg2
;
60 hr
= CoCreateInstance(&CLSID_WshShell
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
61 &IID_IDispatch
, (void**)&disp
);
62 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
64 hr
= IDispatch_QueryInterface(disp
, &IID_IWshShell3
, (void**)&shell
);
66 IDispatch_Release(disp
);
68 hr
= IDispatch_QueryInterface(disp
, &IID_IDispatchEx
, (void**)&dispex
);
69 EXPECT_HR(hr
, E_NOINTERFACE
);
71 hr
= IUnknown_QueryInterface(shell
, &IID_IWshShell3
, (void**)&sh3
);
74 hr
= IWshShell3_get_SpecialFolders(sh3
, &coll
);
77 hr
= IWshCollection_QueryInterface(coll
, &IID_IFolderCollection
, (void**)&folders
);
78 EXPECT_HR(hr
, E_NOINTERFACE
);
80 hr
= IWshCollection_QueryInterface(coll
, &IID_IDispatch
, (void**)&disp
);
83 hr
= IDispatch_GetTypeInfo(disp
, 0, 0, &ti
);
86 hr
= ITypeInfo_GetTypeAttr(ti
, &tattr
);
88 ok(IsEqualIID(&tattr
->guid
, &IID_IWshCollection
), "got wrong type guid\n");
89 ITypeInfo_ReleaseTypeAttr(ti
, tattr
);
91 /* try to call Item() with normal IDispatch procedure */
92 str
= SysAllocString(desktopW
);
96 dp
.rgdispidNamedArgs
= NULL
;
99 hr
= IDispatch_Invoke(disp
, DISPID_VALUE
, &IID_NULL
, 1033, DISPATCH_PROPERTYGET
, &dp
, &res
, &ei
, &err
);
100 EXPECT_HR(hr
, DISP_E_MEMBERNOTFOUND
);
102 /* try Item() directly, it returns directory path apparently */
103 V_VT(&res
) = VT_EMPTY
;
104 hr
= IWshCollection_Item(coll
, &arg
, &res
);
106 ok(V_VT(&res
) == VT_BSTR
, "got res type %d\n", V_VT(&res
));
110 /* CreateShortcut() */
111 str
= SysAllocString(lnk1W
);
112 hr
= IWshShell3_CreateShortcut(sh3
, str
, &shortcut
);
115 hr
= IDispatch_QueryInterface(shortcut
, &IID_IWshShortcut
, (void**)&shcut
);
118 hr
= IWshShortcut_get_Arguments(shcut
, NULL
);
119 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
121 hr
= IWshShortcut_get_IconLocation(shcut
, NULL
);
122 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
124 IWshShortcut_Release(shcut
);
125 IDispatch_Release(shortcut
);
127 /* ExpandEnvironmentStrings */
128 hr
= IWshShell3_ExpandEnvironmentStrings(sh3
, NULL
, NULL
);
129 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
131 str
= SysAllocString(pathW
);
132 hr
= IWshShell3_ExpandEnvironmentStrings(sh3
, str
, NULL
);
133 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
136 V_VT(&arg
) = VT_BSTR
;
137 V_BSTR(&arg
) = SysAllocString(sysW
);
138 hr
= IWshShell3_get_Environment(sh3
, &arg
, &env
);
139 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
142 hr
= IWshEnvironment_get_Item(env
, NULL
, NULL
);
143 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
146 hr
= IWshEnvironment_get_Item(env
, NULL
, &ret
);
147 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
148 ok(ret
&& !*ret
, "got %p\n", ret
);
151 /* invalid var name */
152 str
= SysAllocString(lnk1W
);
153 hr
= IWshEnvironment_get_Item(env
, str
, NULL
);
154 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
157 hr
= IWshEnvironment_get_Item(env
, str
, &ret
);
158 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
159 ok(ret
&& *ret
== 0, "got %s\n", wine_dbgstr_w(ret
));
164 str
= SysAllocString(path2W
);
165 hr
= IWshEnvironment_get_Item(env
, str
, &ret
);
166 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
167 ok(ret
&& *ret
!= 0, "got %s\n", wine_dbgstr_w(ret
));
171 IWshEnvironment_Release(env
);
175 V_VT(&arg2
) = VT_ERROR
;
176 V_ERROR(&arg2
) = DISP_E_PARAMNOTFOUND
;
178 str
= SysAllocString(notepadW
);
179 hr
= IWshShell3_Run(sh3
, str
, &arg
, &arg2
, NULL
);
180 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
183 hr
= IWshShell3_Run(sh3
, str
, NULL
, &arg2
, &retval
);
184 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
185 ok(retval
== 10, "got %u\n", retval
);
188 hr
= IWshShell3_Run(sh3
, str
, &arg
, NULL
, &retval
);
189 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
190 ok(retval
== 10, "got %u\n", retval
);
193 V_VT(&arg2
) = VT_ERROR
;
195 hr
= IWshShell3_Run(sh3
, str
, &arg
, &arg2
, &retval
);
196 ok(hr
== DISP_E_TYPEMISMATCH
, "got 0x%08x\n", hr
);
197 ok(retval
== 10, "got %u\n", retval
);
201 IWshCollection_Release(coll
);
202 IDispatch_Release(disp
);
203 IWshShell3_Release(sh3
);
204 IUnknown_Release(shell
);
207 /* delete key and all its subkeys */
208 static DWORD
delete_key(HKEY hkey
)
213 while (!(ret
= RegEnumKeyA(hkey
, 0, name
, sizeof(name
)))) {
215 if (!(ret
= RegOpenKeyExA(hkey
, name
, 0, KEY_ENUMERATE_SUB_KEYS
, &tmp
))) {
216 ret
= delete_key(tmp
);
221 if (ret
!= ERROR_NO_MORE_ITEMS
) return ret
;
222 RegDeleteKeyA(hkey
, "");
226 static void test_registry(void)
228 static const WCHAR keypathW
[] = {'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R','\\',
229 'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\','T','e','s','t','\\',0};
231 static const WCHAR regszW
[] = {'r','e','g','s','z',0};
232 static const WCHAR regdwordW
[] = {'r','e','g','d','w','o','r','d',0};
233 static const WCHAR regbinaryW
[] = {'r','e','g','b','i','n','a','r','y',0};
234 static const WCHAR regmultiszW
[] = {'r','e','g','m','u','l','t','i','s','z',0};
236 static const WCHAR regsz1W
[] = {'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R','\\',
237 'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\','T','e','s','t','\\','r','e','g','s','z','1',0};
238 static const WCHAR foobarW
[] = {'f','o','o','b','a','r',0};
239 static const WCHAR fooW
[] = {'f','o','o',0};
240 static const WCHAR brokenW
[] = {'H','K','E','Y','_','b','r','o','k','e','n','_','k','e','y',0};
241 static const WCHAR broken2W
[] = {'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R','a',0};
242 WCHAR pathW
[MAX_PATH
];
254 hr
= CoCreateInstance(&CLSID_WshShell
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
255 &IID_IWshShell3
, (void**)&sh3
);
256 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
259 V_VT(&value
) = VT_I2
;
260 hr
= IWshShell3_RegRead(sh3
, NULL
, &value
);
261 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
262 ok(V_VT(&value
) == VT_I2
, "got %d\n", V_VT(&value
));
264 name
= SysAllocString(brokenW
);
265 hr
= IWshShell3_RegRead(sh3
, name
, NULL
);
266 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
267 V_VT(&value
) = VT_I2
;
268 hr
= IWshShell3_RegRead(sh3
, name
, &value
);
269 ok(hr
== HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND
), "got 0x%08x\n", hr
);
270 ok(V_VT(&value
) == VT_I2
, "got %d\n", V_VT(&value
));
273 name
= SysAllocString(broken2W
);
274 V_VT(&value
) = VT_I2
;
275 hr
= IWshShell3_RegRead(sh3
, name
, &value
);
276 ok(hr
== HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND
), "got 0x%08x\n", hr
);
277 ok(V_VT(&value
) == VT_I2
, "got %d\n", V_VT(&value
));
280 ret
= RegCreateKeyA(HKEY_CURRENT_USER
, "Software\\Wine\\Test", &root
);
281 ok(ret
== 0, "got %d\n", ret
);
283 ret
= RegSetValueExA(root
, "regsz", 0, REG_SZ
, (const BYTE
*)"foobar", 7);
284 ok(ret
== 0, "got %d\n", ret
);
286 ret
= RegSetValueExA(root
, "regmultisz", 0, REG_MULTI_SZ
, (const BYTE
*)"foo\0bar\0", 9);
287 ok(ret
== 0, "got %d\n", ret
);
290 ret
= RegSetValueExA(root
, "regdword", 0, REG_DWORD
, (const BYTE
*)&dwvalue
, sizeof(dwvalue
));
291 ok(ret
== 0, "got %d\n", ret
);
294 ret
= RegSetValueExA(root
, "regbinary", 0, REG_BINARY
, (const BYTE
*)&dwvalue
, sizeof(dwvalue
));
295 ok(ret
== 0, "got %d\n", ret
);
298 lstrcpyW(pathW
, keypathW
);
299 lstrcatW(pathW
, regszW
);
300 name
= SysAllocString(pathW
);
302 hr
= IWshShell3_RegRead(sh3
, name
, &value
);
303 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
304 ok(V_VT(&value
) == VT_BSTR
, "got %d\n", V_VT(&value
));
305 ok(!lstrcmpW(V_BSTR(&value
), foobarW
), "got %s\n", wine_dbgstr_w(V_BSTR(&value
)));
306 VariantClear(&value
);
310 lstrcpyW(pathW
, keypathW
);
311 lstrcatW(pathW
, regdwordW
);
312 name
= SysAllocString(pathW
);
314 hr
= IWshShell3_RegRead(sh3
, name
, &value
);
315 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
316 ok(V_VT(&value
) == VT_I4
, "got %d\n", V_VT(&value
));
317 ok(V_I4(&value
) == 10, "got %d\n", V_I4(&value
));
321 lstrcpyW(pathW
, keypathW
);
322 lstrcatW(pathW
, regbinaryW
);
323 name
= SysAllocString(pathW
);
325 hr
= IWshShell3_RegRead(sh3
, name
, &value
);
326 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
327 ok(V_VT(&value
) == (VT_ARRAY
|VT_VARIANT
), "got 0x%x\n", V_VT(&value
));
328 dim
= SafeArrayGetDim(V_ARRAY(&value
));
329 ok(dim
== 1, "got %u\n", dim
);
331 hr
= SafeArrayGetLBound(V_ARRAY(&value
), 1, &bound
);
332 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
333 ok(bound
== 0, "got %u\n", bound
);
335 hr
= SafeArrayGetUBound(V_ARRAY(&value
), 1, &bound
);
336 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
337 ok(bound
== 3, "got %u\n", bound
);
339 hr
= SafeArrayGetVartype(V_ARRAY(&value
), &vartype
);
340 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
341 ok(vartype
== VT_VARIANT
, "got %d\n", vartype
);
344 hr
= SafeArrayGetElement(V_ARRAY(&value
), &bound
, &v
);
345 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
346 ok(V_VT(&v
) == VT_UI1
, "got %d\n", V_VT(&v
));
347 ok(V_UI1(&v
) == 11, "got %u\n", V_UI1(&v
));
349 VariantClear(&value
);
353 lstrcpyW(pathW
, keypathW
);
354 lstrcatW(pathW
, regmultiszW
);
355 name
= SysAllocString(pathW
);
357 hr
= IWshShell3_RegRead(sh3
, name
, &value
);
358 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
359 ok(V_VT(&value
) == (VT_ARRAY
|VT_VARIANT
), "got 0x%x\n", V_VT(&value
));
361 dim
= SafeArrayGetDim(V_ARRAY(&value
));
362 ok(dim
== 1, "got %u\n", dim
);
364 hr
= SafeArrayGetLBound(V_ARRAY(&value
), 1, &bound
);
365 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
366 ok(bound
== 0, "got %u\n", bound
);
368 hr
= SafeArrayGetUBound(V_ARRAY(&value
), 1, &bound
);
369 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
370 ok(bound
== 1, "got %u\n", bound
);
372 hr
= SafeArrayGetVartype(V_ARRAY(&value
), &vartype
);
373 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
374 ok(vartype
== VT_VARIANT
, "got %d\n", vartype
);
377 hr
= SafeArrayGetElement(V_ARRAY(&value
), &bound
, &v
);
378 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
379 ok(V_VT(&v
) == VT_BSTR
, "got %d\n", V_VT(&v
));
380 ok(!lstrcmpW(V_BSTR(&v
), fooW
), "got %s\n", wine_dbgstr_w(V_BSTR(&v
)));
382 VariantClear(&value
);
384 name
= SysAllocString(regsz1W
);
385 V_VT(&value
) = VT_I2
;
386 hr
= IWshShell3_RegRead(sh3
, name
, &value
);
387 ok(hr
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
), "got 0x%08x\n", hr
);
388 ok(V_VT(&value
) == VT_I2
, "got %d\n", V_VT(&value
));
389 VariantClear(&value
);
395 ret
= RegCreateKeyA(HKEY_CURRENT_USER
, "Software\\Wine\\Test", &root
);
396 ok(ret
== 0, "got %d\n", ret
);
398 hr
= IWshShell3_RegWrite(sh3
, NULL
, NULL
, NULL
);
399 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
401 lstrcpyW(pathW
, keypathW
);
402 lstrcatW(pathW
, regszW
);
403 name
= SysAllocString(pathW
);
405 hr
= IWshShell3_RegWrite(sh3
, name
, NULL
, NULL
);
406 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
409 hr
= IWshShell3_RegWrite(sh3
, name
, &value
, NULL
);
410 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
412 hr
= IWshShell3_RegWrite(sh3
, name
, &value
, &value
);
413 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
415 /* type is optional */
417 V_ERROR(&v
) = DISP_E_PARAMNOTFOUND
;
418 hr
= IWshShell3_RegWrite(sh3
, name
, &value
, &v
);
419 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
421 /* default type is REG_SZ */
422 V_VT(&value
) = VT_I4
;
424 hr
= IWshShell3_RegWrite(sh3
, name
, &value
, &v
);
425 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
428 ret
= RegGetValueA(root
, NULL
, "regsz", RRF_RT_ANY
, &type
, NULL
, NULL
);
429 ok(ret
== ERROR_SUCCESS
, "got %d\n", ret
);
430 ok(type
== REG_SZ
, "got %d\n", type
);
432 ret
= RegDeleteValueA(root
, "regsz");
433 ok(ret
== ERROR_SUCCESS
, "got %d\n", ret
);
434 V_VT(&value
) = VT_BSTR
;
435 V_BSTR(&value
) = SysAllocString(regszW
);
436 hr
= IWshShell3_RegWrite(sh3
, name
, &value
, &v
);
437 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
438 VariantClear(&value
);
441 ret
= RegGetValueA(root
, NULL
, "regsz", RRF_RT_ANY
, &type
, NULL
, NULL
);
442 ok(ret
== ERROR_SUCCESS
, "got %d\n", ret
);
443 ok(type
== REG_SZ
, "got %d\n", type
);
445 ret
= RegDeleteValueA(root
, "regsz");
446 ok(ret
== ERROR_SUCCESS
, "got %d\n", ret
);
447 V_VT(&value
) = VT_R4
;
449 hr
= IWshShell3_RegWrite(sh3
, name
, &value
, &v
);
450 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
451 VariantClear(&value
);
454 ret
= RegGetValueA(root
, NULL
, "regsz", RRF_RT_ANY
, &type
, NULL
, NULL
);
455 ok(ret
== ERROR_SUCCESS
, "got %d\n", ret
);
456 ok(type
== REG_SZ
, "got %d\n", type
);
458 ret
= RegDeleteValueA(root
, "regsz");
459 ok(ret
== ERROR_SUCCESS
, "got %d\n", ret
);
460 V_VT(&value
) = VT_R4
;
464 hr
= IWshShell3_RegWrite(sh3
, name
, &value
, &v
);
465 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
466 VariantClear(&value
);
471 IWshShell3_Release(sh3
);
481 hr
= CoCreateInstance(&CLSID_WshShell
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
482 &IID_IUnknown
, (void**)&unk
);
484 win_skip("Could not create WshShell object: %08x\n", hr
);
487 IUnknown_Release(unk
);