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