Make shell32 tests loadable on NT4.
[wine] / dlls / shell32 / tests / shlfolder.c
1 /*
2  * Unit test of the IShellFolder functions.
3  *
4  * Copyright 2004 Vitaliy Margolen
5  *
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.
10  *
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.
15  *
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <stdarg.h>
22 #include <stdio.h>
23
24 #define COBJMACROS
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wtypes.h"
29 #include "shellapi.h"
30
31
32 #include "shlguid.h"
33 #include "shlobj.h"
34 #include "shobjidl.h"
35 #include "shlwapi.h"
36
37
38 #include "wine/unicode.h"
39 #include "wine/test.h"
40
41
42 static IMalloc *ppM;
43
44 static HRESULT (WINAPI *pSHBindToParent)(LPCITEMIDLIST, REFIID, LPVOID*, LPCITEMIDLIST*);
45 static BOOL (WINAPI *pSHGetSpecialFolderPathW)(HWND, LPWSTR, int, BOOL);
46
47 static void init_function_pointers(void)
48 {
49     HMODULE hmod = GetModuleHandleA("shell32.dll");
50
51     if(hmod)
52     {
53         pSHBindToParent = (void*)GetProcAddress(hmod, "SHBindToParent");
54         pSHGetSpecialFolderPathW = (void*)GetProcAddress(hmod, "SHGetSpecialFolderPathW");
55     }
56 }
57
58 /* creates a file with the specified name for tests */
59 static void CreateTestFile(const CHAR *name)
60 {
61     HANDLE file;
62     DWORD written;
63
64     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
65     if (file != INVALID_HANDLE_VALUE)
66     {
67         WriteFile(file, name, strlen(name), &written, NULL);
68         WriteFile(file, "\n", strlen("\n"), &written, NULL);
69         CloseHandle(file);
70     }
71 }
72
73
74 /* initializes the tests */
75 static void CreateFilesFolders(void)
76 {
77     CreateDirectoryA(".\\testdir", NULL);
78     CreateDirectoryA(".\\testdir\\test.txt", NULL);
79     CreateTestFile  (".\\testdir\\test1.txt ");
80     CreateTestFile  (".\\testdir\\test2.txt ");
81     CreateTestFile  (".\\testdir\\test3.txt ");
82     CreateDirectoryA(".\\testdir\\testdir2 ", NULL);
83     CreateDirectoryA(".\\testdir\\testdir2\\subdir", NULL);
84 }
85
86 /* cleans after tests */
87 static void Cleanup(void)
88 {
89     DeleteFileA(".\\testdir\\test1.txt");
90     DeleteFileA(".\\testdir\\test2.txt");
91     DeleteFileA(".\\testdir\\test3.txt");
92     RemoveDirectoryA(".\\testdir\\test.txt");
93     RemoveDirectoryA(".\\testdir\\testdir2\\subdir");
94     RemoveDirectoryA(".\\testdir\\testdir2");
95     RemoveDirectoryA(".\\testdir");
96 }
97
98
99 /* perform test */
100 static void test_EnumObjects(IShellFolder *iFolder)
101 {
102     IEnumIDList *iEnumList;
103     ITEMIDLIST *newPIDL, *(idlArr [5]);
104     ULONG NumPIDLs;
105     int i=0, j;
106     HRESULT hr;
107
108     static const WORD iResults [5][5] =
109     {
110         { 0,-1,-1,-1,-1},
111         { 1, 0,-1,-1,-1},
112         { 1, 1, 0,-1,-1},
113         { 1, 1, 1, 0,-1},
114         { 1, 1, 1, 1, 0}
115     };
116
117     /* Just test SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR for now */
118     static const ULONG attrs[5] =
119     {
120         SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR,
121         SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR,
122         SFGAO_FILESYSTEM,
123         SFGAO_FILESYSTEM,
124         SFGAO_FILESYSTEM,
125     };
126
127     hr = IShellFolder_EnumObjects(iFolder, NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &iEnumList);
128     ok(hr == S_OK, "EnumObjects failed %08lx\n", hr);
129
130     while (IEnumIDList_Next(iEnumList, 1, &newPIDL, &NumPIDLs) == S_OK)
131     {
132         idlArr[i++] = newPIDL;
133     }
134
135     hr = IEnumIDList_Release(iEnumList);
136     ok(hr == S_OK, "IEnumIDList_Release failed %08lx\n", hr);
137     
138     /* Sort them first in case of wrong order from system */
139     for (i=0;i<5;i++) for (j=0;j<5;j++)
140         if ((SHORT)IShellFolder_CompareIDs(iFolder, 0, idlArr[i], idlArr[j]) < 0)
141         {
142             newPIDL = idlArr[i];
143             idlArr[i] = idlArr[j];
144             idlArr[j] = newPIDL;
145         }
146             
147     for (i=0;i<5;i++) for (j=0;j<5;j++)
148     {
149         hr = IShellFolder_CompareIDs(iFolder, 0, idlArr[i], idlArr[j]);
150         ok(hr == iResults[i][j], "Got %lx expected [%d]-[%d]=%x\n", hr, i, j, iResults[i][j]);
151     }
152
153
154     for (i = 0; i < 5; i++)
155     {
156         SFGAOF flags;
157         flags = SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR;
158         hr = IShellFolder_GetAttributesOf(iFolder, 1, (LPCITEMIDLIST*)(idlArr + i), &flags);
159         flags &= SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR;
160         ok(hr == S_OK, "GetAttributesOf returns %08lx\n", hr);
161         ok(flags == attrs[i], "GetAttributesOf gets attrs %08lx, expects %08lx\n", flags, attrs[i]);
162     }
163
164     for (i=0;i<5;i++)
165         IMalloc_Free(ppM, idlArr[i]);
166 }
167
168 static void test_BindToObject(void)
169 {
170     HRESULT hr;
171     UINT cChars;
172     IShellFolder *psfDesktop, *psfChild, *psfMyComputer, *psfSystemDir;
173     SHITEMID emptyitem = { 0, { 0 } };
174     LPITEMIDLIST pidlMyComputer, pidlSystemDir, pidlEmpty = (LPITEMIDLIST)&emptyitem;
175     WCHAR wszSystemDir[MAX_PATH];
176     WCHAR wszMyComputer[] = { 
177         ':',':','{','2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-',
178         'A','2','D','8','-','0','8','0','0','2','B','3','0','3','0','9','D','}',0 };
179
180     /* The following tests shows that BindToObject should fail with E_INVALIDARG if called
181      * with an empty pidl. This is tested for Desktop, MyComputer and the FS ShellFolder
182      */
183     hr = SHGetDesktopFolder(&psfDesktop);
184     ok (SUCCEEDED(hr), "SHGetDesktopFolder failed! hr = %08lx\n", hr);
185     if (FAILED(hr)) return;
186     
187     hr = IShellFolder_BindToObject(psfDesktop, pidlEmpty, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
188     ok (hr == E_INVALIDARG, "Desktop's BindToObject should fail, when called with empty pidl! hr = %08lx\n", hr);
189
190     hr = IShellFolder_ParseDisplayName(psfDesktop, NULL, NULL, wszMyComputer, NULL, &pidlMyComputer, NULL);
191     ok (SUCCEEDED(hr), "Desktop's ParseDisplayName failed to parse MyComputer's CLSID! hr = %08lx\n", hr);
192     if (FAILED(hr)) {
193         IShellFolder_Release(psfDesktop);
194         return;
195     }
196     
197     hr = IShellFolder_BindToObject(psfDesktop, pidlMyComputer, NULL, &IID_IShellFolder, (LPVOID*)&psfMyComputer);
198     ok (SUCCEEDED(hr), "Desktop failed to bind to MyComputer object! hr = %08lx\n", hr);
199     IShellFolder_Release(psfDesktop);
200     ILFree(pidlMyComputer);
201     if (FAILED(hr)) return;
202
203     hr = IShellFolder_BindToObject(psfMyComputer, pidlEmpty, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
204     ok (hr == E_INVALIDARG, "MyComputers's BindToObject should fail, when called with empty pidl! hr = %08lx\n", hr);
205
206     cChars = GetSystemDirectoryW(wszSystemDir, MAX_PATH);
207     ok (cChars > 0 && cChars < MAX_PATH, "GetSystemDirectoryW failed! LastError: %08lx\n", GetLastError());
208     if (cChars == 0 || cChars >= MAX_PATH) {
209         IShellFolder_Release(psfMyComputer);
210         return;
211     }
212     
213     hr = IShellFolder_ParseDisplayName(psfMyComputer, NULL, NULL, wszSystemDir, NULL, &pidlSystemDir, NULL);
214     ok (SUCCEEDED(hr), "MyComputers's ParseDisplayName failed to parse the SystemDirectory! hr = %08lx\n", hr);
215     if (FAILED(hr)) {
216         IShellFolder_Release(psfMyComputer);
217         return;
218     }
219
220     hr = IShellFolder_BindToObject(psfMyComputer, pidlSystemDir, NULL, &IID_IShellFolder, (LPVOID*)&psfSystemDir);
221     ok (SUCCEEDED(hr), "MyComputer failed to bind to a FileSystem ShellFolder! hr = %08lx\n", hr);
222     IShellFolder_Release(psfMyComputer);
223     ILFree(pidlSystemDir);
224     if (FAILED(hr)) return;
225
226     hr = IShellFolder_BindToObject(psfSystemDir, pidlEmpty, NULL, &IID_IShellFolder, (LPVOID*)&psfChild);
227     ok (hr == E_INVALIDARG, 
228         "FileSystem ShellFolder's BindToObject should fail, when called with empty pidl! hr = %08lx\n", hr);
229     
230     IShellFolder_Release(psfSystemDir);
231 }
232   
233 static void test_GetDisplayName(void)
234 {
235     BOOL result;
236     HRESULT hr;
237     HANDLE hTestFile;
238     WCHAR wszTestFile[MAX_PATH], wszTestFile2[MAX_PATH], wszTestDir[MAX_PATH];
239     STRRET strret;
240     LPSHELLFOLDER psfDesktop, psfPersonal;
241     IUnknown *psfFile;
242     LPITEMIDLIST pidlTestFile;
243     LPCITEMIDLIST pidlLast;
244     static const WCHAR wszFileName[] = { 'w','i','n','e','t','e','s','t','.','f','o','o',0 };
245     static const WCHAR wszDirName[] = { 'w','i','n','e','t','e','s','t',0 };
246
247     /* I'm trying to figure if there is a functional difference between calling
248      * SHGetPathFromIDList and calling GetDisplayNameOf(SHGDN_FORPARSING) after
249      * binding to the shellfolder. One thing I thought of was that perhaps 
250      * SHGetPathFromIDList would be able to get the path to a file, which does
251      * not exist anymore, while the other method would'nt. It turns out there's
252      * no functional difference in this respect.
253      */
254
255     if(!pSHGetSpecialFolderPathW) return;
256
257     /* First creating a directory in MyDocuments and a file in this directory. */
258     result = pSHGetSpecialFolderPathW(NULL, wszTestDir, CSIDL_PERSONAL, FALSE);
259     ok(result, "SHGetSpecialFolderPathW failed! Last error: %08lx\n", GetLastError());
260     if (!result) return;
261
262     PathAddBackslashW(wszTestDir);
263     lstrcatW(wszTestDir, wszDirName);
264     result = CreateDirectoryW(wszTestDir, NULL);
265     ok(result, "CreateDirectoryW failed! Last error: %08lx\n", GetLastError());
266     if (!result) return;
267
268     lstrcpyW(wszTestFile, wszTestDir);
269     PathAddBackslashW(wszTestFile);
270     lstrcatW(wszTestFile, wszFileName);
271
272     hTestFile = CreateFileW(wszTestFile, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL);
273     ok(hTestFile != INVALID_HANDLE_VALUE, "CreateFileW failed! Last error: %08lx\n", GetLastError());
274     if (hTestFile == INVALID_HANDLE_VALUE) return;
275     CloseHandle(hTestFile);
276
277     /* Getting an itemidlist for the file. */
278     hr = SHGetDesktopFolder(&psfDesktop);
279     ok(SUCCEEDED(hr), "SHGetDesktopFolder failed! hr = %08lx\n", hr);
280     if (FAILED(hr)) return;
281
282     hr = IShellFolder_ParseDisplayName(psfDesktop, NULL, NULL, wszTestFile, NULL, &pidlTestFile, NULL);
283     ok(SUCCEEDED(hr), "Desktop->ParseDisplayName failed! hr = %08lx\n", hr);
284     if (FAILED(hr)) {
285         IShellFolder_Release(psfDesktop);
286         return;
287     }
288
289     /* It seems as if we cannot bind to regular files on windows, but only directories. 
290      */
291     hr = IShellFolder_BindToObject(psfDesktop, pidlTestFile, NULL, &IID_IUnknown, (VOID**)&psfFile);
292     todo_wine { ok (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "hr = %08lx\n", hr); }
293     if (SUCCEEDED(hr)) {
294         IShellFolder_Release(psfFile);
295     }
296     
297     /* Deleting the file and the directory */
298     DeleteFileW(wszTestFile);
299     RemoveDirectoryW(wszTestDir);
300
301     /* SHGetPathFromIDListW still works, although the file is not present anymore. */
302     result = SHGetPathFromIDListW(pidlTestFile, wszTestFile2);
303     ok (result, "SHGetPathFromIDListW failed! Last error: %08lx\n", GetLastError());
304     ok (!lstrcmpiW(wszTestFile, wszTestFile2), "SHGetPathFromIDListW returns incorrect path!\n");
305
306     if(!pSHBindToParent) return;
307
308     /* Binding to the folder and querying the display name of the file also works. */
309     hr = pSHBindToParent(pidlTestFile, &IID_IShellFolder, (VOID**)&psfPersonal, &pidlLast); 
310     ok (SUCCEEDED(hr), "SHBindToParent failed! hr = %08lx\n", hr);
311     if (FAILED(hr)) {
312         IShellFolder_Release(psfDesktop);
313         return;
314     }
315
316     hr = IShellFolder_GetDisplayNameOf(psfPersonal, pidlLast, SHGDN_FORPARSING, &strret);
317     ok (SUCCEEDED(hr), "Personal->GetDisplayNameOf failed! hr = %08lx\n", hr);
318     if (FAILED(hr)) {
319         IShellFolder_Release(psfDesktop);
320         IShellFolder_Release(psfPersonal);
321         return;
322     }
323     
324     hr = StrRetToBufW(&strret, pidlLast, wszTestFile2, MAX_PATH);
325     ok (SUCCEEDED(hr), "StrRetToBufW failed! hr = %08lx\n", hr);
326     ok (!lstrcmpiW(wszTestFile, wszTestFile2), "GetDisplayNameOf returns incorrect path!\n");
327     
328     IShellFolder_Release(psfDesktop);
329     IShellFolder_Release(psfPersonal);
330 }
331
332 static void test_GetAttributesOf(void) 
333 {
334     HRESULT hr;
335     LPSHELLFOLDER psfDesktop, psfMyComputer;
336     SHITEMID emptyitem = { 0, { 0 } };
337     LPCITEMIDLIST pidlEmpty = (LPCITEMIDLIST)&emptyitem;
338     LPITEMIDLIST pidlMyComputer;
339     DWORD dwFlags;
340     const static DWORD dwDesktopFlags = /* As observed on WinXP SP2 */
341         SFGAO_STORAGE | SFGAO_HASPROPSHEET | SFGAO_STORAGE_ANCESTOR |
342         SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER;
343     const static DWORD dwMyComputerFlags = /* As observed on WinXP SP2 */
344         SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET |
345         SFGAO_DROPTARGET | SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER;
346     WCHAR wszMyComputer[] = { 
347         ':',':','{','2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-',
348         'A','2','D','8','-','0','8','0','0','2','B','3','0','3','0','9','D','}',0 };
349
350     hr = SHGetDesktopFolder(&psfDesktop);
351     ok (SUCCEEDED(hr), "SHGetDesktopFolder failed! hr = %08lx\n", hr);
352     if (FAILED(hr)) return;
353
354     /* The Desktop attributes can be queried with a single empty itemidlist, .. */
355     dwFlags = 0xffffffff;
356     hr = IShellFolder_GetAttributesOf(psfDesktop, 1, &pidlEmpty, &dwFlags);
357     ok (SUCCEEDED(hr), "Desktop->GetAttributesOf(empty pidl) failed! hr = %08lx\n", hr);
358     ok (dwFlags == dwDesktopFlags, "Wrong Desktop attributes: %08lx, expected: %08lx\n", 
359         dwFlags, dwDesktopFlags);
360
361     /* .. or with no itemidlist at all. */
362     dwFlags = 0xffffffff;
363     hr = IShellFolder_GetAttributesOf(psfDesktop, 0, NULL, &dwFlags);
364     ok (SUCCEEDED(hr), "Desktop->GetAttributesOf(NULL) failed! hr = %08lx\n", hr);
365     ok (dwFlags == dwDesktopFlags, "Wrong Desktop attributes: %08lx, expected: %08lx\n", 
366         dwFlags, dwDesktopFlags);
367    
368     /* Testing the attributes of the MyComputer shellfolder */
369     hr = IShellFolder_ParseDisplayName(psfDesktop, NULL, NULL, wszMyComputer, NULL, &pidlMyComputer, NULL);
370     ok (SUCCEEDED(hr), "Desktop's ParseDisplayName failed to parse MyComputer's CLSID! hr = %08lx\n", hr);
371     if (FAILED(hr)) {
372         IShellFolder_Release(psfDesktop);
373         return;
374     }
375
376     /* WinXP SP2 sets the SFGAO_CANLINK flag, when MyComputer is queried via the Desktop 
377      * folder object. It doesn't do this, if MyComputer is queried directly (see below).
378      * SFGAO_CANLINK is the same as DROPEFFECT_LINK, which MSDN says means: "Drag source
379      * should create a link to the original data". You can't create links on MyComputer on
380      * Windows, so this flag shouldn't be set. Seems like a bug in Windows. As long as nobody
381      * depends on this bug, we probably shouldn't imitate it.
382      */
383     dwFlags = 0xffffffff;
384     hr = IShellFolder_GetAttributesOf(psfDesktop, 1, (LPCITEMIDLIST*)&pidlMyComputer, &dwFlags);
385     ok (SUCCEEDED(hr), "Desktop->GetAttributesOf(MyComputer) failed! hr = %08lx\n", hr);
386     todo_wine { ok ((dwFlags & ~(DWORD)SFGAO_CANLINK) == dwMyComputerFlags, 
387                     "Wrong MyComputer attributes: %08lx, expected: %08lx\n", dwFlags, dwMyComputerFlags); }
388
389     hr = IShellFolder_BindToObject(psfDesktop, pidlMyComputer, NULL, &IID_IShellFolder, (LPVOID*)&psfMyComputer);
390     ok (SUCCEEDED(hr), "Desktop failed to bind to MyComputer object! hr = %08lx\n", hr);
391     IShellFolder_Release(psfDesktop);
392     ILFree(pidlMyComputer);
393     if (FAILED(hr)) return;
394
395     hr = IShellFolder_GetAttributesOf(psfMyComputer, 1, &pidlEmpty, &dwFlags);
396     todo_wine {ok (hr == E_INVALIDARG, "MyComputer->GetAttributesOf(emtpy pidl) should fail! hr = %08lx\n", hr); }
397
398     dwFlags = 0xffffffff;
399     hr = IShellFolder_GetAttributesOf(psfMyComputer, 0, NULL, &dwFlags);
400     ok (SUCCEEDED(hr), "MyComputer->GetAttributesOf(NULL) failed! hr = %08lx\n", hr); 
401     todo_wine { ok (dwFlags == dwMyComputerFlags, 
402                     "Wrong MyComputer attributes: %08lx, expected: %08lx\n", dwFlags, dwMyComputerFlags); }
403
404     IShellFolder_Release(psfMyComputer);
405 }    
406
407 static void test_SHGetPathFromIDList(void)
408 {
409     SHITEMID emptyitem = { 0, { 0 } };
410     LPCITEMIDLIST pidlEmpty = (LPCITEMIDLIST)&emptyitem;
411     LPITEMIDLIST pidlMyComputer;
412     WCHAR wszPath[MAX_PATH], wszDesktop[MAX_PATH];
413     BOOL result;
414     HRESULT hr;
415     LPSHELLFOLDER psfDesktop;
416     WCHAR wszMyComputer[] = { 
417         ':',':','{','2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-',
418         'A','2','D','8','-','0','8','0','0','2','B','3','0','3','0','9','D','}',0 };
419
420     if(!pSHGetSpecialFolderPathW) return;
421
422     /* Calling SHGetPathFromIDList with an empty pidl should return the desktop folder's path. */
423     result = pSHGetSpecialFolderPathW(NULL, wszDesktop, CSIDL_DESKTOP, FALSE);
424     ok(result, "SHGetSpecialFolderPathW(CSIDL_DESKTOP) failed! Last error: %08lx\n", GetLastError());
425     if (!result) return;
426     
427     result = SHGetPathFromIDListW(pidlEmpty, wszPath);
428     ok(result, "SHGetPathFromIDListW failed! Last error: %08lx\n", GetLastError());
429     if (!result) return;
430     ok(!lstrcmpiW(wszDesktop, wszPath), "SHGetPathFromIDList didn't return desktop path for empty pidl!\n");
431
432     /* MyComputer does not map to a filesystem path. SHGetPathFromIDList should fail. */
433     hr = SHGetDesktopFolder(&psfDesktop);
434     ok (SUCCEEDED(hr), "SHGetDesktopFolder failed! hr = %08lx\n", hr);
435     if (FAILED(hr)) return;
436
437     hr = IShellFolder_ParseDisplayName(psfDesktop, NULL, NULL, wszMyComputer, NULL, &pidlMyComputer, NULL);
438     ok (SUCCEEDED(hr), "Desktop's ParseDisplayName failed to parse MyComputer's CLSID! hr = %08lx\n", hr);
439     IShellFolder_Release(psfDesktop);
440     if (FAILED(hr)) return;
441
442     SetLastError(0xdeadbeef);
443     result = SHGetPathFromIDListW(pidlMyComputer, wszPath);
444     ok (!result, "SHGetPathFromIDList succeeded where it shouldn't!\n");
445     ok (GetLastError()==0xdeadbeef, "SHGetPathFromIDList shouldn't set last error! Last error: %08lx\n", GetLastError());
446
447     ILFree(pidlMyComputer);
448 }
449
450 START_TEST(shlfolder)
451 {
452     ITEMIDLIST *newPIDL;
453     IShellFolder *IDesktopFolder, *testIShellFolder;
454     char  cCurrDirA [MAX_PATH] = {0};
455     WCHAR cCurrDirW [MAX_PATH];
456     static const WCHAR cTestDirW[] = {'\\','t','e','s','t','d','i','r',0};
457     HRESULT hr;
458     
459     init_function_pointers();
460
461     GetCurrentDirectoryA(MAX_PATH, cCurrDirA);
462     MultiByteToWideChar(CP_ACP, 0, cCurrDirA, -1, cCurrDirW, MAX_PATH);
463     strcatW(cCurrDirW, cTestDirW);
464
465     OleInitialize(NULL);
466
467     hr = SHGetMalloc(&ppM);
468     ok(hr == S_OK, "SHGetMalloc failed %08lx\n", hr);
469
470     CreateFilesFolders();
471     
472     hr = SHGetDesktopFolder(&IDesktopFolder);
473     ok(hr == S_OK, "SHGetDesktopfolder failed %08lx\n", hr);
474
475     hr = IShellFolder_ParseDisplayName(IDesktopFolder, NULL, NULL, cCurrDirW, NULL, &newPIDL, 0);
476     ok(hr == S_OK, "ParseDisplayName failed %08lx\n", hr);
477
478     hr = IShellFolder_BindToObject(IDesktopFolder, newPIDL, NULL, (REFIID)&IID_IShellFolder, (LPVOID *)&testIShellFolder);
479     ok(hr == S_OK, "BindToObject failed %08lx\n", hr);
480         
481     test_EnumObjects(testIShellFolder);
482     test_BindToObject();
483     test_GetDisplayName();
484     test_GetAttributesOf();
485     test_SHGetPathFromIDList();
486
487     hr = IShellFolder_Release(testIShellFolder);
488     ok(hr == S_OK, "IShellFolder_Release failed %08lx\n", hr);
489
490     IMalloc_Free(ppM, newPIDL);
491
492     Cleanup();
493 }