wshom.ocx: Implement RegWrite().
[wine/multimedia.git] / dlls / wshom.ocx / tests / wshom.c
bloba836f106d1cd599a86accdfa8a433b2ac46424f4
1 /*
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
19 #define COBJMACROS
20 #define CONST_VTABLE
22 #include <initguid.h>
23 #include <ole2.h>
24 #include <dispex.h>
26 #include "wshom.h"
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};
42 IWshEnvironment *env;
43 IWshShell3 *sh3;
44 IDispatchEx *dispex;
45 IWshCollection *coll;
46 IDispatch *disp, *shortcut;
47 IUnknown *shell;
48 IFolderCollection *folders;
49 IWshShortcut *shcut;
50 ITypeInfo *ti;
51 HRESULT hr;
52 TYPEATTR *tattr;
53 DISPPARAMS dp;
54 EXCEPINFO ei;
55 VARIANT arg, res, arg2;
56 BSTR str, ret;
57 DWORD retval;
58 UINT err;
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);
65 EXPECT_HR(hr, S_OK);
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);
72 EXPECT_HR(hr, S_OK);
74 hr = IWshShell3_get_SpecialFolders(sh3, &coll);
75 EXPECT_HR(hr, S_OK);
77 hr = IWshCollection_QueryInterface(coll, &IID_IFolderCollection, (void**)&folders);
78 EXPECT_HR(hr, E_NOINTERFACE);
80 hr = IWshCollection_QueryInterface(coll, &IID_IDispatch, (void**)&disp);
81 EXPECT_HR(hr, S_OK);
83 hr = IDispatch_GetTypeInfo(disp, 0, 0, &ti);
84 EXPECT_HR(hr, S_OK);
86 hr = ITypeInfo_GetTypeAttr(ti, &tattr);
87 EXPECT_HR(hr, S_OK);
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);
93 V_VT(&arg) = VT_BSTR;
94 V_BSTR(&arg) = str;
95 dp.rgvarg = &arg;
96 dp.rgdispidNamedArgs = NULL;
97 dp.cArgs = 1;
98 dp.cNamedArgs = 0;
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);
105 EXPECT_HR(hr, S_OK);
106 ok(V_VT(&res) == VT_BSTR, "got res type %d\n", V_VT(&res));
107 SysFreeString(str);
108 VariantClear(&res);
110 /* CreateShortcut() */
111 str = SysAllocString(lnk1W);
112 hr = IWshShell3_CreateShortcut(sh3, str, &shortcut);
113 EXPECT_HR(hr, S_OK);
114 SysFreeString(str);
115 hr = IDispatch_QueryInterface(shortcut, &IID_IWshShortcut, (void**)&shcut);
116 EXPECT_HR(hr, S_OK);
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);
134 SysFreeString(str);
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);
140 VariantClear(&arg);
142 hr = IWshEnvironment_get_Item(env, NULL, NULL);
143 ok(hr == E_POINTER, "got 0x%08x\n", hr);
145 ret = (BSTR)0x1;
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);
149 SysFreeString(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);
156 ret = NULL;
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));
160 SysFreeString(ret);
161 SysFreeString(str);
163 /* valid name */
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));
168 SysFreeString(ret);
169 SysFreeString(str);
171 IWshEnvironment_Release(env);
173 V_VT(&arg) = VT_I2;
174 V_I2(&arg) = 0;
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);
182 retval = 10;
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);
187 retval = 10;
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);
192 retval = 10;
193 V_VT(&arg2) = VT_ERROR;
194 V_ERROR(&arg2) = 0;
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);
199 SysFreeString(str);
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)
210 char name[MAX_PATH];
211 DWORD ret;
213 while (!(ret = RegEnumKeyA(hkey, 0, name, sizeof(name)))) {
214 HKEY tmp;
215 if (!(ret = RegOpenKeyExA(hkey, name, 0, KEY_ENUMERATE_SUB_KEYS, &tmp))) {
216 ret = delete_key(tmp);
217 RegCloseKey(tmp);
219 if (ret) break;
221 if (ret != ERROR_NO_MORE_ITEMS) return ret;
222 RegDeleteKeyA(hkey, "");
223 return 0;
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];
243 DWORD dwvalue, type;
244 VARIANT value, v;
245 IWshShell3 *sh3;
246 VARTYPE vartype;
247 LONG bound;
248 HRESULT hr;
249 BSTR name;
250 HKEY root;
251 LONG ret;
252 UINT dim;
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);
258 /* RegRead() */
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));
271 SysFreeString(name);
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));
278 SysFreeString(name);
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);
289 dwvalue = 10;
290 ret = RegSetValueExA(root, "regdword", 0, REG_DWORD, (const BYTE*)&dwvalue, sizeof(dwvalue));
291 ok(ret == 0, "got %d\n", ret);
293 dwvalue = 11;
294 ret = RegSetValueExA(root, "regbinary", 0, REG_BINARY, (const BYTE*)&dwvalue, sizeof(dwvalue));
295 ok(ret == 0, "got %d\n", ret);
297 /* REG_SZ */
298 lstrcpyW(pathW, keypathW);
299 lstrcatW(pathW, regszW);
300 name = SysAllocString(pathW);
301 VariantInit(&value);
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);
307 SysFreeString(name);
309 /* REG_DWORD */
310 lstrcpyW(pathW, keypathW);
311 lstrcatW(pathW, regdwordW);
312 name = SysAllocString(pathW);
313 VariantInit(&value);
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));
318 SysFreeString(name);
320 /* REG_BINARY */
321 lstrcpyW(pathW, keypathW);
322 lstrcatW(pathW, regbinaryW);
323 name = SysAllocString(pathW);
324 VariantInit(&value);
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);
343 bound = 0;
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));
348 VariantClear(&v);
349 VariantClear(&value);
350 SysFreeString(name);
352 /* REG_MULTI_SZ */
353 lstrcpyW(pathW, keypathW);
354 lstrcatW(pathW, regmultiszW);
355 name = SysAllocString(pathW);
356 VariantInit(&value);
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);
376 bound = 0;
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)));
381 VariantClear(&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);
390 SysFreeString(name);
392 delete_key(root);
394 /* RegWrite() */
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);
408 VariantInit(&value);
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 */
416 V_VT(&v) = VT_ERROR;
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;
423 V_I4(&value) = 12;
424 hr = IWshShell3_RegWrite(sh3, name, &value, &v);
425 ok(hr == S_OK, "got 0x%08x\n", hr);
427 type = REG_NONE;
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);
440 type = REG_NONE;
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;
448 V_R4(&value) = 1.2;
449 hr = IWshShell3_RegWrite(sh3, name, &value, &v);
450 ok(hr == S_OK, "got 0x%08x\n", hr);
451 VariantClear(&value);
453 type = REG_NONE;
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;
461 V_R4(&value) = 1.2;
462 V_VT(&v) = VT_I2;
463 V_I2(&v) = 1;
464 hr = IWshShell3_RegWrite(sh3, name, &value, &v);
465 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
466 VariantClear(&value);
468 SysFreeString(name);
470 delete_key(root);
471 IWshShell3_Release(sh3);
474 START_TEST(wshom)
476 IUnknown *unk;
477 HRESULT hr;
479 CoInitialize(NULL);
481 hr = CoCreateInstance(&CLSID_WshShell, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
482 &IID_IUnknown, (void**)&unk);
483 if (FAILED(hr)) {
484 win_skip("Could not create WshShell object: %08x\n", hr);
485 return;
487 IUnknown_Release(unk);
489 test_wshshell();
490 test_registry();
492 CoUninitialize();