ReactOS  0.4.15-dev-1197-g8081ba9
wshom.c
Go to the documentation of this file.
1 /*
2  * Copyright 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 #define COBJMACROS
20 #define CONST_VTABLE
21 
22 #include <initguid.h>
23 #include <ole2.h>
24 #include <dispex.h>
25 
26 #include "wshom.h"
27 #include "wine/test.h"
28 
29 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
30 
31 #define EXPECT_HR(hr,hr_exp) \
32  ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
33 
34 #define test_provideclassinfo(a, b) _test_provideclassinfo((IDispatch*)a, b, __LINE__)
35 static void _test_provideclassinfo(IDispatch *disp, const GUID *guid, int line)
36 {
38  TYPEATTR *attr;
39  ITypeInfo *ti;
40  HRESULT hr;
41 
42  hr = IDispatch_QueryInterface(disp, &IID_IProvideClassInfo, (void **)&classinfo);
43  ok_(__FILE__,line) (hr == S_OK, "Failed to get IProvideClassInfo, %#x.\n", hr);
44 
45  hr = IProvideClassInfo_GetClassInfo(classinfo, &ti);
46  ok_(__FILE__,line) (hr == S_OK, "GetClassInfo() failed, %#x.\n", hr);
47 
48  hr = ITypeInfo_GetTypeAttr(ti, &attr);
49  ok_(__FILE__,line) (hr == S_OK, "GetTypeAttr() failed, %#x.\n", hr);
50 
51  ok_(__FILE__,line) (IsEqualGUID(&attr->guid, guid), "Unexpected typeinfo %s, expected %s\n", wine_dbgstr_guid(&attr->guid),
53 
54  IProvideClassInfo_Release(classinfo);
55  ITypeInfo_ReleaseTypeAttr(ti, attr);
56  ITypeInfo_Release(ti);
57 }
58 
59 #define CHECK_BSTR_LENGTH(str) check_bstr_length(str, __LINE__)
60 static void check_bstr_length(BSTR str, int line)
61 {
62  ok_(__FILE__, line)(SysStringLen(str) == lstrlenW(str), "Unexpected string length %u vs %u.\n",
64 }
65 
66 static void test_wshshell(void)
67 {
68  static const WCHAR notepadW[] = {'n','o','t','e','p','a','d','.','e','x','e',0};
69  static const WCHAR desktopW[] = {'D','e','s','k','t','o','p',0};
70  static const WCHAR lnk1W[] = {'f','i','l','e','.','l','n','k',0};
71  static const WCHAR pathW[] = {'%','P','A','T','H','%',0};
72  static const WCHAR sysW[] = {'S','Y','S','T','E','M',0};
73  static const WCHAR path2W[] = {'P','A','T','H',0};
74  static const WCHAR dummydirW[] = {'d','e','a','d','p','a','r','r','o','t',0};
75  static const WCHAR emptyW[] = {'e','m','p','t','y',0};
76  static const WCHAR cmdexeW[] = {'\\','c','m','d','.','e','x','e',0};
77  static const WCHAR testdirW[] = {'w','s','h','o','m',' ','t','e','s','t',' ','d','i','r',0};
78  static const WCHAR paramsW[] =
79  {' ','/','c',' ','r','d',' ','/','s',' ','/','q',' ','c',':','\\','n','o','s','u','c','h','d','i','r',0};
80  static const WCHAR cmdW[] =
81  {'c','m','d','.','e','x','e',' ','/','c',' ','r','d',' ','/','s',' ','/','q',' ','c',':','\\',
82  'n','o','s','u','c','h','d','i','r',0};
83  static const WCHAR cmd2W[] =
84  {'"','c','m','d','.','e','x','e',' ','"',' ','/','c',' ','r','d',' ','/','s',' ','/','q',' ','c',':','\\',
85  'n','o','s','u','c','h','d','i','r',0};
87  IWshEnvironment *env;
88  IWshExec *shexec;
89  IWshShell3 *sh3;
90  IDispatchEx *dispex;
91  IWshCollection *coll;
92  IDispatch *disp, *shortcut;
93  IUnknown *shell, *unk;
94  IFolderCollection *folders;
95  IWshShortcut *shcut;
96  ITypeInfo *ti;
97  HRESULT hr;
98  TYPEATTR *tattr;
99  DISPPARAMS dp;
100  EXCEPINFO ei;
101  VARIANT arg, res, arg2;
102  BSTR str, ret;
103  DWORD retval, attrs;
104  UINT err;
105 
106  hr = CoCreateInstance(&CLSID_WshShell, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
107  &IID_IDispatch, (void**)&disp);
108  ok(hr == S_OK, "got 0x%08x\n", hr);
109 
110  hr = IDispatch_QueryInterface(disp, &IID_IWshShell3, (void**)&shell);
111  EXPECT_HR(hr, S_OK);
112  test_provideclassinfo(disp, &IID_IWshShell3);
113 
114  hr = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
116  IDispatch_Release(disp);
117 
118  hr = IUnknown_QueryInterface(shell, &IID_IWshShell3, (void**)&sh3);
119  EXPECT_HR(hr, S_OK);
120 
121  hr = IWshShell3_QueryInterface(sh3, &IID_IObjectWithSite, (void**)&unk);
122  ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
123 
124  hr = IWshShell3_QueryInterface(sh3, &IID_IWshShell, (void**)&unk);
125  ok(hr == S_OK, "got 0x%08x\n", hr);
126  IUnknown_Release(unk);
127 
128  hr = IWshShell3_QueryInterface(sh3, &IID_IWshShell2, (void**)&unk);
129  ok(hr == S_OK, "got 0x%08x\n", hr);
130  IUnknown_Release(unk);
131 
132  hr = IWshShell3_get_SpecialFolders(sh3, &coll);
133  EXPECT_HR(hr, S_OK);
134  test_provideclassinfo(coll, &IID_IWshCollection);
135 
136  hr = IWshCollection_QueryInterface(coll, &IID_IFolderCollection, (void**)&folders);
138 
139  hr = IWshCollection_QueryInterface(coll, &IID_IDispatch, (void**)&disp);
140  EXPECT_HR(hr, S_OK);
141 
142  hr = IDispatch_GetTypeInfo(disp, 0, 0, &ti);
143  EXPECT_HR(hr, S_OK);
144 
145  hr = ITypeInfo_GetTypeAttr(ti, &tattr);
146  EXPECT_HR(hr, S_OK);
147  ok(IsEqualIID(&tattr->guid, &IID_IWshCollection), "got wrong type guid\n");
148  ITypeInfo_ReleaseTypeAttr(ti, tattr);
149 
150  /* try to call Item() with normal IDispatch procedure */
152  V_VT(&arg) = VT_BSTR;
153  V_BSTR(&arg) = str;
154  dp.rgvarg = &arg;
155  dp.rgdispidNamedArgs = NULL;
156  dp.cArgs = 1;
157  dp.cNamedArgs = 0;
158  hr = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 1033, DISPATCH_PROPERTYGET, &dp, &res, &ei, &err);
160 
161  /* try Item() directly, it returns directory path apparently */
162  V_VT(&res) = VT_EMPTY;
163  hr = IWshCollection_Item(coll, &arg, &res);
164  EXPECT_HR(hr, S_OK);
165  ok(V_VT(&res) == VT_BSTR, "got res type %d\n", V_VT(&res));
168  VariantClear(&res);
169 
170  /* CreateShortcut() */
171  str = SysAllocString(lnk1W);
172  hr = IWshShell3_CreateShortcut(sh3, str, &shortcut);
173  EXPECT_HR(hr, S_OK);
175  hr = IDispatch_QueryInterface(shortcut, &IID_IWshShortcut, (void**)&shcut);
176  EXPECT_HR(hr, S_OK);
177  test_provideclassinfo(shortcut, &IID_IWshShortcut);
178 
179  hr = IWshShortcut_get_Arguments(shcut, NULL);
180  ok(hr == E_POINTER, "got 0x%08x\n", hr);
181 
182  hr = IWshShortcut_get_IconLocation(shcut, NULL);
183  ok(hr == E_POINTER, "got 0x%08x\n", hr);
184 
185  IWshShortcut_Release(shcut);
186  IDispatch_Release(shortcut);
187 
188  /* ExpandEnvironmentStrings */
189  hr = IWshShell3_ExpandEnvironmentStrings(sh3, NULL, NULL);
190  ok(hr == E_POINTER, "got 0x%08x\n", hr);
191 
192  str = SysAllocString(pathW);
193  hr = IWshShell3_ExpandEnvironmentStrings(sh3, str, NULL);
194  ok(hr == E_POINTER, "got 0x%08x\n", hr);
196 
197  V_VT(&arg) = VT_BSTR;
199  hr = IWshShell3_get_Environment(sh3, &arg, &env);
200  ok(hr == S_OK, "got 0x%08x\n", hr);
201  VariantClear(&arg);
202 
203  hr = IWshEnvironment_get_Item(env, NULL, NULL);
204  ok(hr == E_POINTER, "got 0x%08x\n", hr);
205  test_provideclassinfo(env, &IID_IWshEnvironment);
206 
207  ret = (BSTR)0x1;
208  hr = IWshEnvironment_get_Item(env, NULL, &ret);
209  ok(hr == S_OK, "got 0x%08x\n", hr);
210  ok(ret && !*ret, "got %p\n", ret);
212 
213  /* invalid var name */
214  str = SysAllocString(lnk1W);
215  hr = IWshEnvironment_get_Item(env, str, NULL);
216  ok(hr == E_POINTER, "got 0x%08x\n", hr);
217 
218  ret = NULL;
219  hr = IWshEnvironment_get_Item(env, str, &ret);
220  ok(hr == S_OK, "got 0x%08x\n", hr);
221  ok(ret && *ret == 0, "got %s\n", wine_dbgstr_w(ret));
225 
226  /* valid name */
227  str = SysAllocString(path2W);
228  hr = IWshEnvironment_get_Item(env, str, &ret);
229  ok(hr == S_OK, "got 0x%08x\n", hr);
230  ok(ret && *ret != 0, "got %s\n", wine_dbgstr_w(ret));
234 
235  IWshEnvironment_Release(env);
236 
237  V_VT(&arg) = VT_I2;
238  V_I2(&arg) = 0;
239  V_VT(&arg2) = VT_ERROR;
241 
242  str = SysAllocString(notepadW);
243  hr = IWshShell3_Run(sh3, str, &arg, &arg2, NULL);
244  ok(hr == E_POINTER, "got 0x%08x\n", hr);
245 
246  retval = 10;
247  hr = IWshShell3_Run(sh3, str, NULL, &arg2, &retval);
248  ok(hr == E_POINTER, "got 0x%08x\n", hr);
249  ok(retval == 10, "got %u\n", retval);
250 
251  retval = 10;
252  hr = IWshShell3_Run(sh3, str, &arg, NULL, &retval);
253  ok(hr == E_POINTER, "got 0x%08x\n", hr);
254  ok(retval == 10, "got %u\n", retval);
255 
256  retval = 10;
257  V_VT(&arg2) = VT_ERROR;
258  V_ERROR(&arg2) = 0;
259  hr = IWshShell3_Run(sh3, str, &arg, &arg2, &retval);
260  ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr);
261  ok(retval == 10, "got %u\n", retval);
263 
264  V_VT(&arg2) = VT_BOOL;
265  V_BOOL(&arg2) = VARIANT_TRUE;
266 
267  retval = 0xdeadbeef;
268  str = SysAllocString(cmdW);
269  hr = IWshShell3_Run(sh3, str, &arg, &arg2, &retval);
270  ok(hr == S_OK, "got 0x%08x\n", hr);
271  todo_wine ok(retval == ERROR_FILE_NOT_FOUND, "got %u\n", retval);
273 
274  retval = 0xdeadbeef;
275  str = SysAllocString(cmd2W);
276  hr = IWshShell3_Run(sh3, str, &arg, &arg2, &retval);
277  ok(hr == S_OK, "got 0x%08x\n", hr);
278  todo_wine ok(retval == ERROR_FILE_NOT_FOUND, "got %u\n", retval);
280 
282  lstrcatW(path, cmdexeW);
283  attrs = GetFileAttributesW(path);
284  ok(attrs != INVALID_FILE_ATTRIBUTES, "cmd.exe not found\n");
285 
286  /* copy cmd.exe to a path with spaces */
288  lstrcatW(path2, testdirW);
290  lstrcatW(path2, cmdexeW);
292 
293  buf[0] = '"';
294  lstrcpyW(buf + 1, path2);
295  buf[lstrlenW(buf)] = '"';
296  lstrcpyW(buf + lstrlenW(path2) + 2, paramsW);
297 
298  retval = 0xdeadbeef;
300  hr = IWshShell3_Run(sh3, str, &arg, &arg2, &retval);
301  ok(hr == S_OK, "got 0x%08x\n", hr);
302  todo_wine ok(retval == ERROR_FILE_NOT_FOUND, "got %u\n", retval);
304 
306  path2[lstrlenW(path2) - lstrlenW(cmdexeW)] = 0;
308 
309  /* current directory */
310  if (0) /* crashes on native */
311  hr = IWshShell3_get_CurrentDirectory(sh3, NULL);
312 
313  str = NULL;
314  hr = IWshShell3_get_CurrentDirectory(sh3, &str);
315  ok(hr == S_OK, "got 0x%08x\n", hr);
316  ok(str && str[0] != 0, "got empty string\n");
319 
320  hr = IWshShell3_put_CurrentDirectory(sh3, NULL);
321  ok(hr == E_INVALIDARG ||
322  broken(hr == HRESULT_FROM_WIN32(ERROR_NOACCESS)), "got 0x%08x\n", hr);
323 
325  hr = IWshShell3_put_CurrentDirectory(sh3, str);
326  ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
328 
329  str = SysAllocString(dummydirW);
330  hr = IWshShell3_put_CurrentDirectory(sh3, str);
331  ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
333 
334  /* Exec */
335  hr = IWshShell3_Exec(sh3, NULL, NULL);
336  ok(hr == E_POINTER, "got 0x%08x\n", hr);
337 
338  hr = IWshShell3_Exec(sh3, NULL, &shexec);
339  ok(hr == DISP_E_EXCEPTION, "got 0x%08x\n", hr);
340 
342  hr = IWshShell3_Exec(sh3, str, &shexec);
343  ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
345 
346  IWshCollection_Release(coll);
347  IDispatch_Release(disp);
348  IWshShell3_Release(sh3);
349  IUnknown_Release(shell);
350 }
351 
352 /* delete key and all its subkeys */
353 static DWORD delete_key(HKEY hkey)
354 {
355  char name[MAX_PATH];
356  DWORD ret;
357 
358  while (!(ret = RegEnumKeyA(hkey, 0, name, sizeof(name)))) {
359  HKEY tmp;
360  if (!(ret = RegOpenKeyExA(hkey, name, 0, KEY_ENUMERATE_SUB_KEYS, &tmp))) {
361  ret = delete_key(tmp);
362  RegCloseKey(tmp);
363  }
364  if (ret) break;
365  }
366  if (ret != ERROR_NO_MORE_ITEMS) return ret;
367  RegDeleteKeyA(hkey, "");
368  return 0;
369 }
370 
371 static void test_registry(void)
372 {
373  static const WCHAR keypathW[] = {'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R','\\',
374  'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\','T','e','s','t','\\',0};
375  static const WCHAR regsz2W[] = {'r','e','g','s','z','2',0};
376  static const WCHAR regszW[] = {'r','e','g','s','z',0};
377  static const WCHAR regdwordW[] = {'r','e','g','d','w','o','r','d',0};
378  static const WCHAR regbinaryW[] = {'r','e','g','b','i','n','a','r','y',0};
379  static const WCHAR regmultiszW[] = {'r','e','g','m','u','l','t','i','s','z',0};
380 
381  static const WCHAR regsz1W[] = {'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R','\\',
382  'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\','T','e','s','t','\\','r','e','g','s','z','1',0};
383  static const WCHAR foobarW[] = {'f','o','o','b','a','r',0};
384  static const WCHAR fooW[] = {'f','o','o',0};
385  static const WCHAR brokenW[] = {'H','K','E','Y','_','b','r','o','k','e','n','_','k','e','y',0};
386  static const WCHAR broken2W[] = {'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R','a',0};
387  WCHAR pathW[MAX_PATH];
388  DWORD dwvalue, type;
389  VARIANT value, v;
390  IWshShell3 *sh3;
392  LONG bound;
393  HRESULT hr;
394  BSTR name;
395  HKEY root;
396  LONG ret;
397  UINT dim;
398 
399  hr = CoCreateInstance(&CLSID_WshShell, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
400  &IID_IWshShell3, (void**)&sh3);
401  ok(hr == S_OK, "got 0x%08x\n", hr);
402 
403  /* RegRead() */
404  V_VT(&value) = VT_I2;
405  hr = IWshShell3_RegRead(sh3, NULL, &value);
406  ok(hr == E_POINTER, "got 0x%08x\n", hr);
407  ok(V_VT(&value) == VT_I2, "got %d\n", V_VT(&value));
408 
409  name = SysAllocString(brokenW);
410  hr = IWshShell3_RegRead(sh3, name, NULL);
411  ok(hr == E_POINTER, "got 0x%08x\n", hr);
412  V_VT(&value) = VT_I2;
413  hr = IWshShell3_RegRead(sh3, name, &value);
414  ok(hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "got 0x%08x\n", hr);
415  ok(V_VT(&value) == VT_I2, "got %d\n", V_VT(&value));
417 
418  name = SysAllocString(broken2W);
419  V_VT(&value) = VT_I2;
420  hr = IWshShell3_RegRead(sh3, name, &value);
421  ok(hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "got 0x%08x\n", hr);
422  ok(V_VT(&value) == VT_I2, "got %d\n", V_VT(&value));
424 
425  ret = RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test", &root);
426  ok(ret == 0, "got %d\n", ret);
427 
428  ret = RegSetValueExA(root, "regsz", 0, REG_SZ, (const BYTE*)"foobar", 7);
429  ok(ret == 0, "got %d\n", ret);
430 
431  ret = RegSetValueExA(root, "regsz2", 0, REG_SZ, (const BYTE*)"foobar\0f", 9);
432  ok(ret == 0, "got %d\n", ret);
433 
434  ret = RegSetValueExA(root, "regmultisz", 0, REG_MULTI_SZ, (const BYTE*)"foo\0bar\0", 9);
435  ok(ret == 0, "got %d\n", ret);
436 
437  dwvalue = 10;
438  ret = RegSetValueExA(root, "regdword", 0, REG_DWORD, (const BYTE*)&dwvalue, sizeof(dwvalue));
439  ok(ret == 0, "got %d\n", ret);
440 
441  dwvalue = 11;
442  ret = RegSetValueExA(root, "regbinary", 0, REG_BINARY, (const BYTE*)&dwvalue, sizeof(dwvalue));
443  ok(ret == 0, "got %d\n", ret);
444 
445  /* REG_SZ */
446  lstrcpyW(pathW, keypathW);
447  lstrcatW(pathW, regszW);
448  name = SysAllocString(pathW);
449  VariantInit(&value);
450  hr = IWshShell3_RegRead(sh3, name, &value);
451  ok(hr == S_OK, "got 0x%08x\n", hr);
452  ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
453  ok(!lstrcmpW(V_BSTR(&value), foobarW), "got %s\n", wine_dbgstr_w(V_BSTR(&value)));
457 
458  /* REG_SZ with embedded NULL */
459  lstrcpyW(pathW, keypathW);
460  lstrcatW(pathW, regsz2W);
461  name = SysAllocString(pathW);
462  VariantInit(&value);
463  hr = IWshShell3_RegRead(sh3, name, &value);
464  ok(hr == S_OK, "got 0x%08x\n", hr);
465  ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value));
466  ok(SysStringLen(V_BSTR(&value)) == 6, "len %d\n", SysStringLen(V_BSTR(&value)));
470 
471  /* REG_DWORD */
472  lstrcpyW(pathW, keypathW);
473  lstrcatW(pathW, regdwordW);
474  name = SysAllocString(pathW);
475  VariantInit(&value);
476  hr = IWshShell3_RegRead(sh3, name, &value);
477  ok(hr == S_OK, "got 0x%08x\n", hr);
478  ok(V_VT(&value) == VT_I4, "got %d\n", V_VT(&value));
479  ok(V_I4(&value) == 10, "got %d\n", V_I4(&value));
481 
482  /* REG_BINARY */
483  lstrcpyW(pathW, keypathW);
484  lstrcatW(pathW, regbinaryW);
485  name = SysAllocString(pathW);
486  VariantInit(&value);
487  hr = IWshShell3_RegRead(sh3, name, &value);
488  ok(hr == S_OK, "got 0x%08x\n", hr);
489  ok(V_VT(&value) == (VT_ARRAY|VT_VARIANT), "got 0x%x\n", V_VT(&value));
490  dim = SafeArrayGetDim(V_ARRAY(&value));
491  ok(dim == 1, "got %u\n", dim);
492 
493  hr = SafeArrayGetLBound(V_ARRAY(&value), 1, &bound);
494  ok(hr == S_OK, "got 0x%08x\n", hr);
495  ok(bound == 0, "got %u\n", bound);
496 
497  hr = SafeArrayGetUBound(V_ARRAY(&value), 1, &bound);
498  ok(hr == S_OK, "got 0x%08x\n", hr);
499  ok(bound == 3, "got %u\n", bound);
500 
502  ok(hr == S_OK, "got 0x%08x\n", hr);
503  ok(vartype == VT_VARIANT, "got %d\n", vartype);
504 
505  bound = 0;
506  hr = SafeArrayGetElement(V_ARRAY(&value), &bound, &v);
507  ok(hr == S_OK, "got 0x%08x\n", hr);
508  ok(V_VT(&v) == VT_UI1, "got %d\n", V_VT(&v));
509  ok(V_UI1(&v) == 11, "got %u\n", V_UI1(&v));
510  VariantClear(&v);
513 
514  /* REG_MULTI_SZ */
515  lstrcpyW(pathW, keypathW);
516  lstrcatW(pathW, regmultiszW);
517  name = SysAllocString(pathW);
518  VariantInit(&value);
519  hr = IWshShell3_RegRead(sh3, name, &value);
520  ok(hr == S_OK, "got 0x%08x\n", hr);
521  ok(V_VT(&value) == (VT_ARRAY|VT_VARIANT), "got 0x%x\n", V_VT(&value));
523 
524  dim = SafeArrayGetDim(V_ARRAY(&value));
525  ok(dim == 1, "got %u\n", dim);
526 
527  hr = SafeArrayGetLBound(V_ARRAY(&value), 1, &bound);
528  ok(hr == S_OK, "got 0x%08x\n", hr);
529  ok(bound == 0, "got %u\n", bound);
530 
531  hr = SafeArrayGetUBound(V_ARRAY(&value), 1, &bound);
532  ok(hr == S_OK, "got 0x%08x\n", hr);
533  ok(bound == 1, "got %u\n", bound);
534 
536  ok(hr == S_OK, "got 0x%08x\n", hr);
537  ok(vartype == VT_VARIANT, "got %d\n", vartype);
538 
539  bound = 0;
540  hr = SafeArrayGetElement(V_ARRAY(&value), &bound, &v);
541  ok(hr == S_OK, "got 0x%08x\n", hr);
542  ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v));
543  ok(!lstrcmpW(V_BSTR(&v), fooW), "got %s\n", wine_dbgstr_w(V_BSTR(&v)));
545  VariantClear(&v);
547 
548  name = SysAllocString(regsz1W);
549  V_VT(&value) = VT_I2;
550  hr = IWshShell3_RegRead(sh3, name, &value);
551  ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
552  ok(V_VT(&value) == VT_I2, "got %d\n", V_VT(&value));
555 
556  delete_key(root);
557 
558  /* RegWrite() */
559  ret = RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test", &root);
560  ok(ret == 0, "got %d\n", ret);
561 
562  hr = IWshShell3_RegWrite(sh3, NULL, NULL, NULL);
563  ok(hr == E_POINTER, "got 0x%08x\n", hr);
564 
565  lstrcpyW(pathW, keypathW);
566  lstrcatW(pathW, regszW);
567  name = SysAllocString(pathW);
568 
569  hr = IWshShell3_RegWrite(sh3, name, NULL, NULL);
570  ok(hr == E_POINTER, "got 0x%08x\n", hr);
571 
572  VariantInit(&value);
573  hr = IWshShell3_RegWrite(sh3, name, &value, NULL);
574  ok(hr == E_POINTER, "got 0x%08x\n", hr);
575 
576  hr = IWshShell3_RegWrite(sh3, name, &value, &value);
577  ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
578 
579  /* type is optional */
580  V_VT(&v) = VT_ERROR;
582  hr = IWshShell3_RegWrite(sh3, name, &value, &v);
583  ok(hr == S_OK, "got 0x%08x\n", hr);
584 
585  /* default type is REG_SZ */
586  V_VT(&value) = VT_I4;
587  V_I4(&value) = 12;
588  hr = IWshShell3_RegWrite(sh3, name, &value, &v);
589  ok(hr == S_OK, "got 0x%08x\n", hr);
590 
591  type = REG_NONE;
592  ret = RegQueryValueExA(root, "regsz", 0, &type, NULL, NULL);
593  ok(ret == ERROR_SUCCESS, "got %d\n", ret);
594  ok(type == REG_SZ, "got %d\n", type);
595 
596  ret = RegDeleteValueA(root, "regsz");
597  ok(ret == ERROR_SUCCESS, "got %d\n", ret);
598  V_VT(&value) = VT_BSTR;
599  V_BSTR(&value) = SysAllocString(regszW);
600  hr = IWshShell3_RegWrite(sh3, name, &value, &v);
601  ok(hr == S_OK, "got 0x%08x\n", hr);
603 
604  type = REG_NONE;
605  ret = RegQueryValueExA(root, "regsz", 0, &type, NULL, NULL);
606  ok(ret == ERROR_SUCCESS, "got %d\n", ret);
607  ok(type == REG_SZ, "got %d\n", type);
608 
609  ret = RegDeleteValueA(root, "regsz");
610  ok(ret == ERROR_SUCCESS, "got %d\n", ret);
611  V_VT(&value) = VT_R4;
612  V_R4(&value) = 1.2;
613  hr = IWshShell3_RegWrite(sh3, name, &value, &v);
614  ok(hr == S_OK, "got 0x%08x\n", hr);
616 
617  type = REG_NONE;
618  ret = RegQueryValueExA(root, "regsz", 0, &type, NULL, NULL);
619  ok(ret == ERROR_SUCCESS, "got %d\n", ret);
620  ok(type == REG_SZ, "got %d\n", type);
621 
622  ret = RegDeleteValueA(root, "regsz");
623  ok(ret == ERROR_SUCCESS, "got %d\n", ret);
624  V_VT(&value) = VT_R4;
625  V_R4(&value) = 1.2;
626  V_VT(&v) = VT_I2;
627  V_I2(&v) = 1;
628  hr = IWshShell3_RegWrite(sh3, name, &value, &v);
629  ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
631 
633 
634  delete_key(root);
635  IWshShell3_Release(sh3);
636 }
637 
638 static void test_popup(void)
639 {
640  static const WCHAR textW[] = {'T','e','x','t',0};
642  IWshShell *sh;
643  int button;
644  HRESULT hr;
645  BSTR text;
646 
647  hr = CoCreateInstance(&CLSID_WshShell, NULL, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER,
648  &IID_IWshShell, (void **)&sh);
649  ok(hr == S_OK, "Failed to create WshShell object, hr %#x.\n", hr);
650 
651  button = 123;
653 
654  hr = IWshShell_Popup(sh, NULL, NULL, NULL, NULL, &button);
655  ok(hr == E_POINTER, "Unexpected retval %#x.\n", hr);
656  ok(button == 123, "Unexpected button id %d.\n", button);
657 
658  hr = IWshShell_Popup(sh, text, NULL, NULL, NULL, &button);
659  ok(hr == E_POINTER, "Unexpected retval %#x.\n", hr);
660  ok(button == 123, "Unexpected button id %d.\n", button);
661 
662  V_VT(&optional) = VT_ERROR;
664 
665  V_VT(&timeout) = VT_I2;
666  V_I2(&timeout) = 1;
667 
668  V_VT(&type) = VT_I2;
669  V_I2(&type) = 1;
670 
671  V_VT(&title) = VT_BSTR;
672  V_BSTR(&title) = NULL;
673 
674  hr = IWshShell_Popup(sh, text, &timeout, &optional, &type, &button);
675  ok(hr == S_OK, "Unexpected retval %#x.\n", hr);
676  ok(button == -1, "Unexpected button id %d.\n", button);
677 
678  hr = IWshShell_Popup(sh, text, &timeout, &title, &optional, &button);
679  ok(hr == S_OK, "Unexpected retval %#x.\n", hr);
680  ok(button == -1, "Unexpected button id %d.\n", button);
681 
683  IWshShell_Release(sh);
684 }
685 
687 {
688  IUnknown *unk;
689  HRESULT hr;
690 
692 
693  hr = CoCreateInstance(&CLSID_WshShell, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
694  &IID_IUnknown, (void**)&unk);
695  if (FAILED(hr)) {
696  win_skip("Could not create WshShell object: %08x\n", hr);
697  return;
698  }
699  IUnknown_Release(unk);
700 
701  test_wshshell();
702  test_registry();
703  test_popup();
704 
705  CoUninitialize();
706 }
#define DISP_E_EXCEPTION
Definition: winerror.h:2518
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
static const WCHAR path2[]
Definition: path.c:29
disp
Definition: i386-dis.c:3181
UINT WINAPI SafeArrayGetDim(SAFEARRAY *psa)
Definition: safearray.c:1094
LONG WINAPI RegQueryValueExA(_In_ HKEY hkeyorg, _In_ LPCSTR name, _In_ LPDWORD reserved, _Out_opt_ LPDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ LPDWORD count)
Definition: reg.c:4023
#define E_NOINTERFACE
Definition: winerror.h:2364
Definition: compat.h:2046
#define DISPATCH_PROPERTYGET
Definition: oleauto.h:1007
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
static void check_bstr_length(BSTR str, int line)
Definition: wshom.c:60
#define ERROR_SUCCESS
Definition: deptool.c:10
HRESULT hr
Definition: shlfolder.c:183
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define REG_BINARY
Definition: nt_native.h:1496
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: atltest.h:87
static void test_registry(void)
Definition: wshom.c:371
const WCHAR * text
Definition: package.c:1827
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
#define HKEY_CURRENT_USER
Definition: winreg.h:11
struct _root root
#define V_ARRAY(A)
Definition: oleauto.h:222
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
DWORD button
Definition: button.c:166
#define V_I2(A)
Definition: oleauto.h:245
static DWORD delete_key(HKEY hkey)
Definition: wshom.c:353
#define DISP_E_MEMBERNOTFOUND
Definition: winerror.h:2512
LONG WINAPI RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3331
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
const char * wine_dbgstr_guid(const GUID *guid)
static void test_popup(void)
Definition: wshom.c:638
classinfo
Definition: clsfactory.c:43
void * arg
Definition: msvc.h:10
Definition: dhcpd.h:245
HRESULT WINAPI SafeArrayGetElement(SAFEARRAY *psa, LONG *rgIndices, void *pvData)
Definition: safearray.c:947
OLECHAR * BSTR
Definition: compat.h:2041
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:568
#define lstrlenW
Definition: compat.h:498
GLbitfield GLuint64 timeout
Definition: glext.h:7164
#define DISP_E_PARAMNOTFOUND
Definition: winerror.h:2513
#define V_I4(A)
Definition: oleauto.h:247
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:9514
#define EXPECT_HR(hr, hr_exp)
Definition: wshom.c:31
#define ERROR_NOACCESS
Definition: winerror.h:578
const GUID * guid
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2079
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
const GUID IID_IProvideClassInfo
#define REG_MULTI_SZ
Definition: nt_native.h:1501
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
#define E_INVALIDARG
Definition: ddrawi.h:101
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
Definition: parser.c:48
#define test_provideclassinfo(a, b)
Definition: wshom.c:34
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
BOOL WINAPI RemoveDirectoryW(IN LPCWSTR lpPathName)
Definition: dir.c:732
LONG WINAPI RegCreateKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1177
static const WCHAR sysW[]
Definition: richole.c:40
Definition: msg.h:41
static void _test_provideclassinfo(IDispatch *disp, const GUID *guid, int line)
Definition: wshom.c:35
DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
#define V_R4(A)
Definition: oleauto.h:260
#define DISP_E_TYPEMISMATCH
Definition: winerror.h:2514
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:79
BOOL WINAPI CopyFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN BOOL bFailIfExists)
Definition: copy.c:439
const GUID IID_IUnknown
#define V_UI1(A)
Definition: oleauto.h:266
#define MAX_PATH
Definition: compat.h:34
static const WCHAR fooW[]
Definition: locale.c:44
const IID IID_IObjectWithSite
#define V_BOOL(A)
Definition: oleauto.h:224
HRESULT WINAPI SafeArrayGetLBound(SAFEARRAY *psa, UINT nDim, LONG *plLbound)
Definition: safearray.c:1066
unsigned long DWORD
Definition: ntddk_ex.h:95
#define CHECK_BSTR_LENGTH(str)
Definition: wshom.c:59
Definition: cookie.c:201
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
const GUID IID_IDispatch
int ret
static const WCHAR desktopW[]
Definition: main.c:46
LONG WINAPI RegEnumKeyA(HKEY hKey, DWORD dwIndex, LPSTR lpName, DWORD cbName)
Definition: reg.c:2391
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
Definition: compat.h:2047
__u8 attr
Definition: mkdosfs.c:359
#define IID_NULL
Definition: guiddef.h:98
#define todo_wine
Definition: test.h:162
#define V_VT(A)
Definition: oleauto.h:211
#define GUID_NULL
Definition: ks.h:106
UINT WINAPI SysStringLen(BSTR str)
Definition: oleaut.c:196
#define err(...)
static const WCHAR textW[]
Definition: itemdlg.c:1559
GLsizei const GLfloat * value
Definition: glext.h:6069
unsigned char BYTE
Definition: xxhash.c:193
#define V_BSTR(A)
Definition: oleauto.h:226
#define broken(x)
Definition: _sntprintf.h:21
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
short sh
Definition: format.c:272
LONG WINAPI RegDeleteKeyA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey)
Definition: reg.c:1222
struct stdole::EXCEPINFO EXCEPINFO
#define S_OK
Definition: intsafe.h:51
HRESULT WINAPI SafeArrayGetUBound(SAFEARRAY *psa, UINT nDim, LONG *plUbound)
Definition: safearray.c:1033
const GLdouble * v
Definition: gl.h:2040
static const WCHAR emptyW[]
Definition: navigate.c:40
#define lstrcpyW
Definition: compat.h:497
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
#define ARRAY_SIZE(a)
Definition: main.h:24
static const WCHAR foobarW[]
Definition: atom.c:32
#define ok(value,...)
Definition: atltest.h:57
LONG WINAPI RegDeleteValueA(HKEY hKey, LPCSTR lpValueName)
Definition: reg.c:2319
unsigned short VARTYPE
Definition: compat.h:2002
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2312
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
#define V_ERROR(A)
Definition: oleauto.h:241
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
HRESULT WINAPI SafeArrayGetVartype(SAFEARRAY *psa, VARTYPE *pvt)
Definition: safearray.c:1534
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp:168
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
Definition: name.c:38
GLuint res
Definition: glext.h:9613
struct stdole::DISPPARAMS DISPPARAMS
START_TEST(wshom)
Definition: wshom.c:686
static void test_wshshell(void)
Definition: wshom.c:66
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4812
#define REG_NONE
Definition: nt_native.h:1492
#define E_POINTER
Definition: winerror.h:2365
#define REG_DWORD
Definition: sdbapi.c:596
#define win_skip
Definition: test.h:149
static char title[]
Definition: ps.c:92
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
Definition: compat.h:2045
#define ok_(x1, x2)
Definition: atltest.h:61
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
#define REG_SZ
Definition: layer.c:22
GLuint const GLchar * name
Definition: glext.h:6031