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
);
448 ok(r
== S_OK
, "FolderItems::get_Count failed: %08x\n", r
);
450 ok(!count
, "expected 0 files, got %d\n", count
);
455 if (0) /* crashes on all versions of Windows */
456 r
= FolderItems_Item(items
, var
, NULL
);
458 r
= FolderItems_Item(items
, var
, &item
);
459 ok(r
== S_FALSE
, "expected S_FALSE, got %08x\n", r
);
460 ok(!item
, "item is not null\n");
462 /* create test files */
463 for (i
= 0; i
< sizeof(file_defs
)/sizeof(file_defs
[0]); i
++)
465 switch (file_defs
[i
].type
)
468 r
= CreateDirectoryA(file_defs
[i
].name
, NULL
);
469 ok(r
, "CreateDirectory failed: %08x\n", GetLastError());
470 PathCombineA(cstr
, file_defs
[i
].name
, "foo.txt");
471 file
= CreateFileA(cstr
, 0, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
472 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFile failed: %08x\n", GetLastError());
477 file
= CreateFileA(file_defs
[i
].name
, 0, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
478 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFile failed: %08x\n", GetLastError());
484 /* test that get_Count is not aware of the newly created files */
486 r
= FolderItems_get_Count(items
, &count
);
488 ok(r
== S_OK
, "FolderItems::get_Count failed: %08x\n", r
);
490 ok(!count
, "expected 0 files, got %d\n", count
);
492 /* test that the newly created files CAN be retrieved by string index */
493 variant_set_string(&var
, file_defs
[0].name
);
495 r
= FolderItems_Item(items
, var
, &item
);
496 ok(r
== S_OK
, "FolderItems::Item failed: %08x\n", r
);
497 ok(!!item
, "item is null\n");
498 if (item
) FolderItem_Release(item
);
501 /* recreate the folder object */
502 FolderItems_Release(items
);
504 r
= Folder_Items(folder
, &items
);
505 ok(r
== S_OK
, "Folder::Items failed: %08x\n", r
);
506 ok(!!items
, "items is null\n");
507 r
= FolderItems_QueryInterface(items
, &IID_FolderItems2
, (void**)&items2
);
508 ok(r
== S_OK
|| broken(r
== E_NOINTERFACE
) /* xp and later */, "FolderItems::QueryInterface failed: %08x\n", r
);
509 if (r
== S_OK
) ok(!!items2
, "items2 is null\n");
510 r
= FolderItems_QueryInterface(items
, &IID_FolderItems3
, (void**)&items3
);
511 ok(r
== S_OK
, "FolderItems::QueryInterface failed: %08x\n", r
);
512 ok(!!items3
, "items3 is null\n");
513 Folder_Release(folder
);
516 r
= FolderItems_get_Count(items
, &count
);
518 ok(r
== S_OK
, "FolderItems::get_Count failed: %08x\n", r
);
520 ok(count
== sizeof(file_defs
)/sizeof(file_defs
[0]),
521 "expected %d files, got %d\n", (LONG
)(sizeof(file_defs
)/sizeof(file_defs
[0])), count
);
523 V_VT(&var
) = VT_EMPTY
;
524 item
= (FolderItem
*)0xdeadbeef;
525 r
= FolderItems_Item(items
, var
, &item
);
526 ok(r
== E_NOTIMPL
, "expected E_NOTIMPL, got %08x\n", r
);
527 ok(!item
, "item is not null\n");
532 r
= FolderItems_Item(items
, var
, &item
);
533 ok(r
== S_OK
, "FolderItems::Item failed: %08x\n", r
);
534 ok(!!item
, "item is null\n");
535 if (item
) FolderItem_Release(item
);
540 r
= FolderItems_Item(items
, var
, &item
);
541 ok(r
== S_OK
, "FolderItems::Item failed: %08x\n", r
);
542 ok(!!item
, "item is null\n");
543 if (item
) FolderItem_Release(item
);
546 item
= (FolderItem
*)0xdeadbeef;
547 r
= FolderItems_Item(items
, var
, &item
);
548 ok(r
== S_FALSE
, "expected S_FALSE, got %08x\n", r
);
549 ok(!item
, "item is not null\n");
551 V_VT(&var
) = VT_ERROR
;
554 r
= FolderItems_Item(items
, var
, &item
);
555 ok(r
== S_OK
, "expected S_OK, got %08x\n", r
);
556 ok(!!item
, "item is null\n");
560 r
= FolderItem_get_Path(item
, &bstr
);
561 ok(r
== S_OK
, "FolderItem::get_Path failed: %08x\n", r
);
562 ok(!lstrcmpW(bstr
, cur_dir
),
563 "expected %s, got %s\n", wine_dbgstr_w(cur_dir
), wine_dbgstr_w(bstr
));
565 FolderItem_Release(item
);
568 V_VT(&int_index
) = VT_I4
;
570 /* test the folder item corresponding to each file */
571 for (i
= 0; i
< sizeof(file_defs
)/sizeof(file_defs
[0]); i
++)
573 V_I4(&int_index
) = i
;
574 variant_set_string(&str_index
, file_defs
[i
].name
);
577 r
= FolderItems_Item(items
, int_index
, &item
);
578 ok(r
== S_OK
, "file_defs[%d]: FolderItems::Item failed: %08x\n", i
, r
);
579 ok(!!item
, "file_defs[%d]: item is null\n", i
);
582 r
= FolderItems_Item(items
, int_index
, &item2
);
583 ok(r
== S_OK
, "file_defs[%d]: FolderItems::Item failed: %08x\n", i
, r
);
584 ok(item2
!= item
, "file_defs[%d]: item and item2 are the same\n", i
);
585 FolderItem_Release(item2
);
588 r
= FolderItem_get_Path(item
, &bstr
);
589 ok(r
== S_OK
, "file_defs[%d]: FolderItem::get_Path failed: %08x\n", i
, r
);
590 PathCombineW(path
, cur_dir
, V_BSTR(&str_index
));
591 ok(!lstrcmpW(bstr
, path
),
592 "file_defs[%d]: expected %s, got %s\n", i
, wine_dbgstr_w(path
), wine_dbgstr_w(bstr
));
596 r
= FolderItems_Item(items
, str_index
, &item
);
597 ok(r
== S_OK
, "file_defs[%d]: FolderItems::Item failed: %08x\n", i
, r
);
598 ok(!!item
, "file_defs[%d]: item is null\n", i
);
601 r
= FolderItem_get_Path(item
, &bstr
);
602 ok(r
== S_OK
, "file_defs[%d]: FolderItem::get_Path failed: %08x\n", i
, r
);
603 PathCombineW(path
, cur_dir
, V_BSTR(&str_index
));
604 ok(!lstrcmpW(bstr
, path
),
605 "file_defs[%d]: expected %s, got %s\n", i
, wine_dbgstr_w(path
), wine_dbgstr_w(bstr
));
608 FolderItem_Release(item
);
610 if (file_defs
[i
].type
== DIRECTORY
)
612 /* test that getting an item object for a file in a subdirectory succeeds */
613 PathCombineA(cstr
, file_defs
[i
].name
, "foo.txt");
614 variant_set_string(&str_index2
, cstr
);
616 r
= FolderItems_Item(items
, str_index2
, &item2
);
617 ok(r
== S_OK
, "file_defs[%d]: FolderItems::Item failed: %08x\n", i
, r
);
618 ok(!!item2
, "file_defs[%d]: item is null\n", i
);
619 if (item2
) FolderItem_Release(item2
);
620 VariantClear(&str_index2
);
622 /* delete the file in the subdirectory */
623 ok(DeleteFileA(cstr
), "file_defs[%d]: DeleteFile failed: %08x\n", i
, GetLastError());
625 /* test that getting an item object via a relative path fails */
626 strcpy(cstr
, file_defs
[i
].name
);
627 strcat(cstr
, "\\..\\");
628 strcat(cstr
, file_defs
[i
].name
);
629 variant_set_string(&str_index2
, cstr
);
630 item2
= (FolderItem
*)0xdeadbeef;
631 r
= FolderItems_Item(items
, str_index2
, &item2
);
632 ok(r
== S_FALSE
, "file_defs[%d]: expected S_FALSE, got %08x\n", i
, r
);
633 ok(!item2
, "file_defs[%d]: item is not null\n", i
);
634 VariantClear(&str_index2
);
636 /* remove the directory */
637 ok(RemoveDirectoryA(file_defs
[i
].name
), "file_defs[%d]: RemoveDirectory failed: %08x\n", i
, GetLastError());
641 ok(DeleteFileA(file_defs
[i
].name
), "file_defs[%d]: DeleteFile failed: %08x\n", i
, GetLastError());
644 /* test that the folder item is still accessible by integer index */
646 r
= FolderItems_Item(items
, int_index
, &item
);
647 ok(r
== S_OK
, "file_defs[%d]: FolderItems::Item failed: %08x\n", i
, r
);
648 ok(!!item
, "file_defs[%d]: item is null\n", i
);
651 r
= FolderItem_get_Path(item
, &bstr
);
652 ok(r
== S_OK
, "file_defs[%d]: FolderItem::get_Path failed: %08x\n", i
, r
);
653 PathCombineW(path
, cur_dir
, V_BSTR(&str_index
));
654 ok(!lstrcmpW(bstr
, path
),
655 "file_defs[%d]: expected %s, got %s\n", i
, wine_dbgstr_w(path
), wine_dbgstr_w(bstr
));
658 FolderItem_Release(item
);
660 /* test that the folder item is no longer accessible by string index */
661 item
= (FolderItem
*)0xdeadbeef;
662 r
= FolderItems_Item(items
, str_index
, &item
);
663 ok(r
== S_FALSE
, "file_defs[%d]: expected S_FALSE, got %08x\n", i
, r
);
664 ok(!item
, "file_defs[%d]: item is not null\n", i
);
666 VariantClear(&str_index
);
669 /* test that there are only as many folder items as there were files */
670 V_I4(&int_index
) = sizeof(file_defs
)/sizeof(file_defs
[0]);
671 item
= (FolderItem
*)0xdeadbeef;
672 r
= FolderItems_Item(items
, int_index
, &item
);
673 ok(r
== S_FALSE
, "expected S_FALSE, got %08x\n", r
);
674 ok(!item
, "item is not null\n");
676 if (0) /* crashes on xp */
678 r
= FolderItems_get_Application(items
, NULL
);
679 ok(r
== E_INVALIDARG
, "expected E_INVALIDARG, got %08x\n", r
);
682 r
= FolderItems_get_Application(items
, &disp
);
684 ok(r
== S_OK
, "FolderItems::get_Application failed: %08x\n", r
);
686 ok(!!disp
, "disp is null\n");
687 if (disp
) IDispatch_Release(disp
);
689 if (0) /* crashes on xp */
691 r
= FolderItems_get_Parent(items
, NULL
);
692 ok(r
== E_NOTIMPL
, "expected E_NOTIMPL, got %08x\n", r
);
695 disp
= (IDispatch
*)0xdeadbeef;
696 r
= FolderItems_get_Parent(items
, &disp
);
697 ok(r
== E_NOTIMPL
, "expected E_NOTIMPL, got %08x\n", r
);
698 ok(!disp
, "disp is not null\n");
700 if (0) /* crashes on xp */
702 r
= FolderItems__NewEnum(items
, NULL
);
703 ok(r
== E_INVALIDARG
, "expected E_INVALIDARG, got %08x\n", r
);
706 r
= FolderItems__NewEnum(items
, &unk
);
708 ok(r
== S_OK
, "FolderItems::_NewEnum failed: %08x\n", r
);
710 ok(!!unk
, "unk is null\n");
711 if (unk
) IUnknown_Release(unk
);
715 r
= FolderItems3_Filter(items3
, 0, NULL
);
717 ok(r
== S_OK
, "expected S_OK, got %08x\n", r
);
719 if (0) /* crashes on xp */
721 r
= FolderItems3_get_Verbs(items3
, NULL
);
722 ok(r
== E_INVALIDARG
, "expected E_INVALIDARG, got %08x\n", r
);
725 r
= FolderItems3_get_Verbs(items3
, &verbs
);
727 ok(r
== S_FALSE
, "expected S_FALSE, got %08x\n", r
);
728 ok(!verbs
, "verbs is not null\n");
731 /* remove the temporary directory and restore the original working directory */
732 GetTempPathW(MAX_PATH
, path
);
733 SetCurrentDirectoryW(path
);
734 ok(RemoveDirectoryW(winetestW
), "RemoveDirectory failed: %08x\n", GetLastError());
735 SetCurrentDirectoryW(orig_dir
);
737 /* test that everything stops working after the directory has been removed */
739 r
= FolderItems_get_Count(items
, &count
);
741 ok(r
== S_OK
, "FolderItems::get_Count failed: %08x\n", r
);
743 ok(!count
, "expected 0 files, got %d\n", count
);
746 V_I4(&int_index
) = 0;
747 item
= (FolderItem
*)0xdeadbeef;
748 r
= FolderItems_Item(items
, int_index
, &item
);
749 ok(r
== S_FALSE
, "expected S_FALSE, got %08x\n", r
);
750 ok(!item
, "item is not null\n");
752 variant_set_string(&str_index
, file_defs
[0].name
);
753 item
= (FolderItem
*)0xdeadbeef;
754 r
= FolderItems_Item(items
, str_index
, &item
);
755 ok(r
== S_FALSE
, "expected S_FALSE, got %08x\n", r
);
756 ok(!item
, "item is not null\n");
757 VariantClear(&str_index
);
759 FolderItems_Release(items
);
760 if (items2
) FolderItems2_Release(items2
);
761 if (items3
) FolderItems3_Release(items3
);
764 static void test_service(void)
766 static const WCHAR spooler
[] = {'S','p','o','o','l','e','r',0};
767 static const WCHAR dummyW
[] = {'d','u','m','m','y',0};
768 SERVICE_STATUS_PROCESS status
;
769 SC_HANDLE scm
, service
;
776 hr
= CoCreateInstance(&CLSID_Shell
, NULL
, CLSCTX_INPROC_SERVER
,
777 &IID_IShellDispatch2
, (void**)&sd
);
780 win_skip("IShellDispatch2 not supported\n");
786 hr
= IShellDispatch2_IsServiceRunning(sd
, NULL
, &v
);
787 ok(V_VT(&v
) == VT_BOOL
, "got %d\n", V_VT(&v
));
788 ok(V_BOOL(&v
) == VARIANT_FALSE
, "got %d\n", V_BOOL(&v
));
791 scm
= OpenSCManagerW(NULL
, NULL
, SC_MANAGER_CONNECT
);
792 service
= OpenServiceW(scm
, spooler
, SERVICE_QUERY_STATUS
);
793 QueryServiceStatusEx(service
, SC_STATUS_PROCESS_INFO
, (BYTE
*)&status
, sizeof(SERVICE_STATUS_PROCESS
), &dummy
);
794 CloseServiceHandle(service
);
795 CloseServiceHandle(scm
);
797 /* service should exist */
798 name
= SysAllocString(spooler
);
800 hr
= IShellDispatch2_IsServiceRunning(sd
, name
, &v
);
802 ok(V_VT(&v
) == VT_BOOL
, "got %d\n", V_VT(&v
));
803 if (status
.dwCurrentState
== SERVICE_RUNNING
)
804 ok(V_BOOL(&v
) == VARIANT_TRUE
, "got %d\n", V_BOOL(&v
));
806 ok(V_BOOL(&v
) == VARIANT_FALSE
, "got %d\n", V_BOOL(&v
));
809 /* service doesn't exist */
810 name
= SysAllocString(dummyW
);
812 hr
= IShellDispatch2_IsServiceRunning(sd
, name
, &v
);
814 ok(V_VT(&v
) == VT_BOOL
, "got %d\n", V_VT(&v
));
815 ok(V_BOOL(&v
) == VARIANT_FALSE
, "got %d\n", V_BOOL(&v
));
818 IShellDispatch2_Release(sd
);
821 static void test_dispatch_typeinfo(IDispatch
*disp
, REFIID
*riid
)
829 hr
= IDispatch_GetTypeInfoCount(disp
, &count
);
830 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
831 ok(count
== 1, "got %u\n", count
);
833 hr
= IDispatch_GetTypeInfo(disp
, 0, LOCALE_SYSTEM_DEFAULT
, &typeinfo
);
834 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
836 hr
= ITypeInfo_GetTypeAttr(typeinfo
, &typeattr
);
837 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
838 while (!IsEqualGUID(*riid
, &IID_NULL
)) {
839 if (IsEqualGUID(&typeattr
->guid
, *riid
))
843 ok(IsEqualGUID(&typeattr
->guid
, *riid
), "unexpected type guid %s\n", wine_dbgstr_guid(&typeattr
->guid
));
845 ITypeInfo_ReleaseTypeAttr(typeinfo
, typeattr
);
846 ITypeInfo_Release(typeinfo
);
849 static void test_ShellFolderViewDual(void)
851 static const IID
*shelldisp_riids
[] = {
852 &IID_IShellDispatch6
,
853 &IID_IShellDispatch5
,
854 &IID_IShellDispatch4
,
855 &IID_IShellDispatch2
,
856 &IID_IWin7ShellDispatch6
,
859 IShellFolderViewDual
*viewdual
;
860 IShellFolder
*desktop
, *tmpdir
;
861 IShellView
*view
, *view2
;
862 IDispatch
*disp
, *disp2
;
863 WCHAR pathW
[MAX_PATH
];
867 /* IShellFolderViewDual is not an IShellView extension */
868 hr
= SHGetDesktopFolder(&desktop
);
869 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
871 hr
= IShellFolder_CreateViewObject(desktop
, NULL
, &IID_IShellView
, (void**)&view
);
872 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
874 hr
= IShellView_QueryInterface(view
, &IID_IShellFolderViewDual
, (void**)&viewdual
);
875 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
877 hr
= IShellView_GetItemObject(view
, SVGIO_BACKGROUND
, &IID_IDispatch
, (void**)&disp
);
878 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
880 hr
= IShellView_GetItemObject(view
, SVGIO_BACKGROUND
, &IID_IDispatch
, (void**)&disp2
);
881 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
882 ok(disp2
== disp
, "got %p, %p\n", disp2
, disp
);
883 IDispatch_Release(disp2
);
885 hr
= IDispatch_QueryInterface(disp
, &IID_IShellFolderViewDual
, (void**)&viewdual
);
886 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
887 ok(disp
== (IDispatch
*)viewdual
, "got %p, expected %p\n", viewdual
, disp
);
889 hr
= IShellFolderViewDual_QueryInterface(viewdual
, &IID_IShellView
, (void**)&view2
);
890 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
892 /* get_Application() */
894 if (0) /* crashes on pre-vista */ {
895 hr
= IShellFolderViewDual_get_Application(viewdual
, NULL
);
896 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
898 hr
= IShellFolderViewDual_get_Application(viewdual
, &disp2
);
899 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
900 ok(disp2
!= (IDispatch
*)viewdual
, "got %p, %p\n", disp2
, viewdual
);
901 test_dispatch_typeinfo(disp2
, shelldisp_riids
);
902 IDispatch_Release(disp2
);
904 IShellFolderViewDual_Release(viewdual
);
905 IDispatch_Release(disp
);
907 disp
= (void*)0xdeadbeef;
908 hr
= IShellView_GetItemObject(view
, SVGIO_BACKGROUND
, &IID_IShellFolderViewDual
, (void**)&disp
);
909 ok(hr
== E_NOINTERFACE
|| broken(hr
== E_NOTIMPL
) /* win2k */, "got 0x%08x\n", hr
);
910 ok(disp
== NULL
, "got %p\n", disp
);
911 IShellView_Release(view
);
913 /* Try with some other folder, that's not a desktop */
914 GetTempPathW(sizeof(pathW
)/sizeof(pathW
[0]), pathW
);
915 hr
= IShellFolder_ParseDisplayName(desktop
, NULL
, NULL
, pathW
, NULL
, &pidl
, NULL
);
916 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
918 hr
= IShellFolder_BindToObject(desktop
, pidl
, NULL
, &IID_IShellFolder
, (void**)&tmpdir
);
919 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
922 hr
= IShellFolder_CreateViewObject(desktop
, NULL
, &IID_IShellView
, (void**)&view
);
923 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
925 hr
= IShellView_QueryInterface(view
, &IID_IShellFolderViewDual
, (void**)&viewdual
);
926 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
928 hr
= IShellView_GetItemObject(view
, SVGIO_BACKGROUND
, &IID_IDispatch
, (void**)&disp
);
929 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
930 IDispatch_Release(disp
);
931 IShellView_Release(view
);
933 IShellFolder_Release(tmpdir
);
934 IShellFolder_Release(desktop
);
937 static void test_ShellWindows(void)
939 IShellWindows
*shellwindows
;
940 LONG cookie
, cookie2
, ret
;
946 hr
= CoCreateInstance(&CLSID_ShellWindows
, NULL
, CLSCTX_LOCAL_SERVER
,
947 &IID_IShellWindows
, (void**)&shellwindows
);
948 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
949 /* TODO: remove when explorer startup with clean prefix is fixed */
953 if (0) /* NULL out argument - currently crashes on Wine */ {
954 hr
= IShellWindows_Register(shellwindows
, NULL
, 0, SWC_EXPLORER
, NULL
);
955 ok(hr
== HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER
), "got 0x%08x\n", hr
);
957 hr
= IShellWindows_Register(shellwindows
, NULL
, 0, SWC_EXPLORER
, &cookie
);
959 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
961 hr
= IShellWindows_Register(shellwindows
, (IDispatch
*)shellwindows
, 0, SWC_EXPLORER
, &cookie
);
963 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
965 hr
= IShellWindows_Register(shellwindows
, (IDispatch
*)shellwindows
, 0, SWC_EXPLORER
, &cookie
);
967 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
969 hwnd
= CreateWindowExA(0, "button", "test", BS_CHECKBOX
| WS_VISIBLE
| WS_POPUP
,
970 0, 0, 50, 14, 0, 0, 0, NULL
);
971 ok(hwnd
!= NULL
, "got %p, error %d\n", hwnd
, GetLastError());
974 hr
= IShellWindows_Register(shellwindows
, NULL
, HandleToLong(hwnd
), SWC_EXPLORER
, &cookie
);
976 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
977 ok(cookie
!= 0, "got %d\n", cookie
);
980 hr
= IShellWindows_Register(shellwindows
, NULL
, HandleToLong(hwnd
), SWC_EXPLORER
, &cookie2
);
982 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
983 ok(cookie2
!= 0 && cookie2
!= cookie
, "got %d\n", cookie2
);
985 hr
= IShellWindows_Revoke(shellwindows
, cookie
);
987 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
988 hr
= IShellWindows_Revoke(shellwindows
, cookie2
);
990 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
992 hr
= IShellWindows_Revoke(shellwindows
, 0);
994 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
996 /* we can register ourselves as desktop, but FindWindowSW still returns real desktop window */
998 hr
= IShellWindows_Register(shellwindows
, NULL
, HandleToLong(hwnd
), SWC_DESKTOP
, &cookie
);
1000 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1001 ok(cookie
!= 0, "got %d\n", cookie
);
1003 disp
= (void*)0xdeadbeef;
1006 hr
= IShellWindows_FindWindowSW(shellwindows
, &v
, &v
, SWC_DESKTOP
, &ret
, SWFO_NEEDDISPATCH
, &disp
);
1007 ok(hr
== S_OK
|| broken(hr
== S_FALSE
), "got 0x%08x\n", hr
);
1008 if (hr
== S_FALSE
) /* winxp and earlier */ {
1009 win_skip("SWC_DESKTOP is not supported, some tests will be skipped.\n");
1010 /* older versions allowed to regiser SWC_DESKTOP and access it with FindWindowSW */
1011 ok(disp
== NULL
, "got %p\n", disp
);
1012 ok(ret
== 0, "got %d\n", ret
);
1015 static const IID
*browser_riids
[] = {
1020 static const IID
*viewdual_riids
[] = {
1021 &IID_IShellFolderViewDual3
,
1025 IShellFolderViewDual
*view
;
1026 IShellBrowser
*sb
, *sb2
;
1027 IServiceProvider
*sp
;
1028 IDispatch
*doc
, *app
;
1033 ok(disp
!= NULL
, "got %p\n", disp
);
1034 ok(ret
!= HandleToUlong(hwnd
), "got %d\n", ret
);
1036 /* IDispatch-related tests */
1037 test_dispatch_typeinfo(disp
, browser_riids
);
1040 hr
= IDispatch_QueryInterface(disp
, &IID_IWebBrowser2
, (void**)&wb
);
1041 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1043 hr
= IWebBrowser2_Refresh(wb
);
1045 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1047 hr
= IWebBrowser2_get_Application(wb
, &app
);
1048 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1049 ok(disp
== app
, "got %p, %p\n", app
, disp
);
1050 IDispatch_Release(app
);
1052 hr
= IWebBrowser2_get_Document(wb
, &doc
);
1054 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1056 test_dispatch_typeinfo(doc
, viewdual_riids
);
1058 IWebBrowser2_Release(wb
);
1060 /* IServiceProvider */
1061 hr
= IDispatch_QueryInterface(disp
, &IID_IShellFolderViewDual
, (void**)&view
);
1062 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
1064 hr
= IDispatch_QueryInterface(disp
, &IID_IServiceProvider
, (void**)&sp
);
1065 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1067 hr
= IServiceProvider_QueryService(sp
, &SID_STopLevelBrowser
, &IID_IShellBrowser
, (void**)&sb
);
1068 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1070 hr
= IServiceProvider_QueryService(sp
, &SID_STopLevelBrowser
, &IID_IShellBrowser
, (void**)&sb2
);
1071 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1072 ok(sb
== sb2
, "got %p, %p\n", sb
, sb2
);
1074 hr
= IServiceProvider_QueryService(sp
, &SID_STopLevelBrowser
, &IID_IOleWindow
, (void**)&unk
);
1075 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1076 IUnknown_Release(unk
);
1078 hr
= IServiceProvider_QueryService(sp
, &SID_STopLevelBrowser
, &IID_IExplorerBrowser
, (void**)&unk
);
1079 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
1081 hr
= IShellBrowser_QueryInterface(sb
, &IID_IExplorerBrowser
, (void**)&unk
);
1082 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
1084 hr
= IShellBrowser_QueryInterface(sb
, &IID_IWebBrowser2
, (void**)&unk
);
1085 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
1087 hr
= IShellBrowser_QueryInterface(sb
, &IID_IDispatch
, (void**)&unk
);
1088 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
1090 hr
= IShellBrowser_QueryActiveShellView(sb
, &sv
);
1091 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1092 IShellView_Release(sv
);
1094 IShellBrowser_Release(sb2
);
1095 IShellBrowser_Release(sb
);
1097 hr
= IServiceProvider_QueryService(sp
, &SID_STopLevelBrowser
, &IID_IUnknown
, (void**)&unk
);
1098 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1100 hr
= IUnknown_QueryInterface(unk
, &IID_IShellBrowser
, (void**)&sb2
);
1101 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1102 IShellBrowser_Release(sb2
);
1103 IUnknown_Release(unk
);
1105 hr
= IServiceProvider_QueryService(sp
, &SID_STopLevelBrowser
, &IID_IShellView
, (void**)&sv
);
1106 ok(hr
== E_NOINTERFACE
, "got 0x%08x\n", hr
);
1108 IServiceProvider_Release(sp
);
1109 IDispatch_Release(disp
);
1112 disp
= (void*)0xdeadbeef;
1115 hr
= IShellWindows_FindWindowSW(shellwindows
, &v
, &v
, SWC_DESKTOP
, &ret
, 0, &disp
);
1116 ok(hr
== S_OK
|| broken(hr
== S_FALSE
) /* winxp */, "got 0x%08x\n", hr
);
1117 ok(disp
== NULL
, "got %p\n", disp
);
1118 ok(ret
!= HandleToUlong(hwnd
), "got %d\n", ret
);
1120 disp
= (void*)0xdeadbeef;
1125 hr
= IShellWindows_FindWindowSW(shellwindows
, &v
, &v2
, SWC_BROWSER
, &ret
, SWFO_COOKIEPASSED
, &disp
);
1127 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1128 ok(disp
== NULL
, "got %p\n", disp
);
1129 ok(ret
== 0, "got %d\n", ret
);
1131 hr
= IShellWindows_Revoke(shellwindows
, cookie
);
1133 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1134 DestroyWindow(hwnd
);
1135 IShellWindows_Release(shellwindows
);
1138 static void test_ParseName(void)
1140 static const WCHAR cadabraW
[] = {'c','a','d','a','b','r','a',0};
1141 WCHAR pathW
[MAX_PATH
];
1149 hr
= CoCreateInstance(&CLSID_Shell
, NULL
, CLSCTX_INPROC_SERVER
,
1150 &IID_IShellDispatch
, (void**)&sd
);
1151 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1153 GetTempPathW(sizeof(pathW
)/sizeof(pathW
[0]), pathW
);
1155 V_BSTR(&v
) = SysAllocString(pathW
);
1156 hr
= IShellDispatch_NameSpace(sd
, v
, &folder
);
1157 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1160 item
= (void*)0xdeadbeef;
1161 hr
= Folder_ParseName(folder
, NULL
, &item
);
1162 ok(hr
== S_FALSE
|| broken(hr
== E_INVALIDARG
) /* win2k */, "got 0x%08x\n", hr
);
1163 ok(item
== NULL
, "got %p\n", item
);
1166 str
= SysAllocStringLen(NULL
, 0);
1167 item
= (void*)0xdeadbeef;
1168 hr
= Folder_ParseName(folder
, str
, &item
);
1169 ok(hr
== S_FALSE
|| broken(hr
== E_INVALIDARG
) /* win2k */, "got 0x%08x\n", hr
);
1170 ok(item
== NULL
, "got %p\n", item
);
1173 /* path doesn't exist */
1174 str
= SysAllocString(cadabraW
);
1175 item
= (void*)0xdeadbeef;
1176 hr
= Folder_ParseName(folder
, str
, &item
);
1177 ok(hr
== S_FALSE
|| broken(hr
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
)) /* win2k */,
1178 "got 0x%08x\n", hr
);
1179 ok(item
== NULL
, "got %p\n", item
);
1182 lstrcatW(pathW
, cadabraW
);
1183 CreateDirectoryW(pathW
, NULL
);
1185 str
= SysAllocString(cadabraW
);
1187 hr
= Folder_ParseName(folder
, str
, &item
);
1188 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1189 ok(item
!= NULL
, "got %p\n", item
);
1192 hr
= FolderItem_get_Path(item
, &str
);
1193 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1194 ok(str
[0] != 0, "path %s\n", wine_dbgstr_w(str
));
1197 RemoveDirectoryW(pathW
);
1198 FolderItem_Release(item
);
1199 Folder_Release(folder
);
1200 IShellDispatch_Release(sd
);
1203 static void test_Verbs(void)
1205 FolderItemVerbs
*verbs
;
1206 WCHAR pathW
[MAX_PATH
];
1207 FolderItemVerb
*verb
;
1217 hr
= CoCreateInstance(&CLSID_Shell
, NULL
, CLSCTX_INPROC_SERVER
,
1218 &IID_IShellDispatch
, (void**)&sd
);
1219 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1221 GetTempPathW(sizeof(pathW
)/sizeof(pathW
[0]), pathW
);
1223 V_BSTR(&v
) = SysAllocString(pathW
);
1224 hr
= IShellDispatch_NameSpace(sd
, v
, &folder
);
1225 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1228 hr
= Folder_QueryInterface(folder
, &IID_Folder2
, (void**)&folder2
);
1229 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1230 Folder_Release(folder
);
1232 hr
= Folder2_get_Self(folder2
, &item
);
1233 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1234 Folder2_Release(folder2
);
1236 if (0) { /* crashes on some systems */
1237 hr
= FolderItem_Verbs(item
, NULL
);
1238 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1240 hr
= FolderItem_Verbs(item
, &verbs
);
1241 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1243 if (0) { /* crashes on winxp/win2k3 */
1244 hr
= FolderItemVerbs_get_Count(verbs
, NULL
);
1245 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1248 hr
= FolderItemVerbs_get_Count(verbs
, &count
);
1249 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1250 ok(count
> 0, "got count %d\n", count
);
1252 if (0) { /* crashes on winxp/win2k3 */
1255 hr
= FolderItemVerbs_Item(verbs
, v
, NULL
);
1256 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
1258 /* there's always one item more, so you can access [0,count],
1259 instead of actual [0,count) */
1260 for (i
= 0; i
<= count
; i
++) {
1263 hr
= FolderItemVerbs_Item(verbs
, v
, &verb
);
1264 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1265 hr
= FolderItemVerb_get_Name(verb
, &str
);
1266 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1267 ok(str
!= NULL
, "%d: name %s\n", i
, wine_dbgstr_w(str
));
1269 ok(str
[0] == 0, "%d: got teminating item %s\n", i
, wine_dbgstr_w(str
));
1272 FolderItemVerb_Release(verb
);
1278 hr
= FolderItemVerbs_Item(verbs
, v
, &verb
);
1279 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1280 ok(verb
== NULL
, "got %p\n", verb
);
1282 FolderItemVerbs_Release(verbs
);
1283 FolderItem_Release(item
);
1284 IShellDispatch_Release(sd
);
1287 static void test_ShellExecute(void)
1290 IShellDispatch2
*sd
;
1292 VARIANT args
, dir
, op
, show
;
1294 static const WCHAR regW
[] = {'r','e','g',0};
1296 hr
= CoCreateInstance(&CLSID_Shell
, NULL
, CLSCTX_INPROC_SERVER
,
1297 &IID_IShellDispatch2
, (void**)&sd
);
1300 win_skip("IShellDispatch2 not supported\n");
1309 V_VT(&show
) = VT_I4
;
1312 name
= SysAllocString(regW
);
1314 hr
= IShellDispatch2_ShellExecute(sd
, name
, args
, dir
, op
, show
);
1315 ok(hr
== S_OK
, "ShellExecute failed: %08x\n", hr
);
1317 /* test invalid value for show */
1318 V_VT(&show
) = VT_BSTR
;
1319 V_BSTR(&show
) = name
;
1321 hr
= IShellDispatch2_ShellExecute(sd
, name
, args
, dir
, op
, show
);
1322 ok(hr
== S_OK
, "ShellExecute failed: %08x\n", hr
);
1324 SysFreeString(name
);
1327 START_TEST(shelldispatch
)
1331 r
= CoInitialize(NULL
);
1332 ok(SUCCEEDED(r
), "CoInitialize failed: %08x\n", r
);
1336 init_function_pointers();
1340 test_ShellFolderViewDual();
1341 test_ShellWindows();
1344 test_ShellExecute();