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 WIN32_NO_STATUS 20 #define _INC_WINDOWS 21 #define COBJMACROS 22 #define CONST_VTABLE 23 24 #include <windef.h> 25 #include <winbase.h> 26 #include <winreg.h> 27 #include <initguid.h> 28 #include <dispex.h> 29 #include <wshom.h> 30 #include <wine/test.h> 31 32 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); 33 34 #define EXPECT_HR(hr,hr_exp) \ 35 ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp) 36 37 #define test_provideclassinfo(a, b) _test_provideclassinfo((IDispatch*)a, b, __LINE__) 38 static void _test_provideclassinfo(IDispatch *disp, const GUID *guid, int line) 39 { 40 IProvideClassInfo *classinfo; 41 TYPEATTR *attr; 42 ITypeInfo *ti; 43 HRESULT hr; 44 45 hr = IDispatch_QueryInterface(disp, &IID_IProvideClassInfo, (void **)&classinfo); 46 ok_(__FILE__,line) (hr == S_OK, "Failed to get IProvideClassInfo, %#x.\n", hr); 47 48 hr = IProvideClassInfo_GetClassInfo(classinfo, &ti); 49 ok_(__FILE__,line) (hr == S_OK, "GetClassInfo() failed, %#x.\n", hr); 50 51 hr = ITypeInfo_GetTypeAttr(ti, &attr); 52 ok_(__FILE__,line) (hr == S_OK, "GetTypeAttr() failed, %#x.\n", hr); 53 54 ok_(__FILE__,line) (IsEqualGUID(&attr->guid, guid), "Unexpected typeinfo %s, expected %s\n", wine_dbgstr_guid(&attr->guid), 55 wine_dbgstr_guid(guid)); 56 57 IProvideClassInfo_Release(classinfo); 58 ITypeInfo_ReleaseTypeAttr(ti, attr); 59 ITypeInfo_Release(ti); 60 } 61 62 static void test_wshshell(void) 63 { 64 static const WCHAR notepadW[] = {'n','o','t','e','p','a','d','.','e','x','e',0}; 65 static const WCHAR desktopW[] = {'D','e','s','k','t','o','p',0}; 66 static const WCHAR lnk1W[] = {'f','i','l','e','.','l','n','k',0}; 67 static const WCHAR pathW[] = {'%','P','A','T','H','%',0}; 68 static const WCHAR sysW[] = {'S','Y','S','T','E','M',0}; 69 static const WCHAR path2W[] = {'P','A','T','H',0}; 70 static const WCHAR dummydirW[] = {'d','e','a','d','p','a','r','r','o','t',0}; 71 static const WCHAR emptyW[] = {'e','m','p','t','y',0}; 72 IWshEnvironment *env; 73 IWshExec *shexec; 74 IWshShell3 *sh3; 75 IDispatchEx *dispex; 76 IWshCollection *coll; 77 IDispatch *disp, *shortcut; 78 IUnknown *shell, *unk; 79 IFolderCollection *folders; 80 IWshShortcut *shcut; 81 ITypeInfo *ti; 82 HRESULT hr; 83 TYPEATTR *tattr; 84 DISPPARAMS dp; 85 EXCEPINFO ei; 86 VARIANT arg, res, arg2; 87 BSTR str, ret; 88 DWORD retval; 89 UINT err; 90 91 hr = CoCreateInstance(&CLSID_WshShell, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, 92 &IID_IDispatch, (void**)&disp); 93 ok(hr == S_OK, "got 0x%08x\n", hr); 94 95 hr = IDispatch_QueryInterface(disp, &IID_IWshShell3, (void**)&shell); 96 EXPECT_HR(hr, S_OK); 97 test_provideclassinfo(disp, &IID_IWshShell3); 98 99 hr = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); 100 EXPECT_HR(hr, E_NOINTERFACE); 101 IDispatch_Release(disp); 102 103 hr = IUnknown_QueryInterface(shell, &IID_IWshShell3, (void**)&sh3); 104 EXPECT_HR(hr, S_OK); 105 106 hr = IWshShell3_QueryInterface(sh3, &IID_IObjectWithSite, (void**)&unk); 107 ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr); 108 109 hr = IWshShell3_QueryInterface(sh3, &IID_IWshShell, (void**)&unk); 110 ok(hr == S_OK, "got 0x%08x\n", hr); 111 IUnknown_Release(unk); 112 113 hr = IWshShell3_QueryInterface(sh3, &IID_IWshShell2, (void**)&unk); 114 ok(hr == S_OK, "got 0x%08x\n", hr); 115 IUnknown_Release(unk); 116 117 hr = IWshShell3_get_SpecialFolders(sh3, &coll); 118 EXPECT_HR(hr, S_OK); 119 test_provideclassinfo(coll, &IID_IWshCollection); 120 121 hr = IWshCollection_QueryInterface(coll, &IID_IFolderCollection, (void**)&folders); 122 EXPECT_HR(hr, E_NOINTERFACE); 123 124 hr = IWshCollection_QueryInterface(coll, &IID_IDispatch, (void**)&disp); 125 EXPECT_HR(hr, S_OK); 126 127 hr = IDispatch_GetTypeInfo(disp, 0, 0, &ti); 128 EXPECT_HR(hr, S_OK); 129 130 hr = ITypeInfo_GetTypeAttr(ti, &tattr); 131 EXPECT_HR(hr, S_OK); 132 ok(IsEqualIID(&tattr->guid, &IID_IWshCollection), "got wrong type guid\n"); 133 ITypeInfo_ReleaseTypeAttr(ti, tattr); 134 135 /* try to call Item() with normal IDispatch procedure */ 136 str = SysAllocString(desktopW); 137 V_VT(&arg) = VT_BSTR; 138 V_BSTR(&arg) = str; 139 dp.rgvarg = &arg; 140 dp.rgdispidNamedArgs = NULL; 141 dp.cArgs = 1; 142 dp.cNamedArgs = 0; 143 hr = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, 1033, DISPATCH_PROPERTYGET, &dp, &res, &ei, &err); 144 EXPECT_HR(hr, DISP_E_MEMBERNOTFOUND); 145 146 /* try Item() directly, it returns directory path apparently */ 147 V_VT(&res) = VT_EMPTY; 148 hr = IWshCollection_Item(coll, &arg, &res); 149 EXPECT_HR(hr, S_OK); 150 ok(V_VT(&res) == VT_BSTR, "got res type %d\n", V_VT(&res)); 151 SysFreeString(str); 152 VariantClear(&res); 153 154 /* CreateShortcut() */ 155 str = SysAllocString(lnk1W); 156 hr = IWshShell3_CreateShortcut(sh3, str, &shortcut); 157 EXPECT_HR(hr, S_OK); 158 SysFreeString(str); 159 hr = IDispatch_QueryInterface(shortcut, &IID_IWshShortcut, (void**)&shcut); 160 EXPECT_HR(hr, S_OK); 161 test_provideclassinfo(shortcut, &IID_IWshShortcut); 162 163 hr = IWshShortcut_get_Arguments(shcut, NULL); 164 ok(hr == E_POINTER, "got 0x%08x\n", hr); 165 166 hr = IWshShortcut_get_IconLocation(shcut, NULL); 167 ok(hr == E_POINTER, "got 0x%08x\n", hr); 168 169 IWshShortcut_Release(shcut); 170 IDispatch_Release(shortcut); 171 172 /* ExpandEnvironmentStrings */ 173 hr = IWshShell3_ExpandEnvironmentStrings(sh3, NULL, NULL); 174 ok(hr == E_POINTER, "got 0x%08x\n", hr); 175 176 str = SysAllocString(pathW); 177 hr = IWshShell3_ExpandEnvironmentStrings(sh3, str, NULL); 178 ok(hr == E_POINTER, "got 0x%08x\n", hr); 179 SysFreeString(str); 180 181 V_VT(&arg) = VT_BSTR; 182 V_BSTR(&arg) = SysAllocString(sysW); 183 hr = IWshShell3_get_Environment(sh3, &arg, &env); 184 ok(hr == S_OK, "got 0x%08x\n", hr); 185 VariantClear(&arg); 186 187 hr = IWshEnvironment_get_Item(env, NULL, NULL); 188 ok(hr == E_POINTER, "got 0x%08x\n", hr); 189 test_provideclassinfo(env, &IID_IWshEnvironment); 190 191 ret = (BSTR)0x1; 192 hr = IWshEnvironment_get_Item(env, NULL, &ret); 193 ok(hr == S_OK, "got 0x%08x\n", hr); 194 ok(ret && !*ret, "got %p\n", ret); 195 SysFreeString(ret); 196 197 /* invalid var name */ 198 str = SysAllocString(lnk1W); 199 hr = IWshEnvironment_get_Item(env, str, NULL); 200 ok(hr == E_POINTER, "got 0x%08x\n", hr); 201 202 ret = NULL; 203 hr = IWshEnvironment_get_Item(env, str, &ret); 204 ok(hr == S_OK, "got 0x%08x\n", hr); 205 ok(ret && *ret == 0, "got %s\n", wine_dbgstr_w(ret)); 206 SysFreeString(ret); 207 SysFreeString(str); 208 209 /* valid name */ 210 str = SysAllocString(path2W); 211 hr = IWshEnvironment_get_Item(env, str, &ret); 212 ok(hr == S_OK, "got 0x%08x\n", hr); 213 ok(ret && *ret != 0, "got %s\n", wine_dbgstr_w(ret)); 214 SysFreeString(ret); 215 SysFreeString(str); 216 217 IWshEnvironment_Release(env); 218 219 V_VT(&arg) = VT_I2; 220 V_I2(&arg) = 0; 221 V_VT(&arg2) = VT_ERROR; 222 V_ERROR(&arg2) = DISP_E_PARAMNOTFOUND; 223 224 str = SysAllocString(notepadW); 225 hr = IWshShell3_Run(sh3, str, &arg, &arg2, NULL); 226 ok(hr == E_POINTER, "got 0x%08x\n", hr); 227 228 retval = 10; 229 hr = IWshShell3_Run(sh3, str, NULL, &arg2, &retval); 230 ok(hr == E_POINTER, "got 0x%08x\n", hr); 231 ok(retval == 10, "got %u\n", retval); 232 233 retval = 10; 234 hr = IWshShell3_Run(sh3, str, &arg, NULL, &retval); 235 ok(hr == E_POINTER, "got 0x%08x\n", hr); 236 ok(retval == 10, "got %u\n", retval); 237 238 retval = 10; 239 V_VT(&arg2) = VT_ERROR; 240 V_ERROR(&arg2) = 0; 241 hr = IWshShell3_Run(sh3, str, &arg, &arg2, &retval); 242 ok(hr == DISP_E_TYPEMISMATCH, "got 0x%08x\n", hr); 243 ok(retval == 10, "got %u\n", retval); 244 245 SysFreeString(str); 246 247 /* current directory */ 248 if (0) /* crashes on native */ 249 hr = IWshShell3_get_CurrentDirectory(sh3, NULL); 250 251 str = NULL; 252 hr = IWshShell3_get_CurrentDirectory(sh3, &str); 253 ok(hr == S_OK, "got 0x%08x\n", hr); 254 ok(str && str[0] != 0, "got empty string\n"); 255 SysFreeString(str); 256 257 hr = IWshShell3_put_CurrentDirectory(sh3, NULL); 258 ok(hr == E_INVALIDARG || 259 broken(hr == HRESULT_FROM_WIN32(ERROR_NOACCESS)), "got 0x%08x\n", hr); 260 261 str = SysAllocString(emptyW); 262 hr = IWshShell3_put_CurrentDirectory(sh3, str); 263 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr); 264 SysFreeString(str); 265 266 str = SysAllocString(dummydirW); 267 hr = IWshShell3_put_CurrentDirectory(sh3, str); 268 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr); 269 SysFreeString(str); 270 271 /* Exec */ 272 hr = IWshShell3_Exec(sh3, NULL, NULL); 273 ok(hr == E_POINTER, "got 0x%08x\n", hr); 274 275 hr = IWshShell3_Exec(sh3, NULL, &shexec); 276 ok(hr == DISP_E_EXCEPTION, "got 0x%08x\n", hr); 277 278 str = SysAllocString(emptyW); 279 hr = IWshShell3_Exec(sh3, str, &shexec); 280 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr); 281 SysFreeString(str); 282 283 IWshCollection_Release(coll); 284 IDispatch_Release(disp); 285 IWshShell3_Release(sh3); 286 IUnknown_Release(shell); 287 } 288 289 /* delete key and all its subkeys */ 290 static DWORD delete_key(HKEY hkey) 291 { 292 char name[MAX_PATH]; 293 DWORD ret; 294 295 while (!(ret = RegEnumKeyA(hkey, 0, name, sizeof(name)))) { 296 HKEY tmp; 297 if (!(ret = RegOpenKeyExA(hkey, name, 0, KEY_ENUMERATE_SUB_KEYS, &tmp))) { 298 ret = delete_key(tmp); 299 RegCloseKey(tmp); 300 } 301 if (ret) break; 302 } 303 if (ret != ERROR_NO_MORE_ITEMS) return ret; 304 RegDeleteKeyA(hkey, ""); 305 return 0; 306 } 307 308 static void test_registry(void) 309 { 310 static const WCHAR keypathW[] = {'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R','\\', 311 'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\','T','e','s','t','\\',0}; 312 static const WCHAR regsz2W[] = {'r','e','g','s','z','2',0}; 313 static const WCHAR regszW[] = {'r','e','g','s','z',0}; 314 static const WCHAR regdwordW[] = {'r','e','g','d','w','o','r','d',0}; 315 static const WCHAR regbinaryW[] = {'r','e','g','b','i','n','a','r','y',0}; 316 static const WCHAR regmultiszW[] = {'r','e','g','m','u','l','t','i','s','z',0}; 317 318 static const WCHAR regsz1W[] = {'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R','\\', 319 'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\','T','e','s','t','\\','r','e','g','s','z','1',0}; 320 static const WCHAR foobarW[] = {'f','o','o','b','a','r',0}; 321 static const WCHAR fooW[] = {'f','o','o',0}; 322 static const WCHAR brokenW[] = {'H','K','E','Y','_','b','r','o','k','e','n','_','k','e','y',0}; 323 static const WCHAR broken2W[] = {'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R','a',0}; 324 WCHAR pathW[MAX_PATH]; 325 DWORD dwvalue, type; 326 VARIANT value, v; 327 IWshShell3 *sh3; 328 VARTYPE vartype; 329 LONG bound; 330 HRESULT hr; 331 BSTR name; 332 HKEY root; 333 LONG ret; 334 UINT dim; 335 336 hr = CoCreateInstance(&CLSID_WshShell, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, 337 &IID_IWshShell3, (void**)&sh3); 338 ok(hr == S_OK, "got 0x%08x\n", hr); 339 340 /* RegRead() */ 341 V_VT(&value) = VT_I2; 342 hr = IWshShell3_RegRead(sh3, NULL, &value); 343 ok(hr == E_POINTER, "got 0x%08x\n", hr); 344 ok(V_VT(&value) == VT_I2, "got %d\n", V_VT(&value)); 345 346 name = SysAllocString(brokenW); 347 hr = IWshShell3_RegRead(sh3, name, NULL); 348 ok(hr == E_POINTER, "got 0x%08x\n", hr); 349 V_VT(&value) = VT_I2; 350 hr = IWshShell3_RegRead(sh3, name, &value); 351 ok(hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "got 0x%08x\n", hr); 352 ok(V_VT(&value) == VT_I2, "got %d\n", V_VT(&value)); 353 SysFreeString(name); 354 355 name = SysAllocString(broken2W); 356 V_VT(&value) = VT_I2; 357 hr = IWshShell3_RegRead(sh3, name, &value); 358 ok(hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "got 0x%08x\n", hr); 359 ok(V_VT(&value) == VT_I2, "got %d\n", V_VT(&value)); 360 SysFreeString(name); 361 362 ret = RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test", &root); 363 ok(ret == 0, "got %d\n", ret); 364 365 ret = RegSetValueExA(root, "regsz", 0, REG_SZ, (const BYTE*)"foobar", 7); 366 ok(ret == 0, "got %d\n", ret); 367 368 ret = RegSetValueExA(root, "regsz2", 0, REG_SZ, (const BYTE*)"foobar\0f", 9); 369 ok(ret == 0, "got %d\n", ret); 370 371 ret = RegSetValueExA(root, "regmultisz", 0, REG_MULTI_SZ, (const BYTE*)"foo\0bar\0", 9); 372 ok(ret == 0, "got %d\n", ret); 373 374 dwvalue = 10; 375 ret = RegSetValueExA(root, "regdword", 0, REG_DWORD, (const BYTE*)&dwvalue, sizeof(dwvalue)); 376 ok(ret == 0, "got %d\n", ret); 377 378 dwvalue = 11; 379 ret = RegSetValueExA(root, "regbinary", 0, REG_BINARY, (const BYTE*)&dwvalue, sizeof(dwvalue)); 380 ok(ret == 0, "got %d\n", ret); 381 382 /* REG_SZ */ 383 lstrcpyW(pathW, keypathW); 384 lstrcatW(pathW, regszW); 385 name = SysAllocString(pathW); 386 VariantInit(&value); 387 hr = IWshShell3_RegRead(sh3, name, &value); 388 ok(hr == S_OK, "got 0x%08x\n", hr); 389 ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value)); 390 ok(!lstrcmpW(V_BSTR(&value), foobarW), "got %s\n", wine_dbgstr_w(V_BSTR(&value))); 391 VariantClear(&value); 392 SysFreeString(name); 393 394 /* REG_SZ with embedded NULL */ 395 lstrcpyW(pathW, keypathW); 396 lstrcatW(pathW, regsz2W); 397 name = SysAllocString(pathW); 398 VariantInit(&value); 399 hr = IWshShell3_RegRead(sh3, name, &value); 400 ok(hr == S_OK, "got 0x%08x\n", hr); 401 ok(V_VT(&value) == VT_BSTR, "got %d\n", V_VT(&value)); 402 ok(SysStringLen(V_BSTR(&value)) == 6, "len %d\n", SysStringLen(V_BSTR(&value))); 403 VariantClear(&value); 404 SysFreeString(name); 405 406 /* REG_DWORD */ 407 lstrcpyW(pathW, keypathW); 408 lstrcatW(pathW, regdwordW); 409 name = SysAllocString(pathW); 410 VariantInit(&value); 411 hr = IWshShell3_RegRead(sh3, name, &value); 412 ok(hr == S_OK, "got 0x%08x\n", hr); 413 ok(V_VT(&value) == VT_I4, "got %d\n", V_VT(&value)); 414 ok(V_I4(&value) == 10, "got %d\n", V_I4(&value)); 415 SysFreeString(name); 416 417 /* REG_BINARY */ 418 lstrcpyW(pathW, keypathW); 419 lstrcatW(pathW, regbinaryW); 420 name = SysAllocString(pathW); 421 VariantInit(&value); 422 hr = IWshShell3_RegRead(sh3, name, &value); 423 ok(hr == S_OK, "got 0x%08x\n", hr); 424 ok(V_VT(&value) == (VT_ARRAY|VT_VARIANT), "got 0x%x\n", V_VT(&value)); 425 dim = SafeArrayGetDim(V_ARRAY(&value)); 426 ok(dim == 1, "got %u\n", dim); 427 428 hr = SafeArrayGetLBound(V_ARRAY(&value), 1, &bound); 429 ok(hr == S_OK, "got 0x%08x\n", hr); 430 ok(bound == 0, "got %u\n", bound); 431 432 hr = SafeArrayGetUBound(V_ARRAY(&value), 1, &bound); 433 ok(hr == S_OK, "got 0x%08x\n", hr); 434 ok(bound == 3, "got %u\n", bound); 435 436 hr = SafeArrayGetVartype(V_ARRAY(&value), &vartype); 437 ok(hr == S_OK, "got 0x%08x\n", hr); 438 ok(vartype == VT_VARIANT, "got %d\n", vartype); 439 440 bound = 0; 441 hr = SafeArrayGetElement(V_ARRAY(&value), &bound, &v); 442 ok(hr == S_OK, "got 0x%08x\n", hr); 443 ok(V_VT(&v) == VT_UI1, "got %d\n", V_VT(&v)); 444 ok(V_UI1(&v) == 11, "got %u\n", V_UI1(&v)); 445 VariantClear(&v); 446 VariantClear(&value); 447 SysFreeString(name); 448 449 /* REG_MULTI_SZ */ 450 lstrcpyW(pathW, keypathW); 451 lstrcatW(pathW, regmultiszW); 452 name = SysAllocString(pathW); 453 VariantInit(&value); 454 hr = IWshShell3_RegRead(sh3, name, &value); 455 ok(hr == S_OK, "got 0x%08x\n", hr); 456 ok(V_VT(&value) == (VT_ARRAY|VT_VARIANT), "got 0x%x\n", V_VT(&value)); 457 SysFreeString(name); 458 459 dim = SafeArrayGetDim(V_ARRAY(&value)); 460 ok(dim == 1, "got %u\n", dim); 461 462 hr = SafeArrayGetLBound(V_ARRAY(&value), 1, &bound); 463 ok(hr == S_OK, "got 0x%08x\n", hr); 464 ok(bound == 0, "got %u\n", bound); 465 466 hr = SafeArrayGetUBound(V_ARRAY(&value), 1, &bound); 467 ok(hr == S_OK, "got 0x%08x\n", hr); 468 ok(bound == 1, "got %u\n", bound); 469 470 hr = SafeArrayGetVartype(V_ARRAY(&value), &vartype); 471 ok(hr == S_OK, "got 0x%08x\n", hr); 472 ok(vartype == VT_VARIANT, "got %d\n", vartype); 473 474 bound = 0; 475 hr = SafeArrayGetElement(V_ARRAY(&value), &bound, &v); 476 ok(hr == S_OK, "got 0x%08x\n", hr); 477 ok(V_VT(&v) == VT_BSTR, "got %d\n", V_VT(&v)); 478 ok(!lstrcmpW(V_BSTR(&v), fooW), "got %s\n", wine_dbgstr_w(V_BSTR(&v))); 479 VariantClear(&v); 480 VariantClear(&value); 481 482 name = SysAllocString(regsz1W); 483 V_VT(&value) = VT_I2; 484 hr = IWshShell3_RegRead(sh3, name, &value); 485 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr); 486 ok(V_VT(&value) == VT_I2, "got %d\n", V_VT(&value)); 487 VariantClear(&value); 488 SysFreeString(name); 489 490 delete_key(root); 491 492 /* RegWrite() */ 493 ret = RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test", &root); 494 ok(ret == 0, "got %d\n", ret); 495 496 hr = IWshShell3_RegWrite(sh3, NULL, NULL, NULL); 497 ok(hr == E_POINTER, "got 0x%08x\n", hr); 498 499 lstrcpyW(pathW, keypathW); 500 lstrcatW(pathW, regszW); 501 name = SysAllocString(pathW); 502 503 hr = IWshShell3_RegWrite(sh3, name, NULL, NULL); 504 ok(hr == E_POINTER, "got 0x%08x\n", hr); 505 506 VariantInit(&value); 507 hr = IWshShell3_RegWrite(sh3, name, &value, NULL); 508 ok(hr == E_POINTER, "got 0x%08x\n", hr); 509 510 hr = IWshShell3_RegWrite(sh3, name, &value, &value); 511 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 512 513 /* type is optional */ 514 V_VT(&v) = VT_ERROR; 515 V_ERROR(&v) = DISP_E_PARAMNOTFOUND; 516 hr = IWshShell3_RegWrite(sh3, name, &value, &v); 517 ok(hr == S_OK, "got 0x%08x\n", hr); 518 519 /* default type is REG_SZ */ 520 V_VT(&value) = VT_I4; 521 V_I4(&value) = 12; 522 hr = IWshShell3_RegWrite(sh3, name, &value, &v); 523 ok(hr == S_OK, "got 0x%08x\n", hr); 524 525 type = REG_NONE; 526 ret = RegQueryValueExA(root, "regsz", 0, &type, NULL, NULL); 527 ok(ret == ERROR_SUCCESS, "got %d\n", ret); 528 ok(type == REG_SZ, "got %d\n", type); 529 530 ret = RegDeleteValueA(root, "regsz"); 531 ok(ret == ERROR_SUCCESS, "got %d\n", ret); 532 V_VT(&value) = VT_BSTR; 533 V_BSTR(&value) = SysAllocString(regszW); 534 hr = IWshShell3_RegWrite(sh3, name, &value, &v); 535 ok(hr == S_OK, "got 0x%08x\n", hr); 536 VariantClear(&value); 537 538 type = REG_NONE; 539 ret = RegQueryValueExA(root, "regsz", 0, &type, NULL, NULL); 540 ok(ret == ERROR_SUCCESS, "got %d\n", ret); 541 ok(type == REG_SZ, "got %d\n", type); 542 543 ret = RegDeleteValueA(root, "regsz"); 544 ok(ret == ERROR_SUCCESS, "got %d\n", ret); 545 V_VT(&value) = VT_R4; 546 V_R4(&value) = 1.2; 547 hr = IWshShell3_RegWrite(sh3, name, &value, &v); 548 ok(hr == S_OK, "got 0x%08x\n", hr); 549 VariantClear(&value); 550 551 type = REG_NONE; 552 ret = RegQueryValueExA(root, "regsz", 0, &type, NULL, NULL); 553 ok(ret == ERROR_SUCCESS, "got %d\n", ret); 554 ok(type == REG_SZ, "got %d\n", type); 555 556 ret = RegDeleteValueA(root, "regsz"); 557 ok(ret == ERROR_SUCCESS, "got %d\n", ret); 558 V_VT(&value) = VT_R4; 559 V_R4(&value) = 1.2; 560 V_VT(&v) = VT_I2; 561 V_I2(&v) = 1; 562 hr = IWshShell3_RegWrite(sh3, name, &value, &v); 563 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 564 VariantClear(&value); 565 566 SysFreeString(name); 567 568 delete_key(root); 569 IWshShell3_Release(sh3); 570 } 571 572 static void test_popup(void) 573 { 574 static const WCHAR textW[] = {'T','e','x','t',0}; 575 VARIANT timeout, type, title, optional; 576 IWshShell *sh; 577 int button; 578 HRESULT hr; 579 BSTR text; 580 581 hr = CoCreateInstance(&CLSID_WshShell, NULL, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, 582 &IID_IWshShell, (void **)&sh); 583 ok(hr == S_OK, "Failed to create WshShell object, hr %#x.\n", hr); 584 585 button = 123; 586 text = SysAllocString(textW); 587 588 hr = IWshShell_Popup(sh, NULL, NULL, NULL, NULL, &button); 589 ok(hr == E_POINTER, "Unexpected retval %#x.\n", hr); 590 ok(button == 123, "Unexpected button id %d.\n", button); 591 592 hr = IWshShell_Popup(sh, text, NULL, NULL, NULL, &button); 593 ok(hr == E_POINTER, "Unexpected retval %#x.\n", hr); 594 ok(button == 123, "Unexpected button id %d.\n", button); 595 596 V_VT(&optional) = VT_ERROR; 597 V_ERROR(&optional) = DISP_E_PARAMNOTFOUND; 598 599 V_VT(&timeout) = VT_I2; 600 V_I2(&timeout) = 1; 601 602 V_VT(&type) = VT_I2; 603 V_I2(&type) = 1; 604 605 V_VT(&title) = VT_BSTR; 606 V_BSTR(&title) = NULL; 607 608 hr = IWshShell_Popup(sh, text, &timeout, &optional, &type, &button); 609 ok(hr == S_OK, "Unexpected retval %#x.\n", hr); 610 ok(button == -1, "Unexpected button id %d.\n", button); 611 612 hr = IWshShell_Popup(sh, text, &timeout, &title, &optional, &button); 613 ok(hr == S_OK, "Unexpected retval %#x.\n", hr); 614 ok(button == -1, "Unexpected button id %d.\n", button); 615 616 SysFreeString(text); 617 IWshShell_Release(sh); 618 } 619 620 START_TEST(wshom) 621 { 622 IUnknown *unk; 623 HRESULT hr; 624 625 CoInitialize(NULL); 626 627 hr = CoCreateInstance(&CLSID_WshShell, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, 628 &IID_IUnknown, (void**)&unk); 629 if (FAILED(hr)) { 630 win_skip("Could not create WshShell object: %08x\n", hr); 631 return; 632 } 633 IUnknown_Release(unk); 634 635 test_wshshell(); 636 test_registry(); 637 test_popup(); 638 639 CoUninitialize(); 640 } 641