version/tests: Check the correct variable.
[wine] / dlls / shlwapi / tests / path.c
1 /* Unit test suite for Path functions
2  *
3  * Copyright 2002 Matthew Mastracci
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19
20 #include <stdarg.h>
21 #include <stdio.h>
22
23 #include "wine/test.h"
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winreg.h"
27 #include "shlwapi.h"
28 #include "wininet.h"
29
30 static HRESULT (WINAPI *pPathIsValidCharA)(char,DWORD);
31 static HRESULT (WINAPI *pPathIsValidCharW)(WCHAR,DWORD);
32 static LPWSTR  (WINAPI *pPathCombineW)(LPWSTR, LPCWSTR, LPCWSTR);
33 static HRESULT (WINAPI *pPathCreateFromUrlA)(LPCSTR, LPSTR, LPDWORD, DWORD);
34 static HRESULT (WINAPI *pPathCreateFromUrlW)(LPCWSTR, LPWSTR, LPDWORD, DWORD);
35 static BOOL    (WINAPI *pPathAppendA)(LPSTR, LPCSTR);
36
37 /* ################ */
38
39 static const struct {
40     const char *url;
41     const char *path;
42     DWORD ret;
43 } TEST_PATHFROMURL[] = {
44     {"file:///c:/foo/ba%5Cr", "c:\\foo\\ba\\r", S_OK},
45     {"file:///c:/foo/../ba%5Cr", "c:\\foo\\..\\ba\\r", S_OK},
46     {"file:///host/c:/foo/bar", "\\host\\c:\\foo\\bar", S_OK},
47     {"file://host/c:/foo/bar", "\\\\hostc:\\foo\\bar", S_OK},
48     {"file://host/c:/foo/bar", "\\\\hostc:\\foo\\bar", S_OK},
49     {"file:\\\\host\\c:\\foo\\bar", "\\\\hostc:\\foo\\bar", S_OK},
50     {"file:\\\\host\\ca\\foo\\bar", "\\\\host\\ca\\foo\\bar", S_OK},
51     {"file:\\\\host\\c|\\foo\\bar", "\\\\hostc|\\foo\\bar", S_OK},
52     {"file:\\%5Chost\\c:\\foo\\bar", "\\\\host\\c:\\foo\\bar", S_OK},
53     {"file:\\\\host\\cx:\\foo\\bar", "\\\\host\\cx:\\foo\\bar", S_OK},
54     {"file://c:/foo/bar", "c:\\foo\\bar", S_OK},
55     {"file://c:/d:/foo/bar", "c:\\d:\\foo\\bar", S_OK},
56     {"file://c|/d|/foo/bar", "c:\\d|\\foo\\bar", S_OK},
57     {"file://host/foo/bar", "\\\\host\\foo\\bar", S_OK},
58     {"file:/foo/bar", "\\foo\\bar", S_OK},
59     {"file:/foo/bar/", "\\foo\\bar\\", S_OK},
60     {"file:foo/bar", "foo\\bar", S_OK},
61     {"file:c:/foo/bar", "c:\\foo\\bar", S_OK},
62     {"file:c|/foo/bar", "c:\\foo\\bar", S_OK},
63     {"file:cx|/foo/bar", "cx|\\foo\\bar", S_OK},
64     {"file:////c:/foo/bar", "c:\\foo\\bar", S_OK},
65 /*    {"file:////c:/foo/foo%20bar", "c:\\foo\\foo%20bar", S_OK},*/
66
67     {"c:\\foo\\bar", NULL, E_INVALIDARG},
68     {"foo/bar", NULL, E_INVALIDARG},
69     {"http://foo/bar", NULL, E_INVALIDARG},
70
71 };
72
73
74 static struct {
75     const char *path;
76     BOOL expect;
77 } TEST_PATH_IS_URL[] = {
78     {"http://foo/bar", TRUE},
79     {"c:\\foo\\bar", FALSE},
80     {"c:/foo/bar", FALSE},
81     {"foo://foo/bar", TRUE},
82     {"foo\\bar", FALSE},
83     {"foo.bar", FALSE},
84     {"bogusscheme:", TRUE},
85     {"http:partial", TRUE},
86     {"www.winehq.org", FALSE},
87     /* More examples that the user might enter as the browser start page */
88     {"winehq.org", FALSE},
89     {"ftp.winehq.org", FALSE},
90     {"http://winehq.org", TRUE},
91     {"http://www.winehq.org", TRUE},
92     {"https://winehq.org", TRUE},
93     {"https://www.winehq.org", TRUE},
94     {"ftp://winehq.org", TRUE},
95     {"ftp://ftp.winehq.org", TRUE},
96     {"file://does_not_exist.txt", TRUE},
97     {"about:blank", TRUE},
98     {"about:home", TRUE},
99     {"about:mozilla", TRUE},
100     /* scheme is case independent */
101     {"HTTP://www.winehq.org", TRUE},
102     /* a space at the start is not allowed */
103     {" http://www.winehq.org", FALSE},
104     {"", FALSE},
105     {NULL, FALSE}
106 };
107
108 static const struct {
109     const char *path;
110     const char *result;
111 } TEST_PATH_UNQUOTE_SPACES[] = {
112     { "abcdef",                    "abcdef"         },
113     { "\"abcdef\"",                "abcdef"         },
114     { "\"abcdef",                  "\"abcdef"       },
115     { "abcdef\"",                  "abcdef\""       },
116     { "\"\"abcdef\"\"",            "\"abcdef\""     },
117     { "abc\"def",                  "abc\"def"       },
118     { "\"abc\"def",                "\"abc\"def"     },
119     { "\"abc\"def\"",              "abc\"def"       },
120     { "\'abcdef\'",                "\'abcdef\'"     },
121     { "\"\"",                      ""               },
122     { "\"",                        ""               }
123 };
124
125 /* ################ */
126
127 static LPWSTR GetWideString(const char* szString)
128 {
129   LPWSTR wszString = HeapAlloc(GetProcessHeap(), 0, (2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR));
130   
131   MultiByteToWideChar(0, 0, szString, -1, wszString, INTERNET_MAX_URL_LENGTH);
132
133   return wszString;
134 }
135
136 static void FreeWideString(LPWSTR wszString)
137 {
138    HeapFree(GetProcessHeap(), 0, wszString);
139 }
140
141 static LPSTR strdupA(LPCSTR p)
142 {
143     LPSTR ret;
144     DWORD len = (strlen(p) + 1);
145     ret = HeapAlloc(GetProcessHeap(), 0, len);
146     memcpy(ret, p, len);
147     return ret;
148 }
149
150 /* ################ */
151
152 static void test_PathSearchAndQualify(void)
153 {
154     WCHAR path1[] = {'c',':','\\','f','o','o',0};
155     WCHAR expect1[] = {'c',':','\\','f','o','o',0};
156     WCHAR path2[] = {'c',':','f','o','o',0};
157     WCHAR c_drive[] = {'c',':',0}; 
158     WCHAR foo[] = {'f','o','o',0}; 
159     WCHAR path3[] = {'\\','f','o','o',0};
160     WCHAR winini[] = {'w','i','n','.','i','n','i',0};
161     WCHAR out[MAX_PATH];
162     WCHAR cur_dir[MAX_PATH];
163     WCHAR dot[] = {'.',0};
164
165     /* c:\foo */
166     ok(PathSearchAndQualifyW(path1, out, MAX_PATH) != 0,
167        "PathSearchAndQualify rets 0\n");
168     ok(!lstrcmpiW(out, expect1), "strings don't match\n");
169
170     /* c:foo */
171     ok(PathSearchAndQualifyW(path2, out, MAX_PATH) != 0,
172        "PathSearchAndQualify rets 0\n");
173     GetFullPathNameW(c_drive, MAX_PATH, cur_dir, NULL);
174     PathAddBackslashW(cur_dir);
175     lstrcatW(cur_dir, foo);
176     ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");    
177
178     /* foo */
179     ok(PathSearchAndQualifyW(foo, out, MAX_PATH) != 0,
180        "PathSearchAndQualify rets 0\n");
181     GetFullPathNameW(dot, MAX_PATH, cur_dir, NULL);
182     PathAddBackslashW(cur_dir);
183     lstrcatW(cur_dir, foo);
184     ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");    
185
186     /* \foo */
187     ok(PathSearchAndQualifyW(path3, out, MAX_PATH) != 0,
188        "PathSearchAndQualify rets 0\n");
189     GetFullPathNameW(dot, MAX_PATH, cur_dir, NULL);
190     lstrcpyW(cur_dir + 2, path3);
191     ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
192
193     /* win.ini */
194     ok(PathSearchAndQualifyW(winini, out, MAX_PATH) != 0,
195        "PathSearchAndQualify rets 0\n");
196     if(!SearchPathW(NULL, winini, NULL, MAX_PATH, cur_dir, NULL))
197         GetFullPathNameW(winini, MAX_PATH, cur_dir, NULL);
198     ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
199
200 }
201
202 static void test_PathCreateFromUrl(void)
203 {
204     size_t i;
205     char ret_path[INTERNET_MAX_URL_LENGTH];
206     DWORD len, ret;
207     WCHAR ret_pathW[INTERNET_MAX_URL_LENGTH];
208     WCHAR *pathW, *urlW;
209     static const char url[] = "http://www.winehq.org";
210
211     if (!pPathCreateFromUrlA) {
212         win_skip("PathCreateFromUrlA not found\n");
213         return;
214     }
215
216     /* Check ret_path = NULL */
217     len = sizeof(url);
218     ret = pPathCreateFromUrlA(url, NULL, &len, 0);
219     ok ( ret == E_INVALIDARG, "got 0x%08x expected E_INVALIDARG\n", ret);
220
221     for(i = 0; i < sizeof(TEST_PATHFROMURL) / sizeof(TEST_PATHFROMURL[0]); i++) {
222         len = INTERNET_MAX_URL_LENGTH;
223         ret = pPathCreateFromUrlA(TEST_PATHFROMURL[i].url, ret_path, &len, 0);
224         ok(ret == TEST_PATHFROMURL[i].ret, "ret %08x from url %s\n", ret, TEST_PATHFROMURL[i].url);
225         if(TEST_PATHFROMURL[i].path) {
226            ok(!lstrcmpi(ret_path, TEST_PATHFROMURL[i].path), "got %s expected %s from url %s\n", ret_path, TEST_PATHFROMURL[i].path,  TEST_PATHFROMURL[i].url);
227            ok(len == strlen(ret_path), "ret len %d from url %s\n", len, TEST_PATHFROMURL[i].url);
228         }
229         if (pPathCreateFromUrlW) {
230             len = INTERNET_MAX_URL_LENGTH;
231             pathW = GetWideString(TEST_PATHFROMURL[i].path);
232             urlW = GetWideString(TEST_PATHFROMURL[i].url);
233             ret = pPathCreateFromUrlW(urlW, ret_pathW, &len, 0);
234             WideCharToMultiByte(CP_ACP, 0, ret_pathW, -1, ret_path, sizeof(ret_path),0,0);
235             ok(ret == TEST_PATHFROMURL[i].ret, "ret %08x from url L\"%s\"\n", ret, TEST_PATHFROMURL[i].url);
236             if(TEST_PATHFROMURL[i].path) {
237                 ok(!lstrcmpiW(ret_pathW, pathW), "got %s expected %s from url L\"%s\"\n",
238                     ret_path, TEST_PATHFROMURL[i].path, TEST_PATHFROMURL[i].url);
239                 ok(len == lstrlenW(ret_pathW), "ret len %d from url L\"%s\"\n", len, TEST_PATHFROMURL[i].url);
240             }
241             FreeWideString(urlW);
242             FreeWideString(pathW);
243         }
244     }
245 }
246
247
248 static void test_PathIsUrl(void)
249 {
250     size_t i;
251     BOOL ret;
252
253     for(i = 0; i < sizeof(TEST_PATH_IS_URL)/sizeof(TEST_PATH_IS_URL[0]); i++) {
254         ret = PathIsURLA(TEST_PATH_IS_URL[i].path);
255         ok(ret == TEST_PATH_IS_URL[i].expect,
256            "returned %d from path %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
257            TEST_PATH_IS_URL[i].expect);
258     }
259 }
260
261 static const DWORD SHELL_charclass[] =
262 {
263     0x00000000, 0x00000000, 0x00000000, 0x00000000,
264     0x00000000, 0x00000000, 0x00000000, 0x00000000,
265     0x00000000, 0x00000000, 0x00000000, 0x00000000,
266     0x00000000, 0x00000000, 0x00000000, 0x00000000,
267     0x00000000, 0x00000000, 0x00000000, 0x00000000,
268     0x00000000, 0x00000000, 0x00000000, 0x00000000,
269     0x00000000, 0x00000000, 0x00000000, 0x00000000,
270     0x00000000, 0x00000000, 0x00000000, 0x00000000,
271     0x00000080, 0x00000100, 0x00000200, 0x00000100,
272     0x00000100, 0x00000100, 0x00000100, 0x00000100,
273     0x00000100, 0x00000100, 0x00000002, 0x00000100,
274     0x00000040, 0x00000100, 0x00000004, 0x00000000,
275     0x00000100, 0x00000100, 0x00000100, 0x00000100,
276     0x00000100, 0x00000100, 0x00000100, 0x00000100,
277     0x00000100, 0x00000100, 0x00000010, 0x00000020,
278     0x00000000, 0x00000100, 0x00000000, 0x00000001,
279     0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
280     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
281     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
282     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
283     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
284     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
285     0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
286     0x00000008, 0x00000100, 0x00000100, 0x00000100,
287     0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
288     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
289     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
290     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
291     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
292     0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
293     0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
294     0x00000000, 0x00000100, 0x00000100
295 };
296
297 static void test_PathIsValidCharA(void)
298 {
299     BOOL ret;
300     unsigned int c;
301
302     /* For whatever reason, PathIsValidCharA and PathAppendA share the same
303      * ordinal number in some native versions. Check this to prevent a crash.
304      */
305     if (!pPathIsValidCharA || pPathIsValidCharA == (void*)pPathAppendA)
306     {
307         win_skip("PathIsValidCharA isn't available\n");
308         return;
309     }
310
311     for (c = 0; c < 0x7f; c++)
312     {
313         ret = pPathIsValidCharA( c, ~0U );
314         ok ( ret || !SHELL_charclass[c], "PathIsValidCharA failed: 0x%02x got 0x%08x\n", c, ret );
315     }
316
317     for (c = 0x7f; c <= 0xff; c++)
318     {
319         ret = pPathIsValidCharA( c, ~0U );
320         ok ( ret, "PathIsValidCharA failed: 0x%02x got 0x%08x\n", c, ret );
321     }
322 }
323
324 static void test_PathIsValidCharW(void)
325 {
326     BOOL ret;
327     unsigned int c;
328
329     if (!pPathIsValidCharW)
330     {
331         win_skip("PathIsValidCharW isn't available\n");
332         return;
333     }
334
335     for (c = 0; c < 0x7f; c++)
336     {
337         ret = pPathIsValidCharW( c, ~0U );
338         ok ( ret || !SHELL_charclass[c], "PathIsValidCharW failed: 0x%02x got 0x%08x\n", c, ret );
339     }
340
341     for (c = 0x007f; c <= 0xffff; c++)
342     {
343         ret = pPathIsValidCharW( c, ~0U );
344         ok ( ret, "PathIsValidCharW failed: 0x%02x got 0x%08x\n", c, ret );
345     }
346 }
347
348 static void test_PathMakePretty(void)
349 {
350    char buff[MAX_PATH];
351
352    ok (PathMakePrettyA(NULL) == FALSE, "PathMakePretty: NULL path succeeded\n");
353    buff[0] = '\0';
354    ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Empty path failed\n");
355
356    strcpy(buff, "C:\\A LONG FILE NAME WITH \\SPACES.TXT");
357    ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Long UC name failed\n");
358    ok (strcmp(buff, "C:\\a long file name with \\spaces.txt") == 0,
359        "PathMakePretty: Long UC name not changed\n");
360
361    strcpy(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT");
362    ok (PathMakePrettyA(buff) == FALSE, "PathMakePretty: Long MC name succeeded\n");
363    ok (strcmp(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT") == 0,
364        "PathMakePretty: Failed but modified path\n");
365
366    strcpy(buff, "TEST");
367    ok (PathMakePrettyA(buff) == TRUE,  "PathMakePretty: Short name failed\n");
368    ok (strcmp(buff, "Test") == 0,  "PathMakePretty: 1st char lowercased %s\n", buff);
369 }
370
371 static void test_PathMatchSpec(void)
372 {
373     static const char file[] = "c:\\foo\\bar\\filename.ext";
374     static const char spec1[] = ".ext";
375     static const char spec2[] = "*.ext";
376     static const char spec3[] = "*.ext ";
377     static const char spec4[] = "  *.ext";
378     static const char spec5[] = "* .ext";
379     static const char spec6[] = "*. ext";
380     static const char spec7[] = "* . ext";
381     static const char spec8[] = "*.e?t";
382     static const char spec9[] = "filename.ext";
383     static const char spec10[] = "*bar\\filename.ext";
384     static const char spec11[] = " foo; *.ext";
385     static const char spec12[] = "*.ext;*.bar";
386     static const char spec13[] = "*bar*";
387
388     ok (PathMatchSpecA(file, spec1) == FALSE, "PathMatchSpec: Spec1 failed\n");
389     ok (PathMatchSpecA(file, spec2) == TRUE, "PathMatchSpec: Spec2 failed\n");
390     ok (PathMatchSpecA(file, spec3) == FALSE, "PathMatchSpec: Spec3 failed\n");
391     ok (PathMatchSpecA(file, spec4) == TRUE, "PathMatchSpec: Spec4 failed\n");
392     todo_wine ok (PathMatchSpecA(file, spec5) == TRUE, "PathMatchSpec: Spec5 failed\n");
393     todo_wine ok (PathMatchSpecA(file, spec6) == TRUE, "PathMatchSpec: Spec6 failed\n");
394     ok (PathMatchSpecA(file, spec7) == FALSE, "PathMatchSpec: Spec7 failed\n");
395     ok (PathMatchSpecA(file, spec8) == TRUE, "PathMatchSpec: Spec8 failed\n");
396     ok (PathMatchSpecA(file, spec9) == FALSE, "PathMatchSpec: Spec9 failed\n");
397     ok (PathMatchSpecA(file, spec10) == TRUE, "PathMatchSpec: Spec10 failed\n");
398     ok (PathMatchSpecA(file, spec11) == TRUE, "PathMatchSpec: Spec11 failed\n");
399     ok (PathMatchSpecA(file, spec12) == TRUE, "PathMatchSpec: Spec12 failed\n");
400     ok (PathMatchSpecA(file, spec13) == TRUE, "PathMatchSpec: Spec13 failed\n");
401 }
402
403 static void test_PathCombineW(void)
404 {
405     LPWSTR wszString, wszString2;
406     WCHAR wbuf[MAX_PATH+1], wstr1[MAX_PATH] = {'C',':','\\',0}, wstr2[MAX_PATH];
407     static const WCHAR expout[] = {'C',':','\\','A','A',0};
408     int i;
409
410     if (!pPathCombineW)
411     {
412         win_skip("PathCombineW isn't available\n");
413         return;
414     }
415
416     wszString2 = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
417
418     /* NULL test */
419     wszString = pPathCombineW(NULL, NULL, NULL);
420     ok (wszString == NULL, "Expected a NULL return\n");
421
422     /* Some NULL */
423     wszString2[0] = 'a';
424     wszString = pPathCombineW(wszString2, NULL, NULL);
425     ok (wszString == NULL ||
426         broken(wszString[0] == 'a'), /* Win95 and some W2K */
427         "Expected a NULL return\n");
428     ok (wszString2[0] == 0 ||
429         broken(wszString2[0] == 'a'), /* Win95 and some W2K */
430         "Destination string not empty\n");
431
432     HeapFree(GetProcessHeap(), 0, wszString2);
433
434     /* overflow test */
435     wstr2[0] = wstr2[1] = wstr2[2] = 'A';
436     for (i=3; i<MAX_PATH/2; i++)
437         wstr1[i] = wstr2[i] = 'A';
438     wstr1[(MAX_PATH/2) - 1] = wstr2[MAX_PATH/2] = 0;
439     memset(wbuf, 0xbf, sizeof(wbuf));
440
441     wszString = pPathCombineW(wbuf, wstr1, wstr2);
442     ok(wszString == NULL, "Expected a NULL return\n");
443     ok(wbuf[0] == 0 ||
444        broken(wbuf[0] == 0xbfbf), /* Win95 and some W2K */
445        "Buffer contains data\n");
446
447     /* PathCombineW can be used in place */
448     wstr1[3] = 0;
449     wstr2[2] = 0;
450     ok(PathCombineW(wstr1, wstr1, wstr2) == wstr1, "Expected a wstr1 return\n");
451     ok(StrCmpW(wstr1, expout) == 0, "Unexpected PathCombine output\n");
452 }
453
454
455 #define LONG_LEN (MAX_PATH * 2)
456 #define HALF_LEN (MAX_PATH / 2 + 1)
457
458 static void test_PathCombineA(void)
459 {
460     LPSTR str;
461     char dest[MAX_PATH];
462     char too_long[LONG_LEN];
463     char one[HALF_LEN], two[HALF_LEN];
464
465     /* try NULL dest */
466     SetLastError(0xdeadbeef);
467     str = PathCombineA(NULL, "C:\\", "one\\two\\three");
468     ok(str == NULL, "Expected NULL, got %p\n", str);
469     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
470
471     /* try NULL dest and NULL directory */
472     SetLastError(0xdeadbeef);
473     str = PathCombineA(NULL, NULL, "one\\two\\three");
474     ok(str == NULL, "Expected NULL, got %p\n", str);
475     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
476
477     /* try all NULL*/
478     SetLastError(0xdeadbeef);
479     str = PathCombineA(NULL, NULL, NULL);
480     ok(str == NULL, "Expected NULL, got %p\n", str);
481     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
482
483     /* try NULL file part */
484     SetLastError(0xdeadbeef);
485     lstrcpyA(dest, "control");
486     str = PathCombineA(dest, "C:\\", NULL);
487     ok(str == dest, "Expected str == dest, got %p\n", str);
488     ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
489     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
490
491     /* try empty file part */
492     SetLastError(0xdeadbeef);
493     lstrcpyA(dest, "control");
494     str = PathCombineA(dest, "C:\\", "");
495     ok(str == dest, "Expected str == dest, got %p\n", str);
496     ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
497     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
498
499     /* try empty directory and file part */
500     SetLastError(0xdeadbeef);
501     lstrcpyA(dest, "control");
502     str = PathCombineA(dest, "", "");
503     ok(str == dest, "Expected str == dest, got %p\n", str);
504     ok(!lstrcmp(str, "\\") ||
505        broken(!lstrcmp(str, "control")), /* Win95 and some W2K */
506        "Expected \\, got %s\n", str);
507     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
508
509     /* try NULL directory */
510     SetLastError(0xdeadbeef);
511     lstrcpyA(dest, "control");
512     str = PathCombineA(dest, NULL, "one\\two\\three");
513     ok(str == dest, "Expected str == dest, got %p\n", str);
514     ok(!lstrcmp(str, "one\\two\\three"), "Expected one\\two\\three, got %s\n", str);
515     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
516
517     /* try NULL directory and empty file part */
518     SetLastError(0xdeadbeef);
519     lstrcpyA(dest, "control");
520     str = PathCombineA(dest, NULL, "");
521     ok(str == dest, "Expected str == dest, got %p\n", str);
522     ok(!lstrcmp(str, "\\") ||
523        broken(!lstrcmp(str, "one\\two\\three")), /* Win95 and some W2K */
524        "Expected \\, got %s\n", str);
525     ok(GetLastError() == 0xdeadbeef ||
526        broken(GetLastError() == ERROR_INVALID_PARAMETER), /* Win95 */
527        "Expected 0xdeadbeef, got %d\n", GetLastError());
528
529     /* try NULL directory and file part */
530     SetLastError(0xdeadbeef);
531     lstrcpyA(dest, "control");
532     str = PathCombineA(dest, NULL, NULL);
533     ok(str == NULL ||
534        broken(str != NULL), /* Win95 and some W2K */
535        "Expected str == NULL, got %p\n", str);
536     ok(lstrlenA(dest) == 0 ||
537        broken(!lstrcmp(dest, "control")), /* Win95 and some W2K */
538        "Expected 0 length, got %i\n", lstrlenA(dest));
539     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
540
541     /* try directory without backslash */
542     SetLastError(0xdeadbeef);
543     lstrcpyA(dest, "control");
544     str = PathCombineA(dest, "C:", "one\\two\\three");
545     ok(str == dest, "Expected str == dest, got %p\n", str);
546     ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
547     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
548
549     /* try directory with backslash */
550     SetLastError(0xdeadbeef);
551     lstrcpyA(dest, "control");
552     str = PathCombineA(dest, "C:\\", "one\\two\\three");
553     ok(str == dest, "Expected str == dest, got %p\n", str);
554     ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
555     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
556
557     /* try directory with backslash and file with prepended backslash */
558     SetLastError(0xdeadbeef);
559     lstrcpyA(dest, "control");
560     str = PathCombineA(dest, "C:\\", "\\one\\two\\three");
561     ok(str == dest, "Expected str == dest, got %p\n", str);
562     ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
563     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
564
565     /* try previous test, with backslash appended as well */
566     SetLastError(0xdeadbeef);
567     lstrcpyA(dest, "control");
568     str = PathCombineA(dest, "C:\\", "\\one\\two\\three\\");
569     ok(str == dest, "Expected str == dest, got %p\n", str);
570     ok(!lstrcmp(str, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str);
571     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
572
573     /* try a relative directory */
574     SetLastError(0xdeadbeef);
575     lstrcpyA(dest, "control");
576     str = PathCombineA(dest, "relative\\dir", "\\one\\two\\three\\");
577     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
578     /* Vista fails which probably makes sense as PathCombineA expects an absolute dir */
579     if (str)
580     {
581         ok(str == dest, "Expected str == dest, got %p\n", str);
582         ok(!lstrcmp(str, "one\\two\\three\\"), "Expected one\\two\\three\\, got %s\n", str);
583     }
584
585     /* try forward slashes */
586     SetLastError(0xdeadbeef);
587     lstrcpyA(dest, "control");
588     str = PathCombineA(dest, "C:\\", "one/two/three\\");
589     ok(str == dest, "Expected str == dest, got %p\n", str);
590     ok(!lstrcmp(str, "C:\\one/two/three\\"), "Expected one/two/three\\, got %s\n", str);
591     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
592
593     /* try a really weird directory */
594     SetLastError(0xdeadbeef);
595     lstrcpyA(dest, "control");
596     str = PathCombineA(dest, "C:\\/\\/", "\\one\\two\\three\\");
597     ok(str == dest, "Expected str == dest, got %p\n", str);
598     ok(!lstrcmp(str, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str);
599     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
600
601     /* try periods */
602     SetLastError(0xdeadbeef);
603     lstrcpyA(dest, "control");
604     str = PathCombineA(dest, "C:\\", "one\\..\\two\\.\\three");
605     ok(str == dest, "Expected str == dest, got %p\n", str);
606     ok(!lstrcmp(str, "C:\\two\\three"), "Expected C:\\two\\three, got %s\n", str);
607     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
608
609     /* try .. as file */
610     /* try forward slashes */
611     SetLastError(0xdeadbeef);
612     lstrcpyA(dest, "control");
613     str = PathCombineA(dest, "C:\\", "..");
614     ok(str == dest, "Expected str == dest, got %p\n", str);
615     ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
616     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
617
618     memset(too_long, 'a', LONG_LEN);
619     too_long[LONG_LEN - 1] = '\0';
620
621     /* try a file longer than MAX_PATH */
622     SetLastError(0xdeadbeef);
623     lstrcpyA(dest, "control");
624     str = PathCombineA(dest, "C:\\", too_long);
625     ok(str == NULL, "Expected str == NULL, got %p\n", str);
626     ok(lstrlenA(dest) == 0 ||
627        broken(!lstrcmp(dest, "control")), /* Win95 and some W2K */
628        "Expected 0 length, got %i\n", lstrlenA(dest));
629     todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
630
631     /* try a directory longer than MAX_PATH */
632     SetLastError(0xdeadbeef);
633     lstrcpyA(dest, "control");
634     str = PathCombineA(dest, too_long, "one\\two\\three");
635     ok(str == NULL, "Expected str == NULL, got %p\n", str);
636     ok(lstrlenA(dest) == 0 ||
637        broken(!lstrcmp(dest, "control")), /* Win95 and some W2K */
638        "Expected 0 length, got %i\n", lstrlenA(dest));
639     todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
640
641     memset(one, 'b', HALF_LEN);
642     memset(two, 'c', HALF_LEN);
643     one[HALF_LEN - 1] = '\0';
644     two[HALF_LEN - 1] = '\0';
645
646     /* destination string is longer than MAX_PATH, but not the constituent parts */
647     SetLastError(0xdeadbeef);
648     lstrcpyA(dest, "control");
649     str = PathCombineA(dest, one, two);
650     ok(str == NULL, "Expected str == NULL, got %p\n", str);
651     ok(lstrlenA(dest) == 0 ||
652        broken(!lstrcmp(dest, "control")), /* Win95 and some W2K */
653        "Expected 0 length, got %i\n", lstrlenA(dest));
654     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
655 }
656
657 static void test_PathAddBackslash(void)
658 {
659     LPSTR str;
660     char path[MAX_PATH];
661     char too_long[LONG_LEN];
662
663     /* try a NULL path */
664     SetLastError(0xdeadbeef);
665     str = PathAddBackslashA(NULL);
666     ok(str == NULL, "Expected str == NULL, got %p\n", str);
667     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
668
669     /* try an empty path */
670     path[0] = '\0';
671     SetLastError(0xdeadbeef);
672     str = PathAddBackslashA(path);
673     ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
674     ok(lstrlenA(path) == 0, "Expected empty string, got %i\n", lstrlenA(path));
675     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
676
677     /* try a relative path */
678     lstrcpyA(path, "one\\two");
679     SetLastError(0xdeadbeef);
680     str = PathAddBackslashA(path);
681     ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
682     ok(!lstrcmp(path, "one\\two\\"), "Expected one\\two\\, got %s\n", path);
683     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
684
685     /* try periods */
686     lstrcpyA(path, "one\\..\\two");
687     SetLastError(0xdeadbeef);
688     str = PathAddBackslashA(path);
689     ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
690     ok(!lstrcmp(path, "one\\..\\two\\"), "Expected one\\..\\two\\, got %s\n", path);
691     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
692
693     /* try just a space */
694     lstrcpyA(path, " ");
695     SetLastError(0xdeadbeef);
696     str = PathAddBackslashA(path);
697     ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
698     ok(!lstrcmp(path, " \\"), "Expected  \\, got %s\n", path);
699     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
700
701     /* path already has backslash */
702     lstrcpyA(path, "C:\\one\\");
703     SetLastError(0xdeadbeef);
704     str = PathAddBackslashA(path);
705     ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
706     ok(!lstrcmp(path, "C:\\one\\"), "Expected C:\\one\\, got %s\n", path);
707     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
708
709     memset(too_long, 'a', LONG_LEN);
710     too_long[LONG_LEN - 1] = '\0';
711
712     /* path is longer than MAX_PATH */
713     SetLastError(0xdeadbeef);
714     str = PathAddBackslashA(too_long);
715     ok(str == NULL, "Expected str == NULL, got %p\n", str);
716     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
717 }
718
719 static void test_PathAppendA(void)
720 {
721     char path[MAX_PATH];
722     char too_long[LONG_LEN];
723     char half[HALF_LEN];
724     BOOL res;
725
726     lstrcpy(path, "C:\\one");
727
728     /* try NULL pszMore */
729     SetLastError(0xdeadbeef);
730     res = PathAppendA(path, NULL);
731     ok(!res, "Expected failure\n");
732     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
733     ok(!lstrcmp(path, "C:\\one"), "Expected C:\\one, got %s\n", path);
734
735     /* try empty pszMore */
736     SetLastError(0xdeadbeef);
737     res = PathAppendA(path, "");
738     ok(res, "Expected success\n");
739     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
740     ok(!lstrcmp(path, "C:\\one"), "Expected C:\\one, got %s\n", path);
741
742     /* try NULL pszPath */
743     SetLastError(0xdeadbeef);
744     res = PathAppendA(NULL, "two\\three");
745     ok(!res, "Expected failure\n");
746     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
747
748     /* try empty pszPath */
749     path[0] = '\0';
750     SetLastError(0xdeadbeef);
751     res = PathAppendA(path, "two\\three");
752     ok(res, "Expected success\n");
753     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
754     ok(!lstrcmp(path, "two\\three"), "Expected \\two\\three, got %s\n", path);
755
756     /* try empty pszPath and empty pszMore */
757     path[0] = '\0';
758     SetLastError(0xdeadbeef);
759     res = PathAppendA(path, "");
760     ok(res, "Expected success\n");
761     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
762     ok(!lstrcmp(path, "\\"), "Expected \\, got %s\n", path);
763
764     /* try legit params */
765     lstrcpy(path, "C:\\one");
766     SetLastError(0xdeadbeef);
767     res = PathAppendA(path, "two\\three");
768     ok(res, "Expected success\n");
769     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
770     ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
771
772     /* try pszPath with backslash after it */
773     lstrcpy(path, "C:\\one\\");
774     SetLastError(0xdeadbeef);
775     res = PathAppendA(path, "two\\three");
776     ok(res, "Expected success\n");
777     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
778     ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
779
780     /* try pszMore with backslash before it */
781     lstrcpy(path, "C:\\one");
782     SetLastError(0xdeadbeef);
783     res = PathAppendA(path, "\\two\\three");
784     ok(res, "Expected success\n");
785     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
786     ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
787
788     /* try pszMore with backslash after it */
789     lstrcpy(path, "C:\\one");
790     SetLastError(0xdeadbeef);
791     res = PathAppendA(path, "two\\three\\");
792     ok(res, "Expected success\n");
793     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
794     ok(!lstrcmp(path, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", path);
795
796     /* try spaces in pszPath */
797     lstrcpy(path, "C: \\ one ");
798     SetLastError(0xdeadbeef);
799     res = PathAppendA(path, "two\\three");
800     ok(res, "Expected success\n");
801     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
802     ok(!lstrcmp(path, "C: \\ one \\two\\three"), "Expected C: \\ one \\two\\three, got %s\n", path);
803
804     /* try spaces in pszMore */
805     lstrcpy(path, "C:\\one");
806     SetLastError(0xdeadbeef);
807     res = PathAppendA(path, " two \\ three ");
808     ok(res, "Expected success\n");
809     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
810     ok(!lstrcmp(path, "C:\\one\\ two \\ three "), "Expected 'C:\\one\\ two \\ three ', got %s\n", path);
811
812     /* pszPath is too long */
813     memset(too_long, 'a', LONG_LEN);
814     too_long[LONG_LEN - 1] = '\0';
815     SetLastError(0xdeadbeef);
816     res = PathAppendA(too_long, "two\\three");
817     ok(!res, "Expected failure\n");
818     todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
819     ok(lstrlen(too_long) == 0 ||
820        broken(lstrlen(too_long) == (LONG_LEN - 1)), /* Win95 and some W2K */
821        "Expected length of too_long to be zero, got %i\n", lstrlen(too_long));
822
823     /* pszMore is too long */
824     lstrcpy(path, "C:\\one");
825     memset(too_long, 'a', LONG_LEN);
826     too_long[LONG_LEN - 1] = '\0';
827     SetLastError(0xdeadbeef);
828     res = PathAppendA(path, too_long);
829     ok(!res, "Expected failure\n");
830     todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
831     ok(lstrlen(path) == 0 ||
832        broken(!lstrcmp(path, "C:\\one")), /* Win95 and some W2K */
833        "Expected length of path to be zero, got %i\n", lstrlen(path));
834
835     /* both params combined are too long */
836     memset(path, 'a', HALF_LEN);
837     path[HALF_LEN - 1] = '\0';
838     memset(half, 'b', HALF_LEN);
839     half[HALF_LEN - 1] = '\0';
840     SetLastError(0xdeadbeef);
841     res = PathAppendA(path, half);
842     ok(!res, "Expected failure\n");
843     ok(lstrlen(path) == 0 ||
844        broken(lstrlen(path) == (HALF_LEN - 1)), /* Win95 and some W2K */
845        "Expected length of path to be zero, got %i\n", lstrlen(path));
846     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
847 }
848
849 static void test_PathCanonicalizeA(void)
850 {
851     char dest[LONG_LEN + MAX_PATH];
852     char too_long[LONG_LEN];
853     BOOL res;
854
855     /* try a NULL source */
856     lstrcpy(dest, "test");
857     SetLastError(0xdeadbeef);
858     res = PathCanonicalizeA(dest, NULL);
859     ok(!res, "Expected failure\n");
860     ok(GetLastError() == ERROR_INVALID_PARAMETER, 
861        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
862     ok(dest[0] == 0 || !lstrcmp(dest, "test"),
863        "Expected either an empty string (Vista) or test, got %s\n", dest);
864
865     /* try an empty source */
866     lstrcpy(dest, "test");
867     SetLastError(0xdeadbeef);
868     res = PathCanonicalizeA(dest, "");
869     ok(res, "Expected success\n");
870     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
871     ok(!lstrcmp(dest, "\\") ||
872        broken(!lstrcmp(dest, "test")), /* Win95 and some W2K */
873        "Expected \\, got %s\n", dest);
874
875     /* try a NULL dest */
876     SetLastError(0xdeadbeef);
877     res = PathCanonicalizeA(NULL, "C:\\");
878     ok(!res, "Expected failure\n");
879     ok(GetLastError() == ERROR_INVALID_PARAMETER, 
880        "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
881
882     /* try empty dest */
883     dest[0] = '\0';
884     SetLastError(0xdeadbeef);
885     res = PathCanonicalizeA(dest, "C:\\");
886     ok(res, "Expected success\n");
887     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
888     ok(!lstrcmp(dest, "C:\\"), "Expected C:\\, got %s\n", dest);
889
890     /* try non-empty dest */
891     lstrcpy(dest, "test");
892     SetLastError(0xdeadbeef);
893     res = PathCanonicalizeA(dest, "C:\\");
894     ok(res, "Expected success\n");
895     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
896     ok(!lstrcmp(dest, "C:\\"), "Expected C:\\, got %s\n", dest);
897
898     /* try a space for source */
899     lstrcpy(dest, "test");
900     SetLastError(0xdeadbeef);
901     res = PathCanonicalizeA(dest, " ");
902     ok(res, "Expected success\n");
903     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
904     ok(!lstrcmp(dest, " "), "Expected ' ', got %s\n", dest);
905
906     /* try a relative path */
907     lstrcpy(dest, "test");
908     SetLastError(0xdeadbeef);
909     res = PathCanonicalizeA(dest, "one\\two");
910     ok(res, "Expected success\n");
911     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
912     ok(!lstrcmp(dest, "one\\two"), "Expected one\\two, got %s\n", dest);
913
914     /* try current dir and previous dir */
915     lstrcpy(dest, "test");
916     SetLastError(0xdeadbeef);
917     res = PathCanonicalizeA(dest, "C:\\one\\.\\..\\two\\three\\..");
918     ok(res, "Expected success\n");
919     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
920     ok(!lstrcmp(dest, "C:\\two"), "Expected C:\\two, got %s\n", dest);
921
922     /* try simple forward slashes */
923     lstrcpy(dest, "test");
924     SetLastError(0xdeadbeef);
925     res = PathCanonicalizeA(dest, "C:\\one/two/three\\four/five\\six");
926     ok(res, "Expected success\n");
927     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
928     ok(!lstrcmp(dest, "C:\\one/two/three\\four/five\\six"),
929        "Expected C:\\one/two/three\\four/five\\six, got %s\n", dest);
930
931     /* try simple forward slashes with same dir */
932     lstrcpy(dest, "test");
933     SetLastError(0xdeadbeef);
934     res = PathCanonicalizeA(dest, "C:\\one/.\\two");
935     ok(res, "Expected success\n");
936     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
937     ok(!lstrcmp(dest, "C:\\one/.\\two"), "Expected C:\\one/.\\two, got %s\n", dest);
938
939     /* try simple forward slashes with change dir */
940     lstrcpy(dest, "test");
941     SetLastError(0xdeadbeef);
942     res = PathCanonicalizeA(dest, "C:\\one/.\\two\\..");
943     ok(res, "Expected success\n");
944     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
945     ok(!lstrcmp(dest, "C:\\one/.") ||
946        !lstrcmp(dest, "C:\\one/"), /* Vista */
947        "Expected \"C:\\one/.\" or \"C:\\one/\", got \"%s\"\n", dest);
948
949     /* try forward slashes with change dirs
950      * NOTE: if there is a forward slash in between two backslashes,
951      * everything in between the two backslashes is considered on dir
952      */
953     lstrcpy(dest, "test");
954     SetLastError(0xdeadbeef);
955     res = PathCanonicalizeA(dest, "C:\\one/.\\..\\two/three\\..\\four/.five");
956     ok(res, "Expected success\n");
957     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
958     ok(!lstrcmp(dest, "C:\\four/.five"), "Expected C:\\four/.five, got %s\n", dest);
959
960     /* try src is too long */
961     memset(too_long, 'a', LONG_LEN);
962     too_long[LONG_LEN - 1] = '\0';
963     lstrcpy(dest, "test");
964     SetLastError(0xdeadbeef);
965     res = PathCanonicalizeA(dest, too_long);
966     ok(!res ||
967        broken(res), /* Win95, some W2K and XP-SP1 */
968        "Expected failure\n");
969     todo_wine
970     {
971         ok(GetLastError() == 0xdeadbeef || GetLastError() == ERROR_FILENAME_EXCED_RANGE /* Vista */,
972         "Expected 0xdeadbeef or ERROR_FILENAME_EXCED_RANGE, got %d\n", GetLastError());
973     }
974     ok(lstrlen(too_long) == LONG_LEN - 1, "Expected length LONG_LEN - 1, got %i\n", lstrlen(too_long));
975 }
976
977 static void test_PathFindExtensionA(void)
978 {
979     LPSTR ext;
980     char path[MAX_PATH];
981     char too_long[LONG_LEN];
982
983     /* try a NULL path */
984     SetLastError(0xdeadbeef);
985     ext = PathFindExtensionA(NULL);
986     ok(ext == NULL, "Expected NULL, got %p\n", ext);
987     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
988
989     /* try an empty path */
990     path[0] = '\0';
991     SetLastError(0xdeadbeef);
992     ext = PathFindExtensionA(path);
993     ok(ext == path, "Expected ext == path, got %p\n", ext);
994     ok(lstrlen(ext) == 0, "Expected length 0, got %i\n", lstrlen(ext));
995     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
996
997     /* try a path without an extension */
998     lstrcpy(path, "file");
999     SetLastError(0xdeadbeef);
1000     ext = PathFindExtensionA(path);
1001     ok(ext == path + lstrlen(path), "Expected ext == path, got %p\n", ext);
1002     ok(lstrlen(ext) == 0, "Expected length 0, got %i\n", lstrlen(ext));
1003     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1004
1005     /* try a path with an extension */
1006     lstrcpy(path, "file.txt");
1007     SetLastError(0xdeadbeef);
1008     ext = PathFindExtensionA(path);
1009     ok(ext == path + lstrlen("file"),
1010        "Expected ext == path + lstrlen(\"file\"), got %p\n", ext);
1011     ok(!lstrcmp(ext, ".txt"), "Expected .txt, got %s\n", ext);
1012     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1013
1014     /* try a path with two extensions */
1015     lstrcpy(path, "file.txt.doc");
1016     SetLastError(0xdeadbeef);
1017     ext = PathFindExtensionA(path);
1018     ok(ext == path + lstrlen("file.txt"),
1019        "Expected ext == path + lstrlen(\"file.txt\"), got %p\n", ext);
1020     ok(!lstrcmp(ext, ".doc"), "Expected .txt, got %s\n", ext);
1021     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1022
1023     /* try a path longer than MAX_PATH without an extension*/
1024     memset(too_long, 'a', LONG_LEN);
1025     too_long[LONG_LEN - 1] = '\0';
1026     SetLastError(0xdeadbeef);
1027     ext = PathFindExtensionA(too_long);
1028     ok(ext == too_long + LONG_LEN - 1, "Expected ext == too_long + LONG_LEN - 1, got %p\n", ext);
1029     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1030
1031     /* try a path longer than MAX_PATH with an extension*/
1032     memset(too_long, 'a', LONG_LEN);
1033     too_long[LONG_LEN - 1] = '\0';
1034     lstrcpy(too_long + 300, ".abcde");
1035     too_long[lstrlen(too_long)] = 'a';
1036     SetLastError(0xdeadbeef);
1037     ext = PathFindExtensionA(too_long);
1038     ok(ext == too_long + 300, "Expected ext == too_long + 300, got %p\n", ext);
1039     ok(lstrlen(ext) == LONG_LEN - 301, "Expected LONG_LEN - 301, got %i\n", lstrlen(ext));
1040     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1041 }
1042
1043 static void test_PathBuildRootA(void)
1044 {
1045     LPSTR root;
1046     char path[10];
1047     char root_expected[26][4];
1048     char drive;
1049     int j;
1050
1051     /* set up the expected paths */
1052     for (drive = 'A'; drive <= 'Z'; drive++)
1053         sprintf(root_expected[drive - 'A'], "%c:\\", drive);
1054
1055     /* test the expected values */
1056     for (j = 0; j < 26; j++)
1057     {
1058         SetLastError(0xdeadbeef);
1059         lstrcpy(path, "aaaaaaaaa");
1060         root = PathBuildRootA(path, j);
1061         ok(root == path, "Expected root == path, got %p\n", root);
1062         ok(!lstrcmp(root, root_expected[j]), "Expected %s, got %s\n", root_expected[j], root);
1063         ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1064     }
1065
1066     /* test a negative drive number */
1067     SetLastError(0xdeadbeef);
1068     lstrcpy(path, "aaaaaaaaa");
1069     root = PathBuildRootA(path, -1);
1070     ok(root == path, "Expected root == path, got %p\n", root);
1071     ok(!lstrcmp(path, "aaaaaaaaa") ||
1072        lstrlenA(path) == 0, /* Vista */
1073        "Expected aaaaaaaaa or empty string, got %s\n", path);
1074     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1075
1076     /* test a drive number greater than 25 */
1077     SetLastError(0xdeadbeef);
1078     lstrcpy(path, "aaaaaaaaa");
1079     root = PathBuildRootA(path, 26);
1080     ok(root == path, "Expected root == path, got %p\n", root);
1081     ok(!lstrcmp(path, "aaaaaaaaa") ||
1082        lstrlenA(path) == 0, /* Vista */
1083        "Expected aaaaaaaaa or empty string, got %s\n", path);
1084     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1085
1086     /* length of path is less than 4 */
1087     SetLastError(0xdeadbeef);
1088     lstrcpy(path, "aa");
1089     root = PathBuildRootA(path, 0);
1090     ok(root == path, "Expected root == path, got %p\n", root);
1091     ok(!lstrcmp(path, "A:\\"), "Expected A:\\, got %s\n", path);
1092     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1093
1094     /* path is NULL */
1095     SetLastError(0xdeadbeef);
1096     root = PathBuildRootA(NULL, 0);
1097     ok(root == NULL, "Expected root == NULL, got %p\n", root);
1098     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1099 }
1100
1101 static void test_PathCommonPrefixA(void)
1102 {
1103     char path1[MAX_PATH], path2[MAX_PATH];
1104     char out[MAX_PATH];
1105     int count;
1106
1107     /* test NULL path1 */
1108     SetLastError(0xdeadbeef);
1109     lstrcpy(path2, "C:\\");
1110     lstrcpy(out, "aaa");
1111     count = PathCommonPrefixA(NULL, path2, out);
1112     ok(count == 0, "Expected 0, got %i\n", count);
1113     todo_wine
1114     {
1115         ok(!lstrcmp(out, "aaa"), "Expected aaa, got %s\n", out);
1116     }
1117     ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1118     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1119
1120     /* test NULL path2 */
1121     SetLastError(0xdeadbeef);
1122     lstrcpy(path1, "C:\\");
1123     lstrcpy(out, "aaa");
1124     count = PathCommonPrefixA(path1, NULL, out);
1125     ok(count == 0, "Expected 0, got %i\n", count);
1126     todo_wine
1127     {
1128         ok(!lstrcmp(out, "aaa"), "Expected aaa, got %s\n", out);
1129     }
1130     ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1131     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1132
1133     /* test empty path1 */
1134     SetLastError(0xdeadbeef);
1135     path1[0] = '\0';
1136     lstrcpy(path2, "C:\\");
1137     lstrcpy(out, "aaa");
1138     count = PathCommonPrefixA(path1, path2, out);
1139     ok(count == 0, "Expected 0, got %i\n", count);
1140     ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1141     ok(lstrlen(path1) == 0, "Expected 0 length path1, got %i\n", lstrlen(path1));
1142     ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1143     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1144
1145     /* test empty path1 */
1146     SetLastError(0xdeadbeef);
1147     path2[0] = '\0';
1148     lstrcpy(path1, "C:\\");
1149     lstrcpy(out, "aaa");
1150     count = PathCommonPrefixA(path1, path2, out);
1151     ok(count == 0, "Expected 0, got %i\n", count);
1152     ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1153     ok(lstrlen(path2) == 0, "Expected 0 length path2, got %i\n", lstrlen(path2));
1154     ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1155     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1156
1157     /* paths are legit, out is NULL */
1158     SetLastError(0xdeadbeef);
1159     lstrcpy(path1, "C:\\");
1160     lstrcpy(path2, "C:\\");
1161     count = PathCommonPrefixA(path1, path2, NULL);
1162     ok(count == 3, "Expected 3, got %i\n", count);
1163     ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1164     ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1165     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1166
1167     /* all parameters legit */
1168     SetLastError(0xdeadbeef);
1169     lstrcpy(path1, "C:\\");
1170     lstrcpy(path2, "C:\\");
1171     lstrcpy(out, "aaa");
1172     count = PathCommonPrefixA(path1, path2, out);
1173     ok(count == 3, "Expected 3, got %i\n", count);
1174     ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1175     ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1176     ok(!lstrcmp(out, "C:\\"), "Expected C:\\, got %s\n", out);
1177     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1178
1179     /* path1 and path2 not the same, but common prefix */
1180     SetLastError(0xdeadbeef);
1181     lstrcpy(path1, "C:\\one\\two");
1182     lstrcpy(path2, "C:\\one\\three");
1183     lstrcpy(out, "aaa");
1184     count = PathCommonPrefixA(path1, path2, out);
1185     ok(count == 6, "Expected 6, got %i\n", count);
1186     ok(!lstrcmp(path1, "C:\\one\\two"), "Expected C:\\one\\two, got %s\n", path1);
1187     ok(!lstrcmp(path2, "C:\\one\\three"), "Expected C:\\one\\three, got %s\n", path2);
1188     ok(!lstrcmp(out, "C:\\one"), "Expected C:\\one, got %s\n", out);
1189     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1190
1191     /* try . prefix */
1192     SetLastError(0xdeadbeef);
1193     lstrcpy(path1, "one\\.two");
1194     lstrcpy(path2, "one\\.three");
1195     lstrcpy(out, "aaa");
1196     count = PathCommonPrefixA(path1, path2, out);
1197     ok(count == 3, "Expected 3, got %i\n", count);
1198     ok(!lstrcmp(path1, "one\\.two"), "Expected one\\.two, got %s\n", path1);
1199     ok(!lstrcmp(path2, "one\\.three"), "Expected one\\.three, got %s\n", path2);
1200     ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1201     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1202
1203     /* try .. prefix */
1204     SetLastError(0xdeadbeef);
1205     lstrcpy(path1, "one\\..two");
1206     lstrcpy(path2, "one\\..three");
1207     lstrcpy(out, "aaa");
1208     count = PathCommonPrefixA(path1, path2, out);
1209     ok(count == 3, "Expected 3, got %i\n", count);
1210     ok(!lstrcmp(path1, "one\\..two"), "Expected one\\..two, got %s\n", path1);
1211     ok(!lstrcmp(path2, "one\\..three"), "Expected one\\..three, got %s\n", path2);
1212     ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1213     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1214
1215     /* try ... prefix */
1216     SetLastError(0xdeadbeef);
1217     lstrcpy(path1, "one\\...two");
1218     lstrcpy(path2, "one\\...three");
1219     lstrcpy(out, "aaa");
1220     count = PathCommonPrefixA(path1, path2, out);
1221     ok(count == 3, "Expected 3, got %i\n", count);
1222     ok(!lstrcmp(path1, "one\\...two"), "Expected one\\...two, got %s\n", path1);
1223     ok(!lstrcmp(path2, "one\\...three"), "Expected one\\...three, got %s\n", path2);
1224     ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1225     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1226
1227     /* try .\ prefix */
1228     SetLastError(0xdeadbeef);
1229     lstrcpy(path1, "one\\.\\two");
1230     lstrcpy(path2, "one\\.\\three");
1231     lstrcpy(out, "aaa");
1232     count = PathCommonPrefixA(path1, path2, out);
1233     ok(count == 5, "Expected 5, got %i\n", count);
1234     ok(!lstrcmp(path1, "one\\.\\two"), "Expected one\\.\\two, got %s\n", path1);
1235     ok(!lstrcmp(path2, "one\\.\\three"), "Expected one\\.\\three, got %s\n", path2);
1236     ok(!lstrcmp(out, "one\\."), "Expected one\\., got %s\n", out);
1237     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1238
1239     /* try ..\ prefix */
1240     SetLastError(0xdeadbeef);
1241     lstrcpy(path1, "one\\..\\two");
1242     lstrcpy(path2, "one\\..\\three");
1243     lstrcpy(out, "aaa");
1244     count = PathCommonPrefixA(path1, path2, out);
1245     ok(count == 6, "Expected 6, got %i\n", count);
1246     ok(!lstrcmp(path1, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1);
1247     ok(!lstrcmp(path2, "one\\..\\three"), "Expected one\\..\\three, got %s\n", path2);
1248     ok(!lstrcmp(out, "one\\.."), "Expected one\\.., got %s\n", out);
1249     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1250
1251     /* try ...\\ prefix */
1252     SetLastError(0xdeadbeef);
1253     lstrcpy(path1, "one\\...\\two");
1254     lstrcpy(path2, "one\\...\\three");
1255     lstrcpy(out, "aaa");
1256     count = PathCommonPrefixA(path1, path2, out);
1257     ok(count == 7, "Expected 7, got %i\n", count);
1258     ok(!lstrcmp(path1, "one\\...\\two"), "Expected one\\...\\two, got %s\n", path1);
1259     ok(!lstrcmp(path2, "one\\...\\three"), "Expected one\\...\\three, got %s\n", path2);
1260     ok(!lstrcmp(out, "one\\..."), "Expected one\\..., got %s\n", out);
1261     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1262
1263     /* try prefix that is not an msdn labeled prefix type */
1264     SetLastError(0xdeadbeef);
1265     lstrcpy(path1, "same");
1266     lstrcpy(path2, "same");
1267     lstrcpy(out, "aaa");
1268     count = PathCommonPrefixA(path1, path2, out);
1269     ok(count == 4, "Expected 4, got %i\n", count);
1270     ok(!lstrcmp(path1, "same"), "Expected same, got %s\n", path1);
1271     ok(!lstrcmp(path2, "same"), "Expected same, got %s\n", path2);
1272     ok(!lstrcmp(out, "same"), "Expected same, got %s\n", out);
1273     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1274
1275     /* try . after directory */
1276     SetLastError(0xdeadbeef);
1277     lstrcpy(path1, "one\\mid.\\two");
1278     lstrcpy(path2, "one\\mid.\\three");
1279     lstrcpy(out, "aaa");
1280     count = PathCommonPrefixA(path1, path2, out);
1281     ok(count == 8, "Expected 8, got %i\n", count);
1282     ok(!lstrcmp(path1, "one\\mid.\\two"), "Expected one\\mid.\\two, got %s\n", path1);
1283     ok(!lstrcmp(path2, "one\\mid.\\three"), "Expected one\\mid.\\three, got %s\n", path2);
1284     ok(!lstrcmp(out, "one\\mid."), "Expected one\\mid., got %s\n", out);
1285     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1286
1287     /* try . in the middle of a directory */
1288     SetLastError(0xdeadbeef);
1289     lstrcpy(path1, "one\\mid.end\\two");
1290     lstrcpy(path2, "one\\mid.end\\three");
1291     lstrcpy(out, "aaa");
1292     count = PathCommonPrefixA(path1, path2, out);
1293     ok(count == 11, "Expected 11, got %i\n", count);
1294     ok(!lstrcmp(path1, "one\\mid.end\\two"), "Expected one\\mid.end\\two, got %s\n", path1);
1295     ok(!lstrcmp(path2, "one\\mid.end\\three"), "Expected one\\mid.end\\three, got %s\n", path2);
1296     ok(!lstrcmp(out, "one\\mid.end"), "Expected one\\mid.end, got %s\n", out);
1297     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1298
1299     /* try comparing a .. with the expanded path */
1300     SetLastError(0xdeadbeef);
1301     lstrcpy(path1, "one\\..\\two");
1302     lstrcpy(path2, "two");
1303     lstrcpy(out, "aaa");
1304     count = PathCommonPrefixA(path1, path2, out);
1305     ok(count == 0, "Expected 0, got %i\n", count);
1306     ok(!lstrcmp(path1, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1);
1307     ok(!lstrcmp(path2, "two"), "Expected two, got %s\n", path2);
1308     ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1309     ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1310 }
1311
1312 static void test_PathUnquoteSpaces(void)
1313 {
1314     int i;
1315     for(i = 0; i < sizeof(TEST_PATH_UNQUOTE_SPACES) / sizeof(TEST_PATH_UNQUOTE_SPACES[0]); i++)
1316     {
1317         char *path = strdupA(TEST_PATH_UNQUOTE_SPACES[i].path);
1318         WCHAR *pathW = GetWideString(TEST_PATH_UNQUOTE_SPACES[i].path);
1319         WCHAR *resultW = GetWideString(TEST_PATH_UNQUOTE_SPACES[i].result);
1320
1321         PathUnquoteSpacesA(path);
1322         ok(!strcmp(path, TEST_PATH_UNQUOTE_SPACES[i].result), "%s (A): got %s expected %s\n",
1323            TEST_PATH_UNQUOTE_SPACES[i].path, path,
1324            TEST_PATH_UNQUOTE_SPACES[i].result);
1325
1326         PathUnquoteSpacesW(pathW);
1327         ok(!lstrcmpW(pathW, resultW), "%s (W): strings differ\n",
1328            TEST_PATH_UNQUOTE_SPACES[i].path);
1329         FreeWideString(pathW);
1330         FreeWideString(resultW);
1331         HeapFree(GetProcessHeap(), 0, path);
1332     }
1333 }
1334
1335 static void test_PathGetDriveNumber(void)
1336 {
1337     static const CHAR test1A[] = "a:\\test.file";
1338     static const CHAR test2A[] = "file:////b:\\test.file";
1339     static const CHAR test3A[] = "file:///c:\\test.file";
1340     static const CHAR test4A[] = "file:\\\\c:\\test.file";
1341     int ret;
1342
1343     SetLastError(0xdeadbeef);
1344     ret = PathGetDriveNumberA(NULL);
1345     ok(ret == -1, "got %d\n", ret);
1346     ok(GetLastError() == 0xdeadbeef, "got %d\n", GetLastError());
1347
1348     ret = PathGetDriveNumberA(test1A);
1349     ok(ret == 0, "got %d\n", ret);
1350     ret = PathGetDriveNumberA(test2A);
1351     ok(ret == -1, "got %d\n", ret);
1352     ret = PathGetDriveNumberA(test3A);
1353     ok(ret == -1, "got %d\n", ret);
1354     ret = PathGetDriveNumberA(test4A);
1355     ok(ret == -1, "got %d\n", ret);
1356 }
1357
1358 /* ################ */
1359
1360 START_TEST(path)
1361 {
1362     HMODULE hShlwapi = GetModuleHandleA("shlwapi.dll");
1363
1364     /* SHCreateStreamOnFileEx was introduced in shlwapi v6.0 */
1365     if(!GetProcAddress(hShlwapi, "SHCreateStreamOnFileEx")){
1366         win_skip("Too old shlwapi version\n");
1367         return;
1368     }
1369
1370     pPathCreateFromUrlA = (void*)GetProcAddress(hShlwapi, "PathCreateFromUrlA");
1371     pPathCreateFromUrlW = (void*)GetProcAddress(hShlwapi, "PathCreateFromUrlW");
1372     pPathCombineW = (void*)GetProcAddress(hShlwapi, "PathCombineW");
1373     pPathIsValidCharA = (void*)GetProcAddress(hShlwapi, (LPSTR)455);
1374     pPathIsValidCharW = (void*)GetProcAddress(hShlwapi, (LPSTR)456);
1375     pPathAppendA = (void*)GetProcAddress(hShlwapi, "PathAppendA");
1376
1377     test_PathSearchAndQualify();
1378     test_PathCreateFromUrl();
1379     test_PathIsUrl();
1380
1381     test_PathAddBackslash();
1382     test_PathMakePretty();
1383     test_PathMatchSpec();
1384
1385     test_PathIsValidCharA();
1386     test_PathIsValidCharW();
1387
1388     test_PathCombineW();
1389     test_PathCombineA();
1390     test_PathAppendA();
1391     test_PathCanonicalizeA();
1392     test_PathFindExtensionA();
1393     test_PathBuildRootA();
1394     test_PathCommonPrefixA();
1395     test_PathUnquoteSpaces();
1396     test_PathGetDriveNumber();
1397 }