2 * Unit tests for IShellDispatch
4 * Copyright 2010 Alexander Morozov for Etersoft
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define NONAMELESSUNION
23 #define NONAMELESSSTRUCT
29 #include "wine/test.h"
33 #define EXPECT_HR(hr,hr_exp) \
34 ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
36 static const WCHAR winetestW
[] = {'w','i','n','e','t','e','s','t',0};
38 static HRESULT (WINAPI
*pSHGetFolderPathW
)(HWND
, int, HANDLE
, DWORD
, LPWSTR
);
39 static HRESULT (WINAPI
*pSHGetNameFromIDList
)(PCIDLIST_ABSOLUTE
,SIGDN
,PWSTR
*);
40 static HRESULT (WINAPI
*pSHGetSpecialFolderLocation
)(HWND
, int, LPITEMIDLIST
*);
41 static DWORD (WINAPI
*pGetLongPathNameW
)(LPCWSTR
, LPWSTR
, DWORD
);
43 /* Updated Windows 7 has a new IShellDispatch6 in its typelib */
44 DEFINE_GUID(IID_IWin7ShellDispatch6
, 0x34936ba1, 0x67ad, 0x4c41, 0x99,0xb8, 0x8c,0x12,0xdf,0xf1,0xe9,0x74);
46 static void variant_set_string(VARIANT
*v
, const char *s
)
49 MultiByteToWideChar(CP_ACP
, 0, s
, -1, wstr
, MAX_PATH
);
51 V_BSTR(v
) = SysAllocString(wstr
);
54 static void init_function_pointers(void)
56 HMODULE hshell32
, hkernel32
;
58 hshell32
= GetModuleHandleA("shell32.dll");
59 hkernel32
= GetModuleHandleA("kernel32.dll");
60 pSHGetFolderPathW
= (void*)GetProcAddress(hshell32
, "SHGetFolderPathW");
61 pSHGetNameFromIDList
= (void*)GetProcAddress(hshell32
, "SHGetNameFromIDList");
62 pSHGetSpecialFolderLocation
= (void*)GetProcAddress(hshell32
,
63 "SHGetSpecialFolderLocation");
64 pGetLongPathNameW
= (void*)GetProcAddress(hkernel32
, "GetLongPathNameW");
67 static void test_namespace(void)
69 static const ShellSpecialFolderConstants special_folders
[] =
111 static const WCHAR backslashW
[] = {'\\',0};
112 static const WCHAR clsidW
[] = {
113 ':',':','{','6','4','5','F','F','0','4','0','-','5','0','8','1','-',
114 '1','0','1','B','-','9','F','0','8','-',
115 '0','0','A','A','0','0','2','F','9','5','4','E','}',0};
117 static WCHAR tempW
[MAX_PATH
], curW
[MAX_PATH
];
118 WCHAR
*long_pathW
= NULL
;
125 BSTR title
, item_path
;
128 r
= CoCreateInstance(&CLSID_Shell
, NULL
, CLSCTX_INPROC_SERVER
,
129 &IID_IShellDispatch
, (LPVOID
*)&sd
);
130 if (r
== REGDB_E_CLASSNOTREG
) /* NT4 */
132 win_skip("skipping IShellDispatch tests\n");
135 ok(SUCCEEDED(r
), "CoCreateInstance failed: %08x\n", r
);
140 folder
= (void*)0xdeadbeef;
141 r
= IShellDispatch_NameSpace(sd
, var
, &folder
);
142 ok(r
== S_FALSE
, "expected S_FALSE, got %08x\n", r
);
143 ok(folder
== NULL
, "expected NULL, got %p\n", folder
);
145 /* test valid folder ids */
146 for (i
= 0; i
< sizeof(special_folders
)/sizeof(special_folders
[0]); i
++)
149 V_I4(&var
) = special_folders
[i
];
150 folder
= (void*)0xdeadbeef;
151 r
= IShellDispatch_NameSpace(sd
, var
, &folder
);
152 if (special_folders
[i
] == ssfALTSTARTUP
|| special_folders
[i
] == ssfCOMMONALTSTARTUP
)
153 ok(r
== S_OK
|| broken(r
== S_FALSE
) /* winxp */, "Failed to get folder for index %#x, got %08x\n", special_folders
[i
], r
);
155 ok(r
== S_OK
, "Failed to get folder for index %#x, got %08x\n", special_folders
[i
], r
);
157 Folder_Release(folder
);
162 folder
= (void*)0xdeadbeef;
163 r
= IShellDispatch_NameSpace(sd
, var
, &folder
);
165 ok(r
== S_FALSE
, "expected S_FALSE, got %08x\n", r
);
166 ok(folder
== NULL
, "got %p\n", folder
);
168 Folder_Release(folder
);
171 V_I4(&var
) = ssfPROGRAMFILES
;
172 r
= IShellDispatch_NameSpace(sd
, var
, &folder
);
174 broken(r
== S_FALSE
), /* NT4 */
175 "IShellDispatch::NameSpace failed: %08x\n", r
);
178 static WCHAR path
[MAX_PATH
];
180 if (pSHGetFolderPathW
)
182 r
= pSHGetFolderPathW(NULL
, CSIDL_PROGRAM_FILES
, NULL
,
183 SHGFP_TYPE_CURRENT
, path
);
184 ok(r
== S_OK
, "SHGetFolderPath failed: %08x\n", r
);
186 r
= Folder_get_Title(folder
, &title
);
188 ok(r
== S_OK
, "Folder::get_Title failed: %08x\n", r
);
191 /* On Win2000-2003 title is equal to program files directory name in
192 HKLM\Software\Microsoft\Windows\CurrentVersion\ProgramFilesDir.
193 On newer Windows it seems constant and is not changed
194 if the program files directory name is changed */
195 if (pSHGetSpecialFolderLocation
&& pSHGetNameFromIDList
)
200 r
= pSHGetSpecialFolderLocation(NULL
, CSIDL_PROGRAM_FILES
, &pidl
);
201 ok(r
== S_OK
, "SHGetSpecialFolderLocation failed: %08x\n", r
);
202 r
= pSHGetNameFromIDList(pidl
, SIGDN_NORMALDISPLAY
, &name
);
203 ok(r
== S_OK
, "SHGetNameFromIDList failed: %08x\n", r
);
205 ok(!lstrcmpW(title
, name
), "expected %s, got %s\n",
206 wine_dbgstr_w(name
), wine_dbgstr_w(title
));
210 else if (pSHGetFolderPathW
)
214 p
= path
+ lstrlenW(path
);
215 while (path
< p
&& *(p
- 1) != '\\')
217 ok(!lstrcmpiW(title
, p
), "expected %s, got %s\n",
218 wine_dbgstr_w(p
), wine_dbgstr_w(title
));
220 else skip("skipping Folder::get_Title test\n");
221 SysFreeString(title
);
223 r
= Folder_QueryInterface(folder
, &IID_Folder2
, (LPVOID
*)&folder2
);
224 ok(r
== S_OK
, "Folder::QueryInterface failed: %08x\n", r
);
227 r
= Folder2_get_Self(folder2
, &item
);
228 ok(r
== S_OK
, "Folder::get_Self failed: %08x\n", r
);
231 r
= FolderItem_get_Path(item
, &item_path
);
232 ok(r
== S_OK
, "FolderItem::get_Path failed: %08x\n", r
);
233 if (pSHGetFolderPathW
)
234 ok(!lstrcmpiW(item_path
, path
), "expected %s, got %s\n",
235 wine_dbgstr_w(path
), wine_dbgstr_w(item_path
));
236 SysFreeString(item_path
);
237 FolderItem_Release(item
);
239 Folder2_Release(folder2
);
241 Folder_Release(folder
);
245 V_I4(&var
) = ssfBITBUCKET
;
246 r
= IShellDispatch_NameSpace(sd
, var
, &folder
);
248 broken(r
== S_FALSE
), /* NT4 */
249 "IShellDispatch::NameSpace failed: %08x\n", r
);
252 r
= Folder_QueryInterface(folder
, &IID_Folder2
, (LPVOID
*)&folder2
);
254 broken(r
== E_NOINTERFACE
), /* NT4 */
255 "Folder::QueryInterface failed: %08x\n", r
);
258 r
= Folder2_get_Self(folder2
, &item
);
259 ok(r
== S_OK
, "Folder::get_Self failed: %08x\n", r
);
262 r
= FolderItem_get_Path(item
, &item_path
);
264 ok(r
== S_OK
, "FolderItem::get_Path failed: %08x\n", r
);
266 ok(!lstrcmpW(item_path
, clsidW
), "expected %s, got %s\n",
267 wine_dbgstr_w(clsidW
), wine_dbgstr_w(item_path
));
268 SysFreeString(item_path
);
269 FolderItem_Release(item
);
271 Folder2_Release(folder2
);
273 Folder_Release(folder
);
276 GetTempPathW(MAX_PATH
, tempW
);
277 GetCurrentDirectoryW(MAX_PATH
, curW
);
278 SetCurrentDirectoryW(tempW
);
279 CreateDirectoryW(winetestW
, NULL
);
280 V_VT(&var
) = VT_BSTR
;
281 V_BSTR(&var
) = SysAllocString(winetestW
);
282 r
= IShellDispatch_NameSpace(sd
, var
, &folder
);
283 ok(r
== S_FALSE
, "expected S_FALSE, got %08x\n", r
);
284 SysFreeString(V_BSTR(&var
));
286 GetFullPathNameW(winetestW
, MAX_PATH
, tempW
, NULL
);
287 if (pGetLongPathNameW
)
289 len
= pGetLongPathNameW(tempW
, NULL
, 0);
290 long_pathW
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
292 pGetLongPathNameW(tempW
, long_pathW
, len
);
294 V_VT(&var
) = VT_BSTR
;
295 V_BSTR(&var
) = SysAllocString(tempW
);
296 r
= IShellDispatch_NameSpace(sd
, var
, &folder
);
297 ok(r
== S_OK
, "IShellDispatch::NameSpace failed: %08x\n", r
);
300 r
= Folder_get_Title(folder
, &title
);
301 ok(r
== S_OK
, "Folder::get_Title failed: %08x\n", r
);
304 ok(!lstrcmpW(title
, winetestW
), "bad title: %s\n",
305 wine_dbgstr_w(title
));
306 SysFreeString(title
);
308 r
= Folder_QueryInterface(folder
, &IID_Folder2
, (LPVOID
*)&folder2
);
310 broken(r
== E_NOINTERFACE
), /* NT4 */
311 "Folder::QueryInterface failed: %08x\n", r
);
314 r
= Folder2_get_Self(folder2
, &item
);
315 ok(r
== S_OK
, "Folder::get_Self failed: %08x\n", r
);
318 r
= FolderItem_get_Path(item
, &item_path
);
319 ok(r
== S_OK
, "FolderItem::get_Path failed: %08x\n", r
);
321 ok(!lstrcmpW(item_path
, long_pathW
),
322 "expected %s, got %s\n", wine_dbgstr_w(long_pathW
),
323 wine_dbgstr_w(item_path
));
324 SysFreeString(item_path
);
325 FolderItem_Release(item
);
327 Folder2_Release(folder2
);
329 Folder_Release(folder
);
331 SysFreeString(V_BSTR(&var
));
333 len
= lstrlenW(tempW
);
334 if (len
< MAX_PATH
- 1)
336 lstrcatW(tempW
, backslashW
);
337 V_VT(&var
) = VT_BSTR
;
338 V_BSTR(&var
) = SysAllocString(tempW
);
339 r
= IShellDispatch_NameSpace(sd
, var
, &folder
);
340 ok(r
== S_OK
, "IShellDispatch::NameSpace failed: %08x\n", r
);
343 r
= Folder_get_Title(folder
, &title
);
344 ok(r
== S_OK
, "Folder::get_Title failed: %08x\n", r
);
347 ok(!lstrcmpW(title
, winetestW
), "bad title: %s\n",
348 wine_dbgstr_w(title
));
349 SysFreeString(title
);
351 r
= Folder_QueryInterface(folder
, &IID_Folder2
, (LPVOID
*)&folder2
);
353 broken(r
== E_NOINTERFACE
), /* NT4 */
354 "Folder::QueryInterface failed: %08x\n", r
);
357 r
= Folder2_get_Self(folder2
, &item
);
358 ok(r
== S_OK
, "Folder::get_Self failed: %08x\n", r
);
361 r
= FolderItem_get_Path(item
, &item_path
);
362 ok(r
== S_OK
, "FolderItem::get_Path failed: %08x\n", r
);
364 ok(!lstrcmpW(item_path
, long_pathW
),
365 "expected %s, got %s\n", wine_dbgstr_w(long_pathW
),
366 wine_dbgstr_w(item_path
));
367 SysFreeString(item_path
);
368 FolderItem_Release(item
);
370 Folder2_Release(folder2
);
372 Folder_Release(folder
);
374 SysFreeString(V_BSTR(&var
));
377 HeapFree(GetProcessHeap(), 0, long_pathW
);
378 RemoveDirectoryW(winetestW
);
379 SetCurrentDirectoryW(curW
);
380 IShellDispatch_Release(sd
);
383 static void test_items(void)
397 { "00-Myfolder", DIRECTORY
},
398 { "01-empty.bin", EMPTY_FILE
},
400 WCHAR path
[MAX_PATH
], cur_dir
[MAX_PATH
], orig_dir
[MAX_PATH
];
402 IShellDispatch
*sd
= NULL
;
403 Folder
*folder
= NULL
;
404 FolderItems
*items
= NULL
;
405 FolderItems2
*items2
= NULL
;
406 FolderItems3
*items3
= NULL
;
407 FolderItem
*item
= (FolderItem
*)0xdeadbeef, *item2
;
408 IDispatch
*disp
= NULL
;
409 IUnknown
*unk
= NULL
;
410 FolderItemVerbs
*verbs
= (FolderItemVerbs
*)0xdeadbeef;
411 VARIANT var
, int_index
, str_index
, str_index2
;
418 r
= CoCreateInstance(&CLSID_Shell
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IShellDispatch
, (void**)&sd
);
419 ok(SUCCEEDED(r
), "CoCreateInstance failed: %08x\n", r
);
420 ok(!!sd
, "sd is null\n");
422 /* create and enter a temporary directory and a folder object for it */
423 GetTempPathW(MAX_PATH
, path
);
424 GetCurrentDirectoryW(MAX_PATH
, orig_dir
);
425 SetCurrentDirectoryW(path
);
426 ok(CreateDirectoryW(winetestW
, NULL
), "CreateDirectory failed: %08x\n", GetLastError());
427 GetFullPathNameW(winetestW
, MAX_PATH
, path
, NULL
);
428 V_VT(&var
) = VT_BSTR
;
429 V_BSTR(&var
) = SysAllocString(path
);
430 r
= IShellDispatch_NameSpace(sd
, var
, &folder
);
431 ok(r
== S_OK
, "IShellDispatch::NameSpace failed: %08x\n", r
);
432 ok(!!folder
, "folder is null\n");
434 IShellDispatch_Release(sd
);
435 SetCurrentDirectoryW(winetestW
);
436 GetCurrentDirectoryW(MAX_PATH
, path
);
437 GetLongPathNameW(path
, cur_dir
, MAX_PATH
);
439 r
= Folder_Items(folder
, &items
);
440 ok(r
== S_OK
, "Folder::Items failed: %08x\n", r
);
441 ok(!!items
, "items is null\n");
443 if (0) /* crashes on all versions of Windows */
444 r
= FolderItems_get_Count(items
, NULL
);
446 r
= FolderItems_get_Count(items
, &count
);
447 ok(r
== S_OK
, "FolderItems::get_Count failed: %08x\n", r
);
448 ok(!count
, "expected 0 files, got %d\n", count
);
453 if (0) /* crashes on all versions of Windows */
454 r
= FolderItems_Item(items
, var
, NULL
);
456 r
= FolderItems_Item(items
, var
, &item
);
457 ok(r
== S_FALSE
, "expected S_FALSE, got %08x\n", r
);
458 ok(!item
, "item is not null\n");
460 /* create test files */
461 for (i
= 0; i
< sizeof(file_defs
)/sizeof(file_defs
[0]); i
++)
463 switch (file_defs
[i
].type
)
466 r
= CreateDirectoryA(file_defs
[i
].name
, NULL
);
467 ok(r
, "CreateDirectory failed: %08x\n", GetLastError());
468 PathCombineA(cstr
, file_defs
[i
].name
, "foo.txt");
469 file
= CreateFileA(cstr
, 0, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
470 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFile failed: %08x\n", GetLastError());
475 file
= CreateFileA(file_defs
[i
].name
, 0, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
476 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFile failed: %08x\n", GetLastError());
482 /* test that get_Count is not aware of the newly created files */
484 r
= FolderItems_get_Count(items
, &count
);
485 ok(r
== S_OK
, "FolderItems::get_Count failed: %08x\n", r
);
486 ok(!count
, "expected 0 files, got %d\n", count
);
488 /* test that the newly created files CAN be retrieved by string index */
489 variant_set_string(&var
, file_defs
[0].name
);
491 r
= FolderItems_Item(items
, var
, &item
);
492 ok(r
== S_OK
, "FolderItems::Item failed: %08x\n", r
);
493 ok(!!item
, "item is null\n");
494 if (item
) FolderItem_Release(item
);
497 /* recreate the folder object */
498 FolderItems_Release(items
);
500 r
= Folder_Items(folder
, &items
);
501 ok(r
== S_OK
, "Folder::Items failed: %08x\n", r
);
502 ok(!!items
, "items is null\n");
503 r
= FolderItems_QueryInterface(items
, &IID_FolderItems2
, (void**)&items2
);
504 ok(r
== S_OK
|| broken(r
== E_NOINTERFACE
) /* xp and later */, "FolderItems::QueryInterface failed: %08x\n", r
);
505 if (r
== S_OK
) ok(!!items2
, "items2 is null\n");
506 r
= FolderItems_QueryInterface(items
, &IID_FolderItems3
, (void**)&items3
);
507 ok(r
== S_OK
, "FolderItems::QueryInterface failed: %08x\n", r
);
508 ok(!!items3
, "items3 is null\n");
509 Folder_Release(folder
);
512 r
= FolderItems_get_Count(items
, &count
);
513 ok(r
== S_OK
, "FolderItems::get_Count failed: %08x\n", r
);
514 ok(count
== sizeof(file_defs
)/sizeof(file_defs
[0]),
515 "expected %d files, got %d\n", (LONG
)(sizeof(file_defs
)/sizeof(file_defs
[0])), count
);
517 V_VT(&var
) = VT_EMPTY
;
518 item
= (FolderItem
*)0xdeadbeef;
519 r
= FolderItems_Item(items
, var
, &item
);
520 ok(r
== E_NOTIMPL
, "expected E_NOTIMPL, got %08x\n", r
);
521 ok(!item
, "item is not null\n");
526 r
= FolderItems_Item(items
, var
, &item
);
527 ok(r
== S_OK
, "FolderItems::Item failed: %08x\n", r
);
528 ok(!!item
, "item is null\n");
529 if (item
) FolderItem_Release(item
);
534 r
= FolderItems_Item(items
, var
, &item
);
535 ok(r
== S_OK
, "FolderItems::Item failed: %08x\n", r
);
536 ok(!!item
, "item is null\n");
537 if (item
) FolderItem_Release(item
);
540 item
= (FolderItem
*)0xdeadbeef;
541 r
= FolderItems_Item(items
, var
, &item
);
542 ok(r
== S_FALSE
, "expected S_FALSE, got %08x\n", r
);
543 ok(!item
, "item is not null\n");
545 V_VT(&var
) = VT_ERROR
;
548 r
= FolderItems_Item(items
, var
, &item
);
549 ok(r
== S_OK
, "expected S_OK, got %08x\n", r
);
550 ok(!!item
, "item is null\n");
554 r
= FolderItem_get_Path(item
, &bstr
);
555 ok(r
== S_OK
, "FolderItem::get_Path failed: %08x\n", r
);
556 ok(!lstrcmpW(bstr
, cur_dir
),
557 "expected %s, got %s\n", wine_dbgstr_w(cur_dir
), wine_dbgstr_w(bstr
));
559 FolderItem_Release(item
);
562 V_VT(&int_index
) = VT_I4
;
564 /* test the folder item corresponding to each file */
565 for (i
= 0; i
< sizeof(file_defs
)/sizeof(file_defs
[0]); i
++)
567 V_I4(&int_index
) = i
;
568 variant_set_string(&str_index
, file_defs
[i
].name
);
571 r
= FolderItems_Item(items
, int_index
, &item
);
572 ok(r
== S_OK
, "file_defs[%d]: FolderItems::Item failed: %08x\n", i
, r
);
573 ok(!!item
, "file_defs[%d]: item is null\n", i
);
576 r
= FolderItems_Item(items
, int_index
, &item2
);
577 ok(r
== S_OK
, "file_defs[%d]: FolderItems::Item failed: %08x\n", i
, r
);
578 ok(item2
!= item
, "file_defs[%d]: item and item2 are the same\n", i
);
579 FolderItem_Release(item2
);
582 r
= FolderItem_get_Path(item
, &bstr
);
583 ok(r
== S_OK
, "file_defs[%d]: FolderItem::get_Path failed: %08x\n", i
, r
);
584 PathCombineW(path
, cur_dir
, V_BSTR(&str_index
));
585 ok(!lstrcmpW(bstr
, path
),
586 "file_defs[%d]: expected %s, got %s\n", i
, wine_dbgstr_w(path
), wine_dbgstr_w(bstr
));
590 r
= FolderItems_Item(items
, str_index
, &item
);
591 ok(r
== S_OK
, "file_defs[%d]: FolderItems::Item failed: %08x\n", i
, r
);
592 ok(!!item
, "file_defs[%d]: item is null\n", i
);
595 r
= FolderItem_get_Path(item
, &bstr
);
596 ok(r
== S_OK
, "file_defs[%d]: FolderItem::get_Path failed: %08x\n", i
, r
);
597 PathCombineW(path
, cur_dir
, V_BSTR(&str_index
));
598 ok(!lstrcmpW(bstr
, path
),
599 "file_defs[%d]: expected %s, got %s\n", i
, wine_dbgstr_w(path
), wine_dbgstr_w(bstr
));
602 FolderItem_Release(item
);
604 if (file_defs
[i
].type
== DIRECTORY
)
606 /* test that getting an item object for a file in a subdirectory succeeds */
607 PathCombineA(cstr
, file_defs
[i
].name
, "foo.txt");
608 variant_set_string(&str_index2
, cstr
);
610 r
= FolderItems_Item(items
, str_index2
, &item2
);
611 ok(r
== S_OK
, "file_defs[%d]: FolderItems::Item failed: %08x\n", i
, r
);
612 ok(!!item2
, "file_defs[%d]: item is null\n", i
);
613 if (item2
) FolderItem_Release(item2
);
614 VariantClear(&str_index2
);
616 /* delete the file in the subdirectory */
617 ok(DeleteFileA(cstr
), "file_defs[%d]: DeleteFile failed: %08x\n", i
, GetLastError());
619 /* test that getting an item object via a relative path fails */
620 strcpy(cstr
, file_defs
[i
].name
);
621 strcat(cstr
, "\\..\\");
622 strcat(cstr
, file_defs
[i
].name
);
623 variant_set_string(&str_index2
, cstr
);
624 item2
= (FolderItem
*)0xdeadbeef;
625 r
= FolderItems_Item(items
, str_index2
, &item2
);
626 ok(r
== S_FALSE
, "file_defs[%d]: expected S_FALSE, got %08x\n", i
, r
);
627 ok(!item2
, "file_defs[%d]: item is not null\n", i
);
628 VariantClear(&str_index2
);
630 /* remove the directory */
631 ok(RemoveDirectoryA(file_defs
[i
].name
), "file_defs[%d]: RemoveDirectory failed: %08x\n", i
, GetLastError());
635 ok(DeleteFileA(file_defs
[i
].name
), "file_defs[%d]: DeleteFile failed: %08x\n", i
, GetLastError());
638 /* test that the folder item is still accessible by integer index */
640 r
= FolderItems_Item(items
, int_index
, &item
);
641 ok(r
== S_OK
, "file_defs[%d]: FolderItems::Item failed: %08x\n", i
, r
);
642 ok(!!item
, "file_defs[%d]: item is null\n", i
);
645 r
= FolderItem_get_Path(item
, &bstr
);
646 ok(r
== S_OK
, "file_defs[%d]: FolderItem::get_Path failed: %08x\n", i
, r
);
647 PathCombineW(path
, cur_dir
, V_BSTR(&str_index
));
648 ok(!lstrcmpW(bstr
, path
),
649 "file_defs[%d]: expected %s, got %s\n", i
, wine_dbgstr_w(path
), wine_dbgstr_w(bstr
));
652 FolderItem_Release(item
);
654 /* test that the folder item is no longer accessible by string index */
655 item
= (FolderItem
*)0xdeadbeef;
656 r
= FolderItems_Item(items
, str_index
, &item
);
657 ok(r
== S_FALSE
, "file_defs[%d]: expected S_FALSE, got %08x\n", i
, r
);
658 ok(!item
, "file_defs[%d]: item is not null\n", i
);
660 VariantClear(&str_index
);
663 /* test that there are only as many folder items as there were files */
664 V_I4(&int_index
) = sizeof(file_defs
)/sizeof(file_defs
[0]);
665 item
= (FolderItem
*)0xdeadbeef;
666 r
= FolderItems_Item(items
, int_index
, &item
);
667 ok(r
== S_FALSE
, "expected S_FALSE, got %08x\n", r
);
668 ok(!item
, "item is not null\n");
670 if (0) /* crashes on xp */
672 r
= FolderItems_get_Application(items
, NULL
);
673 ok(r
== E_INVALIDARG
, "expected E_INVALIDARG, got %08x\n", r
);
676 r
= FolderItems_get_Application(items
, &disp
);
678 ok(r
== S_OK
, "FolderItems::get_Application failed: %08x\n", r
);
680 ok(!!disp
, "disp is null\n");
681 if (disp
) IDispatch_Release(disp
);
683 if (0) /* crashes on xp */
685 r
= FolderItems_get_Parent(items
, NULL
);
686 ok(r
== E_NOTIMPL
, "expected E_NOTIMPL, got %08x\n", r
);
689 disp
= (IDispatch
*)0xdeadbeef;
690 r
= FolderItems_get_Parent(items
, &disp
);
691 ok(r
== E_NOTIMPL
, "expected E_NOTIMPL, got %08x\n", r
);
692 ok(!disp
, "disp is not null\n");
694 if (0) /* crashes on xp */
696 r
= FolderItems__NewEnum(items
, NULL
);
697 ok(r
== E_INVALIDARG
, "expected E_INVALIDARG, got %08x\n", r
);
700 r
= FolderItems__NewEnum(items
, &unk
);
702 ok(r
== S_OK
, "FolderItems::_NewEnum failed: %08x\n", r
);
704 ok(!!unk
, "unk is null\n");
705 if (unk
) IUnknown_Release(unk
);
709 r
= FolderItems3_Filter(items3
, 0, NULL
);
711 ok(r
== S_OK
, "expected S_OK, got %08x\n", r
);
713 if (0) /* crashes on xp */
715 r
= FolderItems3_get_Verbs(items3
, NULL
);
716 ok(r
== E_INVALIDARG
, "expected E_INVALIDARG, got %08x\n", r
);
719 r
= FolderItems3_get_Verbs(items3
, &verbs
);
721 ok(r
== S_FALSE
, "expected S_FALSE, got %08x\n", r
);
722 ok(!verbs
, "verbs is not null\n");
725 /* remove the temporary directory and restore the original working directory */
726 GetTempPathW(MAX_PATH
, path
);
727 SetCurrentDirectoryW(path
);
728 ok(RemoveDirectoryW(winetestW
), "RemoveDirectory failed: %08x\n", GetLastError());
729 SetCurrentDirectoryW(orig_dir
);
731 /* test that everything stops working after the directory has been removed */
733 r
= FolderItems_get_Count(items
, &count
);
734 ok(r
== S_OK
, "FolderItems::get_Count failed: %08x\n", r
);
735 ok(!count
, "expected 0 files, got %d\n", count
);
738 V_I4(&int_index
) = 0;
739 item
= (FolderItem
*)0xdeadbeef;
740 r
= FolderItems_Item(items
, int_index
, &item
);
741 ok(r
== S_FALSE
, "expected S_FALSE, got %08x\n", r
);
742 ok(!item
, "item is not null\n");
744 variant_set_string(&str_index
, file_defs
[0].name
);
745 item
= (FolderItem
*)0xdeadbeef;
746 r
= FolderItems_Item(items
, str_index
, &item
);
747 ok(r
== S_FALSE
, "expected S_FALSE, got %08x\n", r
);
748 ok(!item
, "item is not null\n");
749 VariantClear(&str_index
);
751 FolderItems_Release(items
);
752 if (items2
) FolderItems2_Release(items2
);
753 if (items3
) FolderItems3_Release(items3
);
756 static void test_service(void)
758 static const WCHAR spooler
[] = {'S','p','o','o','l','e','r',0};
759 static const WCHAR dummyW
[] = {'d','u','m','m','y',0};
760 SERVICE_STATUS_PROCESS status
;
761 SC_HANDLE scm
, service
;
768 hr
= CoCreateInstance(&CLSID_Shell
, NULL
, CLSCTX_INPROC_SERVER
,
769 &IID_IShellDispatch2
, (void**)&sd
);
772 win_skip("IShellDispatch2 not supported\n");
778 hr
= IShellDispatch2_IsServiceRunning(sd
, NULL
, &v
);
779 ok(V_VT(&v
) == VT_BOOL
, "got %d\n", V_VT(&v
));
780 ok(V_BOOL(&v
) == VARIANT_FALSE
, "got %d\n", V_BOOL(&v
));
783 scm
= OpenSCManagerW(NULL
, NULL
, SC_MANAGER_CONNECT
);
784 service
= OpenServiceW(scm
, spooler
, SERVICE_QUERY_STATUS
);
785 QueryServiceStatusEx(service
, SC_STATUS_PROCESS_INFO
, (BYTE
*)&status
, sizeof(SERVICE_STATUS_PROCESS
), &dummy
);
786 CloseServiceHandle(service
);
787 CloseServiceHandle(scm
);
789 /* service should exist */
790 name
= SysAllocString(spooler
);
792 hr
= IShellDispatch2_IsServiceRunning(sd
, name
, &v
);
794 ok(V_VT(&v
) == VT_BOOL
, "got %d\n", V_VT(&v
));
795 if (status
.dwCurrentState
== SERVICE_RUNNING
)
796 ok(V_BOOL(&v
) == VARIANT_TRUE
, "got %d\n", V_BOOL(&v
));
798 ok(V_BOOL(&v
) == VARIANT_FALSE
, "got %d\n", V_BOOL(&v
));
801 /* service doesn't exist */
802 name
= SysAllocString(dummyW
);
804 hr
= IShellDispatch2_IsServiceRunning(sd
, name
, &v
);
806 ok(V_VT(&v
) == VT_BOOL
, "got %d\n", V_VT(&v
));
807 ok(V_BOOL(&v
) == VARIANT_FALSE
, "got %d\n", V_BOOL(&v
));
810 IShellDispatch2_Release(sd
);
813 static void test_dispatch_typeinfo(IDispatch
*disp
, REFIID
*riid
)
821 hr
= IDispatch_GetTypeInfoCount(disp
, &count
);
822 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
823 ok(count
== 1, "got %u\n", count
);
825 hr
= IDispatch_GetTypeInfo(disp
, 0, LOCALE_SYSTEM_DEFAULT
, &typeinfo
);
826 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
828 hr
= ITypeInfo_GetTypeAttr(typeinfo
, &typeattr
);
829 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
830 while (!IsEqualGUID(*riid
, &IID_NULL
)) {
831 if (IsEqualGUID(&typeattr
->guid
, *riid
))
835 ok(IsEqualGUID(&typeattr
->guid
, *riid
), "unexpected type guid %s\n", wine_dbgstr_guid(&typeattr
->guid
));
837 ITypeInfo_ReleaseTypeAttr(typeinfo
, typeattr
);
838 ITypeInfo_Release(typeinfo
);
841 static void test_ShellFolderViewDual(void)
843 static const IID
*shelldisp_riids
[] = {
844 &IID_IShellDispatch6
,
845 &IID_IShellDispatch5
,
846 &IID_IShellDispatch4
,
847 &IID_IShellDispatch2
,
848 &IID_IWin7ShellDispatch6
,
851 IShellFolderViewDual
*viewdual
;
852 IShellFolder
*desktop
, *tmpdir
;
853 IShellView
*view
, *view2
;
854 IDispatch
*disp
, *disp2
;
855 WCHAR pathW
[MAX_PATH
];
859 /* IShellFolderViewDual is not an IShellView extension */
860 hr
= SHGetDesktopFolder(&desktop
);
861 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
863 hr
= IShellFolder_CreateViewObject(desktop
, NULL
, &IID_IShellView
, (void**)&view
);
864 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
866 hr
= IShellView_QueryInterface(view
, &IID_IShellFolderViewDual
, (void**)&viewdual
);
867 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
869 hr
= IShellView_GetItemObject(view
, SVGIO_BACKGROUND
, &IID_IDispatch
, (void**)&disp
);
870 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
872 hr
= IShellView_GetItemObject(view
, SVGIO_BACKGROUND
, &IID_IDispatch
, (void**)&disp2
);
873 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
874 ok(disp2
== disp
, "got %p, %p\n", disp2
, disp
);
875 IDispatch_Release(disp2
);
877 hr
= IDispatch_QueryInterface(disp
, &IID_IShellFolderViewDual
, (void**)&viewdual
);
878 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
879 ok(disp
== (IDispatch
*)viewdual
, "got %p, expected %p\n", viewdual
, disp
);
881 hr
= IShellFolderViewDual_QueryInterface(viewdual
, &IID_IShellView
, (void**)&view2
);
882 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
884 /* get_Application() */
886 if (0) /* crashes on pre-vista */ {
887 hr
= IShellFolderViewDual_get_Application(viewdual
, NULL
);
888 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
890 hr
= IShellFolderViewDual_get_Application(viewdual
, &disp2
);
891 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
892 ok(disp2
!= (IDispatch
*)viewdual
, "got %p, %p\n", disp2
, viewdual
);
893 test_dispatch_typeinfo(disp2
, shelldisp_riids
);
894 IDispatch_Release(disp2
);
896 IShellFolderViewDual_Release(viewdual
);
897 IDispatch_Release(disp
);
899 disp
= (void*)0xdeadbeef;
900 hr
= IShellView_GetItemObject(view
, SVGIO_BACKGROUND
, &IID_IShellFolderViewDual
, (void**)&disp
);
901 ok(hr
== E_NOINTERFACE
|| broken(hr
== E_NOTIMPL
) /* win2k */, "got 0x%08x\n", hr
);
902 ok(disp
== NULL
, "got %p\n", disp
);
903 IShellView_Release(view
);
905 /* Try with some other folder, that's not a desktop */
906 GetTempPathW(sizeof(pathW
)/sizeof(pathW
[0]), pathW
);
907 hr
= IShellFolder_ParseDisplayName(desktop
, NULL
, NULL
, pathW
, NULL
, &pidl
, NULL
);
908 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
910 hr
= IShellFolder_BindToObject(desktop
, pidl
, NULL
, &IID_IShellFolder
, (void**)&tmpdir
);
911 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
914 hr
= IShellFolder_CreateViewObject(desktop
, NULL
, &IID_IShellView
, (void**)&view
);
915 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
917 hr
= IShellView_QueryInterface(view
, &IID_IShellFolderViewDual
, (void**)&viewdual
);
918 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
920 hr
= IShellView_GetItemObject(view
, SVGIO_BACKGROUND
, &IID_IDispatch
, (void**)&disp
);
921 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
922 IDispatch_Release(disp
);
923 IShellView_Release(view
);
925 IShellFolder_Release(tmpdir
);
926 IShellFolder_Release(desktop
);
929 static void test_ShellWindows(void)
931 IShellWindows
*shellwindows
;
932 LONG cookie
, cookie2
, ret
;
938 hr
= CoCreateInstance(&CLSID_ShellWindows
, NULL
, CLSCTX_LOCAL_SERVER
,
939 &IID_IShellWindows
, (void**)&shellwindows
);
940 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
941 /* TODO: remove when explorer startup with clean prefix is fixed */
945 if (0) /* NULL out argument - currently crashes on Wine */ {
946 hr
= IShellWindows_Register(shellwindows
, NULL
, 0, SWC_EXPLORER
, NULL
);
947 ok(hr
== HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER
), "got 0x%08x\n", hr
);
949 hr
= IShellWindows_Register(shellwindows
, NULL
, 0, SWC_EXPLORER
, &cookie
);
951 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
953 hr
= IShellWindows_Register(shellwindows
, (IDispatch
*)shellwindows
, 0, SWC_EXPLORER
, &cookie
);
955 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
957 hr
= IShellWindows_Register(shellwindows
, (IDispatch
*)shellwindows
, 0, SWC_EXPLORER
, &cookie
);
959 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
961 hwnd
= CreateWindowExA(0, "button", "test", BS_CHECKBOX
| WS_VISIBLE
| WS_POPUP
,
962 0, 0, 50, 14, 0, 0, 0, NULL
);
963 ok(hwnd
!= NULL
, "got %p, error %d\n", hwnd
, GetLastError());
966 hr
= IShellWindows_Register(shellwindows
, NULL
, HandleToLong(hwnd
), SWC_EXPLORER
, &cookie
);
968 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
969 ok(cookie
!= 0, "got %d\n", cookie
);
972 hr
= IShellWindows_Register(shellwindows
, NULL
, HandleToLong(hwnd
), SWC_EXPLORER
, &cookie2
);
974 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
975 ok(cookie2
!= 0 && cookie2
!= cookie
, "got %d\n", cookie2
);
977 hr
= IShellWindows_Revoke(shellwindows
, cookie
);
979 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
980 hr
= IShellWindows_Revoke(shellwindows
, cookie2
);
982 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
984 hr
= IShellWindows_Revoke(shellwindows
, 0);
986 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
988 /* we can register ourselves as desktop, but FindWindowSW still returns real desktop window */
990 hr
= IShellWindows_Register(shellwindows
, NULL
, HandleToLong(hwnd
), SWC_DESKTOP
, &cookie
);
992 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
993 ok(cookie
!= 0, "got %d\n", cookie
);
995 disp
= (void*)0xdeadbeef;
998 hr
= IShellWindows_FindWindowSW(shellwindows
, &v
, &v
, SWC_DESKTOP
, &ret
, SWFO_NEEDDISPATCH
, &disp
);
999 ok(hr
== S_OK
|| broken(hr
== S_FALSE
), "got 0x%08x\n", hr
);
1000 if (hr
== S_FALSE
) /* winxp and earlier */ {
1001 win_skip("SWC_DESKTOP is not supported, some tests will be skipped.\n");
1002 /* older versions allowed to regiser SWC_DESKTOP and access it with FindWindowSW */
1003 ok(disp
== NULL
, "got %p\n", disp
);
1004 ok(ret
== 0, "got %d\n", ret
);
1007 static const IID
*browser_riids
[] = {
1012 static const IID
*viewdual_riids
[] = {
1013 &IID_IShellFolderViewDual3
,
1017 IShellFolderViewDual
*view
;
1018 IShellBrowser
*sb
, *sb2
;
1019 IServiceProvider
*sp
;
1020 IDispatch
*doc
, *app
;
1025 ok(disp
!= NULL
, "got %p\n", disp
);
1026 ok(ret
!= HandleToUlong(hwnd
), "got %d\n", ret
);
1028 /* IDispatch-related tests */
1029 test_dispatch_typeinfo(disp
, browser_riids
);
1032 hr
= IDispatch_QueryInterface(disp
, &IID_IWebBrowser2
, (void**)&wb
);
1033 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1035 hr
= IWebBrowser2_Refresh(wb
);
1037 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1039 hr
= IWebBrowser2_get_Application(wb
, &app
);
1040 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1041 ok(disp
== app
, "got %p, %p\n", app
, disp
);
1042 IDispatch_Release(app
);
1044 hr
= IWebBrowser2_get_Document(wb
, &doc
);
1046 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1048 test_dispatch_typeinfo(doc
, viewdual_riids
);
1050 IWebBrowser2_Release(wb
);
1052 /* IServiceProvider */
1053 hr
= IDispatch_QueryInterface(disp
, &IID_IShellFolderViewDual
, (void**)&view
);
1054 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
1056 hr
= IDispatch_QueryInterface(disp
, &IID_IServiceProvider
, (void**)&sp
);
1057 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1059 hr
= IServiceProvider_QueryService(sp
, &SID_STopLevelBrowser
, &IID_IShellBrowser
, (void**)&sb
);
1060 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1062 hr
= IServiceProvider_QueryService(sp
, &SID_STopLevelBrowser
, &IID_IShellBrowser
, (void**)&sb2
);
1063 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1064 ok(sb
== sb2
, "got %p, %p\n", sb
, sb2
);
1066 hr
= IServiceProvider_QueryService(sp
, &SID_STopLevelBrowser
, &IID_IOleWindow
, (void**)&unk
);
1067 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1068 IUnknown_Release(unk
);
1070 hr
= IServiceProvider_QueryService(sp
, &SID_STopLevelBrowser
, &IID_IExplorerBrowser
, (void**)&unk
);
1071 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
1073 hr
= IShellBrowser_QueryInterface(sb
, &IID_IExplorerBrowser
, (void**)&unk
);
1074 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
1076 hr
= IShellBrowser_QueryInterface(sb
, &IID_IWebBrowser2
, (void**)&unk
);
1077 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
1079 hr
= IShellBrowser_QueryInterface(sb
, &IID_IDispatch
, (void**)&unk
);
1080 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
1082 hr
= IShellBrowser_QueryActiveShellView(sb
, &sv
);
1083 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1084 IShellView_Release(sv
);
1086 IShellBrowser_Release(sb2
);
1087 IShellBrowser_Release(sb
);
1089 hr
= IServiceProvider_QueryService(sp
, &SID_STopLevelBrowser
, &IID_IUnknown
, (void**)&unk
);
1090 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1092 hr
= IUnknown_QueryInterface(unk
, &IID_IShellBrowser
, (void**)&sb2
);
1093 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1094 IShellBrowser_Release(sb2
);
1095 IUnknown_Release(unk
);
1097 hr
= IServiceProvider_QueryService(sp
, &SID_STopLevelBrowser
, &IID_IShellView
, (void**)&sv
);
1098 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
1100 IServiceProvider_Release(sp
);
1101 IDispatch_Release(disp
);
1104 disp
= (void*)0xdeadbeef;
1107 hr
= IShellWindows_FindWindowSW(shellwindows
, &v
, &v
, SWC_DESKTOP
, &ret
, 0, &disp
);
1108 ok(hr
== S_OK
|| broken(hr
== S_FALSE
) /* winxp */, "got 0x%08x\n", hr
);
1109 ok(disp
== NULL
, "got %p\n", disp
);
1110 ok(ret
!= HandleToUlong(hwnd
), "got %d\n", ret
);
1112 disp
= (void*)0xdeadbeef;
1117 hr
= IShellWindows_FindWindowSW(shellwindows
, &v
, &v2
, SWC_BROWSER
, &ret
, SWFO_COOKIEPASSED
, &disp
);
1119 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1120 ok(disp
== NULL
, "got %p\n", disp
);
1121 ok(ret
== 0, "got %d\n", ret
);
1123 hr
= IShellWindows_Revoke(shellwindows
, cookie
);
1125 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1126 DestroyWindow(hwnd
);
1127 IShellWindows_Release(shellwindows
);
1130 static void test_ParseName(void)
1132 static const WCHAR cadabraW
[] = {'c','a','d','a','b','r','a',0};
1133 WCHAR pathW
[MAX_PATH
];
1141 hr
= CoCreateInstance(&CLSID_Shell
, NULL
, CLSCTX_INPROC_SERVER
,
1142 &IID_IShellDispatch
, (void**)&sd
);
1143 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1145 GetTempPathW(sizeof(pathW
)/sizeof(pathW
[0]), pathW
);
1147 V_BSTR(&v
) = SysAllocString(pathW
);
1148 hr
= IShellDispatch_NameSpace(sd
, v
, &folder
);
1149 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1152 item
= (void*)0xdeadbeef;
1153 hr
= Folder_ParseName(folder
, NULL
, &item
);
1154 ok(hr
== S_FALSE
|| broken(hr
== E_INVALIDARG
) /* win2k */, "got 0x%08x\n", hr
);
1155 ok(item
== NULL
, "got %p\n", item
);
1158 str
= SysAllocStringLen(NULL
, 0);
1159 item
= (void*)0xdeadbeef;
1160 hr
= Folder_ParseName(folder
, str
, &item
);
1161 ok(hr
== S_FALSE
|| broken(hr
== E_INVALIDARG
) /* win2k */, "got 0x%08x\n", hr
);
1162 ok(item
== NULL
, "got %p\n", item
);
1165 /* path doesn't exist */
1166 str
= SysAllocString(cadabraW
);
1167 item
= (void*)0xdeadbeef;
1168 hr
= Folder_ParseName(folder
, str
, &item
);
1169 ok(hr
== S_FALSE
|| broken(hr
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
)) /* win2k */,
1170 "got 0x%08x\n", hr
);
1171 ok(item
== NULL
, "got %p\n", item
);
1174 lstrcatW(pathW
, cadabraW
);
1175 CreateDirectoryW(pathW
, NULL
);
1177 str
= SysAllocString(cadabraW
);
1179 hr
= Folder_ParseName(folder
, str
, &item
);
1180 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1181 ok(item
!= NULL
, "got %p\n", item
);
1184 hr
= FolderItem_get_Path(item
, &str
);
1185 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1186 ok(str
[0] != 0, "path %s\n", wine_dbgstr_w(str
));
1189 RemoveDirectoryW(pathW
);
1190 FolderItem_Release(item
);
1191 Folder_Release(folder
);
1192 IShellDispatch_Release(sd
);
1195 static void test_Verbs(void)
1197 FolderItemVerbs
*verbs
;
1198 WCHAR pathW
[MAX_PATH
];
1199 FolderItemVerb
*verb
;
1209 hr
= CoCreateInstance(&CLSID_Shell
, NULL
, CLSCTX_INPROC_SERVER
,
1210 &IID_IShellDispatch
, (void**)&sd
);
1211 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1213 GetTempPathW(sizeof(pathW
)/sizeof(pathW
[0]), pathW
);
1215 V_BSTR(&v
) = SysAllocString(pathW
);
1216 hr
= IShellDispatch_NameSpace(sd
, v
, &folder
);
1217 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1220 hr
= Folder_QueryInterface(folder
, &IID_Folder2
, (void**)&folder2
);
1221 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1222 Folder_Release(folder
);
1224 hr
= Folder2_get_Self(folder2
, &item
);
1225 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1226 Folder2_Release(folder2
);
1228 if (0) { /* crashes on some systems */
1229 hr
= FolderItem_Verbs(item
, NULL
);
1230 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1232 hr
= FolderItem_Verbs(item
, &verbs
);
1233 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1235 if (0) { /* crashes on winxp/win2k3 */
1236 hr
= FolderItemVerbs_get_Count(verbs
, NULL
);
1237 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1240 hr
= FolderItemVerbs_get_Count(verbs
, &count
);
1241 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1242 ok(count
> 0, "got count %d\n", count
);
1244 if (0) { /* crashes on winxp/win2k3 */
1247 hr
= FolderItemVerbs_Item(verbs
, v
, NULL
);
1248 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1250 /* there's always one item more, so you can access [0,count],
1251 instead of actual [0,count) */
1252 for (i
= 0; i
<= count
; i
++) {
1255 hr
= FolderItemVerbs_Item(verbs
, v
, &verb
);
1256 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1257 hr
= FolderItemVerb_get_Name(verb
, &str
);
1258 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1259 ok(str
!= NULL
, "%d: name %s\n", i
, wine_dbgstr_w(str
));
1261 ok(str
[0] == 0, "%d: got teminating item %s\n", i
, wine_dbgstr_w(str
));
1264 FolderItemVerb_Release(verb
);
1270 hr
= FolderItemVerbs_Item(verbs
, v
, &verb
);
1271 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1272 ok(verb
== NULL
, "got %p\n", verb
);
1274 FolderItemVerbs_Release(verbs
);
1275 FolderItem_Release(item
);
1276 IShellDispatch_Release(sd
);
1279 static void test_ShellExecute(void)
1282 IShellDispatch2
*sd
;
1284 VARIANT args
, dir
, op
, show
;
1286 static const WCHAR regW
[] = {'r','e','g',0};
1288 hr
= CoCreateInstance(&CLSID_Shell
, NULL
, CLSCTX_INPROC_SERVER
,
1289 &IID_IShellDispatch2
, (void**)&sd
);
1292 win_skip("IShellDispatch2 not supported\n");
1301 V_VT(&show
) = VT_I4
;
1304 name
= SysAllocString(regW
);
1306 hr
= IShellDispatch2_ShellExecute(sd
, name
, args
, dir
, op
, show
);
1307 ok(hr
== S_OK
, "ShellExecute failed: %08x\n", hr
);
1309 /* test invalid value for show */
1310 V_VT(&show
) = VT_BSTR
;
1311 V_BSTR(&show
) = name
;
1313 hr
= IShellDispatch2_ShellExecute(sd
, name
, args
, dir
, op
, show
);
1314 ok(hr
== S_OK
, "ShellExecute failed: %08x\n", hr
);
1316 SysFreeString(name
);
1319 START_TEST(shelldispatch
)
1323 r
= CoInitialize(NULL
);
1324 ok(SUCCEEDED(r
), "CoInitialize failed: %08x\n", r
);
1328 init_function_pointers();
1332 test_ShellFolderViewDual();
1333 test_ShellWindows();
1336 test_ShellExecute();