2 * Unit test of the IShellFolder functions.
4 * Copyright 2004 Vitaliy Margolen
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
40 #include "wine/heap.h"
41 #include "wine/test.h"
44 DEFINE_GUID(IID_IParentAndItem
, 0xB3A4B685, 0xB685, 0x4805, 0x99,0xD9, 0x5D,0xEA,0xD2,0x87,0x32,0x36);
45 DEFINE_GUID(CLSID_ShellDocObjView
, 0xe7e4bc40, 0xe76a, 0x11ce, 0xa9,0xbb, 0x00,0xaa,0x00,0x4a,0xe8,0x37);
47 static HRESULT (WINAPI
*pSHCreateItemFromIDList
)(PCIDLIST_ABSOLUTE pidl
, REFIID riid
, void **ppv
);
48 static HRESULT (WINAPI
*pSHCreateItemFromParsingName
)(PCWSTR
,IBindCtx
*,REFIID
,void**);
49 static HRESULT (WINAPI
*pSHCreateItemFromRelativeName
)(IShellItem
*,PCWSTR
,IBindCtx
*,REFIID
,void**);
50 static HRESULT (WINAPI
*pSHCreateItemInKnownFolder
)(REFKNOWNFOLDERID
,DWORD
,PCWSTR
,REFIID
,void **);
51 static HRESULT (WINAPI
*pSHCreateShellItem
)(LPCITEMIDLIST
,IShellFolder
*,LPCITEMIDLIST
,IShellItem
**);
52 static HRESULT (WINAPI
*pSHCreateShellItemArray
)(LPCITEMIDLIST
,IShellFolder
*,UINT
,LPCITEMIDLIST
*,IShellItemArray
**);
53 static HRESULT (WINAPI
*pSHCreateShellItemArrayFromIDLists
)(UINT
, PCIDLIST_ABSOLUTE
*, IShellItemArray
**);
54 static HRESULT (WINAPI
*pSHCreateShellItemArrayFromDataObject
)(IDataObject
*, REFIID
, void **);
55 static HRESULT (WINAPI
*pSHCreateShellItemArrayFromShellItem
)(IShellItem
*, REFIID
, void **);
56 static HRESULT (WINAPI
*pSHGetKnownFolderPath
)(REFKNOWNFOLDERID
,DWORD
,HANDLE
,PWSTR
*);
57 static HRESULT (WINAPI
*pSHGetNameFromIDList
)(PCIDLIST_ABSOLUTE
,SIGDN
,PWSTR
*);
58 static HRESULT (WINAPI
*pSHGetItemFromDataObject
)(IDataObject
*,DATAOBJ_GET_ITEM_FLAGS
,REFIID
,void**);
59 static HRESULT (WINAPI
*pSHGetIDListFromObject
)(IUnknown
*, PIDLIST_ABSOLUTE
*);
60 static HRESULT (WINAPI
*pSHGetItemFromObject
)(IUnknown
*,REFIID
,void**);
61 static BOOL (WINAPI
*pIsWow64Process
)(HANDLE
, PBOOL
);
62 static HRESULT (WINAPI
*pSHCreateDefaultContextMenu
)(const DEFCONTEXTMENU
*,REFIID
,void**);
63 static BOOL (WINAPI
*pSHGetPathFromIDListEx
)(PCIDLIST_ABSOLUTE
,WCHAR
*,DWORD
,GPFIDL_FLAGS
);
64 static HRESULT (WINAPI
*pSHGetSetFolderCustomSettings
)(LPSHFOLDERCUSTOMSETTINGS
,PCWSTR
,DWORD
);
66 static WCHAR
*make_wstr(const char *str
)
74 len
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0);
78 ret
= heap_alloc(len
* sizeof(WCHAR
));
82 MultiByteToWideChar(CP_ACP
, 0, str
, -1, ret
, len
);
86 static void init_function_pointers(void)
91 hmod
= GetModuleHandleA("shell32.dll");
93 #define MAKEFUNC(f) (p##f = (void*)GetProcAddress(hmod, #f))
94 MAKEFUNC(SHCreateItemFromIDList
);
95 MAKEFUNC(SHCreateItemFromParsingName
);
96 MAKEFUNC(SHCreateItemFromRelativeName
);
97 MAKEFUNC(SHCreateItemInKnownFolder
);
98 MAKEFUNC(SHCreateShellItem
);
99 MAKEFUNC(SHCreateShellItemArray
);
100 MAKEFUNC(SHCreateShellItemArrayFromIDLists
);
101 MAKEFUNC(SHCreateShellItemArrayFromDataObject
);
102 MAKEFUNC(SHCreateShellItemArrayFromShellItem
);
103 MAKEFUNC(SHGetKnownFolderPath
);
104 MAKEFUNC(SHGetNameFromIDList
);
105 MAKEFUNC(SHGetItemFromDataObject
);
106 MAKEFUNC(SHGetIDListFromObject
);
107 MAKEFUNC(SHGetItemFromObject
);
108 MAKEFUNC(SHCreateDefaultContextMenu
);
109 MAKEFUNC(SHGetPathFromIDListEx
);
110 MAKEFUNC(SHGetSetFolderCustomSettings
);
113 /* test named exports */
114 ptr
= GetProcAddress(hmod
, "ILFree");
115 ok(broken(ptr
== 0) || ptr
!= 0, "expected named export for ILFree\n");
118 #define TESTNAMED(f) \
119 ptr = (void*)GetProcAddress(hmod, #f); \
120 ok(ptr != 0, "expected named export for " #f "\n");
122 TESTNAMED(ILAppendID
);
124 TESTNAMED(ILCloneFirst
);
125 TESTNAMED(ILCombine
);
126 TESTNAMED(ILCreateFromPath
);
127 TESTNAMED(ILCreateFromPathA
);
128 TESTNAMED(ILCreateFromPathW
);
129 TESTNAMED(ILFindChild
);
130 TESTNAMED(ILFindLastID
);
131 TESTNAMED(ILGetNext
);
132 TESTNAMED(ILGetSize
);
133 TESTNAMED(ILIsEqual
);
134 TESTNAMED(ILIsParent
);
135 TESTNAMED(ILRemoveLastID
);
136 TESTNAMED(ILSaveToStream
);
140 hmod
= GetModuleHandleA("kernel32.dll");
141 pIsWow64Process
= (void*)GetProcAddress(hmod
, "IsWow64Process");
144 /* Based on PathAddBackslashW from dlls/shlwapi/path.c */
145 static LPWSTR
myPathAddBackslashW( LPWSTR lpszPath
)
149 if (!lpszPath
|| (iLen
= lstrlenW(lpszPath
)) >= MAX_PATH
)
155 if (lpszPath
[-1] != '\\')
166 WCHAR path
[MAX_PATH
];
170 {{'c',':','\\',0}, S_OK
},
171 {{'c',':','\\','\\',0}, E_INVALIDARG
, 1},
172 {{'c',':','\\','f','a','k','e',0}, 0x80070002}, /* ERROR_FILE_NOT_FOUND */
173 {{'c',':','f','a','k','e',0}, E_INVALIDARG
, 1},
174 {{'c',':','/',0}, E_INVALIDARG
, 1},
175 {{'c',':','\\','w','i','n','d','o','w','s',0}, S_OK
},
176 {{'c',':','\\','w','i','n','d','o','w','s','\\',0}, S_OK
},
177 {{'c',':','\\','w','i','n','d','o','w','s','\\','.',0}, E_INVALIDARG
, 1},
178 {{'c',':','\\','w','i','n','d','o','w','s','\\','.','.',0}, E_INVALIDARG
, 1},
179 {{'.',0}, E_INVALIDARG
, 1},
180 {{'.','.',0}, E_INVALIDARG
, 1},
181 {{'t','e','s','t',0}, 0x80070002},
182 {{'t','e','s','t','\\',0}, 0x80070002},
183 {{'s','u','b','\\','d','i','r',0}, 0x80070002},
184 {{'s','u','b','/','d','i','r',0}, E_INVALIDARG
, 1},
185 {{'h','t','t','p',':',0}, S_OK
, 1},
186 {{'h','t','t','p',':','t','e','s','t',0}, S_OK
, 1},
187 {{'h','t','t','p',':','\\','t','e','s','t',0}, S_OK
, 1},
188 {{'x','x',':',0}, S_OK
, 1},
191 static void test_ParseDisplayName(void)
193 static WCHAR testdirW
[] = {'p','a','r','s','e','t','e','s','t',0};
194 static WCHAR backslashW
[] = {'\\',0};
195 WCHAR buffer
[MAX_PATH
], buffer2
[MAX_PATH
];
196 IShellFolder
*desktop
;
202 hr
= SHGetDesktopFolder(&desktop
);
203 ok(hr
== S_OK
, "Expected SHGetDesktopFolder to return S_OK, got 0x%08x\n", hr
);
205 hr
= IShellFolder_ParseDisplayName(desktop
, NULL
, NULL
, NULL
, NULL
, &pidl
, NULL
);
206 ok(hr
== E_INVALIDARG
, "got %#x\n", hr
);
208 for (i
= 0; i
< ARRAY_SIZE(parse_tests
); i
++)
210 hr
= IShellFolder_ParseDisplayName(desktop
, NULL
, NULL
, parse_tests
[i
].path
, NULL
, &pidl
, NULL
);
211 todo_wine_if(parse_tests
[i
].todo
)
212 ok(hr
== parse_tests
[i
].hr
, "%s: expected %#x, got %#x\n",
213 wine_dbgstr_w(parse_tests
[i
].path
), parse_tests
[i
].hr
, hr
);
218 /* I thought that perhaps the DesktopFolder's ParseDisplayName would recognize the
219 * path corresponding to CSIDL_PERSONAL and return a CLSID_MyDocuments PIDL. Turns
220 * out it doesn't. The magic seems to happen in the file dialogs, then. */
222 bRes
= SHGetSpecialFolderPathW(NULL
, buffer
, CSIDL_PERSONAL
, FALSE
);
223 ok(bRes
, "SHGetSpecialFolderPath(CSIDL_PERSONAL) failed! %u\n", GetLastError());
225 hr
= IShellFolder_ParseDisplayName(desktop
, NULL
, NULL
, buffer
, NULL
, &pidl
, 0);
226 ok(hr
== S_OK
, "DesktopFolder->ParseDisplayName failed. hr = %08x.\n", hr
);
228 ok(ILFindLastID(pidl
)->mkid
.abID
[0] == 0x31,
229 "Last pidl should be of type PT_FOLDER, but is: %02x\n",
230 ILFindLastID(pidl
)->mkid
.abID
[0]);
233 /* Relative paths are interpreted relative to the desktop. */
234 GetTempPathW(ARRAY_SIZE(buffer
), buffer
);
235 GetLongPathNameW(buffer
, buffer
, ARRAY_SIZE(buffer
));
236 SetCurrentDirectoryW(buffer
);
237 CreateDirectoryW(testdirW
, NULL
);
239 hr
= IShellFolder_ParseDisplayName(desktop
, NULL
, NULL
, testdirW
, NULL
, &pidl
, NULL
);
240 ok(hr
== 0x80070002, "got %#x\n", hr
);
242 RemoveDirectoryW(testdirW
);
244 hr
= SHGetSpecialFolderPathW(NULL
, buffer
, CSIDL_DESKTOP
, FALSE
);
245 ok(hr
== S_FALSE
, "got %#x\n", hr
);
246 SetCurrentDirectoryW(buffer
);
247 CreateDirectoryW(testdirW
, NULL
);
249 hr
= IShellFolder_ParseDisplayName(desktop
, NULL
, NULL
, testdirW
, NULL
, &pidl
, NULL
);
250 ok(hr
== S_OK
, "got %#x\n", hr
);
252 ok(SHGetPathFromIDListW(pidl
, buffer2
), "SHGetPathFromIDList failed\n");
253 lstrcatW(buffer
, backslashW
);
254 lstrcatW(buffer
, testdirW
);
255 ok(!lstrcmpW(buffer
, buffer2
), "expected %s, got %s\n", wine_dbgstr_w(buffer
), wine_dbgstr_w(buffer2
));
257 RemoveDirectoryW(testdirW
);
260 IShellFolder_Release(desktop
);
263 /* creates a file with the specified name for tests */
264 static void CreateTestFile(const CHAR
*name
)
269 file
= CreateFileA(name
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
270 if (file
!= INVALID_HANDLE_VALUE
)
272 WriteFile(file
, name
, strlen(name
), &written
, NULL
);
273 WriteFile(file
, "\n", strlen("\n"), &written
, NULL
);
279 /* initializes the tests */
280 static void CreateFilesFolders(void)
282 CreateDirectoryA(".\\testdir", NULL
);
283 CreateDirectoryA(".\\testdir\\test.txt", NULL
);
284 CreateTestFile (".\\testdir\\test1.txt ");
285 CreateTestFile (".\\testdir\\test2.txt ");
286 CreateTestFile (".\\testdir\\test3.txt ");
287 CreateDirectoryA(".\\testdir\\testdir2 ", NULL
);
288 CreateDirectoryA(".\\testdir\\testdir2\\subdir", NULL
);
291 /* cleans after tests */
292 static void Cleanup(void)
294 DeleteFileA(".\\testdir\\test1.txt");
295 DeleteFileA(".\\testdir\\test2.txt");
296 DeleteFileA(".\\testdir\\test3.txt");
297 RemoveDirectoryA(".\\testdir\\test.txt");
298 RemoveDirectoryA(".\\testdir\\testdir2\\subdir");
299 RemoveDirectoryA(".\\testdir\\testdir2");
300 RemoveDirectoryA(".\\testdir");
305 static void test_EnumObjects(IShellFolder
*iFolder
)
307 IEnumIDList
*iEnumList
;
308 LPITEMIDLIST newPIDL
, idlArr
[10];
313 static const WORD iResults
[5][5] =
322 #define SFGAO_testfor SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR | SFGAO_CAPABILITYMASK
323 /* Don't test for SFGAO_HASSUBFOLDER since we return real state and native cached */
324 static const ULONG attrs
[5] =
326 SFGAO_DROPTARGET
| SFGAO_CANLINK
| SFGAO_CANCOPY
| SFGAO_FILESYSTEM
| SFGAO_FOLDER
| SFGAO_FILESYSANCESTOR
,
327 SFGAO_DROPTARGET
| SFGAO_CANLINK
| SFGAO_CANCOPY
| SFGAO_FILESYSTEM
| SFGAO_FOLDER
| SFGAO_FILESYSANCESTOR
,
328 SFGAO_DROPTARGET
| SFGAO_CANLINK
| SFGAO_CANCOPY
| SFGAO_FILESYSTEM
,
329 SFGAO_DROPTARGET
| SFGAO_CANLINK
| SFGAO_CANCOPY
| SFGAO_FILESYSTEM
,
330 SFGAO_DROPTARGET
| SFGAO_CANLINK
| SFGAO_CANCOPY
| SFGAO_FILESYSTEM
,
332 static const ULONG full_attrs
[5] =
334 SFGAO_CAPABILITYMASK
| SFGAO_STORAGE
| SFGAO_STORAGEANCESTOR
| SFGAO_FILESYSTEM
| SFGAO_FOLDER
| SFGAO_FILESYSANCESTOR
,
335 SFGAO_CAPABILITYMASK
| SFGAO_STORAGE
| SFGAO_STORAGEANCESTOR
| SFGAO_FILESYSTEM
| SFGAO_FOLDER
| SFGAO_FILESYSANCESTOR
,
336 SFGAO_CAPABILITYMASK
| SFGAO_STREAM
| SFGAO_FILESYSTEM
,
337 SFGAO_CAPABILITYMASK
| SFGAO_STREAM
| SFGAO_FILESYSTEM
,
338 SFGAO_CAPABILITYMASK
| SFGAO_STREAM
| SFGAO_FILESYSTEM
,
341 hr
= IShellFolder_EnumObjects(iFolder
, NULL
, SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
| SHCONTF_INCLUDEHIDDEN
, &iEnumList
);
342 ok(hr
== S_OK
, "EnumObjects failed %08x\n", hr
);
344 /* This is to show that, contrary to what is said on MSDN, on IEnumIDList::Next,
345 * the filesystem shellfolders return S_OK even if less than 'celt' items are
346 * returned (in contrast to S_FALSE). We have to do it in a loop since WinXP
347 * only ever returns a single entry per call. */
348 while (IEnumIDList_Next(iEnumList
, 10-i
, &idlArr
[i
], &NumPIDLs
) == S_OK
)
350 ok (i
== 5, "i: %d\n", i
);
352 hr
= IEnumIDList_Release(iEnumList
);
353 ok(hr
== S_OK
, "IEnumIDList_Release failed %08x\n", hr
);
355 /* Sort them first in case of wrong order from system */
356 for (i
=0;i
<5;i
++) for (j
=0;j
<5;j
++)
357 if ((SHORT
)IShellFolder_CompareIDs(iFolder
, 0, idlArr
[i
], idlArr
[j
]) < 0)
360 idlArr
[i
] = idlArr
[j
];
364 for (i
=0;i
<5;i
++) for (j
=0;j
<5;j
++)
366 hr
= IShellFolder_CompareIDs(iFolder
, 0, idlArr
[i
], idlArr
[j
]);
367 ok(hr
== iResults
[i
][j
], "Got %x expected [%d]-[%d]=%x\n", hr
, i
, j
, iResults
[i
][j
]);
370 for (i
= 0; i
< ARRAY_SIZE(attrs
); ++i
)
374 flags
= SFGAO_CANCOPY
;
375 hr
= IShellFolder_GetAttributesOf(iFolder
, 1, (LPCITEMIDLIST
*)(idlArr
+ i
), &flags
);
376 flags
&= SFGAO_testfor
;
377 ok(hr
== S_OK
, "Failed to get item attributes, hr %#x.\n", hr
);
378 ok((flags
& attrs
[i
]) == attrs
[i
], "%i: unexpected attributes got %#x, expected %#x.\n", i
, flags
, attrs
[i
]);
380 flags
= SFGAO_testfor
;
381 hr
= IShellFolder_GetAttributesOf(iFolder
, 1, (LPCITEMIDLIST
*)(idlArr
+ i
), &flags
);
382 flags
&= SFGAO_testfor
;
383 ok(hr
== S_OK
, "Failed to get item attributes, hr %#x.\n", hr
);
384 ok(flags
== (attrs
[i
] | SFGAO_CAPABILITYMASK
), "%i: unexpected attributes got %#x, expected %#x.\n",
388 hr
= IShellFolder_GetAttributesOf(iFolder
, 1, (LPCITEMIDLIST
*)(idlArr
+ i
), &flags
);
389 ok(hr
== S_OK
, "Failed to get item attributes, hr %#x.\n", hr
);
390 ok((flags
& ~(SFGAO_HASSUBFOLDER
|SFGAO_COMPRESSED
)) == full_attrs
[i
], "%d: unexpected attributes %#x, expected %#x\n",
391 i
, flags
, full_attrs
[i
]);
398 static void test_BindToObject(void)
402 IShellFolder
*psfDesktop
, *psfChild
, *psfMyComputer
, *psfSystemDir
;
403 SHITEMID emptyitem
= { 0, { 0 } };
404 LPITEMIDLIST pidlMyComputer
, pidlSystemDir
, pidl
, pidlEmpty
= (LPITEMIDLIST
)&emptyitem
;
405 WCHAR wszSystemDir
[MAX_PATH
];
406 char szSystemDir
[MAX_PATH
];
408 WCHAR path
[MAX_PATH
];
409 CHAR pathA
[MAX_PATH
];
411 WCHAR wszMyComputer
[] = {
412 ':',':','{','2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-',
413 'A','2','D','8','-','0','8','0','0','2','B','3','0','3','0','9','D','}',0 };
414 static const CHAR filename_html
[] = "winetest.html";
415 static const CHAR filename_txt
[] = "winetest.txt";
416 static const CHAR filename_foo
[] = "winetest.foo";
418 /* The following tests shows that BindToObject should fail with E_INVALIDARG if called
419 * with an empty pidl. This is tested for Desktop, MyComputer and the FS ShellFolder
421 hr
= SHGetDesktopFolder(&psfDesktop
);
422 ok (hr
== S_OK
, "SHGetDesktopFolder failed! hr = %08x\n", hr
);
423 if (hr
!= S_OK
) return;
425 hr
= IShellFolder_BindToObject(psfDesktop
, pidlEmpty
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psfChild
);
426 ok (hr
== E_INVALIDARG
, "Desktop's BindToObject should fail, when called with empty pidl! hr = %08x\n", hr
);
428 hr
= IShellFolder_BindToObject(psfDesktop
, NULL
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psfChild
);
429 ok (hr
== E_INVALIDARG
, "Desktop's BindToObject should fail, when called with NULL pidl! hr = %08x\n", hr
);
431 hr
= IShellFolder_ParseDisplayName(psfDesktop
, NULL
, NULL
, wszMyComputer
, NULL
, &pidlMyComputer
, NULL
);
432 ok (hr
== S_OK
, "Desktop's ParseDisplayName failed to parse MyComputer's CLSID! hr = %08x\n", hr
);
434 IShellFolder_Release(psfDesktop
);
438 hr
= IShellFolder_BindToObject(psfDesktop
, pidlMyComputer
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psfMyComputer
);
439 ok (hr
== S_OK
, "Desktop failed to bind to MyComputer object! hr = %08x\n", hr
);
440 IShellFolder_Release(psfDesktop
);
441 ILFree(pidlMyComputer
);
442 if (hr
!= S_OK
) return;
444 hr
= IShellFolder_BindToObject(psfMyComputer
, pidlEmpty
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psfChild
);
445 ok (hr
== E_INVALIDARG
, "MyComputers's BindToObject should fail, when called with empty pidl! hr = %08x\n", hr
);
447 hr
= IShellFolder_BindToObject(psfMyComputer
, NULL
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psfChild
);
448 ok (hr
== E_INVALIDARG
, "MyComputers's BindToObject should fail, when called with NULL pidl! hr = %08x\n", hr
);
450 cChars
= GetSystemDirectoryA(szSystemDir
, MAX_PATH
);
451 ok (cChars
> 0 && cChars
< MAX_PATH
, "GetSystemDirectoryA failed! LastError: %u\n", GetLastError());
452 if (cChars
== 0 || cChars
>= MAX_PATH
) {
453 IShellFolder_Release(psfMyComputer
);
456 MultiByteToWideChar(CP_ACP
, 0, szSystemDir
, -1, wszSystemDir
, MAX_PATH
);
458 hr
= IShellFolder_ParseDisplayName(psfMyComputer
, NULL
, NULL
, wszSystemDir
, NULL
, &pidlSystemDir
, NULL
);
459 ok (hr
== S_OK
, "MyComputers's ParseDisplayName failed to parse the SystemDirectory! hr = %08x\n", hr
);
461 IShellFolder_Release(psfMyComputer
);
465 hr
= IShellFolder_BindToObject(psfMyComputer
, pidlSystemDir
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psfSystemDir
);
466 ok (hr
== S_OK
, "MyComputer failed to bind to a FileSystem ShellFolder! hr = %08x\n", hr
);
467 IShellFolder_Release(psfMyComputer
);
468 ILFree(pidlSystemDir
);
469 if (hr
!= S_OK
) return;
471 hr
= IShellFolder_BindToObject(psfSystemDir
, pidlEmpty
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psfChild
);
472 ok (hr
== E_INVALIDARG
,
473 "FileSystem ShellFolder's BindToObject should fail, when called with empty pidl! hr = %08x\n", hr
);
475 hr
= IShellFolder_BindToObject(psfSystemDir
, NULL
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psfChild
);
476 ok (hr
== E_INVALIDARG
,
477 "FileSystem ShellFolder's BindToObject should fail, when called with NULL pidl! hr = %08x\n", hr
);
479 IShellFolder_Release(psfSystemDir
);
481 cChars
= GetCurrentDirectoryA(MAX_PATH
, buf
);
484 skip("Failed to get current directory, skipping tests.\n");
487 if(buf
[cChars
-1] != '\\') lstrcatA(buf
, "\\");
489 SHGetDesktopFolder(&psfDesktop
);
491 /* Attempt BindToObject on files. */
494 lstrcpyA(pathA
, buf
);
495 lstrcatA(pathA
, filename_html
);
496 hfile
= CreateFileA(pathA
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
497 if(hfile
!= INVALID_HANDLE_VALUE
)
500 MultiByteToWideChar(CP_ACP
, 0, pathA
, -1, path
, MAX_PATH
);
501 hr
= IShellFolder_ParseDisplayName(psfDesktop
, NULL
, NULL
, path
, NULL
, &pidl
, NULL
);
502 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
505 hr
= IShellFolder_BindToObject(psfDesktop
, pidl
, NULL
, &IID_IShellFolder
, (void**)&psfChild
);
507 hr
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
), /* XP, W2K3 */
512 hr
= IShellFolder_QueryInterface(psfChild
, &IID_IPersist
, (void**)&pp
);
513 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
517 hr
= IPersist_GetClassID(pp
, &id
);
518 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
519 ok(IsEqualIID(&id
, &CLSID_ShellDocObjView
), "Unexpected classid %s\n", wine_dbgstr_guid(&id
));
520 IPersist_Release(pp
);
523 IShellFolder_Release(psfChild
);
530 win_skip("Failed to create .html testfile.\n");
533 lstrcpyA(pathA
, buf
);
534 lstrcatA(pathA
, filename_txt
);
535 hfile
= CreateFileA(pathA
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
536 if(hfile
!= INVALID_HANDLE_VALUE
)
539 MultiByteToWideChar(CP_ACP
, 0, pathA
, -1, path
, MAX_PATH
);
540 hr
= IShellFolder_ParseDisplayName(psfDesktop
, NULL
, NULL
, path
, NULL
, &pidl
, NULL
);
541 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
544 hr
= IShellFolder_BindToObject(psfDesktop
, pidl
, NULL
, &IID_IShellFolder
, (void**)&psfChild
);
545 ok(hr
== E_FAIL
|| /* Vista+ */
546 hr
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
), /* XP, W2K3 */
548 if(SUCCEEDED(hr
)) IShellFolder_Release(psfChild
);
554 win_skip("Failed to create .txt testfile.\n");
557 lstrcpyA(pathA
, buf
);
558 lstrcatA(pathA
, filename_foo
);
559 hfile
= CreateFileA(pathA
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
560 if(hfile
!= INVALID_HANDLE_VALUE
)
563 MultiByteToWideChar(CP_ACP
, 0, pathA
, -1, path
, MAX_PATH
);
564 hr
= IShellFolder_ParseDisplayName(psfDesktop
, NULL
, NULL
, path
, NULL
, &pidl
, NULL
);
565 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
568 hr
= IShellFolder_BindToObject(psfDesktop
, pidl
, NULL
, &IID_IShellFolder
, (void**)&psfChild
);
569 ok(hr
== E_FAIL
|| /* Vista+ */
570 hr
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
), /* XP, W2K3 */
572 if(SUCCEEDED(hr
)) IShellFolder_Release(psfChild
);
578 win_skip("Failed to create .foo testfile.\n");
580 /* And on the desktop */
581 SHGetSpecialFolderPathA(NULL
, pathA
, CSIDL_DESKTOP
, FALSE
);
582 lstrcatA(pathA
, "\\");
583 lstrcatA(pathA
, filename_html
);
584 hfile
= CreateFileA(pathA
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
587 MultiByteToWideChar(CP_ACP
, 0, pathA
, -1, path
, MAX_PATH
);
588 hr
= IShellFolder_ParseDisplayName(psfDesktop
, NULL
, NULL
, path
, NULL
, &pidl
, NULL
);
589 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
591 hr
= IShellFolder_BindToObject(psfDesktop
, pidl
, NULL
, &IID_IShellFolder
, (void **)&psfChild
);
593 hr
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
), /* XP, W2K3 */
595 if(SUCCEEDED(hr
)) IShellFolder_Release(psfChild
);
597 if(!DeleteFileA(pathA
))
598 trace("Failed to delete: %d\n", GetLastError());
600 SHGetSpecialFolderPathA(NULL
, pathA
, CSIDL_DESKTOP
, FALSE
);
601 lstrcatA(pathA
, "\\");
602 lstrcatA(pathA
, filename_foo
);
603 hfile
= CreateFileA(pathA
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
606 MultiByteToWideChar(CP_ACP
, 0, pathA
, -1, path
, MAX_PATH
);
607 hr
= IShellFolder_ParseDisplayName(psfDesktop
, NULL
, NULL
, path
, NULL
, &pidl
, NULL
);
608 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
610 hr
= IShellFolder_BindToObject(psfDesktop
, pidl
, NULL
, &IID_IShellFolder
, (void **)&psfChild
);
611 ok(hr
== E_FAIL
|| /* Vista+ */
612 hr
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
), /* XP, W2K3 */
614 if(SUCCEEDED(hr
)) IShellFolder_Release(psfChild
);
618 IShellFolder_Release(psfDesktop
);
621 static void test_GetDisplayName(void)
626 WCHAR wszTestFile
[MAX_PATH
], wszTestFile2
[MAX_PATH
];
627 char szTestFile
[MAX_PATH
], szTestDir
[MAX_PATH
];
630 LPSHELLFOLDER psfDesktop
, psfPersonal
;
632 SHITEMID emptyitem
= { 0, { 0 } };
633 LPITEMIDLIST pidlTestFile
, pidlEmpty
= (LPITEMIDLIST
)&emptyitem
;
634 LPCITEMIDLIST pidlLast
;
635 static const CHAR szFileName
[] = "winetest.foo";
636 static const WCHAR wszFileName
[] = { 'w','i','n','e','t','e','s','t','.','f','o','o',0 };
637 static const WCHAR wszDirName
[] = { 'w','i','n','e','t','e','s','t',0 };
639 /* It's ok to use this fixed path. Call will fail anyway. */
640 WCHAR wszAbsoluteFilename
[] = { 'C',':','\\','w','i','n','e','t','e','s','t', 0 };
641 LPITEMIDLIST pidlNew
;
643 /* I'm trying to figure if there is a functional difference between calling
644 * SHGetPathFromIDListW and calling GetDisplayNameOf(SHGDN_FORPARSING) after
645 * binding to the shellfolder. One thing I thought of was that perhaps
646 * SHGetPathFromIDListW would be able to get the path to a file, which does
647 * not exist anymore, while the other method wouldn't. It turns out there's
648 * no functional difference in this respect.
651 /* First creating a directory in MyDocuments and a file in this directory. */
652 result
= SHGetSpecialFolderPathA(NULL
, szTestDir
, CSIDL_PERSONAL
, FALSE
);
653 ok(result
, "SHGetSpecialFolderPathA failed! Last error: %u\n", GetLastError());
656 /* Use ANSI file functions so this works on Windows 9x */
657 lstrcatA(szTestDir
, "\\winetest");
658 CreateDirectoryA(szTestDir
, NULL
);
659 attr
=GetFileAttributesA(szTestDir
);
660 if (attr
== INVALID_FILE_ATTRIBUTES
|| !(attr
& FILE_ATTRIBUTE_DIRECTORY
))
662 ok(0, "unable to create the '%s' directory\n", szTestDir
);
666 lstrcpyA(szTestFile
, szTestDir
);
667 lstrcatA(szTestFile
, "\\");
668 lstrcatA(szTestFile
, szFileName
);
669 hTestFile
= CreateFileA(szTestFile
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
670 ok((hTestFile
!= INVALID_HANDLE_VALUE
), "CreateFileA failed! Last error: %u\n", GetLastError());
671 if (hTestFile
== INVALID_HANDLE_VALUE
) return;
672 CloseHandle(hTestFile
);
674 /* Getting an itemidlist for the file. */
675 hr
= SHGetDesktopFolder(&psfDesktop
);
676 ok(hr
== S_OK
, "SHGetDesktopFolder failed! hr = %08x\n", hr
);
677 if (hr
!= S_OK
) return;
679 MultiByteToWideChar(CP_ACP
, 0, szTestFile
, -1, wszTestFile
, MAX_PATH
);
681 hr
= IShellFolder_ParseDisplayName(psfDesktop
, NULL
, NULL
, wszTestFile
, NULL
, &pidlTestFile
, NULL
);
682 ok(hr
== S_OK
, "Desktop->ParseDisplayName failed! hr = %08x\n", hr
);
684 IShellFolder_Release(psfDesktop
);
688 pidlLast
= ILFindLastID(pidlTestFile
);
689 ok(pidlLast
->mkid
.cb
>= 76, "Expected pidl length of at least 76, got %d.\n", pidlLast
->mkid
.cb
);
690 if (pidlLast
->mkid
.cb
>= 28) {
691 ok(!lstrcmpA((CHAR
*)&pidlLast
->mkid
.abID
[12], szFileName
),
692 "Filename should be stored as ansi-string at this position!\n");
694 /* WinXP and up store the filenames as both ANSI and UNICODE in the pidls */
695 if (pidlLast
->mkid
.cb
>= 76) {
696 ok(!lstrcmpW((WCHAR
*)&pidlLast
->mkid
.abID
[46], wszFileName
) ||
697 (pidlLast
->mkid
.cb
>= 94 && !lstrcmpW((WCHAR
*)&pidlLast
->mkid
.abID
[64], wszFileName
)) || /* Vista */
698 (pidlLast
->mkid
.cb
>= 98 && !lstrcmpW((WCHAR
*)&pidlLast
->mkid
.abID
[68], wszFileName
)) || /* Win7 */
699 (pidlLast
->mkid
.cb
>= 102 && !lstrcmpW((WCHAR
*)&pidlLast
->mkid
.abID
[72], wszFileName
)), /* Win8 */
700 "Filename should be stored as wchar-string at this position!\n");
703 /* It seems as if we cannot bind to regular files on windows, but only directories.
705 hr
= IShellFolder_BindToObject(psfDesktop
, pidlTestFile
, NULL
, &IID_IUnknown
, (VOID
**)&psfFile
);
706 ok (hr
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
) ||
707 hr
== E_NOTIMPL
, /* Vista */
710 IUnknown_Release(psfFile
);
713 /* Some tests for IShellFolder::SetNameOf */
714 hr
= SHBindToParent(pidlTestFile
, &IID_IShellFolder
, (void **)&psfPersonal
, &pidlLast
);
715 ok(hr
== S_OK
, "SHBindToParent failed! hr = %08x\n", hr
);
717 /* The pidl returned through the last parameter of SetNameOf is a simple one. */
718 hr
= IShellFolder_SetNameOf(psfPersonal
, NULL
, pidlLast
, wszDirName
, SHGDN_NORMAL
, &pidlNew
);
719 ok (hr
== S_OK
, "SetNameOf failed! hr = %08x\n", hr
);
721 ok (((ITEMIDLIST
*)((BYTE
*)pidlNew
+ pidlNew
->mkid
.cb
))->mkid
.cb
== 0,
722 "pidl returned from SetNameOf should be simple!\n");
724 /* Passing an absolute path to SetNameOf fails. The HRESULT code indicates that SetNameOf
725 * is implemented on top of SHFileOperation in WinXP. */
726 hr
= IShellFolder_SetNameOf(psfPersonal
, NULL
, pidlNew
, wszAbsoluteFilename
, SHGDN_FORPARSING
, NULL
);
727 ok (hr
== HRESULT_FROM_WIN32(ERROR_CANCELLED
), "SetNameOf succeeded! hr = %08x\n", hr
);
729 /* Rename the file back to its original name. SetNameOf ignores the fact, that the
730 * SHGDN flags specify an absolute path. */
731 hr
= IShellFolder_SetNameOf(psfPersonal
, NULL
, pidlNew
, wszFileName
, SHGDN_FORPARSING
, NULL
);
732 ok (hr
== S_OK
, "SetNameOf failed! hr = %08x\n", hr
);
735 IShellFolder_Release(psfPersonal
);
737 /* Deleting the file and the directory */
738 DeleteFileA(szTestFile
);
739 RemoveDirectoryA(szTestDir
);
741 /* SHGetPathFromIDListW still works, although the file is not present anymore. */
742 result
= SHGetPathFromIDListW(pidlTestFile
, wszTestFile2
);
743 ok (result
, "SHGetPathFromIDListW failed! Last error: %u\n", GetLastError());
744 ok (!lstrcmpiW(wszTestFile
, wszTestFile2
), "SHGetPathFromIDListW returns incorrect path!\n");
746 /* SHBindToParent fails, if called with a NULL PIDL. */
747 hr
= SHBindToParent(NULL
, &IID_IShellFolder
, (void **)&psfPersonal
, &pidlLast
);
748 ok (hr
== E_INVALIDARG
|| broken(hr
== E_OUTOFMEMORY
) /* XP */,
749 "SHBindToParent(NULL) should fail! hr = %08x\n", hr
);
751 /* But it succeeds with an empty PIDL. */
752 hr
= SHBindToParent(pidlEmpty
, &IID_IShellFolder
, (void **)&psfPersonal
, &pidlLast
);
753 ok (hr
== S_OK
, "SHBindToParent(empty PIDL) should succeed! hr = %08x\n", hr
);
754 ok (pidlLast
== pidlEmpty
, "The last element of an empty PIDL should be the PIDL itself!\n");
756 IShellFolder_Release(psfPersonal
);
758 /* Binding to the folder and querying the display name of the file also works. */
759 hr
= SHBindToParent(pidlTestFile
, &IID_IShellFolder
, (void **)&psfPersonal
, &pidlLast
);
760 ok (hr
== S_OK
, "SHBindToParent failed! hr = %08x\n", hr
);
762 IShellFolder_Release(psfDesktop
);
766 /* This test shows that Windows doesn't allocate a new pidlLast, but returns a pointer into
767 * pidlTestFile (In accordance with MSDN). */
768 ok (ILFindLastID(pidlTestFile
) == pidlLast
,
769 "SHBindToParent doesn't return the last id of the pidl param!\n");
771 hr
= IShellFolder_GetDisplayNameOf(psfPersonal
, pidlLast
, SHGDN_FORPARSING
, &strret
);
772 ok (hr
== S_OK
, "Personal->GetDisplayNameOf failed! hr = %08x\n", hr
);
774 IShellFolder_Release(psfDesktop
);
775 IShellFolder_Release(psfPersonal
);
779 hr
= StrRetToBufW(&strret
, pidlLast
, wszTestFile2
, MAX_PATH
);
780 ok (hr
== S_OK
, "StrRetToBufW failed! hr = %08x\n", hr
);
781 ok (!lstrcmpiW(wszTestFile
, wszTestFile2
), "GetDisplayNameOf returns incorrect path!\n");
783 ILFree(pidlTestFile
);
784 IShellFolder_Release(psfDesktop
);
785 IShellFolder_Release(psfPersonal
);
788 static void test_CallForAttributes(void)
794 LPSHELLFOLDER psfDesktop
;
795 LPITEMIDLIST pidlMyDocuments
;
796 DWORD dwAttributes
, dwCallForAttributes
, dwOrigAttributes
, dwOrigCallForAttributes
;
797 static const WCHAR wszAttributes
[] = { 'A','t','t','r','i','b','u','t','e','s',0 };
798 static const WCHAR wszCallForAttributes
[] = {
799 'C','a','l','l','F','o','r','A','t','t','r','i','b','u','t','e','s',0 };
800 static const WCHAR wszMyDocumentsKey
[] = {
801 'C','L','S','I','D','\\','{','4','5','0','D','8','F','B','A','-','A','D','2','5','-',
802 '1','1','D','0','-','9','8','A','8','-','0','8','0','0','3','6','1','B','1','1','0','3','}',
803 '\\','S','h','e','l','l','F','o','l','d','e','r',0 };
804 WCHAR wszMyDocuments
[] = {
805 ':',':','{','4','5','0','D','8','F','B','A','-','A','D','2','5','-','1','1','D','0','-',
806 '9','8','A','8','-','0','8','0','0','3','6','1','B','1','1','0','3','}',0 };
808 /* For the root of a namespace extension, the attributes are not queried by binding
809 * to the object and calling GetAttributesOf. Instead, the attributes are read from
810 * the registry value HKCR/CLSID/{...}/ShellFolder/Attributes. This is documented on MSDN.
812 * The MyDocuments shellfolder on WinXP has a HKCR/CLSID/{...}/ShellFolder/CallForAttributes
813 * value. It seems that if the folder is queried for one of the flags set in CallForAttributes,
814 * the shell does bind to the folder object and calls GetAttributesOf. This is not documented
815 * on MSDN. This test is meant to document the observed behaviour on WinXP SP2.
817 hr
= SHGetDesktopFolder(&psfDesktop
);
818 ok (hr
== S_OK
, "SHGetDesktopFolder failed! hr = %08x\n", hr
);
819 if (hr
!= S_OK
) return;
821 hr
= IShellFolder_ParseDisplayName(psfDesktop
, NULL
, NULL
, wszMyDocuments
, NULL
,
822 &pidlMyDocuments
, NULL
);
824 "Desktop's ParseDisplayName failed to parse MyDocuments's CLSID! hr = %08x\n", hr
);
826 IShellFolder_Release(psfDesktop
);
830 dwAttributes
= 0xffffffff;
831 hr
= IShellFolder_GetAttributesOf(psfDesktop
, 1,
832 (LPCITEMIDLIST
*)&pidlMyDocuments
, &dwAttributes
);
833 ok (hr
== S_OK
, "Desktop->GetAttributesOf(MyDocuments) failed! hr = %08x\n", hr
);
835 /* We need the following setup (as observed on WinXP SP2), for the tests to make sense. */
836 ok (dwAttributes
& SFGAO_FILESYSTEM
, "SFGAO_FILESYSTEM attribute is not set for MyDocuments!\n");
837 ok (!(dwAttributes
& SFGAO_ISSLOW
), "SFGAO_ISSLOW attribute is set for MyDocuments!\n");
838 ok (!(dwAttributes
& SFGAO_GHOSTED
), "SFGAO_GHOSTED attribute is set for MyDocuments!\n");
840 /* We don't have the MyDocuments shellfolder in wine yet, and thus we don't have the registry
841 * key. So the test will return at this point, if run on wine.
843 lResult
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, wszMyDocumentsKey
, 0, KEY_WRITE
|KEY_READ
, &hKey
);
844 ok (lResult
== ERROR_SUCCESS
||
845 lResult
== ERROR_ACCESS_DENIED
,
846 "RegOpenKeyEx failed! result: %08x\n", lResult
);
847 if (lResult
!= ERROR_SUCCESS
) {
848 if (lResult
== ERROR_ACCESS_DENIED
)
849 skip("Not enough rights to open the registry key\n");
850 ILFree(pidlMyDocuments
);
851 IShellFolder_Release(psfDesktop
);
855 /* Query MyDocuments' Attributes value, to be able to restore it later. */
856 dwSize
= sizeof(DWORD
);
857 lResult
= RegQueryValueExW(hKey
, wszAttributes
, NULL
, NULL
, (LPBYTE
)&dwOrigAttributes
, &dwSize
);
858 ok (lResult
== ERROR_SUCCESS
, "RegQueryValueEx failed! result: %08x\n", lResult
);
859 if (lResult
!= ERROR_SUCCESS
) {
861 ILFree(pidlMyDocuments
);
862 IShellFolder_Release(psfDesktop
);
866 /* Query MyDocuments' CallForAttributes value, to be able to restore it later. */
867 dwSize
= sizeof(DWORD
);
868 lResult
= RegQueryValueExW(hKey
, wszCallForAttributes
, NULL
, NULL
,
869 (LPBYTE
)&dwOrigCallForAttributes
, &dwSize
);
870 ok (lResult
== ERROR_SUCCESS
, "RegQueryValueEx failed! result: %08x\n", lResult
);
871 if (lResult
!= ERROR_SUCCESS
) {
873 ILFree(pidlMyDocuments
);
874 IShellFolder_Release(psfDesktop
);
878 /* Define via the Attributes value that MyDocuments attributes are SFGAO_ISSLOW and
879 * SFGAO_GHOSTED and that MyDocuments should be called for the SFGAO_ISSLOW and
880 * SFGAO_FILESYSTEM attributes. */
881 dwAttributes
= SFGAO_ISSLOW
|SFGAO_GHOSTED
;
882 RegSetValueExW(hKey
, wszAttributes
, 0, REG_DWORD
, (LPBYTE
)&dwAttributes
, sizeof(DWORD
));
883 dwCallForAttributes
= SFGAO_ISSLOW
|SFGAO_FILESYSTEM
;
884 RegSetValueExW(hKey
, wszCallForAttributes
, 0, REG_DWORD
,
885 (LPBYTE
)&dwCallForAttributes
, sizeof(DWORD
));
887 /* Although it is not set in CallForAttributes, the SFGAO_GHOSTED flag is reset by
888 * GetAttributesOf. It seems that once there is a single attribute queried, for which
889 * CallForAttributes is set, all flags are taken from the GetAttributesOf call and
890 * the flags in Attributes are ignored.
892 dwAttributes
= SFGAO_ISSLOW
|SFGAO_GHOSTED
|SFGAO_FILESYSTEM
;
893 hr
= IShellFolder_GetAttributesOf(psfDesktop
, 1,
894 (LPCITEMIDLIST
*)&pidlMyDocuments
, &dwAttributes
);
895 ok (hr
== S_OK
, "Desktop->GetAttributesOf(MyDocuments) failed! hr = %08x\n", hr
);
897 ok (dwAttributes
== SFGAO_FILESYSTEM
,
898 "Desktop->GetAttributes(MyDocuments) returned unexpected attributes: %08x\n",
901 /* Restore MyDocuments' original Attributes and CallForAttributes registry values */
902 RegSetValueExW(hKey
, wszAttributes
, 0, REG_DWORD
, (LPBYTE
)&dwOrigAttributes
, sizeof(DWORD
));
903 RegSetValueExW(hKey
, wszCallForAttributes
, 0, REG_DWORD
,
904 (LPBYTE
)&dwOrigCallForAttributes
, sizeof(DWORD
));
906 ILFree(pidlMyDocuments
);
907 IShellFolder_Release(psfDesktop
);
910 static void test_GetAttributesOf(void)
913 LPSHELLFOLDER psfDesktop
, psfMyComputer
;
914 SHITEMID emptyitem
= { 0, { 0 } };
915 LPCITEMIDLIST pidlEmpty
= (LPCITEMIDLIST
)&emptyitem
;
916 LPITEMIDLIST pidlMyComputer
;
918 static const DWORD desktopFlags
= SFGAO_STORAGE
| SFGAO_HASPROPSHEET
| SFGAO_STORAGEANCESTOR
|
919 SFGAO_FILESYSANCESTOR
| SFGAO_FOLDER
| SFGAO_FILESYSTEM
| SFGAO_HASSUBFOLDER
;
920 static const DWORD myComputerFlags
= SFGAO_CANRENAME
| SFGAO_CANDELETE
| SFGAO_HASPROPSHEET
|
921 SFGAO_DROPTARGET
| SFGAO_FILESYSANCESTOR
| SFGAO_FOLDER
| SFGAO_HASSUBFOLDER
;
922 WCHAR wszMyComputer
[] = {
923 ':',':','{','2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-',
924 'A','2','D','8','-','0','8','0','0','2','B','3','0','3','0','9','D','}',0 };
925 char cCurrDirA
[MAX_PATH
] = {0};
926 WCHAR cCurrDirW
[MAX_PATH
];
927 static WCHAR cTestDirW
[] = {'t','e','s','t','d','i','r',0};
928 IShellFolder
*IDesktopFolder
, *testIShellFolder
;
932 hr
= SHGetDesktopFolder(&psfDesktop
);
933 ok (hr
== S_OK
, "SHGetDesktopFolder failed! hr = %08x\n", hr
);
934 if (hr
!= S_OK
) return;
936 /* The Desktop attributes can be queried with a single empty itemidlist, .. */
937 dwFlags
= 0xffffffff;
938 hr
= IShellFolder_GetAttributesOf(psfDesktop
, 1, &pidlEmpty
, &dwFlags
);
939 ok (hr
== S_OK
, "Desktop->GetAttributesOf(empty pidl) failed! hr = %08x\n", hr
);
940 ok (dwFlags
== desktopFlags
, "Wrong Desktop attributes: %08x\n", dwFlags
);
942 /* .. or with no itemidlist at all. */
943 dwFlags
= 0xffffffff;
944 hr
= IShellFolder_GetAttributesOf(psfDesktop
, 0, NULL
, &dwFlags
);
945 ok (hr
== S_OK
, "Desktop->GetAttributesOf(NULL) failed! hr = %08x\n", hr
);
946 ok (dwFlags
== desktopFlags
, "Wrong Desktop attributes: %08x\n", dwFlags
);
948 /* Testing the attributes of the MyComputer shellfolder */
949 hr
= IShellFolder_ParseDisplayName(psfDesktop
, NULL
, NULL
, wszMyComputer
, NULL
, &pidlMyComputer
, NULL
);
950 ok (hr
== S_OK
, "Desktop's ParseDisplayName failed to parse MyComputer's CLSID! hr = %08x\n", hr
);
952 IShellFolder_Release(psfDesktop
);
956 /* Windows sets the SFGAO_CANLINK flag, when MyComputer is queried via the Desktop
957 * folder object. It doesn't do this, if MyComputer is queried directly (see below).
959 dwFlags
= 0xffffffff;
960 hr
= IShellFolder_GetAttributesOf(psfDesktop
, 1, (LPCITEMIDLIST
*)&pidlMyComputer
, &dwFlags
);
961 ok (hr
== S_OK
, "Desktop->GetAttributesOf(MyComputer) failed! hr = %08x\n", hr
);
963 ok (dwFlags
== (myComputerFlags
| SFGAO_CANLINK
), "Wrong MyComputer attributes: %08x\n", dwFlags
);
965 hr
= IShellFolder_BindToObject(psfDesktop
, pidlMyComputer
, NULL
, &IID_IShellFolder
, (LPVOID
*)&psfMyComputer
);
966 ok (hr
== S_OK
, "Desktop failed to bind to MyComputer object! hr = %08x\n", hr
);
967 IShellFolder_Release(psfDesktop
);
968 ILFree(pidlMyComputer
);
969 if (hr
!= S_OK
) return;
971 hr
= IShellFolder_GetAttributesOf(psfMyComputer
, 1, &pidlEmpty
, &dwFlags
);
973 ok (hr
== E_INVALIDARG
, "MyComputer->GetAttributesOf(empty pidl) should fail! hr = %08x\n", hr
);
975 dwFlags
= 0xffffffff;
976 hr
= IShellFolder_GetAttributesOf(psfMyComputer
, 0, NULL
, &dwFlags
);
977 ok (hr
== S_OK
, "MyComputer->GetAttributesOf(NULL) failed! hr = %08x\n", hr
);
979 ok (dwFlags
== myComputerFlags
, "Wrong MyComputer attributes: %08x\n", dwFlags
);
981 IShellFolder_Release(psfMyComputer
);
983 GetCurrentDirectoryA(MAX_PATH
, cCurrDirA
);
984 len
= lstrlenA(cCurrDirA
);
987 win_skip("GetCurrentDirectoryA returned empty string. Skipping test_GetAttributesOf\n");
990 if (len
> 3 && cCurrDirA
[len
-1] == '\\')
991 cCurrDirA
[len
-1] = 0;
993 /* create test directory */
994 CreateFilesFolders();
996 MultiByteToWideChar(CP_ACP
, 0, cCurrDirA
, -1, cCurrDirW
, MAX_PATH
);
998 hr
= SHGetDesktopFolder(&IDesktopFolder
);
999 ok(hr
== S_OK
, "SHGetDesktopfolder failed %08x\n", hr
);
1001 hr
= IShellFolder_ParseDisplayName(IDesktopFolder
, NULL
, NULL
, cCurrDirW
, NULL
, &newPIDL
, 0);
1002 ok(hr
== S_OK
, "ParseDisplayName failed %08x\n", hr
);
1004 hr
= IShellFolder_BindToObject(IDesktopFolder
, newPIDL
, NULL
, (REFIID
)&IID_IShellFolder
, (LPVOID
*)&testIShellFolder
);
1005 ok(hr
== S_OK
, "BindToObject failed %08x\n", hr
);
1009 /* get relative PIDL */
1010 hr
= IShellFolder_ParseDisplayName(testIShellFolder
, NULL
, NULL
, cTestDirW
, NULL
, &newPIDL
, 0);
1011 ok(hr
== S_OK
, "ParseDisplayName failed %08x\n", hr
);
1013 /* test the shell attributes of the test directory using the relative PIDL */
1014 dwFlags
= SFGAO_FOLDER
;
1015 hr
= IShellFolder_GetAttributesOf(testIShellFolder
, 1, (LPCITEMIDLIST
*)&newPIDL
, &dwFlags
);
1016 ok (hr
== S_OK
, "Desktop->GetAttributesOf() failed! hr = %08x\n", hr
);
1017 ok ((dwFlags
&SFGAO_FOLDER
), "Wrong directory attribute for relative PIDL: %08x\n", dwFlags
);
1022 /* append testdirectory name to path */
1023 if (cCurrDirA
[len
-1] == '\\')
1024 cCurrDirA
[len
-1] = 0;
1025 lstrcatA(cCurrDirA
, "\\testdir");
1026 MultiByteToWideChar(CP_ACP
, 0, cCurrDirA
, -1, cCurrDirW
, MAX_PATH
);
1028 hr
= IShellFolder_ParseDisplayName(IDesktopFolder
, NULL
, NULL
, cCurrDirW
, NULL
, &newPIDL
, 0);
1029 ok(hr
== S_OK
, "ParseDisplayName failed %08x\n", hr
);
1031 /* test the shell attributes of the test directory using the absolute PIDL */
1032 dwFlags
= SFGAO_FOLDER
;
1033 hr
= IShellFolder_GetAttributesOf(IDesktopFolder
, 1, (LPCITEMIDLIST
*)&newPIDL
, &dwFlags
);
1034 ok (hr
== S_OK
, "Desktop->GetAttributesOf() failed! hr = %08x\n", hr
);
1035 ok ((dwFlags
&SFGAO_FOLDER
), "Wrong directory attribute for absolute PIDL: %08x\n", dwFlags
);
1040 IShellFolder_Release(testIShellFolder
);
1044 IShellFolder_Release(IDesktopFolder
);
1047 static void test_SHGetPathFromIDList(void)
1049 SHITEMID emptyitem
= { 0, { 0 } };
1050 LPCITEMIDLIST pidlEmpty
= (LPCITEMIDLIST
)&emptyitem
;
1051 LPITEMIDLIST pidlMyComputer
;
1052 WCHAR wszPath
[MAX_PATH
], wszDesktop
[MAX_PATH
];
1055 LPSHELLFOLDER psfDesktop
;
1056 WCHAR wszMyComputer
[] = {
1057 ':',':','{','2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-',
1058 'A','2','D','8','-','0','8','0','0','2','B','3','0','3','0','9','D','}',0 };
1059 WCHAR wszFileName
[MAX_PATH
];
1060 LPITEMIDLIST pidlTestFile
;
1063 static WCHAR wszTestFile
[] = {
1064 'w','i','n','e','t','e','s','t','.','f','o','o',0 };
1065 LPITEMIDLIST pidlPrograms
;
1067 /* Calling SHGetPathFromIDListW with no pidl should return the empty string */
1070 result
= SHGetPathFromIDListW(NULL
, wszPath
);
1071 ok(!result
, "Expected failure\n");
1072 ok(!wszPath
[0], "Expected empty string\n");
1074 /* Calling SHGetPathFromIDListW with an empty pidl should return the desktop folder's path. */
1075 result
= SHGetSpecialFolderPathW(NULL
, wszDesktop
, CSIDL_DESKTOP
, FALSE
);
1076 ok(result
, "SHGetSpecialFolderPathW(CSIDL_DESKTOP) failed! Last error: %u\n", GetLastError());
1077 if (!result
) return;
1079 result
= SHGetPathFromIDListW(pidlEmpty
, wszPath
);
1080 ok(result
, "SHGetPathFromIDListW failed! Last error: %u\n", GetLastError());
1081 if (!result
) return;
1082 ok(!lstrcmpiW(wszDesktop
, wszPath
), "SHGetPathFromIDListW didn't return desktop path for empty pidl!\n");
1084 /* MyComputer does not map to a filesystem path. SHGetPathFromIDListW should fail. */
1085 hr
= SHGetDesktopFolder(&psfDesktop
);
1086 ok (hr
== S_OK
, "SHGetDesktopFolder failed! hr = %08x\n", hr
);
1087 if (hr
!= S_OK
) return;
1089 hr
= IShellFolder_ParseDisplayName(psfDesktop
, NULL
, NULL
, wszMyComputer
, NULL
, &pidlMyComputer
, NULL
);
1090 ok (hr
== S_OK
, "Desktop's ParseDisplayName failed to parse MyComputer's CLSID! hr = %08x\n", hr
);
1092 IShellFolder_Release(psfDesktop
);
1096 SetLastError(0xdeadbeef);
1099 result
= SHGetPathFromIDListW(pidlMyComputer
, wszPath
);
1100 ok (!result
, "SHGetPathFromIDListW succeeded where it shouldn't!\n");
1101 ok (GetLastError()==0xdeadbeef ||
1102 GetLastError()==ERROR_SUCCESS
, /* Vista and higher */
1103 "Unexpected last error from SHGetPathFromIDListW: %u\n", GetLastError());
1104 ok (!wszPath
[0], "Expected empty path\n");
1106 IShellFolder_Release(psfDesktop
);
1110 ILFree(pidlMyComputer
);
1112 result
= SHGetSpecialFolderPathW(NULL
, wszFileName
, CSIDL_DESKTOPDIRECTORY
, FALSE
);
1113 ok(result
, "SHGetSpecialFolderPathW failed! Last error: %u\n", GetLastError());
1115 IShellFolder_Release(psfDesktop
);
1118 myPathAddBackslashW(wszFileName
);
1119 lstrcatW(wszFileName
, wszTestFile
);
1120 hTestFile
= CreateFileW(wszFileName
, GENERIC_WRITE
, 0, NULL
, CREATE_NEW
, 0, NULL
);
1121 ok(hTestFile
!= INVALID_HANDLE_VALUE
, "CreateFileW failed! Last error: %u\n", GetLastError());
1122 if (hTestFile
== INVALID_HANDLE_VALUE
) {
1123 IShellFolder_Release(psfDesktop
);
1126 CloseHandle(hTestFile
);
1128 hr
= IShellFolder_ParseDisplayName(psfDesktop
, NULL
, NULL
, wszTestFile
, NULL
, &pidlTestFile
, NULL
);
1129 ok (hr
== S_OK
, "Desktop's ParseDisplayName failed to parse filename hr = %08x\n", hr
);
1131 IShellFolder_Release(psfDesktop
);
1132 DeleteFileW(wszFileName
);
1133 ILFree(pidlTestFile
);
1137 /* This test is to show that the Desktop shellfolder prepends the CSIDL_DESKTOPDIRECTORY
1138 * path for files placed on the desktop, if called with SHGDN_FORPARSING. */
1139 hr
= IShellFolder_GetDisplayNameOf(psfDesktop
, pidlTestFile
, SHGDN_FORPARSING
, &strret
);
1140 ok (hr
== S_OK
, "Desktop's GetDisplayNamfOf failed! hr = %08x\n", hr
);
1141 IShellFolder_Release(psfDesktop
);
1142 DeleteFileW(wszFileName
);
1144 ILFree(pidlTestFile
);
1147 StrRetToBufW(&strret
, pidlTestFile
, wszPath
, MAX_PATH
);
1148 ok(0 == lstrcmpW(wszFileName
, wszPath
),
1149 "Desktop->GetDisplayNameOf(pidlTestFile, SHGDN_FORPARSING) "
1150 "returned incorrect path for file placed on desktop\n");
1152 result
= SHGetPathFromIDListW(pidlTestFile
, wszPath
);
1153 ok(result
, "SHGetPathFromIDListW failed! Last error: %u\n", GetLastError());
1154 ok(0 == lstrcmpW(wszFileName
, wszPath
), "SHGetPathFromIDListW returned incorrect path for file placed on desktop\n");
1156 if (pSHGetPathFromIDListEx
)
1158 result
= pSHGetPathFromIDListEx(pidlEmpty
, wszPath
, MAX_PATH
, SFGAO_FILESYSTEM
);
1159 ok(result
, "SHGetPathFromIDListEx failed: %u\n", GetLastError());
1160 ok(!lstrcmpiW(wszDesktop
, wszPath
), "Unexpected SHGetPathFromIDListEx result %s, expected %s\n",
1161 wine_dbgstr_w(wszPath
), wine_dbgstr_w(wszDesktop
));
1163 result
= pSHGetPathFromIDListEx(pidlTestFile
, wszPath
, MAX_PATH
, SFGAO_FILESYSTEM
);
1164 ok(result
, "SHGetPathFromIDListEx failed: %u\n", GetLastError());
1165 ok(!lstrcmpiW(wszFileName
, wszPath
), "Unexpected SHGetPathFromIDListEx result %s, expected %s\n",
1166 wine_dbgstr_w(wszPath
), wine_dbgstr_w(wszFileName
));
1168 SetLastError(0xdeadbeef);
1169 memset(wszPath
, 0x55, sizeof(wszPath
));
1170 result
= pSHGetPathFromIDListEx(pidlTestFile
, wszPath
, 5, SFGAO_FILESYSTEM
);
1171 ok(!result
, "SHGetPathFromIDListEx returned: %x(%u)\n", result
, GetLastError());
1173 SetLastError(0xdeadbeef);
1174 memset(wszPath
, 0x55, sizeof(wszPath
));
1175 result
= pSHGetPathFromIDListEx(pidlEmpty
, wszPath
, 5, SFGAO_FILESYSTEM
);
1176 ok(!result
, "SHGetPathFromIDListEx returned: %x(%u)\n", result
, GetLastError());
1179 win_skip("SHGetPathFromIDListEx not available\n");
1181 ILFree(pidlTestFile
);
1183 /* Test if we can get the path from the start menu "program files" PIDL. */
1184 hr
= SHGetSpecialFolderLocation(NULL
, CSIDL_PROGRAM_FILES
, &pidlPrograms
);
1185 ok(hr
== S_OK
, "SHGetFolderLocation failed: 0x%08x\n", hr
);
1187 SetLastError(0xdeadbeef);
1188 result
= SHGetPathFromIDListW(pidlPrograms
, wszPath
);
1189 ILFree(pidlPrograms
);
1190 ok(result
, "SHGetPathFromIDListW failed\n");
1193 static void test_EnumObjects_and_CompareIDs(void)
1195 ITEMIDLIST
*newPIDL
;
1196 IShellFolder
*IDesktopFolder
, *testIShellFolder
;
1197 char cCurrDirA
[MAX_PATH
] = {0};
1198 static const CHAR cTestDirA
[] = "\\testdir";
1199 WCHAR cTestDirW
[MAX_PATH
];
1203 GetCurrentDirectoryA(MAX_PATH
, cCurrDirA
);
1204 len
= lstrlenA(cCurrDirA
);
1207 win_skip("GetCurrentDirectoryA returned empty string. Skipping test_EnumObjects_and_CompareIDs\n");
1210 if(cCurrDirA
[len
-1] == '\\')
1211 cCurrDirA
[len
-1] = 0;
1213 lstrcatA(cCurrDirA
, cTestDirA
);
1214 MultiByteToWideChar(CP_ACP
, 0, cCurrDirA
, -1, cTestDirW
, MAX_PATH
);
1216 hr
= SHGetDesktopFolder(&IDesktopFolder
);
1217 ok(hr
== S_OK
, "SHGetDesktopfolder failed %08x\n", hr
);
1219 CreateFilesFolders();
1221 hr
= IShellFolder_ParseDisplayName(IDesktopFolder
, NULL
, NULL
, cTestDirW
, NULL
, &newPIDL
, 0);
1222 ok(hr
== S_OK
, "ParseDisplayName failed %08x\n", hr
);
1224 hr
= IShellFolder_BindToObject(IDesktopFolder
, newPIDL
, NULL
, (REFIID
)&IID_IShellFolder
, (LPVOID
*)&testIShellFolder
);
1225 ok(hr
== S_OK
, "BindToObject failed %08x\n", hr
);
1227 test_EnumObjects(testIShellFolder
);
1229 IShellFolder_Release(testIShellFolder
);
1235 IShellFolder_Release(IDesktopFolder
);
1238 /* A simple implementation of an IPropertyBag, which returns fixed values for
1239 * 'Target' and 'Attributes' properties.
1241 static HRESULT WINAPI
InitPropertyBag_IPropertyBag_QueryInterface(IPropertyBag
*iface
, REFIID riid
,
1245 return E_INVALIDARG
;
1247 if (IsEqualIID(&IID_IUnknown
, riid
) || IsEqualIID(&IID_IPropertyBag
, riid
)) {
1250 ok (FALSE
, "InitPropertyBag asked for unknown interface!\n");
1251 return E_NOINTERFACE
;
1254 IPropertyBag_AddRef(iface
);
1258 static ULONG WINAPI
InitPropertyBag_IPropertyBag_AddRef(IPropertyBag
*iface
) {
1262 static ULONG WINAPI
InitPropertyBag_IPropertyBag_Release(IPropertyBag
*iface
) {
1266 static HRESULT WINAPI
InitPropertyBag_IPropertyBag_Read(IPropertyBag
*iface
, LPCOLESTR pszPropName
,
1267 VARIANT
*pVar
, IErrorLog
*pErrorLog
)
1269 static const WCHAR wszTargetSpecialFolder
[] = {
1270 'T','a','r','g','e','t','S','p','e','c','i','a','l','F','o','l','d','e','r',0 };
1271 static const WCHAR wszTarget
[] = {
1272 'T','a','r','g','e','t',0 };
1273 static const WCHAR wszAttributes
[] = {
1274 'A','t','t','r','i','b','u','t','e','s',0 };
1275 static const WCHAR wszResolveLinkFlags
[] = {
1276 'R','e','s','o','l','v','e','L','i','n','k','F','l','a','g','s',0 };
1277 static const WCHAR wszTargetKnownFolder
[] = {
1278 'T','a','r','g','e','t','K','n','o','w','n','F','o','l','d','e','r',0 };
1279 static const WCHAR wszCLSID
[] = {
1280 'C','L','S','I','D',0 };
1282 if (!lstrcmpW(pszPropName
, wszTargetSpecialFolder
)) {
1283 ok(V_VT(pVar
) == VT_I4
, "Wrong variant type for 'TargetSpecialFolder' property!\n");
1284 return E_INVALIDARG
;
1287 if (!lstrcmpW(pszPropName
, wszResolveLinkFlags
))
1289 ok(V_VT(pVar
) == VT_UI4
, "Wrong variant type for 'ResolveLinkFlags' property!\n");
1290 return E_INVALIDARG
;
1293 if (!lstrcmpW(pszPropName
, wszTarget
)) {
1294 WCHAR wszPath
[MAX_PATH
];
1297 ok(V_VT(pVar
) == VT_BSTR
, "Wrong variant type for 'Target' property!\n");
1298 if (V_VT(pVar
) != VT_BSTR
) return E_INVALIDARG
;
1300 result
= SHGetSpecialFolderPathW(NULL
, wszPath
, CSIDL_DESKTOPDIRECTORY
, FALSE
);
1301 ok(result
, "SHGetSpecialFolderPathW(DESKTOPDIRECTORY) failed! %u\n", GetLastError());
1302 if (!result
) return E_INVALIDARG
;
1304 V_BSTR(pVar
) = SysAllocString(wszPath
);
1308 if (!lstrcmpW(pszPropName
, wszAttributes
)) {
1309 ok(V_VT(pVar
) == VT_UI4
, "Wrong variant type for 'Attributes' property!\n");
1310 if (V_VT(pVar
) != VT_UI4
) return E_INVALIDARG
;
1311 V_UI4(pVar
) = SFGAO_FOLDER
|SFGAO_HASSUBFOLDER
|SFGAO_FILESYSANCESTOR
|
1312 SFGAO_CANRENAME
|SFGAO_FILESYSTEM
;
1316 if (!lstrcmpW(pszPropName
, wszTargetKnownFolder
)) {
1317 ok(V_VT(pVar
) == VT_BSTR
, "Wrong variant type for 'TargetKnownFolder' property!\n");
1319 return E_INVALIDARG
;
1322 if (!lstrcmpW(pszPropName
, wszCLSID
)) {
1323 ok(V_VT(pVar
) == VT_EMPTY
, "Wrong variant type for 'CLSID' property!\n");
1325 return E_INVALIDARG
;
1328 ok(FALSE
, "PropertyBag was asked for unknown property %s (vt=%d)!\n", wine_dbgstr_w(pszPropName
), V_VT(pVar
));
1329 return E_INVALIDARG
;
1332 static HRESULT WINAPI
InitPropertyBag_IPropertyBag_Write(IPropertyBag
*iface
, LPCOLESTR pszPropName
,
1335 ok(FALSE
, "Unexpected call to IPropertyBag_Write\n");
1339 static const IPropertyBagVtbl InitPropertyBag_IPropertyBagVtbl
= {
1340 InitPropertyBag_IPropertyBag_QueryInterface
,
1341 InitPropertyBag_IPropertyBag_AddRef
,
1342 InitPropertyBag_IPropertyBag_Release
,
1343 InitPropertyBag_IPropertyBag_Read
,
1344 InitPropertyBag_IPropertyBag_Write
1347 static struct IPropertyBag InitPropertyBag
= {
1348 &InitPropertyBag_IPropertyBagVtbl
1351 static void test_FolderShortcut(void) {
1352 IPersistPropertyBag
*pPersistPropertyBag
;
1353 IShellFolder
*pShellFolder
, *pDesktopFolder
;
1354 IPersistFolder3
*pPersistFolder3
;
1357 WCHAR wszDesktopPath
[MAX_PATH
], wszBuffer
[MAX_PATH
];
1360 LPITEMIDLIST pidlCurrentFolder
, pidlWineTestFolder
, pidlSubFolder
;
1362 WCHAR wszWineTestFolder
[] = {
1363 ':',':','{','9','B','3','5','2','E','B','F','-','2','7','6','5','-','4','5','C','1','-',
1364 'B','4','C','6','-','8','5','C','C','7','F','7','A','B','C','6','4','}',0 };
1365 WCHAR wszShellExtKey
[] = { 'S','o','f','t','w','a','r','e','\\',
1366 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
1367 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
1368 'E','x','p','l','o','r','e','r','\\','D','e','s','k','t','o','p','\\',
1369 'N','a','m','e','S','p','a','c','e','\\',
1370 '{','9','b','3','5','2','e','b','f','-','2','7','6','5','-','4','5','c','1','-',
1371 'b','4','c','6','-','8','5','c','c','7','f','7','a','b','c','6','4','}',0 };
1373 WCHAR wszSomeSubFolder
[] = { 'S','u','b','F','o','l','d','e','r', 0};
1374 static const GUID CLSID_UnixDosFolder
=
1375 {0x9d20aae8, 0x0625, 0x44b0, {0x9c, 0xa7, 0x71, 0x88, 0x9c, 0x22, 0x54, 0xd9}};
1377 /* These tests basically show, that CLSID_FolderShortcuts are initialized
1378 * via their IPersistPropertyBag interface. And that the target folder
1379 * is taken from the IPropertyBag's 'Target' property.
1381 hr
= CoCreateInstance(&CLSID_FolderShortcut
, NULL
, CLSCTX_INPROC_SERVER
,
1382 &IID_IPersistPropertyBag
, (LPVOID
*)&pPersistPropertyBag
);
1383 if (hr
== REGDB_E_CLASSNOTREG
) {
1384 win_skip("CLSID_FolderShortcut is not implemented\n");
1387 ok (hr
== S_OK
, "CoCreateInstance failed! hr = 0x%08x\n", hr
);
1388 if (hr
!= S_OK
) return;
1390 hr
= IPersistPropertyBag_Load(pPersistPropertyBag
, &InitPropertyBag
, NULL
);
1391 ok(hr
== S_OK
, "IPersistPropertyBag_Load failed! hr = %08x\n", hr
);
1393 IPersistPropertyBag_Release(pPersistPropertyBag
);
1397 hr
= IPersistPropertyBag_QueryInterface(pPersistPropertyBag
, &IID_IShellFolder
,
1398 (LPVOID
*)&pShellFolder
);
1399 IPersistPropertyBag_Release(pPersistPropertyBag
);
1400 ok(hr
== S_OK
, "IPersistPropertyBag_QueryInterface(IShellFolder) failed! hr = %08x\n", hr
);
1401 if (hr
!= S_OK
) return;
1403 hr
= IShellFolder_GetDisplayNameOf(pShellFolder
, NULL
, SHGDN_FORPARSING
, &strret
);
1404 ok(hr
== S_OK
|| broken(hr
== E_INVALIDARG
) /* win10 */,
1405 "IShellFolder_GetDisplayNameOf(NULL) failed! hr = %08x\n", hr
);
1407 IShellFolder_Release(pShellFolder
);
1411 result
= SHGetSpecialFolderPathW(NULL
, wszDesktopPath
, CSIDL_DESKTOPDIRECTORY
, FALSE
);
1412 ok(result
, "SHGetSpecialFolderPathW(CSIDL_DESKTOPDIRECTORY) failed! %u\n", GetLastError());
1413 if (!result
) return;
1415 StrRetToBufW(&strret
, NULL
, wszBuffer
, MAX_PATH
);
1416 ok(!lstrcmpiW(wszDesktopPath
, wszBuffer
), "FolderShortcut returned incorrect folder!\n");
1418 hr
= IShellFolder_QueryInterface(pShellFolder
, &IID_IPersistFolder3
, (LPVOID
*)&pPersistFolder3
);
1419 IShellFolder_Release(pShellFolder
);
1420 ok(hr
== S_OK
, "IShellFolder_QueryInterface(IID_IPersistFolder3 failed! hr = 0x%08x\n", hr
);
1421 if (hr
!= S_OK
) return;
1423 hr
= IPersistFolder3_GetClassID(pPersistFolder3
, &clsid
);
1424 ok(hr
== S_OK
, "IPersistFolder3_GetClassID failed! hr=0x%08x\n", hr
);
1425 ok(IsEqualCLSID(&clsid
, &CLSID_FolderShortcut
), "Unexpected CLSID!\n");
1427 hr
= IPersistFolder3_GetCurFolder(pPersistFolder3
, &pidlCurrentFolder
);
1428 todo_wine
ok(hr
== S_FALSE
, "IPersistFolder3_GetCurFolder failed! hr=0x%08x\n", hr
);
1429 ok(!pidlCurrentFolder
, "IPersistFolder3_GetCurFolder should return a NULL pidl!\n");
1431 /* For FolderShortcut objects, the Initialize method initialized the folder's position in the
1432 * shell namespace. The target folder, read from the property bag above, remains untouched.
1433 * The following tests show this: The itemidlist for some imaginary shellfolder object
1434 * is created and the FolderShortcut is initialized with it. GetCurFolder now returns this
1435 * itemidlist, but GetDisplayNameOf still returns the path from above.
1437 hr
= SHGetDesktopFolder(&pDesktopFolder
);
1438 ok (hr
== S_OK
, "SHGetDesktopFolder failed! hr = %08x\n", hr
);
1439 if (hr
!= S_OK
) return;
1441 /* Temporarily register WineTestFolder as a shell namespace extension at the Desktop.
1442 * Otherwise ParseDisplayName fails on WinXP with E_INVALIDARG */
1443 RegCreateKeyW(HKEY_CURRENT_USER
, wszShellExtKey
, &hShellExtKey
);
1444 RegCloseKey(hShellExtKey
);
1445 hr
= IShellFolder_ParseDisplayName(pDesktopFolder
, NULL
, NULL
, wszWineTestFolder
, NULL
,
1446 &pidlWineTestFolder
, NULL
);
1447 RegDeleteKeyW(HKEY_CURRENT_USER
, wszShellExtKey
);
1448 IShellFolder_Release(pDesktopFolder
);
1449 ok (hr
== S_OK
, "IShellFolder::ParseDisplayName failed! hr = %08x\n", hr
);
1450 if (hr
!= S_OK
) return;
1452 hr
= IPersistFolder3_Initialize(pPersistFolder3
, pidlWineTestFolder
);
1453 ok (hr
== S_OK
, "IPersistFolder3::Initialize failed! hr = %08x\n", hr
);
1455 IPersistFolder3_Release(pPersistFolder3
);
1456 ILFree(pidlWineTestFolder
);
1460 hr
= IPersistFolder3_GetCurFolder(pPersistFolder3
, &pidlCurrentFolder
);
1461 ok(hr
== S_OK
, "IPersistFolder3_GetCurFolder failed! hr=0x%08x\n", hr
);
1462 ok(ILIsEqual(pidlCurrentFolder
, pidlWineTestFolder
),
1463 "IPersistFolder3_GetCurFolder should return pidlWineTestFolder!\n");
1464 ILFree(pidlCurrentFolder
);
1465 ILFree(pidlWineTestFolder
);
1467 hr
= IPersistFolder3_QueryInterface(pPersistFolder3
, &IID_IShellFolder
, (LPVOID
*)&pShellFolder
);
1468 IPersistFolder3_Release(pPersistFolder3
);
1469 ok(hr
== S_OK
, "IPersistFolder3_QueryInterface(IShellFolder) failed! hr = %08x\n", hr
);
1470 if (hr
!= S_OK
) return;
1472 hr
= IShellFolder_GetDisplayNameOf(pShellFolder
, NULL
, SHGDN_FORPARSING
, &strret
);
1473 ok(hr
== S_OK
, "IShellFolder_GetDisplayNameOf(NULL) failed! hr = %08x\n", hr
);
1475 IShellFolder_Release(pShellFolder
);
1479 StrRetToBufW(&strret
, NULL
, wszBuffer
, MAX_PATH
);
1480 ok(!lstrcmpiW(wszDesktopPath
, wszBuffer
), "FolderShortcut returned incorrect folder!\n");
1482 /* Next few lines are meant to show that children of FolderShortcuts are not FolderShortcuts,
1483 * but ShellFSFolders. */
1484 myPathAddBackslashW(wszDesktopPath
);
1485 lstrcatW(wszDesktopPath
, wszSomeSubFolder
);
1486 if (!CreateDirectoryW(wszDesktopPath
, NULL
)) {
1487 IShellFolder_Release(pShellFolder
);
1491 hr
= IShellFolder_ParseDisplayName(pShellFolder
, NULL
, NULL
, wszSomeSubFolder
, NULL
,
1492 &pidlSubFolder
, NULL
);
1493 RemoveDirectoryW(wszDesktopPath
);
1494 ok (hr
== S_OK
, "IShellFolder::ParseDisplayName failed! hr = %08x\n", hr
);
1496 IShellFolder_Release(pShellFolder
);
1500 hr
= IShellFolder_BindToObject(pShellFolder
, pidlSubFolder
, NULL
, &IID_IPersistFolder3
,
1501 (LPVOID
*)&pPersistFolder3
);
1502 IShellFolder_Release(pShellFolder
);
1503 ILFree(pidlSubFolder
);
1504 ok (hr
== S_OK
, "IShellFolder::BindToObject failed! hr = %08x\n", hr
);
1508 /* On windows, we expect CLSID_ShellFSFolder. On wine we relax this constraint
1509 * a little bit and also allow CLSID_UnixDosFolder. */
1510 hr
= IPersistFolder3_GetClassID(pPersistFolder3
, &clsid
);
1511 ok(hr
== S_OK
, "IPersistFolder3_GetClassID failed! hr=0x%08x\n", hr
);
1512 ok(IsEqualCLSID(&clsid
, &CLSID_ShellFSFolder
) || IsEqualCLSID(&clsid
, &CLSID_UnixDosFolder
),
1513 "IPersistFolder3::GetClassID returned unexpected CLSID!\n");
1515 IPersistFolder3_Release(pPersistFolder3
);
1518 #include "pshpack1.h"
1519 struct FileStructA
{
1523 WORD uFileDate
; /* In our current implementation this is */
1524 WORD uFileTime
; /* FileTimeToDosDate(WIN32_FIND_DATA->ftLastWriteTime) */
1529 struct FileStructW
{
1530 WORD cbLen
; /* Length of this element. */
1531 BYTE abFooBar1
[6]; /* Beyond any recognition. */
1532 WORD uDate
; /* FileTimeToDosDate(WIN32_FIND_DATA->ftCreationTime)? */
1533 WORD uTime
; /* (this is currently speculation) */
1534 WORD uDate2
; /* FileTimeToDosDate(WIN32_FIND_DATA->ftLastAccessTime)? */
1535 WORD uTime2
; /* (this is currently speculation) */
1536 BYTE abFooBar2
[4]; /* Beyond any recognition. */
1537 WCHAR wszName
[1]; /* The long filename in unicode. */
1538 /* Just for documentation: Right after the unicode string: */
1539 WORD cbOffset
; /* FileStructW's offset from the beginning of the SHITMEID.
1540 * SHITEMID->cb == uOffset + cbLen */
1542 #include "poppack.h"
1544 static void test_ITEMIDLIST_format(void) {
1545 WCHAR wszPersonal
[MAX_PATH
];
1546 LPSHELLFOLDER psfDesktop
, psfPersonal
;
1547 LPITEMIDLIST pidlPersonal
, pidlFile
;
1551 WCHAR wszFile
[3][17] = { { 'e','v','e','n','_',0 }, { 'o','d','d','_',0 },
1552 { 'l','o','n','g','e','r','_','t','h','a','n','.','8','_','3',0 } };
1555 bResult
= SHGetSpecialFolderPathW(NULL
, wszPersonal
, CSIDL_PERSONAL
, FALSE
);
1556 ok(bResult
, "SHGetSpecialFolderPathW failed! Last error: %u\n", GetLastError());
1557 if (!bResult
) return;
1559 SetLastError(0xdeadbeef);
1560 bResult
= SetCurrentDirectoryW(wszPersonal
);
1561 if (!bResult
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
) {
1562 win_skip("Most W-calls are not implemented\n");
1565 ok(bResult
, "SetCurrentDirectory failed! Last error: %u\n", GetLastError());
1566 if (!bResult
) return;
1568 hr
= SHGetDesktopFolder(&psfDesktop
);
1569 ok(hr
== S_OK
, "SHGetDesktopFolder failed! hr: %08x\n", hr
);
1570 if (hr
!= S_OK
) return;
1572 hr
= IShellFolder_ParseDisplayName(psfDesktop
, NULL
, NULL
, wszPersonal
, NULL
, &pidlPersonal
, NULL
);
1573 ok(hr
== S_OK
, "psfDesktop->ParseDisplayName failed! hr = %08x\n", hr
);
1575 IShellFolder_Release(psfDesktop
);
1579 hr
= IShellFolder_BindToObject(psfDesktop
, pidlPersonal
, NULL
, &IID_IShellFolder
,
1580 (LPVOID
*)&psfPersonal
);
1581 IShellFolder_Release(psfDesktop
);
1582 ILFree(pidlPersonal
);
1583 ok(hr
== S_OK
, "psfDesktop->BindToObject failed! hr = %08x\n", hr
);
1584 if (hr
!= S_OK
) return;
1586 for (i
=0; i
<3; i
++) {
1587 CHAR szFile
[MAX_PATH
];
1588 struct FileStructA
*pFileStructA
;
1591 WideCharToMultiByte(CP_ACP
, 0, wszFile
[i
], -1, szFile
, MAX_PATH
, NULL
, NULL
);
1593 hFile
= CreateFileW(wszFile
[i
], GENERIC_WRITE
, 0, NULL
, CREATE_NEW
, FILE_FLAG_WRITE_THROUGH
, NULL
);
1594 ok(hFile
!= INVALID_HANDLE_VALUE
, "CreateFile failed! (%u)\n", GetLastError());
1595 if (hFile
== INVALID_HANDLE_VALUE
) {
1596 IShellFolder_Release(psfPersonal
);
1601 hr
= IShellFolder_ParseDisplayName(psfPersonal
, NULL
, NULL
, wszFile
[i
], NULL
, &pidlFile
, NULL
);
1602 DeleteFileW(wszFile
[i
]);
1603 ok(hr
== S_OK
, "psfPersonal->ParseDisplayName failed! hr: %08x\n", hr
);
1605 IShellFolder_Release(psfPersonal
);
1609 pFileStructA
= (struct FileStructA
*)pidlFile
->mkid
.abID
;
1610 ok(pFileStructA
->type
== 0x32, "PIDLTYPE should be 0x32!\n");
1611 ok(pFileStructA
->dummy
== 0x00, "Dummy Byte should be 0x00!\n");
1612 ok(pFileStructA
->dwFileSize
== 0, "Filesize should be zero!\n");
1614 if (i
< 2) /* First two file names are already in valid 8.3 format */
1615 ok(!strcmp(szFile
, (CHAR
*)&pidlFile
->mkid
.abID
[12]), "Wrong file name!\n");
1617 /* WinXP stores a derived 8.3 dos name (LONGER~1.8_3) here. We probably
1618 * can't implement this correctly, since unix filesystems don't support
1619 * this nasty short/long filename stuff. So we'll probably stay with our
1620 * current habit of storing the long filename here, which seems to work
1623 ok(pidlFile
->mkid
.abID
[18] == '~', "Should be derived 8.3 name!\n");
1625 if (i
== 0) /* First file name has an even number of chars. No need for alignment. */
1626 ok(pidlFile
->mkid
.abID
[12 + strlen(szFile
) + 1] != '\0',
1627 "Alignment byte, where there shouldn't be!\n");
1629 if (i
== 1) /* Second file name has an uneven number of chars => alignment byte */
1630 ok(pidlFile
->mkid
.abID
[12 + strlen(szFile
) + 1] == '\0',
1631 "There should be an alignment byte, but isn't!\n");
1633 /* The offset of the FileStructW member is stored as a WORD at the end of the pidl. */
1634 cbOffset
= *(WORD
*)(((LPBYTE
)pidlFile
)+pidlFile
->mkid
.cb
-sizeof(WORD
));
1635 ok ((cbOffset
>= sizeof(struct FileStructA
) &&
1636 cbOffset
<= pidlFile
->mkid
.cb
- sizeof(struct FileStructW
)),
1637 "Wrong offset value (%d) stored at the end of the PIDL\n", cbOffset
);
1639 if (cbOffset
>= sizeof(struct FileStructA
) &&
1640 cbOffset
<= pidlFile
->mkid
.cb
- sizeof(struct FileStructW
))
1642 struct FileStructW
*pFileStructW
= (struct FileStructW
*)(((LPBYTE
)pidlFile
)+cbOffset
);
1643 WCHAR
*name
= pFileStructW
->wszName
;
1645 ok(pidlFile
->mkid
.cb
== cbOffset
+ pFileStructW
->cbLen
,
1646 "FileStructW's offset and length should add up to the PIDL's length!\n");
1648 if (pidlFile
->mkid
.cb
== cbOffset
+ pFileStructW
->cbLen
) {
1649 /* Since we just created the file, time of creation,
1650 * time of last access and time of last write access just be the same.
1651 * These tests seem to fail sometimes (on WinXP), if the test is run again shortly
1652 * after the first run. I do remember something with NTFS keeping the creation time
1653 * if a file is deleted and then created again within a couple of seconds or so.
1654 * Might be the reason. */
1655 ok (pFileStructA
->uFileDate
== pFileStructW
->uDate
&&
1656 pFileStructA
->uFileTime
== pFileStructW
->uTime
,
1657 "Last write time should match creation time!\n");
1659 /* On FAT filesystems the last access time is midnight
1660 local time, so the values of uDate2 and uTime2 will
1661 depend on the local timezone. If the times are exactly
1662 equal then the dates should be identical for both FAT
1663 and NTFS as no timezone is more than 1 day away from UTC.
1665 if (pFileStructA
->uFileTime
== pFileStructW
->uTime2
)
1667 ok (pFileStructA
->uFileDate
== pFileStructW
->uDate2
,
1668 "Last write date and time should match last access date and time!\n");
1672 /* Filesystem may be FAT. Check date within 1 day
1673 and seconds are zero. */
1674 trace ("Filesystem may be FAT. Performing less strict atime test.\n");
1675 ok ((pFileStructW
->uTime2
& 0x1F) == 0,
1676 "Last access time on FAT filesystems should have zero seconds.\n");
1677 /* TODO: Perform check for date being within one day.*/
1680 ok (!lstrcmpW(wszFile
[i
], name
) ||
1681 !lstrcmpW(wszFile
[i
], name
+ 9) || /* Vista */
1682 !lstrcmpW(wszFile
[i
], name
+ 11) || /* Win7 */
1683 !lstrcmpW(wszFile
[i
], name
+ 13), /* Win8 */
1684 "The filename should be stored in unicode at this position!\n");
1691 IShellFolder_Release(psfPersonal
);
1694 static void test_SHGetFolderPathA(void)
1696 static const BOOL is_win64
= sizeof(void *) > sizeof(int);
1698 char path
[MAX_PATH
];
1699 char path_x86
[MAX_PATH
];
1700 char path_key
[MAX_PATH
];
1704 if (!pIsWow64Process
|| !pIsWow64Process( GetCurrentProcess(), &is_wow64
)) is_wow64
= FALSE
;
1706 hr
= SHGetFolderPathA( 0, CSIDL_PROGRAM_FILES
, 0, SHGFP_TYPE_CURRENT
, path
);
1707 ok( hr
== S_OK
, "SHGetFolderPathA failed %x\n", hr
);
1708 hr
= SHGetFolderPathA( 0, CSIDL_PROGRAM_FILESX86
, 0, SHGFP_TYPE_CURRENT
, path_x86
);
1711 win_skip( "Program Files (x86) not supported\n" );
1714 ok( hr
== S_OK
, "SHGetFolderPathA failed %x\n", hr
);
1717 ok( lstrcmpiA( path
, path_x86
), "paths are identical '%s'\n", path
);
1718 ok( strstr( path
, "x86" ) == NULL
, "64-bit path '%s' contains x86\n", path
);
1719 ok( strstr( path_x86
, "x86" ) != NULL
, "32-bit path '%s' doesn't contain x86\n", path_x86
);
1723 ok( !lstrcmpiA( path
, path_x86
), "paths differ '%s' != '%s'\n", path
, path_x86
);
1725 ok( strstr( path
, "x86" ) != NULL
, "32-bit path '%s' doesn't contain x86\n", path
);
1727 ok( strstr( path
, "x86" ) == NULL
, "32-bit path '%s' contains x86\n", path
);
1729 if (!RegOpenKeyA( HKEY_LOCAL_MACHINE
, "Software\\Microsoft\\Windows\\CurrentVersion", &key
))
1731 DWORD type
, count
= sizeof(path_x86
);
1732 if (!RegQueryValueExA( key
, "ProgramFilesDir (x86)", NULL
, &type
, (BYTE
*)path_key
, &count
))
1734 ok( is_win64
|| is_wow64
, "ProgramFilesDir (x86) exists on 32-bit setup\n" );
1735 ok( !lstrcmpiA( path_key
, path_x86
), "paths differ '%s' != '%s'\n", path_key
, path_x86
);
1737 else ok( !is_win64
&& !is_wow64
, "ProgramFilesDir (x86) should exist on 64-bit setup\n" );
1741 hr
= SHGetFolderPathA( 0, CSIDL_PROGRAM_FILES_COMMON
, 0, SHGFP_TYPE_CURRENT
, path
);
1742 ok( hr
== S_OK
, "SHGetFolderPathA failed %x\n", hr
);
1743 hr
= SHGetFolderPathA( 0, CSIDL_PROGRAM_FILES_COMMONX86
, 0, SHGFP_TYPE_CURRENT
, path_x86
);
1746 win_skip( "Common Files (x86) not supported\n" );
1749 ok( hr
== S_OK
, "SHGetFolderPathA failed %x\n", hr
);
1752 ok( lstrcmpiA( path
, path_x86
), "paths are identical '%s'\n", path
);
1753 ok( strstr( path
, "x86" ) == NULL
, "64-bit path '%s' contains x86\n", path
);
1754 ok( strstr( path_x86
, "x86" ) != NULL
, "32-bit path '%s' doesn't contain x86\n", path_x86
);
1758 ok( !lstrcmpiA( path
, path_x86
), "paths differ '%s' != '%s'\n", path
, path_x86
);
1760 ok( strstr( path
, "x86" ) != NULL
, "32-bit path '%s' doesn't contain x86\n", path
);
1762 ok( strstr( path
, "x86" ) == NULL
, "32-bit path '%s' contains x86\n", path
);
1764 if (!RegOpenKeyA( HKEY_LOCAL_MACHINE
, "Software\\Microsoft\\Windows\\CurrentVersion", &key
))
1766 DWORD type
, count
= sizeof(path_x86
);
1767 if (!RegQueryValueExA( key
, "CommonFilesDir (x86)", NULL
, &type
, (BYTE
*)path_key
, &count
))
1769 ok( is_win64
|| is_wow64
, "CommonFilesDir (x86) exists on 32-bit setup\n" );
1770 ok( !lstrcmpiA( path_key
, path_x86
), "paths differ '%s' != '%s'\n", path_key
, path_x86
);
1772 else ok( !is_win64
&& !is_wow64
, "CommonFilesDir (x86) should exist on 64-bit setup\n" );
1776 static void test_SHGetFolderPathAndSubDirA(void)
1782 static const char wine
[] = "wine";
1783 static const char winetemp
[] = "wine\\temp";
1784 static char appdata
[MAX_PATH
];
1785 static char testpath
[2 * MAX_PATH
];
1786 static char toolongpath
[MAX_PATH
+1];
1788 if(FAILED(SHGetFolderPathA(NULL
, CSIDL_LOCAL_APPDATA
, NULL
, SHGFP_TYPE_CURRENT
, appdata
)))
1790 win_skip("SHGetFolderPathA failed for CSIDL_LOCAL_APPDATA!\n");
1794 sprintf(testpath
, "%s\\%s", appdata
, winetemp
);
1795 delret
= RemoveDirectoryA(testpath
);
1796 if(!delret
&& (ERROR_PATH_NOT_FOUND
!= GetLastError()) ) {
1797 win_skip("RemoveDirectoryA(%s) failed with error %u\n", testpath
, GetLastError());
1801 sprintf(testpath
, "%s\\%s", appdata
, wine
);
1802 delret
= RemoveDirectoryA(testpath
);
1803 if(!delret
&& (ERROR_PATH_NOT_FOUND
!= GetLastError()) && (ERROR_FILE_NOT_FOUND
!= GetLastError())) {
1804 win_skip("RemoveDirectoryA(%s) failed with error %u\n", testpath
, GetLastError());
1808 /* test invalid second parameter */
1809 ret
= SHGetFolderPathAndSubDirA(NULL
, CSIDL_FLAG_DONT_VERIFY
| 0xff, NULL
, SHGFP_TYPE_CURRENT
, wine
, testpath
);
1810 ok(E_INVALIDARG
== ret
, "expected E_INVALIDARG, got %x\n", ret
);
1812 /* test fourth parameter */
1813 ret
= SHGetFolderPathAndSubDirA(NULL
, CSIDL_FLAG_DONT_VERIFY
| CSIDL_LOCAL_APPDATA
, NULL
, 2, winetemp
, testpath
);
1815 case S_OK
: /* winvista */
1816 ok(!strncmp(appdata
, testpath
, strlen(appdata
)),
1817 "expected %s to start with %s\n", testpath
, appdata
);
1818 ok(!lstrcmpA(&testpath
[1 + strlen(appdata
)], winetemp
),
1819 "expected %s to end with %s\n", testpath
, winetemp
);
1821 case E_INVALIDARG
: /* winxp, win2k3 */
1824 ok(0, "expected S_OK or E_INVALIDARG, got %x\n", ret
);
1827 /* test fifth parameter */
1829 ret
= SHGetFolderPathAndSubDirA(NULL
, CSIDL_FLAG_DONT_VERIFY
| CSIDL_LOCAL_APPDATA
, NULL
, SHGFP_TYPE_CURRENT
, NULL
, testpath
);
1830 ok(S_OK
== ret
, "expected S_OK, got %x\n", ret
);
1831 ok(!lstrcmpA(appdata
, testpath
), "expected %s, got %s\n", appdata
, testpath
);
1834 ret
= SHGetFolderPathAndSubDirA(NULL
, CSIDL_FLAG_DONT_VERIFY
| CSIDL_LOCAL_APPDATA
, NULL
, SHGFP_TYPE_CURRENT
, "", testpath
);
1835 ok(S_OK
== ret
, "expected S_OK, got %x\n", ret
);
1836 ok(!lstrcmpA(appdata
, testpath
), "expected %s, got %s\n", appdata
, testpath
);
1839 ret
= SHGetFolderPathAndSubDirA(NULL
, CSIDL_FLAG_DONT_VERIFY
| CSIDL_LOCAL_APPDATA
, NULL
, SHGFP_TYPE_CURRENT
, "\\", testpath
);
1840 ok(S_OK
== ret
, "expected S_OK, got %x\n", ret
);
1841 ok(!lstrcmpA(appdata
, testpath
), "expected %s, got %s\n", appdata
, testpath
);
1843 for(i
=0; i
< MAX_PATH
; i
++)
1844 toolongpath
[i
] = '0' + i
% 10;
1845 toolongpath
[MAX_PATH
] = '\0';
1846 ret
= SHGetFolderPathAndSubDirA(NULL
, CSIDL_FLAG_DONT_VERIFY
| CSIDL_LOCAL_APPDATA
, NULL
, SHGFP_TYPE_CURRENT
, toolongpath
, testpath
);
1847 ok(HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE
) == ret
,
1848 "expected %x, got %x\n", HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE
), ret
);
1851 ret
= SHGetFolderPathAndSubDirA(NULL
, CSIDL_FLAG_DONT_VERIFY
| CSIDL_LOCAL_APPDATA
, NULL
, SHGFP_TYPE_CURRENT
, wine
, NULL
);
1852 ok((S_OK
== ret
) || (E_INVALIDARG
== ret
), "expected S_OK or E_INVALIDARG, got %x\n", ret
);
1854 /* test a not existing path */
1856 ret
= SHGetFolderPathAndSubDirA(NULL
, CSIDL_LOCAL_APPDATA
, NULL
, SHGFP_TYPE_CURRENT
, winetemp
, testpath
);
1857 ok(HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND
) == ret
,
1858 "expected %x, got %x\n", HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND
), ret
);
1860 /* create a directory inside a not existing directory */
1862 ret
= SHGetFolderPathAndSubDirA(NULL
, CSIDL_FLAG_CREATE
| CSIDL_LOCAL_APPDATA
, NULL
, SHGFP_TYPE_CURRENT
, winetemp
, testpath
);
1863 ok(S_OK
== ret
, "expected S_OK, got %x\n", ret
);
1864 ok(!strncmp(appdata
, testpath
, strlen(appdata
)),
1865 "expected %s to start with %s\n", testpath
, appdata
);
1866 ok(!lstrcmpA(&testpath
[1 + strlen(appdata
)], winetemp
),
1867 "expected %s to end with %s\n", testpath
, winetemp
);
1868 dwret
= GetFileAttributesA(testpath
);
1869 ok(FILE_ATTRIBUTE_DIRECTORY
| dwret
, "expected %x to contain FILE_ATTRIBUTE_DIRECTORY\n", dwret
);
1872 sprintf(testpath
, "%s\\%s", appdata
, winetemp
);
1873 RemoveDirectoryA(testpath
);
1874 sprintf(testpath
, "%s\\%s", appdata
, wine
);
1875 RemoveDirectoryA(testpath
);
1878 static void test_LocalizedNames(void)
1880 static char cCurrDirA
[MAX_PATH
];
1881 WCHAR cCurrDirW
[MAX_PATH
], tempbufW
[25];
1882 IShellFolder
*IDesktopFolder
, *testIShellFolder
;
1883 ITEMIDLIST
*newPIDL
;
1886 static char resourcefile
[MAX_PATH
];
1892 static const char desktopini_contents1
[] =
1893 "[.ShellClassInfo]\r\n"
1894 "LocalizedResourceName=@";
1895 static const char desktopini_contents2
[] =
1897 static WCHAR foldernameW
[] = {'t','e','s','t','f','o','l','d','e','r',0};
1898 static const WCHAR folderdisplayW
[] = {'F','o','l','d','e','r',' ','N','a','m','e',' ','R','e','s','o','u','r','c','e',0};
1900 /* create folder with desktop.ini and localized name in GetModuleFileNameA(NULL) */
1901 CreateDirectoryA(".\\testfolder", NULL
);
1903 SetFileAttributesA(".\\testfolder", GetFileAttributesA(".\\testfolder")|FILE_ATTRIBUTE_SYSTEM
);
1905 GetModuleFileNameA(NULL
, resourcefile
, MAX_PATH
);
1907 file
= CreateFileA(".\\testfolder\\desktop.ini", GENERIC_WRITE
, 0, NULL
,
1908 CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1909 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFileA failed %i\n", GetLastError());
1910 ret
= WriteFile(file
, desktopini_contents1
, strlen(desktopini_contents1
), &res
, NULL
) &&
1911 WriteFile(file
, resourcefile
, strlen(resourcefile
), &res
, NULL
) &&
1912 WriteFile(file
, desktopini_contents2
, strlen(desktopini_contents2
), &res
, NULL
);
1913 ok(ret
, "WriteFile failed %i\n", GetLastError());
1916 /* get IShellFolder for parent */
1917 GetCurrentDirectoryA(MAX_PATH
, cCurrDirA
);
1918 len
= lstrlenA(cCurrDirA
);
1921 win_skip("GetCurrentDirectoryA returned empty string. Skipping test_LocalizedNames\n");
1924 if(cCurrDirA
[len
-1] == '\\')
1925 cCurrDirA
[len
-1] = 0;
1927 MultiByteToWideChar(CP_ACP
, 0, cCurrDirA
, -1, cCurrDirW
, MAX_PATH
);
1929 hr
= SHGetDesktopFolder(&IDesktopFolder
);
1930 ok(hr
== S_OK
, "SHGetDesktopfolder failed %08x\n", hr
);
1932 hr
= IShellFolder_ParseDisplayName(IDesktopFolder
, NULL
, NULL
, cCurrDirW
, NULL
, &newPIDL
, 0);
1933 ok(hr
== S_OK
, "ParseDisplayName failed %08x\n", hr
);
1935 hr
= IShellFolder_BindToObject(IDesktopFolder
, newPIDL
, NULL
, (REFIID
)&IID_IShellFolder
, (LPVOID
*)&testIShellFolder
);
1936 ok(hr
== S_OK
, "BindToObject failed %08x\n", hr
);
1940 /* windows reads the display name from the resource */
1941 hr
= IShellFolder_ParseDisplayName(testIShellFolder
, NULL
, NULL
, foldernameW
, NULL
, &newPIDL
, 0);
1942 ok(hr
== S_OK
, "ParseDisplayName failed %08x\n", hr
);
1944 hr
= IShellFolder_GetDisplayNameOf(testIShellFolder
, newPIDL
, SHGDN_INFOLDER
, &strret
);
1945 ok(hr
== S_OK
, "GetDisplayNameOf failed %08x\n", hr
);
1947 hr
= StrRetToBufW(&strret
, newPIDL
, tempbufW
, ARRAY_SIZE(tempbufW
));
1948 ok (hr
== S_OK
, "StrRetToBufW failed! hr = %08x\n", hr
);
1950 ok (!lstrcmpiW(tempbufW
, folderdisplayW
), "GetDisplayNameOf returned %s\n", wine_dbgstr_w(tempbufW
));
1952 /* editing name is also read from the resource */
1953 hr
= IShellFolder_GetDisplayNameOf(testIShellFolder
, newPIDL
, SHGDN_INFOLDER
|SHGDN_FOREDITING
, &strret
);
1954 ok(hr
== S_OK
, "GetDisplayNameOf failed %08x\n", hr
);
1956 hr
= StrRetToBufW(&strret
, newPIDL
, tempbufW
, ARRAY_SIZE(tempbufW
));
1957 ok (hr
== S_OK
, "StrRetToBufW failed! hr = %08x\n", hr
);
1959 ok (!lstrcmpiW(tempbufW
, folderdisplayW
), "GetDisplayNameOf returned %s\n", wine_dbgstr_w(tempbufW
));
1961 /* parsing name is unchanged */
1962 hr
= IShellFolder_GetDisplayNameOf(testIShellFolder
, newPIDL
, SHGDN_INFOLDER
|SHGDN_FORPARSING
, &strret
);
1963 ok(hr
== S_OK
, "GetDisplayNameOf failed %08x\n", hr
);
1965 hr
= StrRetToBufW(&strret
, newPIDL
, tempbufW
, ARRAY_SIZE(tempbufW
));
1966 ok (hr
== S_OK
, "StrRetToBufW failed! hr = %08x\n", hr
);
1967 ok (!lstrcmpiW(tempbufW
, foldernameW
), "GetDisplayNameOf returned %s\n", wine_dbgstr_w(tempbufW
));
1969 IShellFolder_Release(IDesktopFolder
);
1970 IShellFolder_Release(testIShellFolder
);
1975 DeleteFileA(".\\testfolder\\desktop.ini");
1976 SetFileAttributesA(".\\testfolder", GetFileAttributesA(".\\testfolder")&~FILE_ATTRIBUTE_SYSTEM
);
1977 RemoveDirectoryA(".\\testfolder");
1980 static void test_SHCreateShellItem(void)
1982 IShellItem
*shellitem
, *shellitem2
;
1983 IPersistIDList
*persistidl
;
1984 LPITEMIDLIST pidl_cwd
=NULL
, pidl_testfile
, pidl_abstestfile
, pidl_test
, pidl_desktop
;
1986 char curdirA
[MAX_PATH
];
1987 WCHAR curdirW
[MAX_PATH
];
1988 WCHAR fnbufW
[MAX_PATH
];
1989 IShellFolder
*desktopfolder
=NULL
, *currentfolder
=NULL
;
1990 static WCHAR testfileW
[] = {'t','e','s','t','f','i','l','e',0};
1992 GetCurrentDirectoryA(MAX_PATH
, curdirA
);
1994 if (!pSHCreateShellItem
)
1996 win_skip("SHCreateShellItem isn't available\n");
2002 win_skip("GetCurrentDirectoryA returned empty string, skipping test_SHCreateShellItem\n");
2006 ret
= SHGetSpecialFolderLocation(NULL
, CSIDL_DESKTOP
, &pidl_desktop
);
2007 ok(ret
== S_OK
, "Got 0x%08x\n", ret
);
2009 MultiByteToWideChar(CP_ACP
, 0, curdirA
, -1, curdirW
, MAX_PATH
);
2011 ret
= SHGetDesktopFolder(&desktopfolder
);
2012 ok(SUCCEEDED(ret
), "SHGetShellFolder returned %x\n", ret
);
2014 ret
= IShellFolder_ParseDisplayName(desktopfolder
, NULL
, NULL
, curdirW
, NULL
, &pidl_cwd
, NULL
);
2015 ok(SUCCEEDED(ret
), "ParseDisplayName returned %x\n", ret
);
2017 ret
= IShellFolder_BindToObject(desktopfolder
, pidl_cwd
, NULL
, &IID_IShellFolder
, (void**)¤tfolder
);
2018 ok(SUCCEEDED(ret
), "BindToObject returned %x\n", ret
);
2020 CreateTestFile(".\\testfile");
2022 ret
= IShellFolder_ParseDisplayName(currentfolder
, NULL
, NULL
, testfileW
, NULL
, &pidl_testfile
, NULL
);
2023 ok(SUCCEEDED(ret
), "ParseDisplayName returned %x\n", ret
);
2025 pidl_abstestfile
= ILCombine(pidl_cwd
, pidl_testfile
);
2027 shellitem
= (void*)0xdeadbeef;
2028 ret
= pSHCreateShellItem(NULL
, NULL
, NULL
, &shellitem
);
2029 ok(ret
== E_INVALIDARG
, "SHCreateShellItem returned %x\n", ret
);
2030 ok(shellitem
== 0, "Got %p\n", shellitem
);
2032 if (0) /* crashes on Windows XP */
2034 pSHCreateShellItem(NULL
, NULL
, pidl_cwd
, NULL
);
2035 pSHCreateShellItem(pidl_cwd
, NULL
, NULL
, &shellitem
);
2036 pSHCreateShellItem(NULL
, currentfolder
, NULL
, &shellitem
);
2037 pSHCreateShellItem(pidl_cwd
, currentfolder
, NULL
, &shellitem
);
2040 ret
= pSHCreateShellItem(NULL
, NULL
, pidl_cwd
, &shellitem
);
2041 ok(SUCCEEDED(ret
), "SHCreateShellItem returned %x\n", ret
);
2044 ret
= IShellItem_QueryInterface(shellitem
, &IID_IPersistIDList
, (void**)&persistidl
);
2045 ok(SUCCEEDED(ret
), "QueryInterface returned %x\n", ret
);
2048 ret
= IPersistIDList_GetIDList(persistidl
, &pidl_test
);
2049 ok(SUCCEEDED(ret
), "GetIDList returned %x\n", ret
);
2052 ok(ILIsEqual(pidl_cwd
, pidl_test
), "id lists are not equal\n");
2055 IPersistIDList_Release(persistidl
);
2057 IShellItem_Release(shellitem
);
2060 ret
= pSHCreateShellItem(pidl_cwd
, NULL
, pidl_testfile
, &shellitem
);
2061 ok(SUCCEEDED(ret
), "SHCreateShellItem returned %x\n", ret
);
2064 ret
= IShellItem_QueryInterface(shellitem
, &IID_IPersistIDList
, (void**)&persistidl
);
2065 ok(SUCCEEDED(ret
), "QueryInterface returned %x\n", ret
);
2068 ret
= IPersistIDList_GetIDList(persistidl
, &pidl_test
);
2069 ok(SUCCEEDED(ret
), "GetIDList returned %x\n", ret
);
2072 ok(ILIsEqual(pidl_abstestfile
, pidl_test
), "id lists are not equal\n");
2075 IPersistIDList_Release(persistidl
);
2078 ret
= IShellItem_GetParent(shellitem
, &shellitem2
);
2079 ok(SUCCEEDED(ret
), "GetParent returned %x\n", ret
);
2082 ret
= IShellItem_QueryInterface(shellitem2
, &IID_IPersistIDList
, (void**)&persistidl
);
2083 ok(SUCCEEDED(ret
), "QueryInterface returned %x\n", ret
);
2086 ret
= IPersistIDList_GetIDList(persistidl
, &pidl_test
);
2087 ok(SUCCEEDED(ret
), "GetIDList returned %x\n", ret
);
2090 ok(ILIsEqual(pidl_cwd
, pidl_test
), "id lists are not equal\n");
2093 IPersistIDList_Release(persistidl
);
2095 IShellItem_Release(shellitem2
);
2098 IShellItem_Release(shellitem
);
2101 ret
= pSHCreateShellItem(NULL
, currentfolder
, pidl_testfile
, &shellitem
);
2102 ok(SUCCEEDED(ret
), "SHCreateShellItem returned %x\n", ret
);
2105 ret
= IShellItem_QueryInterface(shellitem
, &IID_IPersistIDList
, (void**)&persistidl
);
2106 ok(SUCCEEDED(ret
), "QueryInterface returned %x\n", ret
);
2109 ret
= IPersistIDList_GetIDList(persistidl
, &pidl_test
);
2110 ok(SUCCEEDED(ret
), "GetIDList returned %x\n", ret
);
2113 ok(ILIsEqual(pidl_abstestfile
, pidl_test
), "id lists are not equal\n");
2116 IPersistIDList_Release(persistidl
);
2118 IShellItem_Release(shellitem
);
2121 /* if a parent pidl and shellfolder are specified, the shellfolder is ignored */
2122 ret
= pSHCreateShellItem(pidl_cwd
, desktopfolder
, pidl_testfile
, &shellitem
);
2123 ok(SUCCEEDED(ret
), "SHCreateShellItem returned %x\n", ret
);
2126 ret
= IShellItem_QueryInterface(shellitem
, &IID_IPersistIDList
, (void**)&persistidl
);
2127 ok(SUCCEEDED(ret
), "QueryInterface returned %x\n", ret
);
2130 ret
= IPersistIDList_GetIDList(persistidl
, &pidl_test
);
2131 ok(SUCCEEDED(ret
), "GetIDList returned %x\n", ret
);
2134 ok(ILIsEqual(pidl_abstestfile
, pidl_test
), "id lists are not equal\n");
2137 IPersistIDList_Release(persistidl
);
2139 IShellItem_Release(shellitem
);
2142 ret
= pSHCreateShellItem(NULL
, desktopfolder
, pidl_testfile
, &shellitem
);
2143 ok(SUCCEEDED(ret
), "SHCreateShellItem returned %x\n", ret
);
2146 ret
= IShellItem_QueryInterface(shellitem
, &IID_IPersistIDList
, (void**)&persistidl
);
2147 ok(SUCCEEDED(ret
), "QueryInterface returned %x\n", ret
);
2150 ret
= IPersistIDList_GetIDList(persistidl
, &pidl_test
);
2151 ok(SUCCEEDED(ret
), "GetIDList returned %x\n", ret
);
2154 ok(ILIsEqual(pidl_testfile
, pidl_test
), "id lists are not equal\n");
2157 IPersistIDList_Release(persistidl
);
2160 IShellItem_Release(shellitem
);
2163 ret
= pSHCreateShellItem(NULL
, NULL
, pidl_desktop
, &shellitem
);
2164 ok(SUCCEEDED(ret
), "SHCreateShellItem returned %x\n", ret
);
2167 ret
= IShellItem_GetParent(shellitem
, &shellitem2
);
2168 ok(FAILED(ret
), "Got 0x%08x\n", ret
);
2169 if(SUCCEEDED(ret
)) IShellItem_Release(shellitem2
);
2170 IShellItem_Release(shellitem
);
2173 /* SHCreateItemFromParsingName */
2174 if(pSHCreateItemFromParsingName
)
2178 /* Crashes under windows 7 */
2179 pSHCreateItemFromParsingName(NULL
, NULL
, &IID_IShellItem
, NULL
);
2182 shellitem
= (void*)0xdeadbeef;
2183 ret
= pSHCreateItemFromParsingName(NULL
, NULL
, &IID_IShellItem
, (void**)&shellitem
);
2184 ok(ret
== E_INVALIDARG
, "SHCreateItemFromParsingName returned %x\n", ret
);
2185 ok(shellitem
== NULL
, "shellitem was %p.\n", shellitem
);
2187 ret
= pSHCreateItemFromParsingName(testfileW
, NULL
, &IID_IShellItem
, (void**)&shellitem
);
2188 ok(ret
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
),
2189 "SHCreateItemFromParsingName returned %x\n", ret
);
2190 if(SUCCEEDED(ret
)) IShellItem_Release(shellitem
);
2192 lstrcpyW(fnbufW
, curdirW
);
2193 myPathAddBackslashW(fnbufW
);
2194 lstrcatW(fnbufW
, testfileW
);
2196 ret
= pSHCreateItemFromParsingName(fnbufW
, NULL
, &IID_IShellItem
, (void**)&shellitem
);
2197 ok(ret
== S_OK
, "SHCreateItemFromParsingName returned %x\n", ret
);
2201 ret
= IShellItem_GetDisplayName(shellitem
, SIGDN_FILESYSPATH
, &tmp_fname
);
2202 ok(ret
== S_OK
, "GetDisplayName returned %x\n", ret
);
2205 ok(!lstrcmpW(fnbufW
, tmp_fname
), "strings not equal\n");
2206 CoTaskMemFree(tmp_fname
);
2208 IShellItem_Release(shellitem
);
2212 win_skip("No SHCreateItemFromParsingName\n");
2215 /* SHCreateItemFromIDList */
2216 if(pSHCreateItemFromIDList
)
2220 /* Crashes under win7 */
2221 pSHCreateItemFromIDList(NULL
, &IID_IShellItem
, NULL
);
2224 ret
= pSHCreateItemFromIDList(NULL
, &IID_IShellItem
, (void**)&shellitem
);
2225 ok(ret
== E_INVALIDARG
, "SHCreateItemFromIDList returned %x\n", ret
);
2227 ret
= pSHCreateItemFromIDList(pidl_cwd
, &IID_IShellItem
, (void**)&shellitem
);
2228 ok(ret
== S_OK
, "SHCreateItemFromIDList returned %x\n", ret
);
2231 ret
= IShellItem_QueryInterface(shellitem
, &IID_IPersistIDList
, (void**)&persistidl
);
2232 ok(ret
== S_OK
, "QueryInterface returned %x\n", ret
);
2235 ret
= IPersistIDList_GetIDList(persistidl
, &pidl_test
);
2236 ok(ret
== S_OK
, "GetIDList returned %x\n", ret
);
2239 ok(ILIsEqual(pidl_cwd
, pidl_test
), "id lists are not equal\n");
2242 IPersistIDList_Release(persistidl
);
2244 IShellItem_Release(shellitem
);
2247 ret
= pSHCreateItemFromIDList(pidl_testfile
, &IID_IShellItem
, (void**)&shellitem
);
2248 ok(ret
== S_OK
, "SHCreateItemFromIDList returned %x\n", ret
);
2251 ret
= IShellItem_QueryInterface(shellitem
, &IID_IPersistIDList
, (void**)&persistidl
);
2252 ok(ret
== S_OK
, "QueryInterface returned %x\n", ret
);
2255 ret
= IPersistIDList_GetIDList(persistidl
, &pidl_test
);
2256 ok(ret
== S_OK
, "GetIDList returned %x\n", ret
);
2259 ok(ILIsEqual(pidl_testfile
, pidl_test
), "id lists are not equal\n");
2262 IPersistIDList_Release(persistidl
);
2264 IShellItem_Release(shellitem
);
2268 win_skip("No SHCreateItemFromIDList\n");
2270 /* SHCreateItemFromRelativeName */
2271 if(pSHCreateItemFromRelativeName
&& pSHGetKnownFolderPath
)
2273 IShellItem
*shellitem_desktop
= NULL
;
2274 WCHAR
*desktop_path
, *displayname
;
2275 WCHAR testfile_path
[MAX_PATH
] = {0};
2277 LPITEMIDLIST pidl_desktop_testfile
= NULL
;
2280 ret
= pSHCreateShellItem(NULL
, NULL
, pidl_desktop
, &shellitem_desktop
);
2281 ok(ret
== S_OK
, "SHCreateShellItem failed: 0x%08x.\n", ret
);
2283 shellitem
= (void*)0xdeadbeef;
2284 ret
= pSHCreateItemFromRelativeName(shellitem_desktop
, NULL
, NULL
, &IID_IShellItem
,
2285 (void**)&shellitem
);
2286 ok(ret
== E_INVALIDARG
, "Expected 0x%08x but SHCreateItemFromRelativeName return: 0x%08x.\n",
2288 ok(shellitem
== NULL
, "shellitem was %p.\n", shellitem
);
2290 /* Test with a non-existent file */
2291 shellitem
= (void*)0xdeadbeef;
2292 ret
= pSHCreateItemFromRelativeName(shellitem_desktop
, testfileW
, NULL
, &IID_IShellItem
,
2293 (void**)&shellitem
);
2294 ok(ret
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
),
2295 "Expected 0x%08x but SHCreateItemFromRelativeName return: 0x%08x.\n",
2296 HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
), ret
);
2297 ok(shellitem
== NULL
, "shellitem was %p.\n", shellitem
);
2299 /* Create a file for testing in desktop folder */
2300 pSHGetKnownFolderPath(&FOLDERID_Desktop
, 0, NULL
, &desktop_path
);
2301 lstrcatW(testfile_path
, desktop_path
);
2302 myPathAddBackslashW(testfile_path
);
2303 lstrcatW(testfile_path
, testfileW
);
2304 file
= CreateFileW(testfile_path
, GENERIC_WRITE
, 0, NULL
, CREATE_NEW
, 0, NULL
);
2305 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFileW failed! Last error: 0x%08x.\n", GetLastError());
2308 shellitem
= (void*)0xdeadbeef;
2309 ret
= pSHCreateItemFromRelativeName(shellitem_desktop
, testfileW
, NULL
, &IID_IShellItem
,
2310 (void**)&shellitem
);
2311 ok(ret
== S_OK
, "SHCreateItemFromRelativeName failed: 0x%08x.\n", ret
);
2312 ok(shellitem
!= NULL
, "shellitem was %p.\n", shellitem
);
2315 ret
= IShellItem_GetDisplayName(shellitem
, 0, &displayname
);
2316 ok(ret
== S_OK
, "IShellItem_GetDisplayName failed: 0x%08x.\n", ret
);
2317 ok(!lstrcmpW(displayname
, testfileW
), "got wrong display name: %s.\n", wine_dbgstr_w(displayname
));
2318 CoTaskMemFree(displayname
);
2320 shellitem2
= (void*)0xdeadbeef;
2321 ret
= pSHCreateItemFromRelativeName(shellitem_desktop
, testfileW
, NULL
, &IID_IShellItem
,
2322 (void**)&shellitem2
);
2323 ok(ret
== S_OK
, "SHCreateItemFromRelativeName failed: 0x%08x.\n", ret
);
2324 ret
= IShellItem_Compare(shellitem
, shellitem2
, 0, &order
);
2325 ok(ret
== S_OK
, "IShellItem_Compare failed: 0x%08x.\n", ret
);
2326 ok(!order
, "order got wrong value: %d.\n", order
);
2327 IShellItem_Release(shellitem2
);
2329 shellitem2
= (void*)0xdeadbeef;
2330 ret
= IShellFolder_ParseDisplayName(desktopfolder
, NULL
, NULL
, testfileW
, NULL
,
2331 &pidl_desktop_testfile
, NULL
);
2332 ok(ret
== S_OK
, "ParseDisplayName failed 0x%08x.\n", ret
);
2333 ret
= pSHCreateItemFromIDList(pidl_desktop_testfile
, &IID_IShellItem
, (void**)&shellitem2
);
2334 ret
= IShellItem_Compare(shellitem
, shellitem2
, 0, &order
);
2335 ok(ret
== S_OK
, "IShellItem_Compare fail: 0x%08x.\n", ret
);
2336 ok(!order
, "order got wrong value: %d.\n", order
);
2337 ILFree(pidl_desktop_testfile
);
2338 IShellItem_Release(shellitem2
);
2340 IShellItem_Release(shellitem
);
2343 DeleteFileW(testfile_path
);
2344 CoTaskMemFree(desktop_path
);
2345 IShellItem_Release(shellitem_desktop
);
2348 win_skip("No SHCreateItemFromRelativeName or SHGetKnownFolderPath\n");
2350 /* SHCreateItemInKnownFolder */
2351 if(pSHCreateItemInKnownFolder
&& pSHGetKnownFolderPath
)
2353 WCHAR
*desktop_path
;
2354 WCHAR testfile_path
[MAX_PATH
] = {0};
2356 WCHAR
*displayname
= NULL
;
2358 LPITEMIDLIST pidl_desktop_testfile
= NULL
;
2360 shellitem
= (void*)0xdeadbeef;
2361 ret
= pSHCreateItemInKnownFolder(&FOLDERID_Desktop
, 0, NULL
, &IID_IShellItem
,
2362 (void**)&shellitem
);
2363 ok(ret
== S_OK
, "SHCreateItemInKnownFolder failed: 0x%08x.\n", ret
);
2364 ok(shellitem
!= NULL
, "shellitem was %p.\n", shellitem
);
2367 shellitem2
= (void*)0xdeadbeef;
2368 ret
= pSHCreateShellItem(NULL
, NULL
, pidl_desktop
, &shellitem2
);
2369 ok(SUCCEEDED(ret
), "SHCreateShellItem returned %x\n", ret
);
2372 ret
= IShellItem_Compare(shellitem
, shellitem2
, 0, &order
);
2373 ok(ret
== S_OK
, "IShellItem_Compare failed: 0x%08x.\n", ret
);
2374 ok(!order
, "order got wrong value: %d.\n", order
);
2375 IShellItem_Release(shellitem2
);
2377 IShellItem_Release(shellitem
);
2380 /* Test with a non-existent file */
2381 shellitem
= (void*)0xdeadbeef;
2382 ret
= pSHCreateItemInKnownFolder(&FOLDERID_Desktop
, 0, testfileW
, &IID_IShellItem
,
2383 (void**)&shellitem
);
2384 ok(ret
== HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
),
2385 "Expected 0x%08x but SHCreateItemInKnownFolder return: 0x%08x.\n",
2386 HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
), ret
);
2387 ok(shellitem
== NULL
, "shellitem was %p.\n", shellitem
);
2389 pSHGetKnownFolderPath(&FOLDERID_Desktop
, 0, NULL
, &desktop_path
);
2390 lstrcatW(testfile_path
, desktop_path
);
2391 myPathAddBackslashW(testfile_path
);
2392 lstrcatW(testfile_path
, testfileW
);
2393 file
= CreateFileW(testfile_path
, GENERIC_WRITE
, 0, NULL
, CREATE_NEW
, 0, NULL
);
2394 ok(file
!= INVALID_HANDLE_VALUE
, "CreateFileW failed! Last error: 0x%08x.\n", GetLastError());
2397 shellitem
= (void*)0xdeadbeef;
2398 ret
= pSHCreateItemInKnownFolder(&FOLDERID_Desktop
, 0, testfileW
, &IID_IShellItem
,
2399 (void**)&shellitem
);
2400 ok(ret
== S_OK
, "SHCreateItemInKnownFolder failed: 0x%08x.\n", ret
);
2401 ok(shellitem
!= NULL
, "shellitem was %p.\n", shellitem
);
2404 ret
= IShellItem_GetDisplayName(shellitem
, 0, &displayname
);
2405 ok(ret
== S_OK
, "IShellItem_GetDisplayName failed: 0x%08x.\n", ret
);
2406 ok(!lstrcmpW(displayname
, testfileW
), "got wrong display name: %s.\n",
2407 wine_dbgstr_w(displayname
));
2408 CoTaskMemFree(displayname
);
2410 shellitem2
= (void*)0xdeadbeef;
2411 ret
= pSHCreateItemInKnownFolder(&FOLDERID_Desktop
, 0, testfileW
, &IID_IShellItem
,
2412 (void**)&shellitem2
);
2413 ok(ret
== S_OK
, "SHCreateItemInKnownFolder failed: 0x%08x.\n", ret
);
2414 ok(shellitem2
!= NULL
, "shellitem was %p.\n", shellitem
);
2415 ret
= IShellItem_Compare(shellitem
, shellitem2
, 0, &order
);
2416 ok(ret
== S_OK
, "IShellItem_Compare failed: 0x%08x.\n", ret
);
2417 ok(!order
, "order got wrong value: %d.\n", order
);
2418 IShellItem_Release(shellitem2
);
2420 shellitem2
= (void*)0xdeadbeef;
2421 ret
= IShellFolder_ParseDisplayName(desktopfolder
, NULL
, NULL
, testfileW
, NULL
,
2422 &pidl_desktop_testfile
, NULL
);
2423 ok(SUCCEEDED(ret
), "ParseDisplayName returned %x.\n", ret
);
2424 ret
= pSHCreateItemFromIDList(pidl_desktop_testfile
, &IID_IShellItem
, (void**)&shellitem2
);
2425 ret
= IShellItem_Compare(shellitem
, shellitem2
, 0, &order
);
2426 ok(ret
== S_OK
, "IShellItem_Compare failed: 0x%08x.\n", ret
);
2427 ok(!order
, "order got wrong value: %d.\n", order
);
2428 ILFree(pidl_desktop_testfile
);
2429 IShellItem_Release(shellitem2
);
2431 IShellItem_Release(shellitem
);
2434 shellitem
= (void*)0xdeadbeef;
2435 ret
= pSHCreateItemInKnownFolder(&FOLDERID_Documents
, 0, NULL
, &IID_IShellItem
,
2436 (void**)&shellitem
);
2437 ok(ret
== S_OK
, "SHCreateItemInKnownFolder failed: 0x%08x.\n", ret
);
2438 ok(shellitem
!= NULL
, "shellitem was %p.\n", shellitem
);
2441 shellitem2
= (void*)0xdeadbeef;
2442 ret
= pSHCreateItemInKnownFolder(&FOLDERID_Documents
, 0, NULL
, &IID_IShellItem
,
2443 (void**)&shellitem2
);
2444 ok(ret
== S_OK
, "SHCreateItemInKnownFolder failed: 0x%08x.\n", ret
);
2445 ok(shellitem2
!= NULL
, "shellitem was %p.\n", shellitem
);
2446 ret
= IShellItem_Compare(shellitem
, shellitem2
, 0, &order
);
2447 ok(ret
== S_OK
, "IShellItem_Compare failed: 0x%08x.\n", ret
);
2448 ok(!order
, "order got wrong value: %d.\n", order
);
2449 IShellItem_Release(shellitem2
);
2451 IShellItem_Release(shellitem
);
2453 DeleteFileW(testfile_path
);
2454 CoTaskMemFree(desktop_path
);
2457 win_skip("No SHCreateItemInKnownFolder or SHGetKnownFolderPath\n");
2459 DeleteFileA(".\\testfile");
2460 ILFree(pidl_abstestfile
);
2461 ILFree(pidl_testfile
);
2462 ILFree(pidl_desktop
);
2464 IShellFolder_Release(currentfolder
);
2465 IShellFolder_Release(desktopfolder
);
2468 static void test_SHGetNameFromIDList(void)
2470 IShellItem
*shellitem
;
2475 static const DWORD flags
[] = {
2476 SIGDN_NORMALDISPLAY
, SIGDN_PARENTRELATIVEPARSING
,
2477 SIGDN_DESKTOPABSOLUTEPARSING
,SIGDN_PARENTRELATIVEEDITING
,
2478 SIGDN_DESKTOPABSOLUTEEDITING
, /*SIGDN_FILESYSPATH, SIGDN_URL, */
2479 SIGDN_PARENTRELATIVEFORADDRESSBAR
,SIGDN_PARENTRELATIVE
, -1234};
2481 if(!pSHGetNameFromIDList
)
2483 win_skip("SHGetNameFromIDList missing.\n");
2487 /* This should be available on any platform that passed the above test. */
2488 ok(pSHCreateShellItem
!= NULL
, "SHCreateShellItem missing.\n");
2492 /* Crashes under win7 */
2493 pSHGetNameFromIDList(NULL
, 0, NULL
);
2496 hres
= pSHGetNameFromIDList(NULL
, 0, &name_string
);
2497 ok(hres
== E_INVALIDARG
, "Got 0x%08x\n", hres
);
2499 /* Test the desktop */
2500 hres
= SHGetSpecialFolderLocation(NULL
, CSIDL_DESKTOP
, &pidl
);
2501 ok(hres
== S_OK
, "Got 0x%08x\n", hres
);
2502 hres
= pSHCreateShellItem(NULL
, NULL
, pidl
, &shellitem
);
2503 ok(hres
== S_OK
, "Got 0x%08x\n", hres
);
2506 WCHAR
*nameSI
, *nameSH
;
2507 WCHAR buf
[MAX_PATH
];
2508 HRESULT hrSI
, hrSH
, hrSF
;
2513 SHGetDesktopFolder(&psf
);
2514 for(i
= 0; flags
[i
] != -1234; i
++)
2516 hrSI
= IShellItem_GetDisplayName(shellitem
, flags
[i
], &nameSI
);
2517 ok(hrSI
== S_OK
, "Got 0x%08x\n", hrSI
);
2518 hrSH
= pSHGetNameFromIDList(pidl
, flags
[i
], &nameSH
);
2519 ok(hrSH
== S_OK
, "Got 0x%08x\n", hrSH
);
2520 hrSF
= IShellFolder_GetDisplayNameOf(psf
, pidl
, flags
[i
] & 0xffff, &strret
);
2521 ok(hrSF
== S_OK
, "Got 0x%08x\n", hrSF
);
2523 if(SUCCEEDED(hrSI
) && SUCCEEDED(hrSH
))
2524 ok(!lstrcmpW(nameSI
, nameSH
), "Strings differ.\n");
2528 StrRetToBufW(&strret
, NULL
, buf
, MAX_PATH
);
2530 ok(!lstrcmpW(nameSI
, buf
), "Strings differ.\n");
2532 ok(!lstrcmpW(nameSI
, buf
), "Strings differ.\n");
2534 if(SUCCEEDED(hrSI
)) CoTaskMemFree(nameSI
);
2535 if(SUCCEEDED(hrSH
)) CoTaskMemFree(nameSH
);
2537 IShellFolder_Release(psf
);
2539 hrSI
= pSHGetNameFromIDList(pidl
, SIGDN_FILESYSPATH
, &nameSI
);
2540 ok(hrSI
== S_OK
, "Got 0x%08x\n", hrSI
);
2541 res
= SHGetPathFromIDListW(pidl
, buf
);
2542 ok(res
== TRUE
, "Got %d\n", res
);
2543 if(SUCCEEDED(hrSI
) && res
)
2544 ok(!lstrcmpW(nameSI
, buf
), "Strings differ.\n");
2545 if(SUCCEEDED(hrSI
)) CoTaskMemFree(nameSI
);
2547 hres
= pSHGetNameFromIDList(pidl
, SIGDN_URL
, &name_string
);
2548 todo_wine
ok(hres
== S_OK
, "Got 0x%08x\n", hres
);
2549 if(SUCCEEDED(hres
)) CoTaskMemFree(name_string
);
2551 IShellItem_Release(shellitem
);
2555 /* Test the control panel */
2556 hres
= SHGetSpecialFolderLocation(NULL
, CSIDL_CONTROLS
, &pidl
);
2557 ok(hres
== S_OK
, "Got 0x%08x\n", hres
);
2558 hres
= pSHCreateShellItem(NULL
, NULL
, pidl
, &shellitem
);
2559 ok(hres
== S_OK
, "Got 0x%08x\n", hres
);
2562 WCHAR
*nameSI
, *nameSH
;
2563 WCHAR buf
[MAX_PATH
];
2564 HRESULT hrSI
, hrSH
, hrSF
;
2569 SHGetDesktopFolder(&psf
);
2570 for(i
= 0; flags
[i
] != -1234; i
++)
2572 hrSI
= IShellItem_GetDisplayName(shellitem
, flags
[i
], &nameSI
);
2573 ok(hrSI
== S_OK
, "Got 0x%08x\n", hrSI
);
2574 hrSH
= pSHGetNameFromIDList(pidl
, flags
[i
], &nameSH
);
2575 ok(hrSH
== S_OK
, "Got 0x%08x\n", hrSH
);
2576 hrSF
= IShellFolder_GetDisplayNameOf(psf
, pidl
, flags
[i
] & 0xffff, &strret
);
2577 ok(hrSF
== S_OK
, "Got 0x%08x\n", hrSF
);
2579 if(SUCCEEDED(hrSI
) && SUCCEEDED(hrSH
))
2580 ok(!lstrcmpW(nameSI
, nameSH
), "Strings differ.\n");
2584 StrRetToBufW(&strret
, NULL
, buf
, MAX_PATH
);
2586 ok(!lstrcmpW(nameSI
, buf
), "Strings differ.\n");
2588 ok(!lstrcmpW(nameSI
, buf
), "Strings differ.\n");
2590 if(SUCCEEDED(hrSI
)) CoTaskMemFree(nameSI
);
2591 if(SUCCEEDED(hrSH
)) CoTaskMemFree(nameSH
);
2593 IShellFolder_Release(psf
);
2595 hrSI
= pSHGetNameFromIDList(pidl
, SIGDN_FILESYSPATH
, &nameSI
);
2596 ok(hrSI
== E_INVALIDARG
, "Got 0x%08x\n", hrSI
);
2597 res
= SHGetPathFromIDListW(pidl
, buf
);
2598 ok(res
== FALSE
, "Got %d\n", res
);
2599 if(SUCCEEDED(hrSI
) && res
)
2600 ok(!lstrcmpW(nameSI
, buf
), "Strings differ.\n");
2601 if(SUCCEEDED(hrSI
)) CoTaskMemFree(nameSI
);
2603 hres
= pSHGetNameFromIDList(pidl
, SIGDN_URL
, &name_string
);
2604 todo_wine
ok(hres
== E_NOTIMPL
/* Win7 */ || hres
== S_OK
/* Vista */,
2605 "Got 0x%08x\n", hres
);
2606 if(SUCCEEDED(hres
)) CoTaskMemFree(name_string
);
2608 IShellItem_Release(shellitem
);
2613 static void test_SHGetItemFromDataObject(void)
2615 IShellFolder
*psfdesktop
;
2620 if(!pSHGetItemFromDataObject
)
2622 win_skip("No SHGetItemFromDataObject.\n");
2628 /* Crashes under win7 */
2629 pSHGetItemFromDataObject(NULL
, 0, &IID_IShellItem
, NULL
);
2632 hres
= pSHGetItemFromDataObject(NULL
, 0, &IID_IShellItem
, (void**)&psv
);
2633 ok(hres
== E_INVALIDARG
, "got 0x%08x\n", hres
);
2635 SHGetDesktopFolder(&psfdesktop
);
2637 hres
= IShellFolder_CreateViewObject(psfdesktop
, NULL
, &IID_IShellView
, (void**)&psv
);
2638 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
2645 enum_flags
= SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
| SHCONTF_INCLUDEHIDDEN
;
2646 hres
= IShellFolder_EnumObjects(psfdesktop
, NULL
, enum_flags
, &peidl
);
2647 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
2650 LPITEMIDLIST apidl
[5];
2653 for(count
= 0; count
< 5; count
++)
2654 if(IEnumIDList_Next(peidl
, 1, &apidl
[count
], NULL
) != S_OK
)
2659 hres
= IShellFolder_GetUIObjectOf(psfdesktop
, NULL
, 1, (LPCITEMIDLIST
*)apidl
,
2660 &IID_IDataObject
, NULL
, (void**)&pdo
);
2661 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
2664 hres
= pSHGetItemFromDataObject(pdo
, DOGIF_DEFAULT
, &IID_IShellItem
, (void**)&psi
);
2665 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
2666 if(SUCCEEDED(hres
)) IShellItem_Release(psi
);
2667 hres
= pSHGetItemFromDataObject(pdo
, DOGIF_TRAVERSE_LINK
, &IID_IShellItem
, (void**)&psi
);
2668 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
2669 if(SUCCEEDED(hres
)) IShellItem_Release(psi
);
2670 hres
= pSHGetItemFromDataObject(pdo
, DOGIF_NO_HDROP
, &IID_IShellItem
, (void**)&psi
);
2671 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
2672 if(SUCCEEDED(hres
)) IShellItem_Release(psi
);
2673 hres
= pSHGetItemFromDataObject(pdo
, DOGIF_NO_URL
, &IID_IShellItem
, (void**)&psi
);
2674 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
2675 if(SUCCEEDED(hres
)) IShellItem_Release(psi
);
2676 hres
= pSHGetItemFromDataObject(pdo
, DOGIF_ONLY_IF_ONE
, &IID_IShellItem
, (void**)&psi
);
2677 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
2678 if(SUCCEEDED(hres
)) IShellItem_Release(psi
);
2680 IDataObject_Release(pdo
);
2684 skip("No file(s) found - skipping single-file test.\n");
2688 hres
= IShellFolder_GetUIObjectOf(psfdesktop
, NULL
, count
, (LPCITEMIDLIST
*)apidl
,
2689 &IID_IDataObject
, NULL
, (void**)&pdo
);
2690 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
2693 hres
= pSHGetItemFromDataObject(pdo
, DOGIF_DEFAULT
, &IID_IShellItem
, (void**)&psi
);
2694 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
2695 if(SUCCEEDED(hres
)) IShellItem_Release(psi
);
2696 hres
= pSHGetItemFromDataObject(pdo
, DOGIF_TRAVERSE_LINK
, &IID_IShellItem
, (void**)&psi
);
2697 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
2698 if(SUCCEEDED(hres
)) IShellItem_Release(psi
);
2699 hres
= pSHGetItemFromDataObject(pdo
, DOGIF_NO_HDROP
, &IID_IShellItem
, (void**)&psi
);
2700 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
2701 if(SUCCEEDED(hres
)) IShellItem_Release(psi
);
2702 hres
= pSHGetItemFromDataObject(pdo
, DOGIF_NO_URL
, &IID_IShellItem
, (void**)&psi
);
2703 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
2704 if(SUCCEEDED(hres
)) IShellItem_Release(psi
);
2705 hres
= pSHGetItemFromDataObject(pdo
, DOGIF_ONLY_IF_ONE
, &IID_IShellItem
, (void**)&psi
);
2706 ok(hres
== E_FAIL
, "got 0x%08x\n", hres
);
2707 if(SUCCEEDED(hres
)) IShellItem_Release(psi
);
2708 IDataObject_Release(pdo
);
2712 skip("zero or one file found - skipping multi-file test.\n");
2714 for(i
= 0; i
< count
; i
++)
2717 IEnumIDList_Release(peidl
);
2720 IShellView_Release(psv
);
2723 IShellFolder_Release(psfdesktop
);
2726 static void test_ShellItemCompare(void)
2728 IShellItem
*psi
[9]; /* a\a, a\b, a\c, b\a, .. */
2729 IShellItem
*psi_a
= NULL
, *psi_b
= NULL
, *psi_c
= NULL
;
2730 IShellFolder
*psf_desktop
, *psf_current
;
2731 LPITEMIDLIST pidl_cwd
;
2732 WCHAR curdirW
[MAX_PATH
];
2735 static const WCHAR filesW
[][9] = {
2736 {'a','\\','a',0}, {'a','\\','b',0}, {'a','\\','c',0},
2737 {'b','\\','a',0}, {'b','\\','b',0}, {'b','\\','c',0},
2738 {'c','\\','a',0}, {'c','\\','b',0}, {'c','\\','c',0} };
2742 if(!pSHCreateShellItem
)
2744 win_skip("SHCreateShellItem missing.\n");
2748 GetCurrentDirectoryW(MAX_PATH
, curdirW
);
2751 skip("Failed to get current directory, skipping.\n");
2755 CreateDirectoryA(".\\a", NULL
);
2756 CreateDirectoryA(".\\b", NULL
);
2757 CreateDirectoryA(".\\c", NULL
);
2758 CreateTestFile(".\\a\\a");
2759 CreateTestFile(".\\a\\b");
2760 CreateTestFile(".\\a\\c");
2761 CreateTestFile(".\\b\\a");
2762 CreateTestFile(".\\b\\b");
2763 CreateTestFile(".\\b\\c");
2764 CreateTestFile(".\\c\\a");
2765 CreateTestFile(".\\c\\b");
2766 CreateTestFile(".\\c\\c");
2768 SHGetDesktopFolder(&psf_desktop
);
2769 hr
= IShellFolder_ParseDisplayName(psf_desktop
, NULL
, NULL
, curdirW
, NULL
, &pidl_cwd
, NULL
);
2770 ok(SUCCEEDED(hr
), "ParseDisplayName returned %x\n", hr
);
2771 hr
= IShellFolder_BindToObject(psf_desktop
, pidl_cwd
, NULL
, &IID_IShellFolder
, (void**)&psf_current
);
2772 ok(SUCCEEDED(hr
), "BindToObject returned %x\n", hr
);
2773 IShellFolder_Release(psf_desktop
);
2776 /* Generate ShellItems for the files */
2777 memset(&psi
, 0, sizeof(psi
));
2779 for(i
= 0; i
< 9; i
++)
2781 LPITEMIDLIST pidl_testfile
= NULL
;
2783 hr
= IShellFolder_ParseDisplayName(psf_current
, NULL
, NULL
, (LPWSTR
)filesW
[i
],
2784 NULL
, &pidl_testfile
, NULL
);
2785 ok(SUCCEEDED(hr
), "ParseDisplayName returned %x\n", hr
);
2788 hr
= pSHCreateShellItem(NULL
, NULL
, pidl_testfile
, &psi
[i
]);
2789 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
2790 ILFree(pidl_testfile
);
2792 if(FAILED(hr
)) failed
= TRUE
;
2796 skip("Failed to create all shellitems.\n");
2800 /* Generate ShellItems for the folders */
2801 hr
= IShellItem_GetParent(psi
[0], &psi_a
);
2802 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
2803 if(FAILED(hr
)) failed
= TRUE
;
2804 hr
= IShellItem_GetParent(psi
[3], &psi_b
);
2805 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
2806 if(FAILED(hr
)) failed
= TRUE
;
2807 hr
= IShellItem_GetParent(psi
[6], &psi_c
);
2808 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
2809 if(FAILED(hr
)) failed
= TRUE
;
2813 skip("Failed to create shellitems.\n");
2819 /* Crashes on native (win7, winxp) */
2820 IShellItem_Compare(psi_a
, NULL
, 0, NULL
);
2821 IShellItem_Compare(psi_a
, psi_b
, 0, NULL
);
2822 IShellItem_Compare(psi_a
, NULL
, 0, &order
);
2826 for(i
= 0; i
< 9; i
++)
2828 hr
= IShellItem_Compare(psi
[i
], psi
[i
], SICHINT_DISPLAY
, &order
);
2829 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
2830 ok(order
== 0, "Got order %d\n", order
);
2831 hr
= IShellItem_Compare(psi
[i
], psi
[i
], SICHINT_CANONICAL
, &order
);
2832 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
2833 ok(order
== 0, "Got order %d\n", order
);
2834 hr
= IShellItem_Compare(psi
[i
], psi
[i
], SICHINT_ALLFIELDS
, &order
);
2835 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
2836 ok(order
== 0, "Got order %d\n", order
);
2840 /* a\b:a\a , a\b:a\c, a\b:a\b */
2841 hr
= IShellItem_Compare(psi
[1], psi
[0], SICHINT_DISPLAY
, &order
);
2842 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
2843 ok(order
== 1, "Got order %d\n", order
);
2844 hr
= IShellItem_Compare(psi
[1], psi
[2], SICHINT_DISPLAY
, &order
);
2845 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
2846 ok(order
== -1, "Got order %d\n", order
);
2847 hr
= IShellItem_Compare(psi
[1], psi
[1], SICHINT_DISPLAY
, &order
);
2848 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
2849 ok(order
== 0, "Got order %d\n", order
);
2851 /* b\b:a\b, b\b:c\b, b\b:c\b */
2852 hr
= IShellItem_Compare(psi
[4], psi
[1], SICHINT_DISPLAY
, &order
);
2853 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
2854 ok(order
== 1, "Got order %d\n", order
);
2855 hr
= IShellItem_Compare(psi
[4], psi
[7], SICHINT_DISPLAY
, &order
);
2856 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
2857 ok(order
== -1, "Got order %d\n", order
);
2858 hr
= IShellItem_Compare(psi
[4], psi
[4], SICHINT_DISPLAY
, &order
);
2859 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
2860 ok(order
== 0, "Got order %d\n", order
);
2862 /* b:a\a, b:a\c, b:a\b */
2863 hr
= IShellItem_Compare(psi_b
, psi
[0], SICHINT_DISPLAY
, &order
);
2864 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
2865 todo_wine
ok(order
== 1, "Got order %d\n", order
);
2866 hr
= IShellItem_Compare(psi_b
, psi
[2], SICHINT_DISPLAY
, &order
);
2867 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
2868 todo_wine
ok(order
== 1, "Got order %d\n", order
);
2869 hr
= IShellItem_Compare(psi_b
, psi
[1], SICHINT_DISPLAY
, &order
);
2870 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
2871 todo_wine
ok(order
== 1, "Got order %d\n", order
);
2873 /* b:c\a, b:c\c, b:c\b */
2874 hr
= IShellItem_Compare(psi_b
, psi
[6], SICHINT_DISPLAY
, &order
);
2875 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
2876 ok(order
== -1, "Got order %d\n", order
);
2877 hr
= IShellItem_Compare(psi_b
, psi
[8], SICHINT_DISPLAY
, &order
);
2878 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
2879 ok(order
== -1, "Got order %d\n", order
);
2880 hr
= IShellItem_Compare(psi_b
, psi
[7], SICHINT_DISPLAY
, &order
);
2881 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
2882 ok(order
== -1, "Got order %d\n", order
);
2884 /* a\b:a\a , a\b:a\c, a\b:a\b */
2885 hr
= IShellItem_Compare(psi
[1], psi
[0], SICHINT_CANONICAL
, &order
);
2886 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
2887 ok(order
== 1, "Got order %d\n", order
);
2888 hr
= IShellItem_Compare(psi
[1], psi
[2], SICHINT_CANONICAL
, &order
);
2889 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
2890 ok(order
== -1, "Got order %d\n", order
);
2891 hr
= IShellItem_Compare(psi
[1], psi
[1], SICHINT_CANONICAL
, &order
);
2892 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
2893 ok(order
== 0, "Got order %d\n", order
);
2895 /* b\b:a\b, b\b:c\b, b\b:c\b */
2896 hr
= IShellItem_Compare(psi
[4], psi
[1], SICHINT_CANONICAL
, &order
);
2897 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
2898 ok(order
== 1, "Got order %d\n", order
);
2899 hr
= IShellItem_Compare(psi
[4], psi
[7], SICHINT_CANONICAL
, &order
);
2900 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
2901 ok(order
== -1, "Got order %d\n", order
);
2902 hr
= IShellItem_Compare(psi
[4], psi
[4], SICHINT_CANONICAL
, &order
);
2903 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
2904 ok(order
== 0, "Got order %d\n", order
);
2906 /* b:a\a, b:a\c, b:a\b */
2907 hr
= IShellItem_Compare(psi_b
, psi
[0], SICHINT_CANONICAL
, &order
);
2908 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
2909 todo_wine
ok(order
== 1, "Got order %d\n", order
);
2910 hr
= IShellItem_Compare(psi_b
, psi
[2], SICHINT_CANONICAL
, &order
);
2911 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
2912 todo_wine
ok(order
== 1, "Got order %d\n", order
);
2913 hr
= IShellItem_Compare(psi_b
, psi
[1], SICHINT_CANONICAL
, &order
);
2914 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
2915 todo_wine
ok(order
== 1, "Got order %d\n", order
);
2917 /* b:c\a, b:c\c, b:c\b */
2918 hr
= IShellItem_Compare(psi_b
, psi
[6], SICHINT_CANONICAL
, &order
);
2919 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
2920 ok(order
== -1, "Got order %d\n", order
);
2921 hr
= IShellItem_Compare(psi_b
, psi
[8], SICHINT_CANONICAL
, &order
);
2922 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
2923 ok(order
== -1, "Got order %d\n", order
);
2924 hr
= IShellItem_Compare(psi_b
, psi
[7], SICHINT_CANONICAL
, &order
);
2925 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
2926 ok(order
== -1, "Got order %d\n", order
);
2929 IShellFolder_Release(psf_current
);
2931 DeleteFileA(".\\a\\a");
2932 DeleteFileA(".\\a\\b");
2933 DeleteFileA(".\\a\\c");
2934 DeleteFileA(".\\b\\a");
2935 DeleteFileA(".\\b\\b");
2936 DeleteFileA(".\\b\\c");
2937 DeleteFileA(".\\c\\a");
2938 DeleteFileA(".\\c\\b");
2939 DeleteFileA(".\\c\\c");
2940 RemoveDirectoryA(".\\a");
2941 RemoveDirectoryA(".\\b");
2942 RemoveDirectoryA(".\\c");
2944 if(psi_a
) IShellItem_Release(psi_a
);
2945 if(psi_b
) IShellItem_Release(psi_b
);
2946 if(psi_c
) IShellItem_Release(psi_c
);
2948 for(i
= 0; i
< 9; i
++)
2949 if(psi
[i
]) IShellItem_Release(psi
[i
]);
2952 /**************************************************************/
2953 /* IUnknown implementation for counting QueryInterface calls. */
2955 IUnknown IUnknown_iface
;
2963 static inline IUnknownImpl
*impl_from_IUnknown(IUnknown
*iface
)
2965 return CONTAINING_RECORD(iface
, IUnknownImpl
, IUnknown_iface
);
2968 static HRESULT WINAPI
unk_fnQueryInterface(IUnknown
*iunk
, REFIID riid
, void** punk
)
2970 IUnknownImpl
*This
= impl_from_IUnknown(iunk
);
2973 for(i
= 0; This
->ifaces
[i
].id
!= NULL
; i
++)
2975 if(IsEqualIID(This
->ifaces
[i
].id
, riid
))
2977 This
->ifaces
[i
].count
++;
2984 return E_NOINTERFACE
;
2987 static ULONG WINAPI
unk_fnAddRef(IUnknown
*iunk
)
2992 static ULONG WINAPI
unk_fnRelease(IUnknown
*iunk
)
2997 static const IUnknownVtbl vt_IUnknown
= {
2998 unk_fnQueryInterface
,
3003 static void test_SHGetIDListFromObject(void)
3005 IUnknownImpl
*punkimpl
;
3006 IShellFolder
*psfdesktop
;
3008 LPITEMIDLIST pidl
, pidl_desktop
;
3011 struct if_count ifaces
[] =
3012 { {&IID_IPersistIDList
, 0},
3013 {&IID_IPersistFolder2
, 0},
3014 {&IID_IDataObject
, 0},
3015 {&IID_IParentAndItem
, 0},
3016 {&IID_IFolderView
, 0},
3019 if(!pSHGetIDListFromObject
)
3021 win_skip("SHGetIDListFromObject missing.\n");
3027 /* Crashes native */
3028 pSHGetIDListFromObject(NULL
, NULL
);
3029 pSHGetIDListFromObject((void*)0xDEADBEEF, NULL
);
3032 hres
= pSHGetIDListFromObject(NULL
, &pidl
);
3033 ok(hres
== E_NOINTERFACE
, "Got %x\n", hres
);
3035 punkimpl
= heap_alloc(sizeof(*punkimpl
));
3036 punkimpl
->IUnknown_iface
.lpVtbl
= &vt_IUnknown
;
3037 punkimpl
->ifaces
= ifaces
;
3038 punkimpl
->unknown
= 0;
3040 hres
= pSHGetIDListFromObject(&punkimpl
->IUnknown_iface
, &pidl
);
3041 ok(hres
== E_NOINTERFACE
, "Got %x\n", hres
);
3042 ok(ifaces
[0].count
, "interface not requested.\n");
3043 ok(ifaces
[1].count
, "interface not requested.\n");
3044 ok(ifaces
[2].count
, "interface not requested.\n");
3046 ok(ifaces
[3].count
|| broken(!ifaces
[3].count
/*vista*/),
3047 "interface not requested.\n");
3048 ok(ifaces
[4].count
|| broken(!ifaces
[4].count
/*vista*/),
3049 "interface not requested.\n");
3051 ok(!punkimpl
->unknown
, "Got %d unknown.\n", punkimpl
->unknown
);
3052 heap_free(punkimpl
);
3054 pidl_desktop
= NULL
;
3055 SHGetSpecialFolderLocation(NULL
, CSIDL_DESKTOP
, &pidl_desktop
);
3056 ok(pidl_desktop
!= NULL
, "Failed to get desktop pidl.\n");
3058 SHGetDesktopFolder(&psfdesktop
);
3060 /* Test IShellItem */
3061 if(pSHCreateShellItem
)
3063 IShellItem
*shellitem
;
3064 hres
= pSHCreateShellItem(NULL
, NULL
, pidl_desktop
, &shellitem
);
3065 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
3068 hres
= pSHGetIDListFromObject((IUnknown
*)shellitem
, &pidl
);
3069 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
3072 ok(ILIsEqual(pidl_desktop
, pidl
), "pidl not equal.\n");
3075 IShellItem_Release(shellitem
);
3079 skip("no SHCreateShellItem.\n");
3081 /* Test IShellFolder */
3082 hres
= pSHGetIDListFromObject((IUnknown
*)psfdesktop
, &pidl
);
3083 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
3086 ok(ILIsEqual(pidl_desktop
, pidl
), "pidl not equal.\n");
3090 hres
= IShellFolder_CreateViewObject(psfdesktop
, NULL
, &IID_IShellView
, (void**)&psv
);
3091 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
3098 /* Test IFolderView */
3099 hres
= pSHGetIDListFromObject((IUnknown
*)psv
, &pidl
);
3100 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
3103 ok(ILIsEqual(pidl_desktop
, pidl
), "pidl not equal.\n");
3107 /* Test IDataObject */
3108 enum_flags
= SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
| SHCONTF_INCLUDEHIDDEN
;
3109 hres
= IShellFolder_EnumObjects(psfdesktop
, NULL
, enum_flags
, &peidl
);
3110 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
3113 LPITEMIDLIST apidl
[5];
3115 for(count
= 0; count
< 5; count
++)
3116 if(IEnumIDList_Next(peidl
, 1, &apidl
[count
], NULL
) != S_OK
)
3121 hres
= IShellFolder_GetUIObjectOf(psfdesktop
, NULL
, 1, (LPCITEMIDLIST
*)apidl
,
3122 &IID_IDataObject
, NULL
, (void**)&pdo
);
3123 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
3126 pidl
= (void*)0xDEADBEEF;
3127 hres
= pSHGetIDListFromObject((IUnknown
*)pdo
, &pidl
);
3128 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
3129 ok(pidl
!= NULL
, "pidl is NULL.\n");
3130 ok(ILIsEqual(pidl
, apidl
[0]), "pidl not equal.\n");
3133 IDataObject_Release(pdo
);
3137 skip("No files found - skipping single-file test.\n");
3141 hres
= IShellFolder_GetUIObjectOf(psfdesktop
, NULL
, count
, (LPCITEMIDLIST
*)apidl
,
3142 &IID_IDataObject
, NULL
, (void**)&pdo
);
3143 ok(hres
== S_OK
, "got 0x%08x\n", hres
);
3146 pidl
= (void*)0xDEADBEEF;
3147 hres
= pSHGetIDListFromObject((IUnknown
*)pdo
, &pidl
);
3148 ok(hres
== E_NOINTERFACE
|| hres
== E_FAIL
/*Vista*/,
3149 "got 0x%08x\n", hres
);
3150 ok(pidl
== NULL
, "pidl is not NULL.\n");
3152 IDataObject_Release(pdo
);
3156 skip("zero or one file found - skipping multi-file test.\n");
3158 for(i
= 0; i
< count
; i
++)
3161 IEnumIDList_Release(peidl
);
3164 IShellView_Release(psv
);
3167 IShellFolder_Release(psfdesktop
);
3168 ILFree(pidl_desktop
);
3171 static void test_SHGetItemFromObject(void)
3173 IUnknownImpl
*punkimpl
;
3174 IShellFolder
*psfdesktop
;
3179 struct if_count ifaces
[] =
3180 { {&IID_IPersistIDList
, 0},
3181 {&IID_IPersistFolder2
, 0},
3182 {&IID_IDataObject
, 0},
3183 {&IID_IParentAndItem
, 0},
3184 {&IID_IFolderView
, 0},
3187 if(!pSHGetItemFromObject
)
3189 skip("No SHGetItemFromObject.\n");
3193 SHGetDesktopFolder(&psfdesktop
);
3197 /* Crashes with Windows 7 */
3198 pSHGetItemFromObject((IUnknown
*)psfdesktop
, &IID_IUnknown
, NULL
);
3199 pSHGetItemFromObject(NULL
, &IID_IUnknown
, NULL
);
3200 pSHGetItemFromObject((IUnknown
*)psfdesktop
, NULL
, (void**)&punk
);
3203 hres
= pSHGetItemFromObject(NULL
, &IID_IUnknown
, (void**)&punk
);
3204 ok(hres
== E_NOINTERFACE
, "Got 0x%08x\n", hres
);
3206 punkimpl
= heap_alloc(sizeof(*punkimpl
));
3207 punkimpl
->IUnknown_iface
.lpVtbl
= &vt_IUnknown
;
3208 punkimpl
->ifaces
= ifaces
;
3209 punkimpl
->unknown
= 0;
3211 /* The same as SHGetIDListFromObject */
3212 hres
= pSHGetIDListFromObject(&punkimpl
->IUnknown_iface
, &pidl
);
3213 ok(hres
== E_NOINTERFACE
, "Got %x\n", hres
);
3214 ok(ifaces
[0].count
, "interface not requested.\n");
3215 ok(ifaces
[1].count
, "interface not requested.\n");
3216 ok(ifaces
[2].count
, "interface not requested.\n");
3218 ok(ifaces
[3].count
|| broken(!ifaces
[3].count
/*vista*/),
3219 "interface not requested.\n");
3220 ok(ifaces
[4].count
|| broken(!ifaces
[4].count
/*vista*/),
3221 "interface not requested.\n");
3223 ok(!punkimpl
->unknown
, "Got %d unknown.\n", punkimpl
->unknown
);
3224 heap_free(punkimpl
);
3226 /* Test IShellItem */
3227 hres
= pSHGetItemFromObject((IUnknown
*)psfdesktop
, &IID_IShellItem
, (void**)&psi
);
3228 ok(hres
== S_OK
, "Got 0x%08x\n", hres
);
3232 hres
= pSHGetItemFromObject((IUnknown
*)psi
, &IID_IShellItem
, (void**)&psi2
);
3233 ok(hres
== S_OK
, "Got 0x%08x\n", hres
);
3237 ok(psi
== psi2
, "Different instances (%p != %p).\n", psi
, psi2
);
3238 IShellItem_Release(psi2
);
3240 IShellItem_Release(psi
);
3243 IShellFolder_Release(psfdesktop
);
3246 static void test_SHCreateShellItemArray(void)
3248 IShellFolder
*pdesktopsf
, *psf
;
3249 IShellItemArray
*psia
;
3252 WCHAR cTestDirW
[MAX_PATH
];
3253 LPITEMIDLIST pidl_testdir
, pidl
;
3254 static const WCHAR testdirW
[] = {'t','e','s','t','d','i','r',0};
3256 if(!pSHCreateShellItemArray
) {
3257 skip("No pSHCreateShellItemArray!\n");
3263 /* Crashes under native */
3264 pSHCreateShellItemArray(NULL
, NULL
, 0, NULL
, NULL
);
3265 pSHCreateShellItemArray(NULL
, NULL
, 1, NULL
, NULL
);
3266 pSHCreateShellItemArray(NULL
, pdesktopsf
, 0, NULL
, NULL
);
3267 pSHCreateShellItemArray(pidl
, NULL
, 0, NULL
, NULL
);
3270 hr
= pSHCreateShellItemArray(NULL
, NULL
, 0, NULL
, &psia
);
3271 ok(hr
== E_POINTER
, "got 0x%08x\n", hr
);
3273 SHGetDesktopFolder(&pdesktopsf
);
3274 hr
= pSHCreateShellItemArray(NULL
, pdesktopsf
, 0, NULL
, &psia
);
3275 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3277 hr
= pSHCreateShellItemArray(NULL
, pdesktopsf
, 1, NULL
, &psia
);
3278 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3280 SHGetSpecialFolderLocation(NULL
, CSIDL_DESKTOP
, &pidl
);
3281 hr
= pSHCreateShellItemArray(pidl
, NULL
, 0, NULL
, &psia
);
3282 ok(hr
== E_INVALIDARG
, "got 0x%08x\n", hr
);
3285 GetCurrentDirectoryW(MAX_PATH
, cTestDirW
);
3286 myPathAddBackslashW(cTestDirW
);
3287 lstrcatW(cTestDirW
, testdirW
);
3289 CreateFilesFolders();
3291 hr
= IShellFolder_ParseDisplayName(pdesktopsf
, NULL
, NULL
, cTestDirW
, NULL
, &pidl_testdir
, 0);
3292 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3295 hr
= IShellFolder_BindToObject(pdesktopsf
, pidl_testdir
, NULL
, (REFIID
)&IID_IShellFolder
,
3297 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3299 IShellFolder_Release(pdesktopsf
);
3303 skip("Failed to set up environment for SHCreateShellItemArray tests.\n");
3304 ILFree(pidl_testdir
);
3309 hr
= IShellFolder_EnumObjects(psf
, NULL
, SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
, &peidl
);
3310 ok(hr
== S_OK
, "Got %08x\n", hr
);
3313 LPITEMIDLIST apidl
[5];
3314 UINT done
, numitems
, i
;
3316 for(done
= 0; done
< 5; done
++)
3317 if(IEnumIDList_Next(peidl
, 1, &apidl
[done
], NULL
) != S_OK
)
3319 ok(done
== 5, "Got %d pidls\n", done
);
3320 IEnumIDList_Release(peidl
);
3322 /* Create a ShellItemArray */
3323 hr
= pSHCreateShellItemArray(NULL
, psf
, done
, (LPCITEMIDLIST
*)apidl
, &psia
);
3324 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3331 /* Crashes in Windows 7 */
3332 IShellItemArray_GetCount(psia
, NULL
);
3335 IShellItemArray_GetCount(psia
, &numitems
);
3336 ok(numitems
== done
, "Got %d, expected %d\n", numitems
, done
);
3338 hr
= IShellItemArray_GetItemAt(psia
, numitems
, &psi
);
3339 ok(hr
== E_FAIL
, "Got 0x%08x\n", hr
);
3341 /* Compare all the items */
3342 for(i
= 0; i
< numitems
; i
++)
3344 LPITEMIDLIST pidl_abs
;
3345 pidl_abs
= ILCombine(pidl_testdir
, apidl
[i
]);
3347 hr
= IShellItemArray_GetItemAt(psia
, i
, &psi
);
3348 ok(hr
== S_OK
, "(%d) Failed with 0x%08x\n", i
, hr
);
3351 hr
= pSHGetIDListFromObject((IUnknown
*)psi
, &pidl
);
3352 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3355 ok(ILIsEqual(pidl_abs
, pidl
), "Pidl not equal.\n");
3358 IShellItem_Release(psi
);
3362 for(i
= 0; i
< done
; i
++)
3364 IShellItemArray_Release(psia
);
3368 /* SHCreateShellItemArrayFromShellItem */
3369 if(pSHCreateShellItemArrayFromShellItem
)
3375 /* Crashes under Windows 7 */
3376 pSHCreateShellItemArrayFromShellItem(NULL
, &IID_IShellItemArray
, NULL
);
3377 pSHCreateShellItemArrayFromShellItem(NULL
, &IID_IShellItemArray
, (void**)&psia
);
3378 pSHCreateShellItemArrayFromShellItem(psi
, &IID_IShellItemArray
, NULL
);
3381 hr
= pSHCreateItemFromIDList(pidl_testdir
, &IID_IShellItem
, (void**)&psi
);
3382 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3385 hr
= pSHCreateShellItemArrayFromShellItem(psi
, &IID_IShellItemArray
, (void**)&psia
);
3386 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3391 hr
= IShellItemArray_GetCount(psia
, &count
);
3392 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3393 ok(count
== 1, "Got count %d\n", count
);
3394 hr
= IShellItemArray_GetItemAt(psia
, 0, &psi2
);
3395 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3397 ok(psi
!= psi2
, "ShellItems are of the same instance.\n");
3400 LPITEMIDLIST pidl1
, pidl2
;
3401 hr
= pSHGetIDListFromObject((IUnknown
*)psi
, &pidl1
);
3402 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3403 ok(pidl1
!= NULL
, "pidl1 was null.\n");
3404 hr
= pSHGetIDListFromObject((IUnknown
*)psi2
, &pidl2
);
3405 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3406 ok(pidl2
!= NULL
, "pidl2 was null.\n");
3407 ok(ILIsEqual(pidl1
, pidl2
), "pidls not equal.\n");
3410 IShellItem_Release(psi2
);
3412 hr
= IShellItemArray_GetItemAt(psia
, 1, &psi2
);
3413 ok(hr
== E_FAIL
, "Got 0x%08x\n", hr
);
3414 IShellItemArray_Release(psia
);
3416 IShellItem_Release(psi
);
3420 skip("No SHCreateShellItemArrayFromShellItem.\n");
3422 if(pSHCreateShellItemArrayFromDataObject
)
3428 /* Crashes under Windows 7 */
3429 pSHCreateShellItemArrayFromDataObject(NULL
, &IID_IShellItemArray
, NULL
);
3431 hr
= pSHCreateShellItemArrayFromDataObject(NULL
, &IID_IShellItemArray
, (void**)&psia
);
3432 ok(hr
== E_INVALIDARG
, "Got 0x%08x\n", hr
);
3434 hr
= IShellFolder_CreateViewObject(psf
, NULL
, &IID_IShellView
, (void**)&psv
);
3435 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3442 enum_flags
= SHCONTF_NONFOLDERS
| SHCONTF_FOLDERS
| SHCONTF_INCLUDEHIDDEN
;
3443 hr
= IShellFolder_EnumObjects(psf
, NULL
, enum_flags
, &peidl
);
3444 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3447 LPITEMIDLIST apidl
[5];
3450 for(count
= 0; count
< 5; count
++)
3451 if(IEnumIDList_Next(peidl
, 1, &apidl
[count
], NULL
) != S_OK
)
3453 ok(count
== 5, "Got %d\n", count
);
3457 hr
= IShellFolder_GetUIObjectOf(psf
, NULL
, count
, (LPCITEMIDLIST
*)apidl
,
3458 &IID_IDataObject
, NULL
, (void**)&pdo
);
3459 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3462 hr
= pSHCreateShellItemArrayFromDataObject(pdo
, &IID_IShellItemArray
,
3464 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3468 hr
= IShellItemArray_GetCount(psia
, &count_sia
);
3469 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3470 ok(count_sia
== count
, "Counts differ (%d, %d)\n", count
, count_sia
);
3471 for(i
= 0; i
< count_sia
; i
++)
3473 LPITEMIDLIST pidl_abs
= ILCombine(pidl_testdir
, apidl
[i
]);
3475 hr
= IShellItemArray_GetItemAt(psia
, i
, &psi
);
3476 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3480 hr
= pSHGetIDListFromObject((IUnknown
*)psi
, &pidl
);
3481 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3482 ok(pidl
!= NULL
, "pidl as NULL.\n");
3483 ok(ILIsEqual(pidl
, pidl_abs
), "pidls differ.\n");
3485 IShellItem_Release(psi
);
3490 IShellItemArray_Release(psia
);
3493 IDataObject_Release(pdo
);
3495 for(i
= 0; i
< count
; i
++)
3499 skip("No files found - skipping test.\n");
3501 IEnumIDList_Release(peidl
);
3503 IShellView_Release(psv
);
3507 skip("No SHCreateShellItemArrayFromDataObject.\n");
3509 if(pSHCreateShellItemArrayFromIDLists
)
3511 WCHAR test1W
[] = {'t','e','s','t','1','.','t','x','t',0};
3512 WCHAR test1pathW
[MAX_PATH
];
3513 LPITEMIDLIST pidltest1
;
3514 LPCITEMIDLIST pidl_array
[2];
3519 hr
= pSHCreateShellItemArrayFromIDLists(0, NULL
, NULL
);
3522 psia
= (void*)0xdeadbeef;
3523 hr
= pSHCreateShellItemArrayFromIDLists(0, NULL
, &psia
);
3524 ok(hr
== E_INVALIDARG
, "Got 0x%08x\n", hr
);
3525 ok(psia
== NULL
, "Got %p\n", psia
);
3527 psia
= (void*)0xdeadbeef;
3528 hr
= pSHCreateShellItemArrayFromIDLists(0, pidl_array
, &psia
);
3529 ok(hr
== E_INVALIDARG
, "Got 0x%08x\n", hr
);
3530 ok(psia
== NULL
, "Got %p\n", psia
);
3532 psia
= (void*)0xdeadbeef;
3533 pidl_array
[0] = NULL
;
3534 hr
= pSHCreateShellItemArrayFromIDLists(1, pidl_array
, &psia
);
3535 todo_wine
ok(hr
== E_OUTOFMEMORY
, "Got 0x%08x\n", hr
);
3536 ok(psia
== NULL
, "Got %p\n", psia
);
3538 psia
= (void*)0xdeadbeef;
3539 pidl_array
[0] = pidl_testdir
;
3540 pidl_array
[1] = NULL
;
3541 hr
= pSHCreateShellItemArrayFromIDLists(2, pidl_array
, &psia
);
3542 todo_wine
ok(hr
== S_OK
|| broken(hr
== E_INVALIDARG
) /* Vista */, "Got 0x%08x\n", hr
);
3543 todo_wine
ok(psia
!= NULL
|| broken(psia
== NULL
) /* Vista */, "Got %p\n", psia
);
3549 hr
= IShellItemArray_GetCount(psia
, &count
);
3550 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3551 ok(count
== 2, "Got %d\n", count
);
3553 hr
= IShellItemArray_GetItemAt(psia
, 0, &psi
);
3554 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3558 hr
= IShellItem_GetDisplayName(psi
, SIGDN_DESKTOPABSOLUTEPARSING
, &path
);
3559 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3560 ok(!lstrcmpW(path
, cTestDirW
), "Got %s\n", wine_dbgstr_w(path
));
3562 CoTaskMemFree(path
);
3564 IShellItem_Release(psi
);
3567 hr
= IShellItemArray_GetItemAt(psia
, 1, &psi
);
3568 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3572 WCHAR desktoppath
[MAX_PATH
];
3575 result
= SHGetSpecialFolderPathW(NULL
, desktoppath
, CSIDL_DESKTOPDIRECTORY
, FALSE
);
3576 ok(result
, "SHGetSpecialFolderPathW(CSIDL_DESKTOPDIRECTORY) failed! %u\n", GetLastError());
3578 hr
= IShellItem_GetDisplayName(psi
, SIGDN_DESKTOPABSOLUTEPARSING
, &path
);
3579 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3580 ok(!lstrcmpW(path
, desktoppath
), "Got %s\n", wine_dbgstr_w(path
));
3582 CoTaskMemFree(path
);
3584 IShellItem_Release(psi
);
3588 IShellItemArray_Release(psia
);
3593 psia
= (void*)0xdeadbeef;
3594 pidl_array
[0] = pidl_testdir
;
3595 hr
= pSHCreateShellItemArrayFromIDLists(1, pidl_array
, &psia
);
3596 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3602 hr
= IShellItemArray_GetCount(psia
, &count
);
3603 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3604 ok(count
== 1, "Got %d\n", count
);
3606 hr
= IShellItemArray_GetItemAt(psia
, 0, &psi
);
3607 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3611 hr
= IShellItem_GetDisplayName(psi
, SIGDN_DESKTOPABSOLUTEPARSING
, &path
);
3612 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3613 ok(!lstrcmpW(path
, cTestDirW
), "Got %s\n", wine_dbgstr_w(path
));
3615 CoTaskMemFree(path
);
3617 IShellItem_Release(psi
);
3620 IShellItemArray_Release(psia
);
3624 lstrcpyW(test1pathW
, cTestDirW
);
3625 myPathAddBackslashW(test1pathW
);
3626 lstrcatW(test1pathW
, test1W
);
3628 SHGetDesktopFolder(&pdesktopsf
);
3630 hr
= IShellFolder_ParseDisplayName(pdesktopsf
, NULL
, NULL
, test1pathW
, NULL
, &pidltest1
, NULL
);
3631 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3634 psia
= (void*)0xdeadbeef;
3635 pidl_array
[0] = pidl_testdir
;
3636 pidl_array
[1] = pidltest1
;
3637 hr
= pSHCreateShellItemArrayFromIDLists(2, pidl_array
, &psia
);
3638 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3644 hr
= IShellItemArray_GetCount(psia
, &count
);
3645 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3646 ok(count
== 2, "Got %d\n", count
);
3648 hr
= IShellItemArray_GetItemAt(psia
, 0, &psi
);
3649 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3653 hr
= IShellItem_GetDisplayName(psi
, SIGDN_DESKTOPABSOLUTEPARSING
, &path
);
3654 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3655 ok(!lstrcmpW(path
, cTestDirW
), "Got %s\n", wine_dbgstr_w(path
));
3657 CoTaskMemFree(path
);
3659 IShellItem_Release(psi
);
3662 hr
= IShellItemArray_GetItemAt(psia
, 1, &psi
);
3663 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3667 hr
= IShellItem_GetDisplayName(psi
, SIGDN_DESKTOPABSOLUTEPARSING
, &path
);
3668 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3669 ok(!lstrcmpW(path
, test1pathW
), "Got %s\n", wine_dbgstr_w(path
));
3671 CoTaskMemFree(path
);
3673 IShellItem_Release(psi
);
3677 IShellItemArray_Release(psia
);
3683 IShellFolder_Release(pdesktopsf
);
3686 skip("No SHCreateShellItemArrayFromIDLists.\n");
3688 IShellFolder_Release(psf
);
3689 ILFree(pidl_testdir
);
3693 static void test_ShellItemArrayEnumItems(void)
3695 IShellFolder
*pdesktopsf
, *psf
;
3697 WCHAR cTestDirW
[MAX_PATH
];
3699 LPITEMIDLIST pidl_testdir
;
3700 static const WCHAR testdirW
[] = {'t','e','s','t','d','i','r',0};
3702 if(!pSHCreateShellItemArray
)
3704 win_skip("No SHCreateShellItemArray, skipping test...\n");
3708 CreateFilesFolders();
3710 SHGetDesktopFolder(&pdesktopsf
);
3712 GetCurrentDirectoryW(MAX_PATH
, cTestDirW
);
3713 myPathAddBackslashW(cTestDirW
);
3714 lstrcatW(cTestDirW
, testdirW
);
3716 hr
= IShellFolder_ParseDisplayName(pdesktopsf
, NULL
, NULL
, cTestDirW
, NULL
, &pidl_testdir
, 0);
3717 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
3720 hr
= IShellFolder_BindToObject(pdesktopsf
, pidl_testdir
, NULL
, (REFIID
)&IID_IShellFolder
,
3722 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3723 ILFree(pidl_testdir
);
3725 IShellFolder_Release(pdesktopsf
);
3726 if (FAILED(hr
)) return;
3728 hr
= IShellFolder_EnumObjects(psf
, NULL
, SHCONTF_FOLDERS
| SHCONTF_NONFOLDERS
, &peidl
);
3729 ok(hr
== S_OK
, "Got %08x\n", hr
);
3732 IShellItemArray
*psia
;
3733 LPITEMIDLIST apidl
[5];
3734 UINT done
, numitems
, i
;
3736 for(done
= 0; done
< 5; done
++)
3737 if(IEnumIDList_Next(peidl
, 1, &apidl
[done
], NULL
) != S_OK
)
3739 ok(done
== 5, "Got %d pidls\n", done
);
3740 IEnumIDList_Release(peidl
);
3742 /* Create a ShellItemArray */
3743 hr
= pSHCreateShellItemArray(NULL
, psf
, done
, (LPCITEMIDLIST
*)apidl
, &psia
);
3744 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3747 IEnumShellItems
*iesi
;
3748 IShellItem
*my_array
[10];
3751 IShellItemArray_GetCount(psia
, &numitems
);
3752 ok(numitems
== done
, "Got %d, expected %d\n", numitems
, done
);
3755 hr
= IShellItemArray_EnumItems(psia
, &iesi
);
3756 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3757 ok(iesi
!= NULL
, "Got NULL\n");
3760 IEnumShellItems
*iesi2
;
3762 /* This should fail according to the documentation and Win7+ */
3763 for(i
= 0; i
< 10; i
++) my_array
[i
] = (void*)0xdeadbeef;
3764 hr
= IEnumShellItems_Next(iesi
, 2, my_array
, NULL
);
3765 ok(hr
== E_INVALIDARG
|| broken(hr
== S_OK
) /* Vista */, "Got 0x%08x\n", hr
);
3766 for(i
= 0; i
< 2; i
++)
3768 ok(my_array
[i
] == (void*)0xdeadbeef ||
3769 broken(my_array
[i
] != (void*)0xdeadbeef && my_array
[i
] != NULL
), /* Vista */
3770 "Got %p (%d)\n", my_array
[i
], i
);
3772 if(my_array
[i
] != (void*)0xdeadbeef)
3773 IShellItem_Release(my_array
[i
]);
3775 ok(my_array
[2] == (void*)0xdeadbeef, "Got %p\n", my_array
[2]);
3777 IEnumShellItems_Reset(iesi
);
3778 for(i
= 0; i
< 10; i
++) my_array
[i
] = (void*)0xdeadbeef;
3779 hr
= IEnumShellItems_Next(iesi
, 1, my_array
, NULL
);
3780 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3781 ok(my_array
[0] != NULL
&& my_array
[0] != (void*)0xdeadbeef, "Got %p\n", my_array
[0]);
3782 if(my_array
[0] != NULL
&& my_array
[0] != (void*)0xdeadbeef)
3783 IShellItem_Release(my_array
[0]);
3784 ok(my_array
[1] == (void*)0xdeadbeef, "Got %p\n", my_array
[1]);
3786 IEnumShellItems_Reset(iesi
);
3788 for(i
= 0; i
< 10; i
++) my_array
[i
] = (void*)0xdeadbeef;
3789 hr
= IEnumShellItems_Next(iesi
, numitems
, my_array
, &fetched
);
3790 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3791 ok(fetched
== numitems
, "Got %d\n", fetched
);
3792 for(i
= 0;i
< numitems
; i
++)
3794 ok(my_array
[i
] != NULL
&& my_array
[i
] != (void*)0xdeadbeef,
3795 "Got %p at %d\n", my_array
[i
], i
);
3797 if(my_array
[i
] != NULL
&& my_array
[i
] != (void*)0xdeadbeef)
3798 IShellItem_Release(my_array
[i
]);
3800 ok(my_array
[i
] == (void*)0xdeadbeef, "Got %p\n", my_array
[i
]);
3802 /* Compare all the items */
3803 IEnumShellItems_Reset(iesi
);
3804 for(i
= 0; i
< numitems
; i
++)
3809 hr
= IShellItemArray_GetItemAt(psia
, i
, &psi
);
3810 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3811 hr
= IEnumShellItems_Next(iesi
, 1, my_array
, &fetched
);
3812 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3813 ok(fetched
== 1, "Got %d\n", fetched
);
3815 hr
= IShellItem_Compare(psi
, my_array
[0], 0, &order
);
3816 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3817 ok(order
== 0, "Got %d\n", order
);
3819 IShellItem_Release(psi
);
3820 IShellItem_Release(my_array
[0]);
3823 my_array
[0] = (void*)0xdeadbeef;
3824 hr
= IEnumShellItems_Next(iesi
, 1, my_array
, &fetched
);
3825 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
3826 ok(fetched
== 0, "Got %d\n", fetched
);
3827 ok(my_array
[0] == (void*)0xdeadbeef, "Got %p\n", my_array
[0]);
3829 /* Cloning not implemented anywhere */
3830 iesi2
= (void*)0xdeadbeef;
3831 hr
= IEnumShellItems_Clone(iesi
, &iesi2
);
3832 ok(hr
== E_NOTIMPL
, "Got 0x%08x\n", hr
);
3833 ok(iesi2
== NULL
|| broken(iesi2
== (void*)0xdeadbeef) /* Vista */, "Got %p\n", iesi2
);
3835 IEnumShellItems_Release(iesi
);
3838 IShellItemArray_Release(psia
);
3841 for(i
= 0; i
< done
; i
++)
3845 IShellFolder_Release(psf
);
3849 static void test_ShellItemBindToHandler(void)
3852 LPITEMIDLIST pidl_desktop
;
3855 if(!pSHCreateShellItem
)
3857 skip("SHCreateShellItem missing.\n");
3861 hr
= SHGetSpecialFolderLocation(NULL
, CSIDL_DESKTOP
, &pidl_desktop
);
3862 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3865 hr
= pSHCreateShellItem(NULL
, NULL
, pidl_desktop
, &psi
);
3866 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3870 IPersistFolder2
*ppf2
;
3875 /* Crashes under Windows 7 */
3876 IShellItem_BindToHandler(psi
, NULL
, NULL
, NULL
, NULL
);
3877 IShellItem_BindToHandler(psi
, NULL
, &IID_IUnknown
, &IID_IUnknown
, NULL
);
3879 hr
= IShellItem_BindToHandler(psi
, NULL
, &IID_IUnknown
, &IID_IUnknown
, (void**)&punk
);
3880 ok(hr
== MK_E_NOOBJECT
, "Got 0x%08x\n", hr
);
3883 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_SFObject
, &IID_IShellFolder
, (void**)&punk
);
3884 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3885 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
3886 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_SFObject
, &IID_IPersistFolder2
, (void**)&ppf2
);
3887 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3890 LPITEMIDLIST pidl_tmp
;
3891 hr
= IPersistFolder2_GetCurFolder(ppf2
, &pidl_tmp
);
3892 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3895 ok(ILIsEqual(pidl_desktop
, pidl_tmp
), "Pidl not equal (%p, %p)\n", pidl_desktop
, pidl_tmp
);
3898 IPersistFolder2_Release(ppf2
);
3901 /* BHID_SFUIObject */
3902 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_SFUIObject
, &IID_IDataObject
, (void**)&punk
);
3903 ok(hr
== S_OK
|| broken(hr
== E_NOINTERFACE
/* XP */), "Got 0x%08x\n", hr
);
3904 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
3905 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_SFUIObject
, &IID_IContextMenu
, (void**)&punk
);
3906 ok(hr
== S_OK
|| broken(hr
== E_NOINTERFACE
/* XP */), "Got 0x%08x\n", hr
);
3907 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
3909 /* BHID_DataObject */
3910 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_DataObject
, &IID_IDataObject
, (void**)&punk
);
3911 ok(hr
== S_OK
|| broken(hr
== MK_E_NOOBJECT
/* XP */), "Got 0x%08x\n", hr
);
3912 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
3916 /* BHID_SFViewObject */
3917 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_SFViewObject
, &IID_IShellView
, (void**)&punk
);
3918 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3919 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
3920 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_SFViewObject
, &IID_IShellFolderView
, (void**)&punk
);
3921 ok(hr
== E_NOINTERFACE
, "Got 0x%08x\n", hr
);
3922 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
3925 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_Storage
, &IID_IStream
, (void**)&punk
);
3926 ok(hr
== E_NOINTERFACE
, "Got 0x%08x\n", hr
);
3927 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
3928 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_Storage
, &IID_IUnknown
, (void**)&punk
);
3929 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3930 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
3933 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_Stream
, &IID_IStream
, (void**)&punk
);
3934 ok(hr
== E_NOINTERFACE
, "Got 0x%08x\n", hr
);
3935 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
3936 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_Stream
, &IID_IUnknown
, (void**)&punk
);
3937 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3938 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
3940 /* BHID_StorageEnum */
3941 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_StorageEnum
, &IID_IEnumShellItems
, (void**)&punk
);
3942 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3943 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
3946 ITransferSource and ITransferDestination are accessible starting from Vista, IUnknown is
3947 supported starting from Win8. */
3948 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_Transfer
, &IID_ITransferSource
, (void**)&punk
);
3949 ok(hr
== S_OK
|| broken(FAILED(hr
)) /* pre-Vista */, "Got 0x%08x\n", hr
);
3952 IUnknown_Release(punk
);
3954 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_Transfer
, &IID_ITransferDestination
, (void**)&punk
);
3955 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
3956 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
3958 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_Transfer
, &IID_IUnknown
, (void**)&punk
);
3959 ok(hr
== S_OK
|| broken(hr
== E_NOINTERFACE
) /* pre-Win8 */, "Got 0x%08x\n", hr
);
3960 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
3963 /* BHID_EnumItems */
3964 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_EnumItems
, &IID_IEnumShellItems
, (void**)&punk
);
3965 ok(hr
== S_OK
|| broken(hr
== MK_E_NOOBJECT
/* XP */), "Got 0x%08x\n", hr
);
3966 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
3969 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_Filter
, &IID_IUnknown
, (void**)&punk
);
3970 ok(hr
== S_OK
|| broken(hr
== MK_E_NOOBJECT
/* XP */), "Got 0x%08x\n", hr
);
3971 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
3973 /* BHID_LinkTargetItem */
3974 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_LinkTargetItem
, &IID_IShellItem
, (void**)&punk
);
3975 ok(hr
== E_NOINTERFACE
|| broken(hr
== E_INVALIDARG
/* XP */), "Got 0x%08x\n", hr
);
3976 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
3977 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_LinkTargetItem
, &IID_IUnknown
, (void**)&punk
);
3978 ok(hr
== E_NOINTERFACE
|| broken(hr
== E_INVALIDARG
/* XP */), "Got 0x%08x\n", hr
);
3979 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
3981 /* BHID_PropertyStore */
3982 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_PropertyStore
, &IID_IPropertyStore
, (void**)&punk
);
3983 ok(hr
== E_NOINTERFACE
|| broken(hr
== MK_E_NOOBJECT
/* XP */), "Got 0x%08x\n", hr
);
3984 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
3985 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_PropertyStore
, &IID_IPropertyStoreFactory
, (void**)&punk
);
3986 ok(hr
== E_NOINTERFACE
|| broken(hr
== MK_E_NOOBJECT
/* XP */), "Got 0x%08x\n", hr
);
3987 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
3989 /* BHID_ThumbnailHandler */
3990 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_ThumbnailHandler
, &IID_IUnknown
, (void**)&punk
);
3991 ok(hr
== E_INVALIDARG
|| broken(hr
== MK_E_NOOBJECT
/* XP */), "Got 0x%08x\n", hr
);
3992 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
3994 /* BHID_AssociationArray */
3995 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_AssociationArray
, &IID_IQueryAssociations
, (void**)&punk
);
3996 ok(hr
== S_OK
|| broken(hr
== MK_E_NOOBJECT
/* XP */), "Got 0x%08x\n", hr
);
3997 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
3999 /* BHID_EnumAssocHandlers */
4000 hr
= IShellItem_BindToHandler(psi
, NULL
, &BHID_EnumAssocHandlers
, &IID_IUnknown
, (void**)&punk
);
4001 ok(hr
== E_NOINTERFACE
|| broken(hr
== MK_E_NOOBJECT
/* XP */), "Got 0x%08x\n", hr
);
4002 if(SUCCEEDED(hr
)) IUnknown_Release(punk
);
4005 IShellItem_Release(psi
);
4008 skip("Failed to create ShellItem.\n");
4010 ILFree(pidl_desktop
);
4013 static void test_ShellItemGetAttributes(void)
4015 IShellItem
*psi
, *psi_folder1
, *psi_file1
;
4016 IShellFolder
*pdesktopsf
;
4017 LPITEMIDLIST pidl_desktop
, pidl
;
4020 WCHAR curdirW
[MAX_PATH
];
4021 WCHAR buf
[MAX_PATH
];
4022 static const WCHAR testdir1W
[] = {'t','e','s','t','d','i','r',0};
4023 static const WCHAR testfile1W
[] = {'t','e','s','t','d','i','r','\\','t','e','s','t','1','.','t','x','t',0};
4025 if(!pSHCreateShellItem
)
4027 skip("SHCreateShellItem missing.\n");
4031 hr
= SHGetSpecialFolderLocation(NULL
, CSIDL_DESKTOP
, &pidl_desktop
);
4032 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
4035 hr
= pSHCreateShellItem(NULL
, NULL
, pidl_desktop
, &psi
);
4036 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
4037 ILFree(pidl_desktop
);
4041 skip("Skipping tests.\n");
4047 /* Crashes on native (Win 7) */
4048 IShellItem_GetAttributes(psi
, 0, NULL
);
4051 /* Test GetAttributes on the desktop folder. */
4053 hr
= IShellItem_GetAttributes(psi
, SFGAO_FOLDER
, &sfgao
);
4054 ok(hr
== S_OK
|| broken(hr
== E_FAIL
) /* <Vista */, "Got 0x%08x\n", hr
);
4055 ok(sfgao
== SFGAO_FOLDER
|| broken(sfgao
== 0) /* <Vista */, "Got 0x%08x\n", sfgao
);
4057 IShellItem_Release(psi
);
4059 CreateFilesFolders();
4061 SHGetDesktopFolder(&pdesktopsf
);
4063 GetCurrentDirectoryW(MAX_PATH
, curdirW
);
4064 myPathAddBackslashW(curdirW
);
4066 lstrcpyW(buf
, curdirW
);
4067 lstrcatW(buf
, testdir1W
);
4068 hr
= IShellFolder_ParseDisplayName(pdesktopsf
, NULL
, NULL
, buf
, NULL
, &pidl
, NULL
);
4069 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4070 hr
= pSHCreateShellItem(NULL
, NULL
, pidl
, &psi_folder1
);
4071 ok(hr
== S_OK
, "Got 0x%08x\n", sfgao
);
4074 lstrcpyW(buf
, curdirW
);
4075 lstrcatW(buf
, testfile1W
);
4076 hr
= IShellFolder_ParseDisplayName(pdesktopsf
, NULL
, NULL
, buf
, NULL
, &pidl
, NULL
);
4077 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4078 hr
= pSHCreateShellItem(NULL
, NULL
, pidl
, &psi_file1
);
4079 ok(hr
== S_OK
, "Got 0x%08x\n", sfgao
);
4082 IShellFolder_Release(pdesktopsf
);
4085 hr
= IShellItem_GetAttributes(psi_folder1
, 0, &sfgao
);
4086 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
4087 ok(sfgao
== 0, "Got 0x%08x\n", sfgao
);
4090 hr
= IShellItem_GetAttributes(psi_folder1
, SFGAO_FOLDER
, &sfgao
);
4091 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
4092 ok(sfgao
== SFGAO_FOLDER
, "Got 0x%08x\n", sfgao
);
4095 hr
= IShellItem_GetAttributes(psi_file1
, SFGAO_FOLDER
, &sfgao
);
4096 ok(hr
== S_FALSE
, "Got 0x%08x\n", hr
);
4097 ok(sfgao
== 0, "Got 0x%08x\n", sfgao
);
4099 IShellItem_Release(psi_folder1
);
4100 IShellItem_Release(psi_file1
);
4105 static void test_ShellItemArrayGetAttributes(void)
4107 IShellItemArray
*psia_files
, *psia_folders1
, *psia_folders2
, *psia_all
;
4108 IShellFolder
*pdesktopsf
;
4109 LPCITEMIDLIST pidl_array
[5];
4112 WCHAR curdirW
[MAX_PATH
];
4113 WCHAR buf
[MAX_PATH
];
4115 static const WCHAR testdir1W
[] = {'t','e','s','t','d','i','r',0};
4116 static const WCHAR testdir2W
[] = {'t','e','s','t','d','i','r','\\','t','e','s','t','d','i','r','2',0};
4117 static const WCHAR testdir3W
[] = {'t','e','s','t','d','i','r','\\','t','e','s','t','d','i','r','3',0};
4118 static const WCHAR testfile1W
[] = {'t','e','s','t','d','i','r','\\','t','e','s','t','1','.','t','x','t',0};
4119 static const WCHAR testfile2W
[] = {'t','e','s','t','d','i','r','\\','t','e','s','t','2','.','t','x','t',0};
4120 static const WCHAR
*testfilesW
[5] = { testdir1W
, testdir2W
, testdir3W
, testfile1W
, testfile2W
};
4122 if(!pSHCreateShellItemArrayFromShellItem
)
4124 win_skip("No SHCreateShellItemArrayFromShellItem, skipping test...\n");
4128 CreateFilesFolders();
4129 CreateDirectoryA(".\\testdir\\testdir3", NULL
);
4131 SHGetDesktopFolder(&pdesktopsf
);
4133 GetCurrentDirectoryW(MAX_PATH
, curdirW
);
4134 myPathAddBackslashW(curdirW
);
4136 for(i
= 0; i
< 5; i
++)
4138 lstrcpyW(buf
, curdirW
);
4139 lstrcatW(buf
, testfilesW
[i
]);
4140 hr
= IShellFolder_ParseDisplayName(pdesktopsf
, NULL
, NULL
, buf
, NULL
, (LPITEMIDLIST
*)&pidl_array
[i
], NULL
);
4141 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4143 IShellFolder_Release(pdesktopsf
);
4145 hr
= pSHCreateShellItemArrayFromIDLists(2, pidl_array
, &psia_folders1
);
4146 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4147 hr
= pSHCreateShellItemArrayFromIDLists(2, &pidl_array
[1], &psia_folders2
);
4148 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4149 hr
= pSHCreateShellItemArrayFromIDLists(2, &pidl_array
[3], &psia_files
);
4150 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4151 hr
= pSHCreateShellItemArrayFromIDLists(4, &pidl_array
[1], &psia_all
); /* All except the first */
4152 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
4154 for(i
= 0; i
< 5; i
++)
4155 ILFree((LPITEMIDLIST
)pidl_array
[i
]);
4157 /* [testfolder/, testfolder/testfolder2] seems to break in Vista */
4159 hr
= IShellItemArray_GetAttributes(psia_folders1
, SIATTRIBFLAGS_AND
, SFGAO_FOLDER
, &attr
);
4160 ok(hr
== S_OK
|| broken(hr
== E_UNEXPECTED
) /* Vista */, "Got 0x%08x\n", hr
);
4161 ok(attr
== SFGAO_FOLDER
|| broken(attr
== 0) /* Vista */, "Got 0x%08x\n", attr
);
4163 hr
= IShellItemArray_GetAttributes(psia_folders1
, SIATTRIBFLAGS_OR
, SFGAO_FOLDER
, &attr
);
4164 ok(hr
== S_OK
|| broken(hr
== E_UNEXPECTED
) /* Vista */, "Got 0x%08x\n", hr
);
4165 ok(attr
== SFGAO_FOLDER
|| broken(attr
== 0) /* Vista */, "Got 0x%08x\n", attr
);
4167 /* [testfolder/testfolder2, testfolder/testfolder3] works */
4169 hr
= IShellItemArray_GetAttributes(psia_folders2
, SIATTRIBFLAGS_AND
, SFGAO_FOLDER
, &attr
);
4170 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
4171 ok(attr
== SFGAO_FOLDER
, "Got 0x%08x\n", attr
);
4173 hr
= IShellItemArray_GetAttributes(psia_files
, SIATTRIBFLAGS_AND
, SFGAO_FOLDER
, &attr
);
4174 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* Vista */, "Got 0x%08x\n", hr
);
4175 ok(attr
== 0, "Got 0x%08x\n", attr
);
4177 hr
= IShellItemArray_GetAttributes(psia_all
, SIATTRIBFLAGS_AND
, SFGAO_FOLDER
, &attr
);
4178 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* Vista */, "Got 0x%08x\n", hr
);
4179 ok(attr
== 0, "Got 0x%08x\n", attr
);
4181 hr
= IShellItemArray_GetAttributes(psia_folders2
, SIATTRIBFLAGS_OR
, SFGAO_FOLDER
, &attr
);
4182 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
4183 ok(attr
== SFGAO_FOLDER
, "Got 0x%08x\n", attr
);
4185 hr
= IShellItemArray_GetAttributes(psia_files
, SIATTRIBFLAGS_OR
, SFGAO_FOLDER
, &attr
);
4186 ok(hr
== S_FALSE
|| broken(hr
== S_OK
) /* Vista */, "Got 0x%08x\n", hr
);
4187 ok(attr
== 0, "Got 0x%08x\n", attr
);
4189 hr
= IShellItemArray_GetAttributes(psia_all
, SIATTRIBFLAGS_OR
, SFGAO_FOLDER
, &attr
);
4190 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
4191 ok(attr
== SFGAO_FOLDER
, "Got 0x%08x\n", attr
);
4193 IShellItemArray_Release(psia_folders1
);
4194 IShellItemArray_Release(psia_folders2
);
4195 IShellItemArray_Release(psia_files
);
4196 IShellItemArray_Release(psia_all
);
4198 RemoveDirectoryA(".\\testdir\\testdir3");
4202 static void test_SHParseDisplayName(void)
4204 LPITEMIDLIST pidl1
, pidl2
;
4205 IShellFolder
*desktop
;
4206 WCHAR dirW
[MAX_PATH
];
4213 /* crashes on native */
4214 SHParseDisplayName(NULL
, NULL
, NULL
, 0, NULL
);
4216 SHParseDisplayName(nameW
, NULL
, NULL
, 0, NULL
);
4219 pidl1
= (LPITEMIDLIST
)0xdeadbeef;
4220 hr
= SHParseDisplayName(NULL
, NULL
, &pidl1
, 0, NULL
);
4221 ok(broken(hr
== E_OUTOFMEMORY
) /* < Vista */ ||
4222 hr
== E_INVALIDARG
, "failed %08x\n", hr
);
4223 ok(pidl1
== 0, "expected null ptr, got %p\n", pidl1
);
4227 hr
= SHParseDisplayName(nameW
, NULL
, &pidl1
, 0, NULL
);
4228 ok(hr
== S_OK
, "failed %08x\n", hr
);
4229 hr
= SHGetDesktopFolder(&desktop
);
4230 ok(hr
== S_OK
, "failed %08x\n", hr
);
4231 hr
= IShellFolder_ParseDisplayName(desktop
, NULL
, NULL
, nameW
, NULL
, &pidl2
, NULL
);
4232 ok(hr
== S_OK
, "failed %08x\n", hr
);
4233 ret
= ILIsEqual(pidl1
, pidl2
);
4234 ok(ret
== TRUE
, "expected equal idls\n");
4239 GetWindowsDirectoryW( dirW
, MAX_PATH
);
4241 hr
= SHParseDisplayName(dirW
, NULL
, &pidl1
, 0, NULL
);
4242 ok(hr
== S_OK
, "failed %08x\n", hr
);
4243 hr
= IShellFolder_ParseDisplayName(desktop
, NULL
, NULL
, dirW
, NULL
, &pidl2
, NULL
);
4244 ok(hr
== S_OK
, "failed %08x\n", hr
);
4246 ret
= ILIsEqual(pidl1
, pidl2
);
4247 ok(ret
== TRUE
, "expected equal idls\n");
4251 /* system32 is not redirected to syswow64 on WOW64 */
4252 if (!pIsWow64Process
|| !pIsWow64Process( GetCurrentProcess(), &is_wow64
)) is_wow64
= FALSE
;
4257 len
= GetSystemDirectoryW(dirW
, MAX_PATH
);
4258 ok(len
> 0, "GetSystemDirectoryW failed: %u\n", GetLastError());
4259 hr
= SHParseDisplayName(dirW
, NULL
, &pidl1
, 0, NULL
);
4260 ok(hr
== S_OK
, "failed %08x\n", hr
);
4262 len
= GetSystemWow64DirectoryW(dirW
, MAX_PATH
);
4263 ok(len
> 0, "GetSystemWow64DirectoryW failed: %u\n", GetLastError());
4264 hr
= SHParseDisplayName(dirW
, NULL
, &pidl2
, 0, NULL
);
4265 ok(hr
== S_OK
, "failed %08x\n", hr
);
4266 ret
= ILIsEqual(pidl1
, pidl2
);
4267 ok(ret
== FALSE
, "expected different idls\n");
4272 IShellFolder_Release(desktop
);
4275 static void test_desktop_IPersist(void)
4277 IShellFolder
*desktop
;
4279 IPersistFolder2
*ppf2
;
4283 hr
= SHGetDesktopFolder(&desktop
);
4284 ok(hr
== S_OK
, "failed %08x\n", hr
);
4286 hr
= IShellFolder_QueryInterface(desktop
, &IID_IPersist
, (void**)&persist
);
4287 ok(hr
== S_OK
, "failed %08x\n", hr
);
4293 /* crashes on native */
4294 IPersist_GetClassID(persist
, NULL
);
4296 memset(&clsid
, 0, sizeof(clsid
));
4297 hr
= IPersist_GetClassID(persist
, &clsid
);
4298 ok(hr
== S_OK
, "failed %08x\n", hr
);
4299 ok(IsEqualIID(&CLSID_ShellDesktop
, &clsid
), "Expected CLSID_ShellDesktop\n");
4300 IPersist_Release(persist
);
4303 hr
= IShellFolder_QueryInterface(desktop
, &IID_IPersistFolder2
, (void**)&ppf2
);
4304 ok(hr
== S_OK
|| broken(hr
== E_NOINTERFACE
) /* pre-Vista */, "failed %08x\n", hr
);
4307 IPersistFolder
*ppf
;
4309 hr
= IShellFolder_QueryInterface(desktop
, &IID_IPersistFolder
, (void**)&ppf
);
4310 ok(hr
== S_OK
, "IID_IPersistFolder2 without IID_IPersistFolder.\n");
4312 IPersistFolder_Release(ppf
);
4315 hr
= IPersistFolder2_Initialize(ppf2
, NULL
);
4316 ok(hr
== S_OK
, "got %08x\n", hr
);
4320 hr
= IPersistFolder2_GetCurFolder(ppf2
, &pidl
);
4321 ok(hr
== S_OK
, "got %08x\n", hr
);
4322 ok(pidl
!= NULL
, "pidl was NULL.\n");
4323 if(SUCCEEDED(hr
)) ILFree(pidl
);
4325 IPersistFolder2_Release(ppf2
);
4328 IShellFolder_Release(desktop
);
4331 static void test_contextmenu_qi(IContextMenu
*menu
, BOOL todo
)
4336 hr
= IContextMenu_QueryInterface(menu
, &IID_IShellExtInit
, (void **)&unk
);
4338 ok(hr
== S_OK
, "Failed to get IShellExtInit, hr %#x.\n", hr
);
4340 IUnknown_Release(unk
);
4342 hr
= IContextMenu_QueryInterface(menu
, &IID_IObjectWithSite
, (void **)&unk
);
4344 ok(hr
== S_OK
, "Failed to get IShellExtInit, hr %#x.\n", hr
);
4346 IUnknown_Release(unk
);
4349 static void test_contextmenu(IContextMenu
*menu
, BOOL background
)
4351 HMENU hmenu
= CreatePopupMenu();
4352 UINT count
, i
, max_id
;
4355 test_contextmenu_qi(menu
, FALSE
);
4357 hr
= IContextMenu_QueryContextMenu(menu
, hmenu
, 0, 64, 32767, CMF_NORMAL
);
4358 ok(SUCCEEDED(hr
), "Failed to query the menu, hr %#x.\n", hr
);
4360 max_id
= HRESULT_CODE(hr
) - 1; /* returns max_id + 1 */
4361 ok(max_id
<= 32767, "Got %d\n", max_id
);
4362 count
= GetMenuItemCount(hmenu
);
4363 ok(count
, "Got %d\n", count
);
4365 for (i
= 0; i
< count
; i
++)
4369 char buf
[255], buf2
[255];
4370 ZeroMemory(&mii
, sizeof(MENUITEMINFOA
));
4371 mii
.cbSize
= sizeof(MENUITEMINFOA
);
4372 mii
.fMask
= MIIM_ID
| MIIM_FTYPE
| MIIM_STRING
;
4373 mii
.dwTypeData
= buf2
;
4374 mii
.cch
= sizeof(buf2
);
4376 res
= GetMenuItemInfoA(hmenu
, i
, TRUE
, &mii
);
4377 ok(res
, "Failed to get menu item info, error %d.\n", GetLastError());
4379 if (!(mii
.fType
& MFT_SEPARATOR
))
4381 ok(mii
.wID
>= 64 && mii
.wID
<= 64 + max_id
,
4382 "Expected between 64 and %d, got %d.\n", 64 + max_id
, mii
.wID
);
4383 hr
= IContextMenu_GetCommandString(menu
, mii
.wID
- 64, GCS_VERBA
, 0, buf
, sizeof(buf
));
4384 todo_wine_if(background
)
4385 ok(hr
== S_OK
|| hr
== E_NOTIMPL
|| hr
== E_INVALIDARG
,
4386 "Got unexpected hr %#x for ID %d, string %s.\n", hr
, mii
.wID
, debugstr_a(mii
.dwTypeData
));
4388 trace("Got ID %d, verb %s, string %s.\n", mii
.wID
, debugstr_a(buf
), debugstr_a(mii
.dwTypeData
));
4390 trace("Got ID %d, hr %#x, string %s.\n", mii
.wID
, hr
, debugstr_a(mii
.dwTypeData
));
4396 CMINVOKECOMMANDINFO cmi
;
4398 memset(&cmi
, 0, sizeof(CMINVOKECOMMANDINFO
));
4399 cmi
.cbSize
= sizeof(CMINVOKECOMMANDINFO
);
4401 /* Attempt to execute a nonexistent command */
4402 cmi
.lpVerb
= MAKEINTRESOURCEA(9999);
4403 hr
= IContextMenu_InvokeCommand(menu
, &cmi
);
4404 todo_wine_if(background
)
4405 ok(hr
== E_INVALIDARG
, "Got 0x%08x\n", hr
);
4407 cmi
.lpVerb
= "foobar_wine_test";
4408 hr
= IContextMenu_InvokeCommand(menu
, &cmi
);
4409 todo_wine_if(background
)
4410 ok((hr
== E_INVALIDARG
) || (hr
== E_FAIL
/* Win7 */) ||
4411 (hr
== HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION
) /* Vista */),
4412 "Unexpected hr %#x.\n", hr
);
4418 static void test_GetUIObject(void)
4420 IShellFolder
*psf_desktop
;
4424 WCHAR path
[MAX_PATH
];
4425 const WCHAR filename
[] =
4426 {'\\','t','e','s','t','d','i','r','\\','t','e','s','t','1','.','t','x','t',0};
4427 LPCITEMIDLIST pidl_child
;
4430 GetCurrentDirectoryW(MAX_PATH
, path
);
4433 skip("GetCurrentDirectoryW returned an empty string.\n");
4436 lstrcatW(path
, filename
);
4437 SHGetDesktopFolder(&psf_desktop
);
4439 CreateFilesFolders();
4441 hr
= IShellFolder_ParseDisplayName(psf_desktop
, NULL
, NULL
, path
, NULL
, &pidl
, 0);
4442 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
4444 hr
= SHBindToParent(pidl
, &IID_IShellFolder
, (void **)&psf
, &pidl_child
);
4445 ok(hr
== S_OK
, "Failed to bind to folder, hr %#x.\n", hr
);
4448 hr
= IShellFolder_GetUIObjectOf(psf
, NULL
, 1, &pidl_child
, &IID_IContextMenu
, NULL
, (void **)&pcm
);
4449 ok(hr
== S_OK
, "GetUIObjectOf() failed, hr %#x.\n", hr
);
4450 test_contextmenu(pcm
, FALSE
);
4451 IContextMenu_Release(pcm
);
4453 /* Background menu */
4454 hr
= IShellFolder_GetUIObjectOf(psf_desktop
, NULL
, 0, NULL
, &IID_IContextMenu
, NULL
, (void **)&pcm
);
4455 ok(hr
== S_OK
, "GetUIObjectOf() failed, hr %#x.\n", hr
);
4456 test_contextmenu(pcm
, TRUE
);
4457 IContextMenu_Release(pcm
);
4459 IShellFolder_Release(psf
);
4462 IShellFolder_Release(psf_desktop
);
4466 #define verify_pidl(i,p) r_verify_pidl(__LINE__, i, p)
4467 static void r_verify_pidl(unsigned l
, LPCITEMIDLIST pidl
, const WCHAR
*path
)
4469 LPCITEMIDLIST child
;
4470 IShellFolder
*parent
;
4476 ok_(__FILE__
,l
)(0, "didn't get expected path (%s), instead: NULL\n", wine_dbgstr_w(path
));
4480 hr
= SHBindToParent(pidl
, &IID_IShellFolder
, (void **)&parent
, &child
);
4481 ok_(__FILE__
,l
)(hr
== S_OK
, "SHBindToParent failed: 0x%08x\n", hr
);
4485 hr
= IShellFolder_GetDisplayNameOf(parent
, child
, SHGDN_FORPARSING
, &filename
);
4486 ok_(__FILE__
,l
)(hr
== S_OK
, "GetDisplayNameOf failed: 0x%08x\n", hr
);
4488 IShellFolder_Release(parent
);
4492 ok_(__FILE__
,l
)(filename
.uType
== STRRET_WSTR
|| filename
.uType
== STRRET_CSTR
,
4493 "Got unexpected string type: %d\n", filename
.uType
);
4494 if(filename
.uType
== STRRET_WSTR
){
4495 ok_(__FILE__
,l
)(lstrcmpW(path
, U(filename
).pOleStr
) == 0,
4496 "didn't get expected path (%s), instead: %s\n",
4497 wine_dbgstr_w(path
), wine_dbgstr_w(U(filename
).pOleStr
));
4498 SHFree(U(filename
).pOleStr
);
4500 else if(filename
.uType
== STRRET_CSTR
)
4502 WCHAR
*strW
= make_wstr(U(filename
).cStr
);
4503 ok_(__FILE__
,l
)(!lstrcmpW(path
, strW
), "didn't get expected path (%s), instead: %s\n",
4504 wine_dbgstr_w(path
), U(filename
).cStr
);
4508 IShellFolder_Release(parent
);
4510 ok_(__FILE__
,l
)(pidl
== NULL
, "Expected PIDL to be NULL\n");
4513 static void test_SHSimpleIDListFromPath(void)
4515 const WCHAR adirW
[] = {'C',':','\\','s','i','d','l','f','p','d','i','r',0};
4516 const CHAR adirA
[] = "C:\\sidlfpdir";
4517 BOOL br
, is_unicode
= !(GetVersion() & 0x80000000);
4519 LPITEMIDLIST pidl
= NULL
;
4521 br
= CreateDirectoryA(adirA
, NULL
);
4522 ok(br
== TRUE
, "CreateDirectory failed: %d\n", GetLastError());
4525 pidl
= SHSimpleIDListFromPath(adirW
);
4527 pidl
= SHSimpleIDListFromPath((const WCHAR
*)adirA
);
4528 verify_pidl(pidl
, adirW
);
4531 br
= RemoveDirectoryA(adirA
);
4532 ok(br
== TRUE
, "RemoveDirectory failed: %d\n", GetLastError());
4535 pidl
= SHSimpleIDListFromPath(adirW
);
4537 pidl
= SHSimpleIDListFromPath((const WCHAR
*)adirA
);
4538 verify_pidl(pidl
, adirW
);
4542 /* IFileSystemBindData impl */
4543 static HRESULT WINAPI
fsbd_QueryInterface(IFileSystemBindData
*fsbd
,
4544 REFIID riid
, void **ppv
)
4546 if(IsEqualIID(riid
, &IID_IFileSystemBindData
) ||
4547 IsEqualIID(riid
, &IID_IUnknown
)){
4551 return E_NOINTERFACE
;
4554 static ULONG WINAPI
fsbd_AddRef(IFileSystemBindData
*fsbd
)
4559 static ULONG WINAPI
fsbd_Release(IFileSystemBindData
*fsbd
)
4564 static HRESULT WINAPI
fsbd_SetFindData(IFileSystemBindData
*fsbd
,
4565 const WIN32_FIND_DATAW
*pfd
)
4567 ok(0, "SetFindData called\n");
4571 static HRESULT WINAPI
fsbd_GetFindData_nul(IFileSystemBindData
*fsbd
,
4572 WIN32_FIND_DATAW
*pfd
)
4574 memset(pfd
, 0, sizeof(WIN32_FIND_DATAW
));
4578 static HRESULT WINAPI
fsbd_GetFindData_junk(IFileSystemBindData
*fsbd
,
4579 WIN32_FIND_DATAW
*pfd
)
4581 memset(pfd
, 0xef, sizeof(WIN32_FIND_DATAW
));
4585 static HRESULT WINAPI
fsbd_GetFindData_invalid(IFileSystemBindData
*fsbd
,
4586 WIN32_FIND_DATAW
*pfd
)
4588 memset(pfd
, 0, sizeof(WIN32_FIND_DATAW
));
4589 *pfd
->cFileName
= 'a';
4590 *pfd
->cAlternateFileName
= 'a';
4594 static HRESULT WINAPI
fsbd_GetFindData_valid(IFileSystemBindData
*fsbd
,
4595 WIN32_FIND_DATAW
*pfd
)
4597 static const WCHAR adirW
[] = {'C',':','\\','f','s','b','d','d','i','r',0};
4598 HANDLE handle
= FindFirstFileW(adirW
, pfd
);
4603 static HRESULT WINAPI
fsbd_GetFindData_fail(IFileSystemBindData
*fsbd
,
4604 WIN32_FIND_DATAW
*pfd
)
4609 static IFileSystemBindDataVtbl fsbdVtbl
= {
4610 fsbd_QueryInterface
,
4617 static IFileSystemBindData fsbd
= { &fsbdVtbl
};
4619 static void test_ParseDisplayNamePBC(void)
4621 WCHAR wFileSystemBindData
[] =
4622 {'F','i','l','e',' ','S','y','s','t','e','m',' ','B','i','n','d',' ','D','a','t','a',0};
4623 WCHAR adirW
[] = {'C',':','\\','f','s','b','d','d','i','r',0};
4624 WCHAR afileW
[] = {'C',':','\\','f','s','b','d','d','i','r','\\','f','i','l','e','.','t','x','t',0};
4625 WCHAR afile2W
[] = {'C',':','\\','f','s','b','d','d','i','r','\\','s','\\','f','i','l','e','.','t','x','t',0};
4626 const HRESULT exp_err
= HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND
);
4633 /* Check if we support WCHAR functions */
4634 SetLastError(0xdeadbeef);
4635 lstrcmpiW(adirW
, adirW
);
4636 if(GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
){
4637 win_skip("Most W-calls are not implemented\n");
4641 hres
= SHGetDesktopFolder(&psf
);
4642 ok(hres
== S_OK
, "SHGetDesktopFolder failed: 0x%08x\n", hres
);
4644 win_skip("Failed to get IShellFolder, can't run tests\n");
4648 /* fails on unknown dir with no IBindCtx */
4649 hres
= IShellFolder_ParseDisplayName(psf
, NULL
, NULL
, adirW
, NULL
, &pidl
, NULL
);
4650 ok(hres
== exp_err
, "ParseDisplayName failed with wrong error: 0x%08x\n", hres
);
4651 hres
= IShellFolder_ParseDisplayName(psf
, NULL
, NULL
, afileW
, NULL
, &pidl
, NULL
);
4652 ok(hres
== exp_err
, "ParseDisplayName failed with wrong error: 0x%08x\n", hres
);
4653 hres
= IShellFolder_ParseDisplayName(psf
, NULL
, NULL
, afile2W
, NULL
, &pidl
, NULL
);
4654 ok(hres
== exp_err
, "ParseDisplayName failed with wrong error: 0x%08x\n", hres
);
4656 /* fails on unknown dir with IBindCtx with no IFileSystemBindData */
4657 hres
= CreateBindCtx(0, &pbc
);
4658 ok(hres
== S_OK
, "CreateBindCtx failed: 0x%08x\n", hres
);
4660 hres
= IShellFolder_ParseDisplayName(psf
, NULL
, pbc
, adirW
, NULL
, &pidl
, NULL
);
4661 ok(hres
== exp_err
, "ParseDisplayName failed with wrong error: 0x%08x\n", hres
);
4662 hres
= IShellFolder_ParseDisplayName(psf
, NULL
, pbc
, afileW
, NULL
, &pidl
, NULL
);
4663 ok(hres
== exp_err
, "ParseDisplayName failed with wrong error: 0x%08x\n", hres
);
4664 hres
= IShellFolder_ParseDisplayName(psf
, NULL
, pbc
, afile2W
, NULL
, &pidl
, NULL
);
4665 ok(hres
== exp_err
, "ParseDisplayName failed with wrong error: 0x%08x\n", hres
);
4667 /* unknown dir with IBindCtx with IFileSystemBindData */
4668 hres
= IBindCtx_RegisterObjectParam(pbc
, wFileSystemBindData
, (IUnknown
*)&fsbd
);
4669 ok(hres
== S_OK
, "RegisterObjectParam failed: 0x%08x\n", hres
);
4671 /* return E_FAIL from GetFindData */
4672 pidl
= (ITEMIDLIST
*)0xdeadbeef;
4673 fsbdVtbl
.GetFindData
= fsbd_GetFindData_fail
;
4674 hres
= IShellFolder_ParseDisplayName(psf
, NULL
, pbc
, adirW
, NULL
, &pidl
, NULL
);
4675 ok(hres
== S_OK
, "ParseDisplayName failed: 0x%08x\n", hres
);
4676 if(SUCCEEDED(hres
)){
4677 verify_pidl(pidl
, adirW
);
4681 hres
= IShellFolder_ParseDisplayName(psf
, NULL
, pbc
, afileW
, NULL
, &pidl
, NULL
);
4682 ok(hres
== S_OK
, "ParseDisplayName failed: 0x%08x\n", hres
);
4683 if(SUCCEEDED(hres
)){
4684 verify_pidl(pidl
, afileW
);
4688 hres
= IShellFolder_ParseDisplayName(psf
, NULL
, pbc
, afile2W
, NULL
, &pidl
, NULL
);
4689 ok(hres
== S_OK
, "ParseDisplayName failed: 0x%08x\n", hres
);
4690 if(SUCCEEDED(hres
)){
4691 verify_pidl(pidl
, afile2W
);
4695 /* set FIND_DATA struct to NULLs */
4696 pidl
= (ITEMIDLIST
*)0xdeadbeef;
4697 fsbdVtbl
.GetFindData
= fsbd_GetFindData_nul
;
4698 hres
= IShellFolder_ParseDisplayName(psf
, NULL
, pbc
, adirW
, NULL
, &pidl
, NULL
);
4699 ok(hres
== S_OK
, "ParseDisplayName failed: 0x%08x\n", hres
);
4700 if(SUCCEEDED(hres
)){
4701 verify_pidl(pidl
, adirW
);
4705 hres
= IShellFolder_ParseDisplayName(psf
, NULL
, pbc
, afileW
, NULL
, &pidl
, NULL
);
4706 ok(hres
== S_OK
, "ParseDisplayName failed: 0x%08x\n", hres
);
4707 if(SUCCEEDED(hres
)){
4708 verify_pidl(pidl
, afileW
);
4712 hres
= IShellFolder_ParseDisplayName(psf
, NULL
, pbc
, afile2W
, NULL
, &pidl
, NULL
);
4713 ok(hres
== S_OK
, "ParseDisplayName failed: 0x%08x\n", hres
);
4714 if(SUCCEEDED(hres
)){
4715 verify_pidl(pidl
, afile2W
);
4719 /* set FIND_DATA struct to junk */
4720 pidl
= (ITEMIDLIST
*)0xdeadbeef;
4721 fsbdVtbl
.GetFindData
= fsbd_GetFindData_junk
;
4722 hres
= IShellFolder_ParseDisplayName(psf
, NULL
, pbc
, adirW
, NULL
, &pidl
, NULL
);
4723 ok(hres
== S_OK
, "ParseDisplayName failed: 0x%08x\n", hres
);
4724 if(SUCCEEDED(hres
)){
4725 verify_pidl(pidl
, adirW
);
4729 hres
= IShellFolder_ParseDisplayName(psf
, NULL
, pbc
, afileW
, NULL
, &pidl
, NULL
);
4730 ok(hres
== S_OK
, "ParseDisplayName failed: 0x%08x\n", hres
);
4731 if(SUCCEEDED(hres
)){
4732 verify_pidl(pidl
, afileW
);
4736 hres
= IShellFolder_ParseDisplayName(psf
, NULL
, pbc
, afile2W
, NULL
, &pidl
, NULL
);
4737 ok(hres
== S_OK
, "ParseDisplayName failed: 0x%08x\n", hres
);
4738 if(SUCCEEDED(hres
)){
4739 verify_pidl(pidl
, afile2W
);
4743 /* set FIND_DATA struct to invalid data */
4744 pidl
= (ITEMIDLIST
*)0xdeadbeef;
4745 fsbdVtbl
.GetFindData
= fsbd_GetFindData_invalid
;
4746 hres
= IShellFolder_ParseDisplayName(psf
, NULL
, pbc
, adirW
, NULL
, &pidl
, NULL
);
4747 ok(hres
== S_OK
, "ParseDisplayName failed: 0x%08x\n", hres
);
4748 if(SUCCEEDED(hres
)){
4749 verify_pidl(pidl
, adirW
);
4753 hres
= IShellFolder_ParseDisplayName(psf
, NULL
, pbc
, afileW
, NULL
, &pidl
, NULL
);
4754 ok(hres
== S_OK
, "ParseDisplayName failed: 0x%08x\n", hres
);
4755 if(SUCCEEDED(hres
)){
4756 verify_pidl(pidl
, afileW
);
4760 hres
= IShellFolder_ParseDisplayName(psf
, NULL
, pbc
, afile2W
, NULL
, &pidl
, NULL
);
4761 ok(hres
== S_OK
, "ParseDisplayName failed: 0x%08x\n", hres
);
4762 if(SUCCEEDED(hres
)){
4763 verify_pidl(pidl
, afile2W
);
4767 /* set FIND_DATA struct to valid data */
4768 pidl
= (ITEMIDLIST
*)0xdeadbeef;
4769 fsbdVtbl
.GetFindData
= fsbd_GetFindData_valid
;
4770 hres
= IShellFolder_ParseDisplayName(psf
, NULL
, pbc
, adirW
, NULL
, &pidl
, NULL
);
4771 ok(hres
== S_OK
, "ParseDisplayName failed: 0x%08x\n", hres
);
4772 if(SUCCEEDED(hres
)){
4773 verify_pidl(pidl
, adirW
);
4777 hres
= IShellFolder_ParseDisplayName(psf
, NULL
, pbc
, afileW
, NULL
, &pidl
, NULL
);
4778 ok(hres
== S_OK
, "ParseDisplayName failed: 0x%08x\n", hres
);
4779 if(SUCCEEDED(hres
)){
4780 verify_pidl(pidl
, afileW
);
4784 hres
= IShellFolder_ParseDisplayName(psf
, NULL
, pbc
, afile2W
, NULL
, &pidl
, NULL
);
4785 ok(hres
== S_OK
, "ParseDisplayName failed: 0x%08x\n", hres
);
4786 if(SUCCEEDED(hres
)){
4787 verify_pidl(pidl
, afile2W
);
4791 IBindCtx_Release(pbc
);
4792 IShellFolder_Release(psf
);
4795 static const CHAR testwindow_class
[] = "testwindow";
4796 #define WM_USER_NOTIFY (WM_APP+1)
4798 struct ChNotifyTest
{
4800 const UINT notify_count
;
4801 UINT missing_events
;
4803 const char path_1
[256];
4804 const char path_2
[256];
4805 } chnotify_tests
[] = {
4806 {"MKDIR", 1, 0, SHCNE_MKDIR
, "C:\\shell32_cn_test\\test", ""},
4807 {"CREATE", 1, 0, SHCNE_CREATE
, "C:\\shell32_cn_test\\test\\file.txt", ""},
4808 {"RMDIR", 1, 0, SHCNE_RMDIR
, "C:\\shell32_cn_test\\test", ""},
4811 struct ChNotifyTest
*exp_data
;
4812 BOOL test_new_delivery_flag
;
4814 static LRESULT CALLBACK
testwindow_wndproc(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
4816 LONG signal
= (LONG
)lparam
;
4819 case WM_USER_NOTIFY
:
4820 if(exp_data
->missing_events
> 0) {
4821 WCHAR
*path1
, *path2
;
4822 LPITEMIDLIST
*pidls
= (LPITEMIDLIST
*)wparam
;
4823 HANDLE hLock
= NULL
;
4825 if(test_new_delivery_flag
) {
4826 hLock
= SHChangeNotification_Lock((HANDLE
)wparam
, lparam
, &pidls
, &signal
);
4827 ok(hLock
!= NULL
, "SHChangeNotification_Lock returned NULL\n");
4830 ok(exp_data
->signal
== signal
,
4831 "%s: expected notification type %x, got: %x\n",
4832 exp_data
->id
, exp_data
->signal
, signal
);
4834 trace("verifying pidls for: %s\n", exp_data
->id
);
4835 path1
= make_wstr(exp_data
->path_1
);
4836 path2
= make_wstr(exp_data
->path_2
);
4837 verify_pidl(pidls
[0], path1
);
4838 verify_pidl(pidls
[1], path2
);
4842 exp_data
->missing_events
--;
4844 if(test_new_delivery_flag
)
4845 SHChangeNotification_Unlock(hLock
);
4847 ok(0, "Didn't expect a WM_USER_NOTIFY message (event: %x)\n", signal
);
4850 return DefWindowProcA(hwnd
, msg
, wparam
, lparam
);
4853 static void register_testwindow_class(void)
4858 ZeroMemory(&cls
, sizeof(cls
));
4859 cls
.cbSize
= sizeof(cls
);
4861 cls
.lpfnWndProc
= testwindow_wndproc
;
4862 cls
.hInstance
= GetModuleHandleA(NULL
);
4863 cls
.lpszClassName
= testwindow_class
;
4866 ret
= RegisterClassExA(&cls
);
4867 ok(ret
!= 0, "RegisterClassExA failed: %d\n", GetLastError());
4870 /* SHCNF_FLUSH doesn't seem to work as advertised for SHCNF_PATHA, so we
4871 * have to poll repeatedly for the message to appear */
4872 static void do_events(void)
4875 while (exp_data
->missing_events
&& (c
++ < 10)){
4877 while(PeekMessageA(&msg
, NULL
, 0, 0, PM_REMOVE
)){
4878 TranslateMessage(&msg
);
4879 DispatchMessageA(&msg
);
4881 if(exp_data
->missing_events
)
4884 trace("%s: took %d tries\n", exp_data
->id
, c
);
4887 static void test_SHChangeNotify(BOOL test_new_delivery
)
4892 BOOL br
, has_unicode
;
4893 SHChangeNotifyEntry entries
[1];
4894 const CHAR root_dirA
[] = "C:\\shell32_cn_test";
4895 const WCHAR root_dirW
[] = {'C',':','\\','s','h','e','l','l','3','2','_','c','n','_','t','e','s','t',0};
4897 trace("SHChangeNotify tests (%x)\n", test_new_delivery
);
4899 CreateDirectoryW(NULL
, NULL
);
4900 has_unicode
= !(GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
);
4902 test_new_delivery_flag
= test_new_delivery
;
4903 if(!test_new_delivery
)
4904 register_testwindow_class();
4906 wnd
= CreateWindowExA(0, testwindow_class
, testwindow_class
, 0,
4907 CW_USEDEFAULT
, CW_USEDEFAULT
, 130, 105,
4908 NULL
, NULL
, GetModuleHandleA(NULL
), 0);
4909 ok(wnd
!= NULL
, "Failed to make a window\n");
4911 br
= CreateDirectoryA(root_dirA
, NULL
);
4912 ok(br
== TRUE
, "CreateDirectory failed: %d\n", GetLastError());
4914 entries
[0].pidl
= NULL
;
4916 hr
= SHILCreateFromPath(root_dirW
, (LPITEMIDLIST
*)&entries
[0].pidl
, 0);
4918 hr
= SHILCreateFromPath((const void *)root_dirA
, (LPITEMIDLIST
*)&entries
[0].pidl
, 0);
4919 ok(hr
== S_OK
, "SHILCreateFromPath failed: 0x%08x\n", hr
);
4920 entries
[0].fRecursive
= TRUE
;
4922 notifyID
= SHChangeNotifyRegister(wnd
, !test_new_delivery
? SHCNRF_ShellLevel
: SHCNRF_ShellLevel
|SHCNRF_NewDelivery
,
4923 SHCNE_ALLEVENTS
, WM_USER_NOTIFY
, 1, entries
);
4924 ok(notifyID
!= 0, "Failed to register a window for change notifications\n");
4926 for (i
= 0; i
< ARRAY_SIZE(chnotify_tests
); ++i
)
4928 exp_data
= chnotify_tests
+ i
;
4930 exp_data
->missing_events
= exp_data
->notify_count
;
4931 SHChangeNotify(exp_data
->signal
, SHCNF_PATHA
| SHCNF_FLUSH
,
4932 exp_data
->path_1
[0] ? exp_data
->path_1
: NULL
,
4933 exp_data
->path_2
[0] ? exp_data
->path_2
: NULL
);
4935 ok(exp_data
->missing_events
== 0, "%s: Expected wndproc to be called\n", exp_data
->id
);
4938 WCHAR
*path1
, *path2
;
4940 path1
= make_wstr(exp_data
->path_1
);
4941 path2
= make_wstr(exp_data
->path_2
);
4943 exp_data
->missing_events
= exp_data
->notify_count
;
4944 SHChangeNotify(exp_data
->signal
, SHCNF_PATHW
| SHCNF_FLUSH
, path1
, path2
);
4946 ok(exp_data
->missing_events
== 0, "%s: Expected wndproc to be called\n", exp_data
->id
);
4953 SHChangeNotifyDeregister(notifyID
);
4956 ILFree((LPITEMIDLIST
)entries
[0].pidl
);
4957 br
= RemoveDirectoryA(root_dirA
);
4958 ok(br
== TRUE
, "RemoveDirectory failed: %d\n", GetLastError());
4961 static void test_SHCreateDefaultContextMenu(void)
4964 WCHAR path
[MAX_PATH
];
4965 IShellFolder
*desktop
,*folder
;
4966 IPersistFolder2
*persist
;
4967 IContextMenu
*cmenu
;
4969 LPITEMIDLIST pidlFolder
, pidl_child
, pidl
;
4970 DEFCONTEXTMENU cminfo
;
4973 const WCHAR filename
[] =
4974 {'\\','t','e','s','t','d','i','r','\\','t','e','s','t','1','.','t','x','t',0};
4975 if(!pSHCreateDefaultContextMenu
)
4977 win_skip("SHCreateDefaultContextMenu missing.\n");
4981 GetCurrentDirectoryW(MAX_PATH
, path
);
4984 skip("GetCurrentDirectoryW returned an empty string.\n");
4987 lstrcatW(path
, filename
);
4988 SHGetDesktopFolder(&desktop
);
4990 CreateFilesFolders();
4992 hr
= IShellFolder_ParseDisplayName(desktop
, NULL
, NULL
, path
, NULL
, &pidl
, 0);
4993 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
4996 hr
= SHBindToParent(pidl
, &IID_IShellFolder
, (void **)&folder
, (const ITEMIDLIST
**)&pidl_child
);
4997 ok(hr
== S_OK
, "Got 0x%08x\n", hr
);
4999 IShellFolder_QueryInterface(folder
,&IID_IPersistFolder2
,(void**)&persist
);
5000 IPersistFolder2_GetCurFolder(persist
,&pidlFolder
);
5001 IPersistFolder2_Release(persist
);
5007 cminfo
.pidlFolder
=NULL
;
5008 cminfo
.apidl
=(LPCITEMIDLIST
*)&pidl_child
;
5012 cminfo
.punkAssociationInfo
=NULL
;
5014 hr
= pSHCreateDefaultContextMenu(&cminfo
,&IID_IContextMenu
,(void**)&cmenu
);
5015 ok(hr
==S_OK
,"Got 0x%08x\n", hr
);
5016 test_contextmenu_qi(cmenu
, TRUE
);
5017 IContextMenu_Release(cmenu
);
5019 cminfo
.pidlFolder
=pidlFolder
;
5020 hr
= pSHCreateDefaultContextMenu(&cminfo
,&IID_IContextMenu
,(void**)&cmenu
);
5021 ok(hr
==S_OK
,"Got 0x%08x\n", hr
);
5022 test_contextmenu_qi(cmenu
, TRUE
);
5023 IContextMenu_Release(cmenu
);
5025 status
= RegOpenKeyExA(HKEY_CLASSES_ROOT
,"*",0,KEY_READ
,keys
);
5026 if(status
==ERROR_SUCCESS
){
5031 hr
= pSHCreateDefaultContextMenu(&cminfo
,&IID_IContextMenu
,(void**)&cmenu
);
5032 RegCloseKey(keys
[0]);
5033 ok(hr
==S_OK
,"Got 0x%08x\n", hr
);
5034 IContextMenu_Release(cmenu
);
5038 IShellFolder_Release(folder
);
5040 IShellFolder_Release(desktop
);
5045 static void test_DataObject(void)
5047 IShellFolder
*desktop
;
5048 IDataObject
*data_obj
;
5053 DWORD cf_shellidlist
;
5056 SHGetDesktopFolder(&desktop
);
5058 hres
= IShellFolder_EnumObjects(desktop
, NULL
,
5059 SHCONTF_NONFOLDERS
|SHCONTF_FOLDERS
|SHCONTF_INCLUDEHIDDEN
, &peidl
);
5060 ok(hres
== S_OK
, "got %x\n", hres
);
5062 if(IEnumIDList_Next(peidl
, 1, &apidl
, NULL
) != S_OK
) {
5063 skip("no files on desktop - skipping GetDataObject tests\n");
5064 IEnumIDList_Release(peidl
);
5065 IShellFolder_Release(desktop
);
5068 IEnumIDList_Release(peidl
);
5070 hres
= IShellFolder_GetUIObjectOf(desktop
, NULL
, 1, (LPCITEMIDLIST
*)&apidl
,
5071 &IID_IDataObject
, NULL
, (void**)&data_obj
);
5072 ok(hres
== S_OK
, "got %x\n", hres
);
5074 IShellFolder_Release(desktop
);
5076 cf_shellidlist
= RegisterClipboardFormatW(CFSTR_SHELLIDLISTW
);
5077 fmt
.cfFormat
= cf_shellidlist
;
5079 fmt
.dwAspect
= DVASPECT_CONTENT
;
5081 fmt
.tymed
= TYMED_HGLOBAL
;
5082 hres
= IDataObject_QueryGetData(data_obj
, &fmt
);
5083 ok(hres
== S_OK
, "got %x\n", hres
);
5085 fmt
.tymed
= TYMED_HGLOBAL
| TYMED_ISTREAM
;
5086 hres
= IDataObject_QueryGetData(data_obj
, &fmt
);
5087 ok(hres
== S_OK
, "got %x\n", hres
);
5089 fmt
.tymed
= TYMED_ISTREAM
;
5090 hres
= IDataObject_QueryGetData(data_obj
, &fmt
);
5091 todo_wine
ok(hres
== S_FALSE
, "got %x\n", hres
);
5093 fmt
.tymed
= TYMED_HGLOBAL
| TYMED_ISTREAM
;
5094 hres
= IDataObject_GetData(data_obj
, &fmt
, &medium
);
5095 ok(hres
== S_OK
, "got %x\n", hres
);
5096 ok(medium
.tymed
== TYMED_HGLOBAL
, "medium.tymed = %x\n", medium
.tymed
);
5097 ReleaseStgMedium(&medium
);
5099 IDataObject_Release(data_obj
);
5102 static void test_GetDefaultColumn(void)
5104 static const CLSID
*folders
[] =
5108 &CLSID_ControlPanel
,
5109 &CLSID_NetworkPlaces
,
5112 &CLSID_ShellDesktop
,
5119 for (i
= 0; i
< ARRAY_SIZE(folders
); i
++)
5121 IShellFolder2
*folder
;
5122 ULONG sort
, display
;
5124 hr
= CoCreateInstance(folders
[i
], NULL
, CLSCTX_INPROC_SERVER
, &IID_IShellFolder2
, (void **)&folder
);
5127 win_skip("Failed to create folder %s, hr %#x.\n", wine_dbgstr_guid(folders
[i
]), hr
);
5131 hr
= IShellFolder2_GetDefaultColumn(folder
, 0, NULL
, NULL
);
5132 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
5134 sort
= display
= 123;
5135 hr
= IShellFolder2_GetDefaultColumn(folder
, 0, &sort
, &display
);
5136 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
5137 ok(sort
== 123 && display
== 123, "Unexpected default column.\n");
5140 hr
= IShellFolder2_GetDefaultColumn(folder
, 0, NULL
, &display
);
5141 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
5142 ok(display
== 123, "Unexpected default column.\n");
5145 hr
= IShellFolder2_GetDefaultColumn(folder
, 0, &sort
, NULL
);
5146 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
5147 ok(sort
== 123, "Unexpected default column.\n");
5149 IShellFolder2_Release(folder
);
5155 static void test_GetDefaultSearchGUID(void)
5157 static const CLSID
*folders
[] =
5161 &CLSID_ControlPanel
,
5162 &CLSID_NetworkPlaces
,
5165 &CLSID_ShellDesktop
,
5172 for (i
= 0; i
< ARRAY_SIZE(folders
); i
++)
5174 IShellFolder2
*folder
;
5177 hr
= CoCreateInstance(folders
[i
], NULL
, CLSCTX_INPROC_SERVER
, &IID_IShellFolder2
, (void **)&folder
);
5180 win_skip("Failed to create folder %s, hr %#x.\n", wine_dbgstr_guid(folders
[i
]), hr
);
5187 hr
= IShellFolder2_GetDefaultSearchGUID(folder
, NULL
);
5188 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
5191 memcpy(&guid
, &CLSID_MyComputer
, sizeof(guid
));
5192 hr
= IShellFolder2_GetDefaultSearchGUID(folder
, &guid
);
5193 ok(hr
== E_NOTIMPL
|| broken(hr
== S_OK
) /* Method was last supported on XP */, "Unexpected hr %#x.\n", hr
);
5194 if (hr
== E_NOTIMPL
)
5195 ok(IsEqualGUID(&guid
, &CLSID_MyComputer
), "Unexpected guid %s.\n", wine_dbgstr_guid(&guid
));
5197 IShellFolder2_Release(folder
);
5203 static void test_SHLimitInputEdit(void)
5205 IShellFolder
*desktop
;
5209 hr
= SHGetDesktopFolder(&desktop
);
5210 ok(hr
== S_OK
, "Failed to get desktop folder, hr %#x.\n", hr
);
5212 hr
= SHLimitInputEdit(NULL
, desktop
);
5214 ok(hr
== E_FAIL
, "Unexpected hr %#x.\n", hr
);
5216 hwnd
= CreateWindowA("EDIT", NULL
, WS_VISIBLE
, 0, 0, 100, 30, NULL
, NULL
, NULL
, NULL
);
5217 ok(hwnd
!= NULL
, "Failed to create Edit control.\n");
5219 hr
= SHLimitInputEdit(hwnd
, desktop
);
5221 ok(hr
== S_OK
, "Failed to set input limits, hr %#x.\n", hr
);
5223 hr
= SHLimitInputEdit(hwnd
, desktop
);
5225 ok(hr
== S_OK
, "Failed to set input limits, hr %#x.\n", hr
);
5227 DestroyWindow(hwnd
);
5228 IShellFolder_Release(desktop
);
5231 static void test_SHGetSetFolderCustomSettings(void)
5234 SHFOLDERCUSTOMSETTINGS fcs
;
5235 WCHAR pathW
[MAX_PATH
];
5236 WCHAR bufferW
[MAX_PATH
];
5237 WCHAR iconpathW
[MAX_PATH
];
5238 static const WCHAR somedirW
[] = {'s','o','m','e','_','d','i','r',0};
5239 static const WCHAR iconW
[] = {'\\','s','o','m','e','_','i','c','o','n','.','i','c','o',0};
5240 static const WCHAR desktop_iniW
[] = {'\\','D','e','s','k','t','o','p','.','i','n','i',0};
5242 if (!pSHGetSetFolderCustomSettings
)
5244 win_skip("SHGetSetFolderCustomSetting is not available.\n");
5248 GetTempPathW(MAX_PATH
, pathW
);
5249 lstrcatW(pathW
, somedirW
);
5250 CreateDirectoryW(pathW
, NULL
);
5252 lstrcpyW(iconpathW
, pathW
);
5253 lstrcatW(iconpathW
, iconW
);
5255 memset(&fcs
, 0, sizeof(fcs
));
5256 fcs
.dwSize
= sizeof(fcs
);
5257 fcs
.dwMask
= FCSM_ICONFILE
;
5258 fcs
.pszIconFile
= iconpathW
;
5260 hr
= pSHGetSetFolderCustomSettings(&fcs
, pathW
, FCS_FORCEWRITE
); /*creates and writes to a Desktop.ini*/
5261 ok(hr
== S_OK
, "Expected S_OK, got %#x\n", hr
);
5263 memset(&fcs
, 0, sizeof(fcs
));
5264 fcs
.dwSize
= sizeof(fcs
);
5265 fcs
.dwMask
= FCSM_ICONFILE
;
5266 fcs
.cchIconFile
= MAX_PATH
;
5267 fcs
.pszIconFile
= bufferW
;
5270 hr
= pSHGetSetFolderCustomSettings(&fcs
, pathW
, FCS_READ
);
5271 todo_wine
ok(hr
== S_OK
, "Expected S_OK, got %#x\n", hr
);
5272 todo_wine
ok(!lstrcmpiW(iconpathW
, fcs
.pszIconFile
), "Expected %s, got %s\n", wine_dbgstr_w(iconpathW
), wine_dbgstr_w(fcs
.pszIconFile
));
5274 hr
= pSHGetSetFolderCustomSettings(&fcs
, NULL
, FCS_READ
);
5275 ok(FAILED(hr
), "Unexpected hr %#x.\n", hr
);
5277 lstrcpyW(bufferW
, pathW
);
5278 lstrcatW(bufferW
, desktop_iniW
);
5279 DeleteFileW(bufferW
);
5280 RemoveDirectoryW(pathW
);
5283 START_TEST(shlfolder
)
5285 init_function_pointers();
5286 /* if OleInitialize doesn't get called, ParseDisplayName returns
5287 CO_E_NOTINITIALIZED for malformed directory names */
5288 OleInitialize(NULL
);
5290 test_ParseDisplayName();
5291 test_SHParseDisplayName();
5292 test_BindToObject();
5293 test_EnumObjects_and_CompareIDs();
5294 test_GetDisplayName();
5295 test_GetAttributesOf();
5296 test_SHGetPathFromIDList();
5297 test_CallForAttributes();
5298 test_FolderShortcut();
5299 test_ITEMIDLIST_format();
5300 test_SHGetFolderPathA();
5301 test_SHGetFolderPathAndSubDirA();
5302 test_LocalizedNames();
5303 test_SHCreateShellItem();
5304 test_SHCreateShellItemArray();
5305 test_ShellItemArrayEnumItems();
5306 test_desktop_IPersist();
5308 test_SHSimpleIDListFromPath();
5309 test_ParseDisplayNamePBC();
5310 test_SHGetNameFromIDList();
5311 test_SHGetItemFromDataObject();
5312 test_SHGetIDListFromObject();
5313 test_SHGetItemFromObject();
5314 test_ShellItemCompare();
5315 test_SHChangeNotify(FALSE
);
5316 test_SHChangeNotify(TRUE
);
5317 test_ShellItemBindToHandler();
5318 test_ShellItemGetAttributes();
5319 test_ShellItemArrayGetAttributes();
5320 test_SHCreateDefaultContextMenu();
5322 test_GetDefaultColumn();
5323 test_GetDefaultSearchGUID();
5324 test_SHLimitInputEdit();
5325 test_SHGetSetFolderCustomSettings();