1 /* Unit test suite for Path functions
3 * Copyright 2002 Matthew Mastracci
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.
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.
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
24 #include "wine/test.h"
31 static HMODULE hShlwapi;
32 static HRESULT (WINAPI *pPathIsValidCharA)(char,DWORD);
33 static HRESULT (WINAPI *pPathIsValidCharW)(WCHAR,DWORD);
34 static LPWSTR (WINAPI *pPathCombineW)(LPWSTR, LPCWSTR, LPCWSTR);
36 const char* TEST_URL_1 = "http://www.winehq.org/tests?date=10/10/1923";
37 const char* TEST_URL_2 = "http://localhost:8080/tests%2e.html?date=Mon%2010/10/1923";
38 const char* TEST_URL_3 = "http://foo:bar@localhost:21/internal.php?query=x&return=y";
40 typedef struct _TEST_URL_CANONICALIZE {
44 const char *expecturl;
45 } TEST_URL_CANONICALIZE;
47 const TEST_URL_CANONICALIZE TEST_CANONICALIZE[] = {
48 /*FIXME {"http://www.winehq.org/tests/../tests/../..", 0, S_OK, "http://www.winehq.org/"},*/
49 {"http://www.winehq.org/tests/../tests", 0, S_OK, "http://www.winehq.org/tests"},
50 {"http://www.winehq.org/tests\n", URL_WININET_COMPATIBILITY|URL_ESCAPE_SPACES_ONLY|URL_ESCAPE_UNSAFE, S_OK, "http://www.winehq.org/tests"},
51 {"http://www.winehq.org/tests\r", URL_WININET_COMPATIBILITY|URL_ESCAPE_SPACES_ONLY|URL_ESCAPE_UNSAFE, S_OK, "http://www.winehq.org/tests"},
52 {"http://www.winehq.org/tests\r", 0, S_OK, "http://www.winehq.org/tests"},
53 {"http://www.winehq.org/tests\r", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests"},
54 {"http://www.winehq.org/tests/../tests/", 0, S_OK, "http://www.winehq.org/tests/"},
55 {"http://www.winehq.org/tests/../tests/..", 0, S_OK, "http://www.winehq.org/"},
56 {"http://www.winehq.org/tests/../tests/../", 0, S_OK, "http://www.winehq.org/"},
57 {"http://www.winehq.org/tests/..", 0, S_OK, "http://www.winehq.org/"},
58 {"http://www.winehq.org/tests/../", 0, S_OK, "http://www.winehq.org/"},
59 {"http://www.winehq.org/tests/..?query=x&return=y", 0, S_OK, "http://www.winehq.org/?query=x&return=y"},
60 {"http://www.winehq.org/tests/../?query=x&return=y", 0, S_OK, "http://www.winehq.org/?query=x&return=y"},
61 {"http://www.winehq.org/tests/..#example", 0, S_OK, "http://www.winehq.org/#example"},
62 {"http://www.winehq.org/tests/../#example", 0, S_OK, "http://www.winehq.org/#example"},
63 {"http://www.winehq.org/tests\\../#example", 0, S_OK, "http://www.winehq.org/#example"},
64 {"http://www.winehq.org/tests/..\\#example", 0, S_OK, "http://www.winehq.org/#example"},
65 {"http://www.winehq.org\\tests/../#example", 0, S_OK, "http://www.winehq.org/#example"},
66 {"http://www.winehq.org/tests/../#example", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests/../#example"},
67 {"http://www.winehq.org/tests/foo bar", URL_ESCAPE_SPACES_ONLY| URL_DONT_ESCAPE_EXTRA_INFO , S_OK, "http://www.winehq.org/tests/foo%20bar"},
68 {"http://www.winehq.org/tests/foo%20bar", URL_UNESCAPE , S_OK, "http://www.winehq.org/tests/foo bar"},
69 {"file:///c:/tests/foo%20bar", URL_UNESCAPE , S_OK, "file:///c:/tests/foo bar"},
70 {"file:///c:/tests\\foo%20bar", URL_UNESCAPE , S_OK, "file:///c:/tests/foo bar"},
71 {"file:///c:/tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar"},
72 {"file://c:/tests/../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar"},
73 {"file://c:/tests\\../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar"},
74 {"file://c:/tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar"},
75 {"file:///c://tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\\\tests\\foo bar"},
76 {"file:///c:\\tests\\foo bar", 0, S_OK, "file:///c:/tests/foo bar"},
77 {"file:///c:\\tests\\foo bar", URL_DONT_SIMPLIFY, S_OK, "file:///c:/tests/foo bar"},
78 {"http://www.winehq.org/site/about", URL_FILE_USE_PATHURL, S_OK, "http://www.winehq.org/site/about"},
79 {"file_://www.winehq.org/site/about", URL_FILE_USE_PATHURL, S_OK, "file_://www.winehq.org/site/about"},
80 {"c:\\dir\\file", 0, S_OK, "file:///c:/dir/file"},
81 {"file:///c:\\dir\\file", 0, S_OK, "file:///c:/dir/file"},
82 {"c:dir\\file", 0, S_OK, "file:///c:dir/file"},
87 typedef struct _TEST_URL_ESCAPE {
92 const char *expecturl;
95 const TEST_URL_ESCAPE TEST_ESCAPE[] = {
96 {"http://www.winehq.org/tests0", 0, 0, S_OK, "http://www.winehq.org/tests0"},
97 {"http://www.winehq.org/tests1\n", 0, 0, S_OK, "http://www.winehq.org/tests1%0A"},
98 {"http://www.winehq.org/tests2\r", 0, 0, S_OK, "http://www.winehq.org/tests2%0D"},
99 {"http://www.winehq.org/tests3\r", URL_ESCAPE_SPACES_ONLY|URL_ESCAPE_UNSAFE, 0, S_OK, "http://www.winehq.org/tests3\r"},
100 {"http://www.winehq.org/tests4\r", URL_ESCAPE_SPACES_ONLY, 0, S_OK, "http://www.winehq.org/tests4\r"},
101 {"http://www.winehq.org/tests5\r", URL_WININET_COMPATIBILITY|URL_ESCAPE_SPACES_ONLY, 0, S_OK, "http://www.winehq.org/tests5\r"},
102 {"/direct/swhelp/series6/6.2i_latestservicepack.dat\r", URL_ESCAPE_SPACES_ONLY, 0, S_OK, "/direct/swhelp/series6/6.2i_latestservicepack.dat\r"},
104 {"file://////foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
105 {"file://///foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
106 {"file:////foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
107 {"file:///localhost/foo/bar\\baz", 0, 0, S_OK, "file:///localhost/foo/bar/baz"},
108 {"file:///foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
109 {"file://loCalHost/foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
110 {"file://foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
111 {"file:/localhost/foo/bar\\baz", 0, 0, S_OK, "file:///localhost/foo/bar/baz"},
112 {"file:/foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
113 {"file:foo/bar\\baz", 0, 0, S_OK, "file:foo/bar/baz"},
114 {"file:\\foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
115 {"file:\\\\foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"},
116 {"file:\\\\\\foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
117 {"file:\\\\localhost\\foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"},
118 {"file:///f oo/b?a r\\baz", 0, 0, S_OK, "file:///f%20oo/b?a r\\baz"},
119 {"file:///foo/b#a r\\baz", 0, 0, S_OK, "file:///foo/b%23a%20r/baz"},
120 {"file:///f o^&`{}|][\"<>\\%o/b#a r\\baz", 0, 0, S_OK, "file:///f%20o%5E%26%60%7B%7D%7C%5D%5B%22%3C%3E/%o/b%23a%20r/baz"},
121 {"file:///f o%o/b?a r\\b%az", URL_ESCAPE_PERCENT, 0, S_OK, "file:///f%20o%25o/b?a r\\b%az"},
122 {"file:/foo/bar\\baz", URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "file:%2Ffoo%2Fbar%5Cbaz"},
124 {"foo/b%ar\\ba?z\\", URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "foo%2Fb%ar%5Cba%3Fz%5C"},
125 {"foo/b%ar\\ba?z\\", URL_ESCAPE_PERCENT | URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "foo%2Fb%25ar%5Cba%3Fz%5C"},
126 {"foo/bar\\ba?z\\", 0, 0, S_OK, "foo/bar%5Cba?z\\"},
127 {"/foo/bar\\ba?z\\", 0, 0, S_OK, "/foo/bar%5Cba?z\\"},
128 {"/foo/bar\\ba#z\\", 0, 0, S_OK, "/foo/bar%5Cba#z\\"},
129 {"/foo/%5C", 0, 0, S_OK, "/foo/%5C"},
130 {"/foo/%5C", URL_ESCAPE_PERCENT, 0, S_OK, "/foo/%255C"},
132 {"http://////foo/bar\\baz", 0, 0, S_OK, "http://////foo/bar/baz"},
133 {"http://///foo/bar\\baz", 0, 0, S_OK, "http://///foo/bar/baz"},
134 {"http:////foo/bar\\baz", 0, 0, S_OK, "http:////foo/bar/baz"},
135 {"http:///foo/bar\\baz", 0, 0, S_OK, "http:///foo/bar/baz"},
136 {"http://localhost/foo/bar\\baz", 0, 0, S_OK, "http://localhost/foo/bar/baz"},
137 {"http://foo/bar\\baz", 0, 0, S_OK, "http://foo/bar/baz"},
138 {"http:/foo/bar\\baz", 0, 0, S_OK, "http:/foo/bar/baz"},
139 {"http:foo/bar\\ba?z\\", 0, 0, S_OK, "http:foo%2Fbar%2Fba?z\\"},
140 {"http:foo/bar\\ba#z\\", 0, 0, S_OK, "http:foo%2Fbar%2Fba#z\\"},
141 {"http:\\foo/bar\\baz", 0, 0, S_OK, "http:/foo/bar/baz"},
142 {"http:\\\\foo/bar\\baz", 0, 0, S_OK, "http://foo/bar/baz"},
143 {"http:\\\\\\foo/bar\\baz", 0, 0, S_OK, "http:///foo/bar/baz"},
144 {"http:\\\\\\\\foo/bar\\baz", 0, 0, S_OK, "http:////foo/bar/baz"},
145 {"http:/fo ?o/b ar\\baz", 0, 0, S_OK, "http:/fo%20?o/b ar\\baz"},
146 {"http:fo ?o/b ar\\baz", 0, 0, S_OK, "http:fo%20?o/b ar\\baz"},
147 {"http:/foo/bar\\baz", URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "http:%2Ffoo%2Fbar%5Cbaz"},
149 {"https://foo/bar\\baz", 0, 0, S_OK, "https://foo/bar/baz"},
150 {"https:/foo/bar\\baz", 0, 0, S_OK, "https:/foo/bar/baz"},
151 {"https:\\foo/bar\\baz", 0, 0, S_OK, "https:/foo/bar/baz"},
153 {"foo:////foo/bar\\baz", 0, 0, S_OK, "foo:////foo/bar%5Cbaz"},
154 {"foo:///foo/bar\\baz", 0, 0, S_OK, "foo:///foo/bar%5Cbaz"},
155 {"foo://localhost/foo/bar\\baz", 0, 0, S_OK, "foo://localhost/foo/bar%5Cbaz"},
156 {"foo://foo/bar\\baz", 0, 0, S_OK, "foo://foo/bar%5Cbaz"},
157 {"foo:/foo/bar\\baz", 0, 0, S_OK, "foo:/foo/bar%5Cbaz"},
158 {"foo:foo/bar\\baz", 0, 0, S_OK, "foo:foo%2Fbar%5Cbaz"},
159 {"foo:\\foo/bar\\baz", 0, 0, S_OK, "foo:%5Cfoo%2Fbar%5Cbaz"},
160 {"foo:/foo/bar\\ba?\\z", 0, 0, S_OK, "foo:/foo/bar%5Cba?\\z"},
161 {"foo:/foo/bar\\ba#\\z", 0, 0, S_OK, "foo:/foo/bar%5Cba#\\z"},
163 {"mailto:/fo/o@b\\%a?\\r.b#\\az", 0, 0, S_OK, "mailto:%2Ffo%2Fo@b%5C%a%3F%5Cr.b%23%5Caz"},
164 {"mailto:fo/o@b\\%a?\\r.b#\\az", 0, 0, S_OK, "mailto:fo%2Fo@b%5C%a%3F%5Cr.b%23%5Caz"},
165 {"mailto:fo/o@b\\%a?\\r.b#\\az", URL_ESCAPE_PERCENT, 0, S_OK, "mailto:fo%2Fo@b%5C%25a%3F%5Cr.b%23%5Caz"},
167 {"ftp:fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:fo%2Fo@bar.baz%2Ffoo%2Fbar"},
168 {"ftp:/fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:/fo/o@bar.baz/foo/bar"},
169 {"ftp://fo/o@bar.baz/fo?o\\bar", 0, 0, S_OK, "ftp://fo/o@bar.baz/fo?o\\bar"},
170 {"ftp://fo/o@bar.baz/fo#o\\bar", 0, 0, S_OK, "ftp://fo/o@bar.baz/fo#o\\bar"},
171 {"ftp://localhost/o@bar.baz/fo#o\\bar", 0, 0, S_OK, "ftp://localhost/o@bar.baz/fo#o\\bar"},
172 {"ftp:///fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:///fo/o@bar.baz/foo/bar"},
173 {"ftp:////fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:////fo/o@bar.baz/foo/bar"}
176 typedef struct _TEST_URL_COMBINE {
181 const char *expecturl;
184 const TEST_URL_COMBINE TEST_COMBINE[] = {
185 {"http://www.winehq.org/tests", "tests1", 0, S_OK, "http://www.winehq.org/tests1"},
186 {"http://www.%77inehq.org/tests", "tests1", 0, S_OK, "http://www.%77inehq.org/tests1"},
187 /*FIXME {"http://www.winehq.org/tests", "../tests2", 0, S_OK, "http://www.winehq.org/tests2"},*/
188 {"http://www.winehq.org/tests/", "../tests3", 0, S_OK, "http://www.winehq.org/tests3"},
189 {"http://www.winehq.org/tests/test1", "test2", 0, S_OK, "http://www.winehq.org/tests/test2"},
190 {"http://www.winehq.org/tests/../tests", "tests4", 0, S_OK, "http://www.winehq.org/tests4"},
191 {"http://www.winehq.org/tests/../tests/", "tests5", 0, S_OK, "http://www.winehq.org/tests/tests5"},
192 {"http://www.winehq.org/tests/../tests/", "/tests6/..", 0, S_OK, "http://www.winehq.org/"},
193 {"http://www.winehq.org/tests/../tests/..", "tests7/..", 0, S_OK, "http://www.winehq.org/"},
194 {"http://www.winehq.org/tests/?query=x&return=y", "tests8", 0, S_OK, "http://www.winehq.org/tests/tests8"},
195 {"http://www.winehq.org/tests/#example", "tests9", 0, S_OK, "http://www.winehq.org/tests/tests9"},
196 {"http://www.winehq.org/tests/../tests/", "/tests10/..", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests10/.."},
197 {"http://www.winehq.org/tests/../", "tests11", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests/../tests11"},
198 {"file:///C:\\dir\\file.txt", "test.txt", 0, S_OK, "file:///C:/dir/test.txt"}
205 } TEST_URLFROMPATH [] = {
206 {"foo", "file:foo", S_OK},
207 {"foo\\bar", "file:foo/bar", S_OK},
208 {"\\foo\\bar", "file:///foo/bar", S_OK},
209 {"c:\\foo\\bar", "file:///c:/foo/bar", S_OK},
210 {"c:foo\\bar", "file:///c:foo/bar", S_OK},
211 {"c:\\foo/b a%r", "file:///c:/foo/b%20a%25r", S_OK},
212 {"c:\\foo\\foo bar", "file:///c:/foo/foo%20bar", S_OK},
214 /* The following test fails on native shlwapi as distributed with Win95/98.
215 * Wine matches the behaviour of later versions.
217 {"xx:c:\\foo\\bar", "xx:c:\\foo\\bar", S_FALSE}
225 } TEST_PATHFROMURL[] = {
226 {"file:///c:/foo/ba%5Cr", "c:\\foo\\ba\\r", S_OK},
227 {"file:///c:/foo/../ba%5Cr", "c:\\foo\\..\\ba\\r", S_OK},
228 {"file:///host/c:/foo/bar", "\\host\\c:\\foo\\bar", S_OK},
229 {"file://host/c:/foo/bar", "\\\\hostc:\\foo\\bar", S_OK},
230 {"file://host/c:/foo/bar", "\\\\hostc:\\foo\\bar", S_OK},
231 {"file:\\\\host\\c:\\foo\\bar", "\\\\hostc:\\foo\\bar", S_OK},
232 {"file:\\\\host\\ca\\foo\\bar", "\\\\host\\ca\\foo\\bar", S_OK},
233 {"file:\\\\host\\c|\\foo\\bar", "\\\\hostc|\\foo\\bar", S_OK},
234 {"file:\\%5Chost\\c:\\foo\\bar", "\\\\host\\c:\\foo\\bar", S_OK},
235 {"file:\\\\host\\cx:\\foo\\bar", "\\\\host\\cx:\\foo\\bar", S_OK},
236 {"file://c:/foo/bar", "c:\\foo\\bar", S_OK},
237 {"file://c:/d:/foo/bar", "c:\\d:\\foo\\bar", S_OK},
238 {"file://c|/d|/foo/bar", "c:\\d|\\foo\\bar", S_OK},
239 {"file://host/foo/bar", "\\\\host\\foo\\bar", S_OK},
240 {"file:/foo/bar", "\\foo\\bar", S_OK},
241 {"file:/foo/bar/", "\\foo\\bar\\", S_OK},
242 {"file:foo/bar", "foo\\bar", S_OK},
243 {"file:c:/foo/bar", "c:\\foo\\bar", S_OK},
244 {"file:c|/foo/bar", "c:\\foo\\bar", S_OK},
245 {"file:cx|/foo/bar", "cx|\\foo\\bar", S_OK},
246 {"file:////c:/foo/bar", "c:\\foo\\bar", S_OK},
247 /* {"file:////c:/foo/foo%20bar", "c:\\foo\\foo%20bar", S_OK},*/
249 {"c:\\foo\\bar", NULL, E_INVALIDARG},
250 {"foo/bar", NULL, E_INVALIDARG},
251 {"http://foo/bar", NULL, E_INVALIDARG},
258 } TEST_URL_UNESCAPE[] = {
259 {"file://foo/bar", "file://foo/bar"},
260 {"file://fo%20o%5Ca/bar", "file://fo o\\a/bar"}
267 } TEST_PATH_IS_URL[] = {
268 {"http://foo/bar", TRUE},
269 {"c:\\foo\\bar", FALSE},
270 {"foo://foo/bar", TRUE},
273 {"bogusscheme:", TRUE},
274 {"http:partial", TRUE}
281 } TEST_URLIS_ATTRIBS[] = {
282 { "ftp:", FALSE, FALSE },
283 { "http:", FALSE, FALSE },
284 { "gopher:", FALSE, FALSE },
285 { "mailto:", TRUE, FALSE },
286 { "news:", FALSE, FALSE },
287 { "nntp:", FALSE, FALSE },
288 { "telnet:", FALSE, FALSE },
289 { "wais:", FALSE, FALSE },
290 { "file:", FALSE, TRUE },
291 { "mk:", FALSE, FALSE },
292 { "https:", FALSE, FALSE },
293 { "shell:", TRUE, FALSE },
294 { "https:", FALSE, FALSE },
295 { "snews:", FALSE, FALSE },
296 { "local:", FALSE, FALSE },
297 { "javascript:", TRUE, FALSE },
298 { "vbscript:", TRUE, FALSE },
299 { "about:", TRUE, FALSE },
300 { "res:", FALSE, FALSE },
301 { "bogusscheme:", FALSE, FALSE },
302 { "file:\\\\e:\\b\\c", FALSE, TRUE },
303 { "file://e:/b/c", FALSE, TRUE },
304 { "http:partial", FALSE, FALSE },
305 { "mailto://www.winehq.org/test.html", TRUE, FALSE },
306 { "file:partial", FALSE, TRUE }
310 static LPWSTR GetWideString(const char* szString)
312 LPWSTR wszString = HeapAlloc(GetProcessHeap(), 0, (2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR));
314 MultiByteToWideChar(0, 0, szString, -1, wszString, INTERNET_MAX_URL_LENGTH);
319 static void FreeWideString(LPWSTR wszString)
321 HeapFree(GetProcessHeap(), 0, wszString);
324 static void hash_url(const char* szUrl)
326 LPCSTR szTestUrl = szUrl;
327 LPWSTR wszTestUrl = GetWideString(szTestUrl);
329 DWORD cbSize = sizeof(DWORD);
330 DWORD dwHash1, dwHash2;
331 ok(UrlHashA(szTestUrl, (LPBYTE)&dwHash1, cbSize) == S_OK, "UrlHashA didn't return S_OK\n");
332 ok(UrlHashW(wszTestUrl, (LPBYTE)&dwHash2, cbSize) == S_OK, "UrlHashW didn't return S_OK\n");
334 FreeWideString(wszTestUrl);
336 ok(dwHash1 == dwHash2, "Hashes didn't compare\n");
339 static void test_UrlHash(void)
341 hash_url(TEST_URL_1);
342 hash_url(TEST_URL_2);
343 hash_url(TEST_URL_3);
346 static void test_url_part(const char* szUrl, DWORD dwPart, DWORD dwFlags, const char* szExpected)
348 CHAR szPart[INTERNET_MAX_URL_LENGTH];
349 WCHAR wszPart[INTERNET_MAX_URL_LENGTH];
350 LPWSTR wszUrl = GetWideString(szUrl);
351 LPWSTR wszConvertedPart;
355 dwSize = INTERNET_MAX_URL_LENGTH;
356 ok( UrlGetPartA(szUrl, szPart, &dwSize, dwPart, dwFlags) == S_OK, "UrlGetPartA for \"%s\" part 0x%08lx didn't return S_OK but \"%s\"\n", szUrl, dwPart, szPart);
357 dwSize = INTERNET_MAX_URL_LENGTH;
358 ok( UrlGetPartW(wszUrl, wszPart, &dwSize, dwPart, dwFlags) == S_OK, "UrlGetPartW didn't return S_OK\n" );
360 wszConvertedPart = GetWideString(szPart);
362 ok(lstrcmpW(wszPart,wszConvertedPart)==0, "Strings didn't match between ascii and unicode UrlGetPart!\n");
364 FreeWideString(wszUrl);
365 FreeWideString(wszConvertedPart);
367 /* Note that v6.0 and later don't return '?' with the query */
368 ok(strcmp(szPart,szExpected)==0 ||
369 (*szExpected=='?' && !strcmp(szPart,szExpected+1)),
370 "Expected %s, but got %s\n", szExpected, szPart);
373 static void test_UrlGetPart(void)
375 CHAR szPart[INTERNET_MAX_URL_LENGTH];
379 dwSize = sizeof szPart;
380 szPart[0]='x'; szPart[1]=0;
381 res = UrlGetPartA("hi", szPart, &dwSize, URL_PART_SCHEME, 0);
383 ok (res==S_FALSE, "UrlGetPartA(\"hi\") returned %08lX\n", res);
384 ok(szPart[0]==0, "UrlGetPartA(\"hi\") return \"%s\" instead of \"\"\n", szPart);
386 dwSize = sizeof szPart;
387 szPart[0]='x'; szPart[1]=0;
388 res = UrlGetPartA("hi", szPart, &dwSize, URL_PART_QUERY, 0);
390 ok (res==S_FALSE, "UrlGetPartA(\"hi\") returned %08lX\n", res);
391 ok(szPart[0]==0, "UrlGetPartA(\"hi\") return \"%s\" instead of \"\"\n", szPart);
394 test_url_part(TEST_URL_3, URL_PART_HOSTNAME, 0, "localhost");
395 test_url_part(TEST_URL_3, URL_PART_PORT, 0, "21");
396 test_url_part(TEST_URL_3, URL_PART_USERNAME, 0, "foo");
397 test_url_part(TEST_URL_3, URL_PART_PASSWORD, 0, "bar");
398 test_url_part(TEST_URL_3, URL_PART_SCHEME, 0, "http");
399 test_url_part(TEST_URL_3, URL_PART_QUERY, 0, "?query=x&return=y");
402 static void test_url_escape(const char *szUrl, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl)
404 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
406 WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
407 WCHAR *urlW, *expected_urlW;
408 dwEscaped=INTERNET_MAX_URL_LENGTH;
410 ok(UrlEscapeA(szUrl, szReturnUrl, &dwEscaped, dwFlags) == dwExpectReturn, "UrlEscapeA didn't return 0x%08lx from \"%s\"\n", dwExpectReturn, szUrl);
411 ok(strcmp(szReturnUrl,szExpectUrl)==0, "Expected \"%s\", but got \"%s\" from \"%s\"\n", szExpectUrl, szReturnUrl, szUrl);
413 dwEscaped = INTERNET_MAX_URL_LENGTH;
414 urlW = GetWideString(szUrl);
415 expected_urlW = GetWideString(szExpectUrl);
416 ok(UrlEscapeW(urlW, ret_urlW, &dwEscaped, dwFlags) == dwExpectReturn, "UrlEscapeW didn't return 0x%08lx from \"%s\"\n", dwExpectReturn, szUrl);
417 WideCharToMultiByte(CP_ACP,0,ret_urlW,-1,szReturnUrl,INTERNET_MAX_URL_LENGTH,0,0);
418 ok(lstrcmpW(ret_urlW, expected_urlW)==0, "Expected \"%s\", but got \"%s\" from \"%s\" flags %08lx\n", szExpectUrl, szReturnUrl, szUrl, dwFlags);
419 FreeWideString(urlW);
420 FreeWideString(expected_urlW);
424 static void test_url_canonicalize(const char *szUrl, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl)
426 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
427 WCHAR wszReturnUrl[INTERNET_MAX_URL_LENGTH];
428 LPWSTR wszUrl = GetWideString(szUrl);
429 LPWSTR wszExpectUrl = GetWideString(szExpectUrl);
430 LPWSTR wszConvertedUrl;
434 dwSize = INTERNET_MAX_URL_LENGTH;
435 ok(UrlCanonicalizeA(szUrl, NULL, &dwSize, dwFlags) != dwExpectReturn, "Unexpected return for NULL buffer\n");
436 ok(UrlCanonicalizeA(szUrl, szReturnUrl, &dwSize, dwFlags) == dwExpectReturn, "UrlCanonicalizeA didn't return 0x%08lx\n", dwExpectReturn);
437 ok(strcmp(szReturnUrl,szExpectUrl)==0, "UrlCanonicalizeA dwFlags 0x%08lx Expected \"%s\", but got \"%s\"\n", dwFlags, szExpectUrl, szReturnUrl);
439 dwSize = INTERNET_MAX_URL_LENGTH;
440 ok(UrlCanonicalizeW(wszUrl, NULL, &dwSize, dwFlags) != dwExpectReturn, "Unexpected return for NULL buffer\n");
441 ok(UrlCanonicalizeW(wszUrl, wszReturnUrl, &dwSize, dwFlags) == dwExpectReturn, "UrlCanonicalizeW didn't return 0x%08lx\n", dwExpectReturn);
442 wszConvertedUrl = GetWideString(szReturnUrl);
443 ok(lstrcmpW(wszReturnUrl, wszConvertedUrl)==0, "Strings didn't match between ascii and unicode UrlCanonicalize!\n");
444 FreeWideString(wszConvertedUrl);
447 FreeWideString(wszUrl);
448 FreeWideString(wszExpectUrl);
452 static void test_UrlEscape(void)
455 for(i=0; i<sizeof(TEST_ESCAPE)/sizeof(TEST_ESCAPE[0]); i++) {
456 test_url_escape(TEST_ESCAPE[i].url, TEST_ESCAPE[i].flags,
457 TEST_ESCAPE[i].expectret, TEST_ESCAPE[i].expecturl);
461 static void test_UrlCanonicalize(void)
464 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
467 for(i=0; i<sizeof(TEST_CANONICALIZE)/sizeof(TEST_CANONICALIZE[0]); i++) {
468 test_url_canonicalize(TEST_CANONICALIZE[i].url, TEST_CANONICALIZE[i].flags,
469 TEST_CANONICALIZE[i].expectret, TEST_CANONICALIZE[i].expecturl);
472 /* move to TEST_CANONICALIZE when fixed */
473 dwSize = sizeof szReturnUrl;
474 ok(UrlCanonicalizeA("c:\\tests\\foo bar", szReturnUrl, &dwSize, 0) == S_OK, "UrlCanonicalizeA didn't return 0x%08lx\n", S_OK);
476 ok(strcmp(szReturnUrl,"file:///c:/tests/foo%20bar")==0, "UrlCanonicalizeA got %s\n", szReturnUrl);
480 static void test_url_combine(const char *szUrl1, const char *szUrl2, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl)
483 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
484 WCHAR wszReturnUrl[INTERNET_MAX_URL_LENGTH];
485 LPWSTR wszUrl1 = GetWideString(szUrl1);
486 LPWSTR wszUrl2 = GetWideString(szUrl2);
487 LPWSTR wszExpectUrl = GetWideString(szExpectUrl);
488 LPWSTR wszConvertedUrl;
491 DWORD dwExpectLen = lstrlen(szExpectUrl);
493 hr = UrlCombineA(szUrl1, szUrl2, NULL, NULL, dwFlags);
494 ok(hr == E_INVALIDARG, "UrlCombineA returned 0x%08lx, expected 0x%08lx\n", hr, E_INVALIDARG);
497 hr = UrlCombineA(szUrl1, szUrl2, NULL, &dwSize, dwFlags);
498 ok(hr == E_POINTER, "Checking length of string, return was 0x%08lx, expected 0x%08lx\n", hr, E_POINTER);
499 ok(dwSize == dwExpectLen+1, "Got length %ld, expected %ld\n", dwSize, dwExpectLen+1);
502 hr = UrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags);
503 ok(hr == E_POINTER, "UrlCombineA returned 0x%08lx, expected 0x%08lx\n", hr, E_POINTER);
504 ok(dwSize == dwExpectLen+1, "Got length %ld, expected %ld\n", dwSize, dwExpectLen+1);
506 hr = UrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags);
507 ok(hr == dwExpectReturn, "UrlCombineA returned 0x%08lx, expected 0x%08lx\n", hr, dwExpectReturn);
508 ok(dwSize == dwExpectLen, "Got length %ld, expected %ld\n", dwSize, dwExpectLen);
510 ok(strcmp(szReturnUrl,szExpectUrl)==0, "Expected %s, but got %s\n", szExpectUrl, szReturnUrl);
514 hr = UrlCombineW(wszUrl1, wszUrl2, NULL, &dwSize, dwFlags);
515 ok(hr == E_POINTER, "Checking length of string, return was 0x%08lx, expected 0x%08lx\n", hr, E_POINTER);
516 ok(dwSize == dwExpectLen+1, "Got length %ld, expected %ld\n", dwSize, dwExpectLen+1);
519 hr = UrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags);
520 ok(hr == E_POINTER, "UrlCombineA returned 0x%08lx, expected 0x%08lx\n", hr, E_POINTER);
521 ok(dwSize == dwExpectLen+1, "Got length %ld, expected %ld\n", dwSize, dwExpectLen+1);
523 hr = UrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags);
524 ok(hr == dwExpectReturn, "UrlCombineW returned 0x%08lx, expected 0x%08lx\n", hr, dwExpectReturn);
525 ok(dwSize == dwExpectLen, "Got length %ld, expected %ld\n", dwSize, dwExpectLen);
527 wszConvertedUrl = GetWideString(szReturnUrl);
528 ok(lstrcmpW(wszReturnUrl, wszConvertedUrl)==0, "Strings didn't match between ascii and unicode UrlCombine!\n");
529 FreeWideString(wszConvertedUrl);
532 FreeWideString(wszUrl1);
533 FreeWideString(wszUrl2);
534 FreeWideString(wszExpectUrl);
537 static void test_UrlCombine(void)
540 for(i=0; i<sizeof(TEST_COMBINE)/sizeof(TEST_COMBINE[0]); i++) {
541 test_url_combine(TEST_COMBINE[i].url1, TEST_COMBINE[i].url2, TEST_COMBINE[i].flags,
542 TEST_COMBINE[i].expectret, TEST_COMBINE[i].expecturl);
546 static void test_UrlCreateFromPath(void)
549 char ret_url[INTERNET_MAX_URL_LENGTH];
551 WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
554 for(i = 0; i < sizeof(TEST_URLFROMPATH) / sizeof(TEST_URLFROMPATH[0]); i++) {
555 len = INTERNET_MAX_URL_LENGTH;
556 ret = UrlCreateFromPathA(TEST_URLFROMPATH[i].path, ret_url, &len, 0);
557 ok(ret == TEST_URLFROMPATH[i].ret, "ret %08lx from path %s\n", ret, TEST_URLFROMPATH[i].path);
558 ok(!lstrcmpi(ret_url, TEST_URLFROMPATH[i].url), "url %s from path %s\n", ret_url, TEST_URLFROMPATH[i].path);
559 ok(len == strlen(ret_url), "ret len %ld from path %s\n", len, TEST_URLFROMPATH[i].path);
561 len = INTERNET_MAX_URL_LENGTH;
562 pathW = GetWideString(TEST_URLFROMPATH[i].path);
563 urlW = GetWideString(TEST_URLFROMPATH[i].url);
564 ret = UrlCreateFromPathW(pathW, ret_urlW, &len, 0);
565 WideCharToMultiByte(CP_ACP, 0, ret_urlW, -1, ret_url, sizeof(ret_url),0,0);
566 ok(ret == TEST_URLFROMPATH[i].ret, "ret %08lx from path L\"%s\", expected %08lx\n",
567 ret, TEST_URLFROMPATH[i].path, TEST_URLFROMPATH[i].ret);
568 ok(!lstrcmpiW(ret_urlW, urlW), "got %s expected %s from path L\"%s\"\n", ret_url, TEST_URLFROMPATH[i].url, TEST_URLFROMPATH[i].path);
569 ok(len == lstrlenW(ret_urlW), "ret len %ld from path L\"%s\"\n", len, TEST_URLFROMPATH[i].path);
570 FreeWideString(urlW);
571 FreeWideString(pathW);
575 static void test_UrlIs(void)
581 for(i = 0; i < sizeof(TEST_PATH_IS_URL) / sizeof(TEST_PATH_IS_URL[0]); i++) {
582 MultiByteToWideChar(CP_ACP, 0, TEST_PATH_IS_URL[i].path, -1, wurl, 80);
584 ret = UrlIsA( TEST_PATH_IS_URL[i].path, URLIS_URL );
585 ok( ret == TEST_PATH_IS_URL[i].expect,
586 "returned %d from path %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
587 TEST_PATH_IS_URL[i].expect );
589 ret = UrlIsW( wurl, URLIS_URL );
590 ok( ret == TEST_PATH_IS_URL[i].expect,
591 "returned %d from path (UrlIsW) %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
592 TEST_PATH_IS_URL[i].expect );
594 for(i = 0; i < sizeof(TEST_URLIS_ATTRIBS) / sizeof(TEST_URLIS_ATTRIBS[0]); i++) {
595 MultiByteToWideChar(CP_ACP, 0, TEST_URLIS_ATTRIBS[i].url, -1, wurl, 80);
597 ret = UrlIsA( TEST_URLIS_ATTRIBS[i].url, URLIS_OPAQUE);
598 ok( ret == TEST_URLIS_ATTRIBS[i].expectOpaque,
599 "returned %d for URLIS_OPAQUE, url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
600 TEST_URLIS_ATTRIBS[i].expectOpaque );
601 ret = UrlIsA( TEST_URLIS_ATTRIBS[i].url, URLIS_FILEURL);
602 ok( ret == TEST_URLIS_ATTRIBS[i].expectFile,
603 "returned %d for URLIS_FILEURL, url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
604 TEST_URLIS_ATTRIBS[i].expectFile );
606 ret = UrlIsW( wurl, URLIS_OPAQUE);
607 ok( ret == TEST_URLIS_ATTRIBS[i].expectOpaque,
608 "returned %d for URLIS_OPAQUE (UrlIsW), url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
609 TEST_URLIS_ATTRIBS[i].expectOpaque );
610 ret = UrlIsW( wurl, URLIS_FILEURL);
611 ok( ret == TEST_URLIS_ATTRIBS[i].expectFile,
612 "returned %d for URLIS_FILEURL (UrlIsW), url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url,
613 TEST_URLIS_ATTRIBS[i].expectFile );
617 static void test_UrlUnescape(void)
619 CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
620 WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH];
621 WCHAR *urlW, *expected_urlW;
624 static char inplace[] = "file:///C:/Program%20Files";
625 static WCHAR inplaceW[] = {'f','i','l','e',':','/','/','/','C',':','/',
626 'P','r','o','g','r','a','m','%','2','0','F','i','l','e','s',0};
628 for(i=0; i<sizeof(TEST_URL_UNESCAPE)/sizeof(TEST_URL_UNESCAPE[0]); i++) {
629 dwEscaped=INTERNET_MAX_URL_LENGTH;
630 ok(UrlUnescapeA(TEST_URL_UNESCAPE[i].url, szReturnUrl, &dwEscaped, 0) == S_OK, "UrlEscapeA didn't return 0x%08lx from \"%s\"\n", S_OK, TEST_URL_UNESCAPE[i].url);
631 ok(strcmp(szReturnUrl,TEST_URL_UNESCAPE[i].expect)==0, "Expected \"%s\", but got \"%s\" from \"%s\"\n", TEST_URL_UNESCAPE[i].expect, szReturnUrl, TEST_URL_UNESCAPE[i].url);
633 dwEscaped = INTERNET_MAX_URL_LENGTH;
634 urlW = GetWideString(TEST_URL_UNESCAPE[i].url);
635 expected_urlW = GetWideString(TEST_URL_UNESCAPE[i].expect);
636 ok(UrlUnescapeW(urlW, ret_urlW, &dwEscaped, 0) == S_OK, "UrlEscapeW didn't return 0x%08lx from \"%s\"\n", S_OK, TEST_URL_UNESCAPE[i].url);
637 WideCharToMultiByte(CP_ACP,0,ret_urlW,-1,szReturnUrl,INTERNET_MAX_URL_LENGTH,0,0);
638 ok(lstrcmpW(ret_urlW, expected_urlW)==0, "Expected \"%s\", but got \"%s\" from \"%s\" flags %08lx\n", TEST_URL_UNESCAPE[i].expect, szReturnUrl, TEST_URL_UNESCAPE[i].url, 0L);
639 FreeWideString(urlW);
640 FreeWideString(expected_urlW);
643 dwEscaped = sizeof(inplace);
644 ok(UrlUnescapeA(inplace, NULL, &dwEscaped, URL_UNESCAPE_INPLACE) == S_OK, "UrlUnescapeA failed unexpectedly\n");
646 dwEscaped = sizeof(inplaceW);
647 ok(UrlUnescapeW(inplaceW, NULL, &dwEscaped, URL_UNESCAPE_INPLACE) == S_OK, "UrlUnescapeW failed unexpectedly\n");
650 static void test_PathSearchAndQualify(void)
652 WCHAR path1[] = {'c',':','\\','f','o','o',0};
653 WCHAR expect1[] = {'c',':','\\','f','o','o',0};
654 WCHAR path2[] = {'c',':','f','o','o',0};
655 WCHAR c_drive[] = {'c',':',0};
656 WCHAR foo[] = {'f','o','o',0};
657 WCHAR path3[] = {'\\','f','o','o',0};
658 WCHAR winini[] = {'w','i','n','.','i','n','i',0};
660 WCHAR cur_dir[MAX_PATH];
661 WCHAR dot[] = {'.',0};
664 ok(PathSearchAndQualifyW(path1, out, MAX_PATH) != 0,
665 "PathSearchAndQualify rets 0\n");
666 ok(!lstrcmpiW(out, expect1), "strings don't match\n");
669 ok(PathSearchAndQualifyW(path2, out, MAX_PATH) != 0,
670 "PathSearchAndQualify rets 0\n");
671 GetFullPathNameW(c_drive, MAX_PATH, cur_dir, NULL);
672 PathAddBackslashW(cur_dir);
673 lstrcatW(cur_dir, foo);
674 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
677 ok(PathSearchAndQualifyW(foo, out, MAX_PATH) != 0,
678 "PathSearchAndQualify rets 0\n");
679 GetFullPathNameW(dot, MAX_PATH, cur_dir, NULL);
680 PathAddBackslashW(cur_dir);
681 lstrcatW(cur_dir, foo);
682 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
685 ok(PathSearchAndQualifyW(path3, out, MAX_PATH) != 0,
686 "PathSearchAndQualify rets 0\n");
687 GetFullPathNameW(dot, MAX_PATH, cur_dir, NULL);
688 lstrcpyW(cur_dir + 2, path3);
689 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
692 ok(PathSearchAndQualifyW(winini, out, MAX_PATH) != 0,
693 "PathSearchAndQualify rets 0\n");
694 if(!SearchPathW(NULL, winini, NULL, MAX_PATH, cur_dir, NULL))
695 GetFullPathNameW(winini, MAX_PATH, cur_dir, NULL);
696 ok(!lstrcmpiW(out, cur_dir), "strings don't match\n");
700 static void test_PathCreateFromUrl(void)
703 char ret_path[INTERNET_MAX_URL_LENGTH];
705 WCHAR ret_pathW[INTERNET_MAX_URL_LENGTH];
708 for(i = 0; i < sizeof(TEST_PATHFROMURL) / sizeof(TEST_PATHFROMURL[0]); i++) {
709 len = INTERNET_MAX_URL_LENGTH;
710 ret = PathCreateFromUrlA(TEST_PATHFROMURL[i].url, ret_path, &len, 0);
711 ok(ret == TEST_PATHFROMURL[i].ret, "ret %08lx from url %s\n", ret, TEST_PATHFROMURL[i].url);
712 if(TEST_PATHFROMURL[i].path) {
713 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);
714 ok(len == strlen(ret_path), "ret len %ld from url %s\n", len, TEST_PATHFROMURL[i].url);
716 len = INTERNET_MAX_URL_LENGTH;
717 pathW = GetWideString(TEST_PATHFROMURL[i].path);
718 urlW = GetWideString(TEST_PATHFROMURL[i].url);
719 ret = PathCreateFromUrlW(urlW, ret_pathW, &len, 0);
720 WideCharToMultiByte(CP_ACP, 0, ret_pathW, -1, ret_path, sizeof(ret_path),0,0);
721 ok(ret == TEST_PATHFROMURL[i].ret, "ret %08lx from url L\"%s\"\n", ret, TEST_PATHFROMURL[i].url);
722 if(TEST_PATHFROMURL[i].path) {
723 ok(!lstrcmpiW(ret_pathW, pathW), "got %s expected %s from url L\"%s\"\n", ret_path, TEST_PATHFROMURL[i].path, TEST_PATHFROMURL[i].url);
724 ok(len == lstrlenW(ret_pathW), "ret len %ld from url L\"%s\"\n", len, TEST_PATHFROMURL[i].url);
726 FreeWideString(urlW);
727 FreeWideString(pathW);
732 static void test_PathIsUrl(void)
737 for(i = 0; i < sizeof(TEST_PATH_IS_URL)/sizeof(TEST_PATH_IS_URL[0]); i++) {
738 ret = PathIsURLA(TEST_PATH_IS_URL[i].path);
739 ok(ret == TEST_PATH_IS_URL[i].expect,
740 "returned %d from path %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path,
741 TEST_PATH_IS_URL[i].expect);
745 static const DWORD SHELL_charclass[] =
747 0x00000000, 0x00000000, 0x00000000, 0x00000000,
748 0x00000000, 0x00000000, 0x00000000, 0x00000000,
749 0x00000000, 0x00000000, 0x00000000, 0x00000000,
750 0x00000000, 0x00000000, 0x00000000, 0x00000000,
751 0x00000000, 0x00000000, 0x00000000, 0x00000000,
752 0x00000000, 0x00000000, 0x00000000, 0x00000000,
753 0x00000000, 0x00000000, 0x00000000, 0x00000000,
754 0x00000000, 0x00000000, 0x00000000, 0x00000000,
755 0x00000080, 0x00000100, 0x00000200, 0x00000100,
756 0x00000100, 0x00000100, 0x00000100, 0x00000100,
757 0x00000100, 0x00000100, 0x00000002, 0x00000100,
758 0x00000040, 0x00000100, 0x00000004, 0x00000000,
759 0x00000100, 0x00000100, 0x00000100, 0x00000100,
760 0x00000100, 0x00000100, 0x00000100, 0x00000100,
761 0x00000100, 0x00000100, 0x00000010, 0x00000020,
762 0x00000000, 0x00000100, 0x00000000, 0x00000001,
763 0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
764 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
765 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
766 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
767 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
768 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
769 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
770 0x00000008, 0x00000100, 0x00000100, 0x00000100,
771 0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
772 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
773 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
774 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
775 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
776 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
777 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
778 0x00000000, 0x00000100, 0x00000100
781 static void test_PathIsValidCharA(void)
786 ret = pPathIsValidCharA( 0x7f, 0 );
787 ok ( !ret, "PathIsValidCharA succeeded: 0x%08lx\n", (DWORD)ret );
789 ret = pPathIsValidCharA( 0x7f, 1 );
790 ok ( !ret, "PathIsValidCharA succeeded: 0x%08lx\n", (DWORD)ret );
792 for (c = 0; c < 0x7f; c++)
794 ret = pPathIsValidCharA( c, ~0U );
795 ok ( ret == SHELL_charclass[c] || (ret == 1 && SHELL_charclass[c] == 0xffffffff),
796 "PathIsValidCharA failed: 0x%02x got 0x%08lx expected 0x%08lx\n",
797 c, (DWORD)ret, SHELL_charclass[c] );
800 for (c = 0x7f; c <= 0xff; c++)
802 ret = pPathIsValidCharA( c, ~0U );
803 ok ( ret == 0x00000100,
804 "PathIsValidCharA failed: 0x%02x got 0x%08lx expected 0x00000100\n",
809 static void test_PathIsValidCharW(void)
812 unsigned int c, err_count = 0;
814 ret = pPathIsValidCharW( 0x7f, 0 );
815 ok ( !ret, "PathIsValidCharW succeeded: 0x%08lx\n", (DWORD)ret );
817 ret = pPathIsValidCharW( 0x7f, 1 );
818 ok ( !ret, "PathIsValidCharW succeeded: 0x%08lx\n", (DWORD)ret );
820 for (c = 0; c < 0x7f; c++)
822 ret = pPathIsValidCharW( c, ~0U );
823 ok ( ret == SHELL_charclass[c] || (ret == 1 && SHELL_charclass[c] == 0xffffffff),
824 "PathIsValidCharW failed: 0x%02x got 0x%08lx expected 0x%08lx\n",
825 c, (DWORD)ret, SHELL_charclass[c] );
828 for (c = 0x007f; c <= 0xffff; c++)
830 ret = pPathIsValidCharW( c, ~0U );
831 ok ( ret == 0x00000100,
832 "PathIsValidCharW failed: 0x%02x got 0x%08lx expected 0x00000100\n",
834 if (ret != 0x00000100)
836 if(++err_count > 100 ) {
837 trace("skipping rest of PathIsValidCharW tests "
838 "because of the current number of errors\n");
845 static void test_PathMakePretty(void)
849 ok (PathMakePrettyA(NULL) == FALSE, "PathMakePretty: NULL path succeeded\n");
851 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Empty path failed\n");
853 strcpy(buff, "C:\\A LONG FILE NAME WITH \\SPACES.TXT");
854 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Long UC name failed\n");
855 ok (strcmp(buff, "C:\\a long file name with \\spaces.txt") == 0,
856 "PathMakePretty: Long UC name not changed\n");
858 strcpy(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT");
859 ok (PathMakePrettyA(buff) == FALSE, "PathMakePretty: Long MC name succeeded\n");
860 ok (strcmp(buff, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT") == 0,
861 "PathMakePretty: Failed but modified path\n");
863 strcpy(buff, "TEST");
864 ok (PathMakePrettyA(buff) == TRUE, "PathMakePretty: Short name failed\n");
865 ok (strcmp(buff, "Test") == 0, "PathMakePretty: 1st char lowercased %s\n", buff);
868 static void test_PathMatchSpec(void)
870 static const char file[] = "c:\\foo\\bar\\filename.ext";
871 static const char spec1[] = ".ext";
872 static const char spec2[] = "*.ext";
873 static const char spec3[] = "*.ext ";
874 static const char spec4[] = " *.ext";
875 static const char spec5[] = "* .ext";
876 static const char spec6[] = "*. ext";
877 static const char spec7[] = "* . ext";
878 static const char spec8[] = "*.e?t";
879 static const char spec9[] = "filename.ext";
880 static const char spec10[] = "*bar\\filename.ext";
881 static const char spec11[] = " foo; *.ext";
882 static const char spec12[] = "*.ext;*.bar";
883 static const char spec13[] = "*bar*";
885 ok (PathMatchSpecA(file, spec1) == FALSE, "PathMatchSpec: Spec1 failed\n");
886 ok (PathMatchSpecA(file, spec2) == TRUE, "PathMatchSpec: Spec2 failed\n");
887 ok (PathMatchSpecA(file, spec3) == FALSE, "PathMatchSpec: Spec3 failed\n");
888 ok (PathMatchSpecA(file, spec4) == TRUE, "PathMatchSpec: Spec4 failed\n");
889 todo_wine ok (PathMatchSpecA(file, spec5) == TRUE, "PathMatchSpec: Spec5 failed\n");
890 todo_wine ok (PathMatchSpecA(file, spec6) == TRUE, "PathMatchSpec: Spec6 failed\n");
891 ok (PathMatchSpecA(file, spec7) == FALSE, "PathMatchSpec: Spec7 failed\n");
892 ok (PathMatchSpecA(file, spec8) == TRUE, "PathMatchSpec: Spec8 failed\n");
893 ok (PathMatchSpecA(file, spec9) == FALSE, "PathMatchSpec: Spec9 failed\n");
894 ok (PathMatchSpecA(file, spec10) == TRUE, "PathMatchSpec: Spec10 failed\n");
895 ok (PathMatchSpecA(file, spec11) == TRUE, "PathMatchSpec: Spec11 failed\n");
896 ok (PathMatchSpecA(file, spec12) == TRUE, "PathMatchSpec: Spec12 failed\n");
897 ok (PathMatchSpecA(file, spec13) == TRUE, "PathMatchSpec: Spec13 failed\n");
900 static void test_PathCombineW(void)
902 LPWSTR wszString, wszString2;
904 wszString2 = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
907 wszString = pPathCombineW(NULL, NULL, NULL);
908 ok (wszString == NULL, "Expected a NULL return\n");
911 wszString = pPathCombineW(wszString2, NULL, NULL);
912 ok (wszString == NULL, "Expected a NULL return\n");
914 HeapFree(GetProcessHeap(), 0, wszString2);
917 #define LONG_LEN (MAX_PATH * 2)
918 #define HALF_LEN (MAX_PATH / 2 + 1)
920 static void test_PathCombineA(void)
924 char too_long[LONG_LEN];
925 char one[HALF_LEN], two[HALF_LEN];
928 SetLastError(0xdeadbeef);
929 str = PathCombineA(NULL, "C:\\", "one\\two\\three");
930 ok(str == NULL, "Expected NULL, got %p\n", str);
931 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
933 /* try NULL dest and NULL directory */
934 SetLastError(0xdeadbeef);
935 str = PathCombineA(NULL, NULL, "one\\two\\three");
936 ok(str == NULL, "Expected NULL, got %p\n", str);
937 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
940 SetLastError(0xdeadbeef);
941 str = PathCombineA(NULL, NULL, NULL);
942 ok(str == NULL, "Expected NULL, got %p\n", str);
943 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
945 /* try NULL file part */
946 SetLastError(0xdeadbeef);
947 lstrcpyA(dest, "control");
948 str = PathCombineA(dest, "C:\\", NULL);
949 ok(str == dest, "Expected str == dest, got %p\n", str);
950 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
951 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
953 /* try empty file part */
954 SetLastError(0xdeadbeef);
955 lstrcpyA(dest, "control");
956 str = PathCombineA(dest, "C:\\", "");
957 ok(str == dest, "Expected str == dest, got %p\n", str);
958 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
959 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
961 /* try empty directory and file part */
962 SetLastError(0xdeadbeef);
963 lstrcpyA(dest, "control");
964 str = PathCombineA(dest, "", "");
965 ok(str == dest, "Expected str == dest, got %p\n", str);
966 ok(!lstrcmp(str, "\\"), "Expected \\, got %s\n", str);
967 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
969 /* try NULL directory */
970 SetLastError(0xdeadbeef);
971 lstrcpyA(dest, "control");
972 str = PathCombineA(dest, NULL, "one\\two\\three");
973 ok(str == dest, "Expected str == dest, got %p\n", str);
974 ok(!lstrcmp(str, "one\\two\\three"), "Expected one\\two\\three, got %s\n", str);
975 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
977 /* try NULL directory and empty file part */
978 SetLastError(0xdeadbeef);
979 lstrcpyA(dest, "control");
980 str = PathCombineA(dest, NULL, "");
981 ok(str == dest, "Expected str == dest, got %p\n", str);
982 ok(!lstrcmp(str, "\\"), "Expected \\, got %s\n", str);
983 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
985 /* try NULL directory and file part */
986 SetLastError(0xdeadbeef);
987 lstrcpyA(dest, "control");
988 str = PathCombineA(dest, NULL, NULL);
989 ok(str == NULL, "Expected str == NULL, got %p\n", str);
992 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
994 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
996 /* try directory without backslash */
997 SetLastError(0xdeadbeef);
998 lstrcpyA(dest, "control");
999 str = PathCombineA(dest, "C:", "one\\two\\three");
1000 ok(str == dest, "Expected str == dest, got %p\n", str);
1001 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
1002 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1004 /* try directory with backslash */
1005 SetLastError(0xdeadbeef);
1006 lstrcpyA(dest, "control");
1007 str = PathCombineA(dest, "C:\\", "one\\two\\three");
1008 ok(str == dest, "Expected str == dest, got %p\n", str);
1009 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
1010 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1012 /* try directory with backslash and file with prepended backslash */
1013 SetLastError(0xdeadbeef);
1014 lstrcpyA(dest, "control");
1015 str = PathCombineA(dest, "C:\\", "\\one\\two\\three");
1016 ok(str == dest, "Expected str == dest, got %p\n", str);
1017 ok(!lstrcmp(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str);
1018 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1020 /* try previous test, with backslash appended as well */
1021 SetLastError(0xdeadbeef);
1022 lstrcpyA(dest, "control");
1023 str = PathCombineA(dest, "C:\\", "\\one\\two\\three\\");
1024 ok(str == dest, "Expected str == dest, got %p\n", str);
1025 ok(!lstrcmp(str, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str);
1026 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1028 /* try a relative directory */
1029 SetLastError(0xdeadbeef);
1030 lstrcpyA(dest, "control");
1031 str = PathCombineA(dest, "relative\\dir", "\\one\\two\\three\\");
1032 ok(str == dest, "Expected str == dest, got %p\n", str);
1033 ok(!lstrcmp(str, "one\\two\\three\\"), "Expected one\\two\\three\\, got %s\n", str);
1034 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1036 /* try forward slashes */
1037 SetLastError(0xdeadbeef);
1038 lstrcpyA(dest, "control");
1039 str = PathCombineA(dest, "C:\\", "one/two/three\\");
1040 ok(str == dest, "Expected str == dest, got %p\n", str);
1041 ok(!lstrcmp(str, "C:\\one/two/three\\"), "Expected one/two/three\\, got %s\n", str);
1042 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1044 /* try a really weird directory */
1045 SetLastError(0xdeadbeef);
1046 lstrcpyA(dest, "control");
1047 str = PathCombineA(dest, "C:\\/\\/", "\\one\\two\\three\\");
1048 ok(str == dest, "Expected str == dest, got %p\n", str);
1049 ok(!lstrcmp(str, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str);
1050 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1053 SetLastError(0xdeadbeef);
1054 lstrcpyA(dest, "control");
1055 str = PathCombineA(dest, "C:\\", "one\\..\\two\\.\\three");
1056 ok(str == dest, "Expected str == dest, got %p\n", str);
1057 ok(!lstrcmp(str, "C:\\two\\three"), "Expected C:\\two\\three, got %s\n", str);
1058 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1060 /* try .. as file */
1061 /* try forward slashes */
1062 SetLastError(0xdeadbeef);
1063 lstrcpyA(dest, "control");
1064 str = PathCombineA(dest, "C:\\", "..");
1065 ok(str == dest, "Expected str == dest, got %p\n", str);
1066 ok(!lstrcmp(str, "C:\\"), "Expected C:\\, got %s\n", str);
1067 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1069 memset(too_long, 'a', LONG_LEN);
1070 too_long[LONG_LEN - 1] = '\0';
1072 /* try a file longer than MAX_PATH */
1073 SetLastError(0xdeadbeef);
1074 lstrcpyA(dest, "control");
1075 str = PathCombineA(dest, "C:\\", too_long);
1078 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1079 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
1080 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1083 /* try a directory longer than MAX_PATH */
1084 SetLastError(0xdeadbeef);
1085 lstrcpyA(dest, "control");
1086 str = PathCombineA(dest, too_long, "one\\two\\three");
1089 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1090 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
1091 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1094 memset(one, 'b', HALF_LEN);
1095 memset(two, 'c', HALF_LEN);
1096 one[HALF_LEN - 1] = '\0';
1097 two[HALF_LEN - 1] = '\0';
1099 /* destination string is longer than MAX_PATH, but not the constituent parts */
1100 SetLastError(0xdeadbeef);
1101 lstrcpyA(dest, "control");
1102 str = PathCombineA(dest, one, two);
1105 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1106 ok(lstrlenA(dest) == 0, "Expected 0 length, got %i\n", lstrlenA(dest));
1108 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1111 static void test_PathAddBackslash(void)
1114 char path[MAX_PATH];
1115 char too_long[LONG_LEN];
1117 /* try a NULL path */
1118 SetLastError(0xdeadbeef);
1119 str = PathAddBackslashA(NULL);
1120 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1121 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1123 /* try an empty path */
1125 SetLastError(0xdeadbeef);
1126 str = PathAddBackslashA(path);
1127 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1128 ok(lstrlenA(path) == 0, "Expected empty string, got %i\n", lstrlenA(path));
1129 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1131 /* try a relative path */
1132 lstrcpyA(path, "one\\two");
1133 SetLastError(0xdeadbeef);
1134 str = PathAddBackslashA(path);
1135 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1136 ok(!lstrcmp(path, "one\\two\\"), "Expected one\\two\\, got %s\n", path);
1137 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1140 lstrcpyA(path, "one\\..\\two");
1141 SetLastError(0xdeadbeef);
1142 str = PathAddBackslashA(path);
1143 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1144 ok(!lstrcmp(path, "one\\..\\two\\"), "Expected one\\..\\two\\, got %s\n", path);
1145 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1147 /* try just a space */
1148 lstrcpyA(path, " ");
1149 SetLastError(0xdeadbeef);
1150 str = PathAddBackslashA(path);
1151 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1152 ok(!lstrcmp(path, " \\"), "Expected \\, got %s\n", path);
1153 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1155 /* path already has backslash */
1156 lstrcpyA(path, "C:\\one\\");
1157 SetLastError(0xdeadbeef);
1158 str = PathAddBackslashA(path);
1159 ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str);
1160 ok(!lstrcmp(path, "C:\\one\\"), "Expected C:\\one\\, got %s\n", path);
1161 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1163 memset(too_long, 'a', LONG_LEN);
1164 too_long[LONG_LEN - 1] = '\0';
1166 /* path is longer than MAX_PATH */
1167 SetLastError(0xdeadbeef);
1168 str = PathAddBackslashA(too_long);
1169 ok(str == NULL, "Expected str == NULL, got %p\n", str);
1170 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1173 static void test_PathAppendA(void)
1175 char path[MAX_PATH];
1176 char too_long[LONG_LEN];
1177 char one[HALF_LEN], two[HALF_LEN];
1180 lstrcpy(path, "C:\\one");
1182 /* try NULL pszMore */
1183 SetLastError(0xdeadbeef);
1184 res = PathAppendA(path, NULL);
1185 ok(!res, "Expected failure\n");
1186 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1187 ok(!lstrcmp(path, "C:\\one"), "Expected C:\\one, got %s\n", path);
1189 /* try empty pszMore */
1190 SetLastError(0xdeadbeef);
1191 res = PathAppendA(path, "");
1192 ok(res, "Expected success\n");
1193 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1194 ok(!lstrcmp(path, "C:\\one"), "Expected C:\\one, got %s\n", path);
1196 /* try NULL pszPath */
1197 SetLastError(0xdeadbeef);
1198 res = PathAppendA(NULL, "two\\three");
1199 ok(!res, "Expected failure\n");
1200 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1202 /* try empty pszPath */
1204 SetLastError(0xdeadbeef);
1205 res = PathAppendA(path, "two\\three");
1206 ok(res, "Expected success\n");
1207 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1208 ok(!lstrcmp(path, "two\\three"), "Expected \\two\\three, got %s\n", path);
1210 /* try empty pszPath and empty pszMore */
1212 SetLastError(0xdeadbeef);
1213 res = PathAppendA(path, "");
1214 ok(res, "Expected success\n");
1215 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1216 ok(!lstrcmp(path, "\\"), "Expected \\, got %s\n", path);
1218 /* try legit params */
1219 lstrcpy(path, "C:\\one");
1220 SetLastError(0xdeadbeef);
1221 res = PathAppendA(path, "two\\three");
1222 ok(res, "Expected success\n");
1223 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1224 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
1226 /* try pszPath with backslash after it */
1227 lstrcpy(path, "C:\\one\\");
1228 SetLastError(0xdeadbeef);
1229 res = PathAppendA(path, "two\\three");
1230 ok(res, "Expected success\n");
1231 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1232 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
1234 /* try pszMore with backslash before it */
1235 lstrcpy(path, "C:\\one");
1236 SetLastError(0xdeadbeef);
1237 res = PathAppendA(path, "\\two\\three");
1238 ok(res, "Expected success\n");
1239 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1240 ok(!lstrcmp(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path);
1242 /* try pszMore with backslash after it */
1243 lstrcpy(path, "C:\\one");
1244 SetLastError(0xdeadbeef);
1245 res = PathAppendA(path, "two\\three\\");
1246 ok(res, "Expected success\n");
1247 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1248 ok(!lstrcmp(path, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", path);
1250 /* try spaces in pszPath */
1251 lstrcpy(path, "C: \\ one ");
1252 SetLastError(0xdeadbeef);
1253 res = PathAppendA(path, "two\\three");
1254 ok(res, "Expected success\n");
1255 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1256 ok(!lstrcmp(path, "C: \\ one \\two\\three"), "Expected C: \\ one \\two\\three, got %s\n", path);
1258 /* try spaces in pszMore */
1259 lstrcpy(path, "C:\\one");
1260 SetLastError(0xdeadbeef);
1261 res = PathAppendA(path, " two \\ three ");
1262 ok(res, "Expected success\n");
1263 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1264 ok(!lstrcmp(path, "C:\\one\\ two \\ three "), "Expected 'C:\\one\\ two \\ three ', got %s\n", path);
1266 /* pszPath is too long */
1267 memset(too_long, 'a', LONG_LEN);
1268 too_long[LONG_LEN - 1] = '\0';
1269 SetLastError(0xdeadbeef);
1270 res = PathAppendA(too_long, "two\\three");
1273 ok(!res, "Expected failure\n");
1274 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1275 ok(lstrlen(too_long) == 0, "Expected length of too_long to be zero, got %i\n", lstrlen(too_long));
1278 /* pszMore is too long */
1279 lstrcpy(path, "C:\\one");
1280 memset(too_long, 'a', LONG_LEN);
1281 too_long[LONG_LEN - 1] = '\0';
1282 SetLastError(0xdeadbeef);
1283 res = PathAppendA(path, too_long);
1286 ok(!res, "Expected failure\n");
1287 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1288 ok(lstrlen(path) == 0, "Expected length of path to be zero, got %i\n", lstrlen(path));
1291 /* both params combined are too long */
1292 memset(one, 'a', HALF_LEN);
1293 one[HALF_LEN - 1] = '\0';
1294 memset(two, 'b', HALF_LEN);
1295 two[HALF_LEN - 1] = '\0';
1296 SetLastError(0xdeadbeef);
1297 res = PathAppendA(one, two);
1300 ok(!res, "Expected failure\n");
1301 ok(lstrlen(one) == 0, "Expected length of one to be zero, got %i\n", lstrlen(one));
1303 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1306 static void test_PathCanonicalizeA(void)
1308 char dest[MAX_PATH];
1309 char too_long[LONG_LEN];
1312 /* try a NULL source */
1313 lstrcpy(dest, "test");
1314 SetLastError(0xdeadbeef);
1315 res = PathCanonicalizeA(dest, NULL);
1316 ok(!res, "Expected failure\n");
1317 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1318 "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
1321 ok(!lstrcmp(dest, "test"), "Expected test, got %s\n", dest);
1324 /* try an empty source */
1325 lstrcpy(dest, "test");
1326 SetLastError(0xdeadbeef);
1327 res = PathCanonicalizeA(dest, "");
1328 ok(res, "Expected success\n");
1329 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1330 ok(!lstrcmp(dest, "\\"), "Expected \\, got %s\n", dest);
1332 /* try a NULL dest */
1333 SetLastError(0xdeadbeef);
1334 res = PathCanonicalizeA(NULL, "C:\\");
1335 ok(!res, "Expected failure\n");
1336 ok(GetLastError() == ERROR_INVALID_PARAMETER,
1337 "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
1339 /* try empty dest */
1341 SetLastError(0xdeadbeef);
1342 res = PathCanonicalizeA(dest, "C:\\");
1343 ok(res, "Expected success\n");
1344 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1345 ok(!lstrcmp(dest, "C:\\"), "Expected C:\\, got %s\n", dest);
1347 /* try non-empty dest */
1348 lstrcpy(dest, "test");
1349 SetLastError(0xdeadbeef);
1350 res = PathCanonicalizeA(dest, "C:\\");
1351 ok(res, "Expected success\n");
1352 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1353 ok(!lstrcmp(dest, "C:\\"), "Expected C:\\, got %s\n", dest);
1355 /* try a space for source */
1356 lstrcpy(dest, "test");
1357 SetLastError(0xdeadbeef);
1358 res = PathCanonicalizeA(dest, " ");
1359 ok(res, "Expected success\n");
1360 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1361 ok(!lstrcmp(dest, " "), "Expected ' ', got %s\n", dest);
1363 /* try a relative path */
1364 lstrcpy(dest, "test");
1365 SetLastError(0xdeadbeef);
1366 res = PathCanonicalizeA(dest, "one\\two");
1367 ok(res, "Expected success\n");
1368 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1369 ok(!lstrcmp(dest, "one\\two"), "Expected one\\two, got %s\n", dest);
1371 /* try current dir and previous dir */
1372 lstrcpy(dest, "test");
1373 SetLastError(0xdeadbeef);
1374 res = PathCanonicalizeA(dest, "C:\\one\\.\\..\\two\\three\\..");
1375 ok(res, "Expected success\n");
1376 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1377 ok(!lstrcmp(dest, "C:\\two"), "Expected C:\\two, got %s\n", dest);
1379 /* try simple forward slashes */
1380 lstrcpy(dest, "test");
1381 SetLastError(0xdeadbeef);
1382 res = PathCanonicalizeA(dest, "C:\\one/two/three\\four/five\\six");
1383 ok(res, "Expected success\n");
1384 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1385 ok(!lstrcmp(dest, "C:\\one/two/three\\four/five\\six"),
1386 "Expected C:\\one/two/three\\four/five\\six, got %s\n", dest);
1388 /* try simple forward slashes with same dir */
1389 lstrcpy(dest, "test");
1390 SetLastError(0xdeadbeef);
1391 res = PathCanonicalizeA(dest, "C:\\one/.\\two");
1392 ok(res, "Expected success\n");
1393 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1394 ok(!lstrcmp(dest, "C:\\one/.\\two"), "Expected C:\\one/.\\two, got %s\n", dest);
1396 /* try simple forward slashes with change dir */
1397 lstrcpy(dest, "test");
1398 SetLastError(0xdeadbeef);
1399 res = PathCanonicalizeA(dest, "C:\\one/.\\two\\..");
1400 ok(res, "Expected success\n");
1401 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1402 ok(!lstrcmp(dest, "C:\\one/."), "Expected C:\\one/., got %s\n", dest);
1404 /* try forward slashes with change dirs
1405 * NOTE: if there is a forward slash in between two backslashes,
1406 * everything in between the two backslashes is considered on dir
1408 lstrcpy(dest, "test");
1409 SetLastError(0xdeadbeef);
1410 res = PathCanonicalizeA(dest, "C:\\one/.\\..\\two/three\\..\\four/.five");
1411 ok(res, "Expected success\n");
1412 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1413 ok(!lstrcmp(dest, "C:\\four/.five"), "Expected C:\\four/.five, got %s\n", dest);
1415 /* try src is too long */
1416 memset(too_long, 'a', LONG_LEN);
1417 too_long[LONG_LEN - 1] = '\0';
1418 lstrcpy(dest, "test");
1419 SetLastError(0xdeadbeef);
1420 res = PathCanonicalizeA(dest, too_long);
1423 ok(!res, "Expected failure\n");
1424 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1426 ok(lstrlen(too_long) == LONG_LEN - 1, "Expected length LONG_LEN - 1, got %i\n", lstrlen(too_long));
1429 static void test_PathFindExtensionA(void)
1432 char path[MAX_PATH];
1433 char too_long[LONG_LEN];
1435 /* try a NULL path */
1436 SetLastError(0xdeadbeef);
1437 ext = PathFindExtensionA(NULL);
1438 ok(ext == NULL, "Expected NULL, got %p\n", ext);
1439 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1441 /* try an empty path */
1443 SetLastError(0xdeadbeef);
1444 ext = PathFindExtensionA(path);
1445 ok(ext == path, "Expected ext == path, got %p\n", ext);
1446 ok(lstrlen(ext) == 0, "Expected length 0, got %i\n", lstrlen(ext));
1447 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1449 /* try a path without an extension */
1450 lstrcpy(path, "file");
1451 SetLastError(0xdeadbeef);
1452 ext = PathFindExtensionA(path);
1453 ok(ext == path + lstrlen(path), "Expected ext == path, got %p\n", ext);
1454 ok(lstrlen(ext) == 0, "Expected length 0, got %i\n", lstrlen(ext));
1455 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1457 /* try a path with an extension */
1458 lstrcpy(path, "file.txt");
1459 SetLastError(0xdeadbeef);
1460 ext = PathFindExtensionA(path);
1461 ok(ext == path + lstrlen("file"),
1462 "Expected ext == path + lstrlen(\"file\"), got %p\n", ext);
1463 ok(!lstrcmp(ext, ".txt"), "Expected .txt, got %s\n", ext);
1464 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1466 /* try a path with two extensions */
1467 lstrcpy(path, "file.txt.doc");
1468 SetLastError(0xdeadbeef);
1469 ext = PathFindExtensionA(path);
1470 ok(ext == path + lstrlen("file.txt"),
1471 "Expected ext == path + lstrlen(\"file.txt\"), got %p\n", ext);
1472 ok(!lstrcmp(ext, ".doc"), "Expected .txt, got %s\n", ext);
1473 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1475 /* try a path longer than MAX_PATH without an extension*/
1476 memset(too_long, 'a', LONG_LEN);
1477 too_long[LONG_LEN - 1] = '\0';
1478 SetLastError(0xdeadbeef);
1479 ext = PathFindExtensionA(too_long);
1480 ok(ext == too_long + LONG_LEN - 1, "Expected ext == too_long + LONG_LEN - 1, got %p\n", ext);
1481 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1483 /* try a path longer than MAX_PATH with an extension*/
1484 memset(too_long, 'a', LONG_LEN);
1485 too_long[LONG_LEN - 1] = '\0';
1486 lstrcpy(too_long + 300, ".abcde");
1487 too_long[lstrlen(too_long)] = 'a';
1488 SetLastError(0xdeadbeef);
1489 ext = PathFindExtensionA(too_long);
1490 ok(ext == too_long + 300, "Expected ext == too_long + 300, got %p\n", ext);
1491 ok(lstrlen(ext) == LONG_LEN - 301, "Expected LONG_LEN - 301, got %i\n", lstrlen(ext));
1492 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1495 static void test_PathBuildRootA(void)
1499 char root_expected[26][4];
1503 /* set up the expected paths */
1504 for (drive = 'A'; drive <= 'Z'; drive++)
1505 sprintf(root_expected[drive - 'A'], "%c:\\", drive);
1507 /* test the expected values */
1508 for (j = 0; j < 26; j++)
1510 SetLastError(0xdeadbeef);
1511 lstrcpy(path, "aaaaaaaaa");
1512 root = PathBuildRootA(path, j);
1513 ok(root == path, "Expected root == path, got %p\n", root);
1514 ok(!lstrcmp(root, root_expected[j]), "Expected %s, got %s\n", root_expected[j], root);
1515 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1518 /* test a negative drive number */
1519 SetLastError(0xdeadbeef);
1520 lstrcpy(path, "aaaaaaaaa");
1521 root = PathBuildRootA(path, -1);
1522 ok(root == path, "Expected root == path, got %p\n", root);
1523 ok(!lstrcmp(path, "aaaaaaaaa"), "Expected aaaaaaaaa, got %s\n", path);
1524 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1526 /* test a drive number greater than 25 */
1527 SetLastError(0xdeadbeef);
1528 lstrcpy(path, "aaaaaaaaa");
1529 root = PathBuildRootA(path, 26);
1530 ok(root == path, "Expected root == path, got %p\n", root);
1531 ok(!lstrcmp(path, "aaaaaaaaa"), "Expected aaaaaaaaa, got %s\n", path);
1532 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1534 /* length of path is less than 4 */
1535 SetLastError(0xdeadbeef);
1536 lstrcpy(path, "aa");
1537 root = PathBuildRootA(path, 0);
1538 ok(root == path, "Expected root == path, got %p\n", root);
1539 ok(!lstrcmp(path, "A:\\"), "Expected A:\\, got %s\n", path);
1540 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1543 SetLastError(0xdeadbeef);
1544 root = PathBuildRootA(NULL, 0);
1545 ok(root == NULL, "Expected root == NULL, got %p\n", root);
1546 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1549 static void test_PathCommonPrefixA(void)
1551 char path1[MAX_PATH], path2[MAX_PATH];
1555 /* test NULL path1 */
1556 SetLastError(0xdeadbeef);
1557 lstrcpy(path2, "C:\\");
1558 lstrcpy(out, "aaa");
1559 count = PathCommonPrefixA(NULL, path2, out);
1560 ok(count == 0, "Expected 0, got %i\n", count);
1563 ok(!lstrcmp(out, "aaa"), "Expected aaa, got %s\n", out);
1565 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1566 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1568 /* test NULL path2 */
1569 SetLastError(0xdeadbeef);
1570 lstrcpy(path1, "C:\\");
1571 lstrcpy(out, "aaa");
1572 count = PathCommonPrefixA(path1, NULL, out);
1573 ok(count == 0, "Expected 0, got %i\n", count);
1576 ok(!lstrcmp(out, "aaa"), "Expected aaa, got %s\n", out);
1578 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1579 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1581 /* test empty path1 */
1582 SetLastError(0xdeadbeef);
1584 lstrcpy(path2, "C:\\");
1585 lstrcpy(out, "aaa");
1586 count = PathCommonPrefixA(path1, path2, out);
1587 ok(count == 0, "Expected 0, got %i\n", count);
1588 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1589 ok(lstrlen(path1) == 0, "Expected 0 length path1, got %i\n", lstrlen(path1));
1590 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1591 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1593 /* test empty path1 */
1594 SetLastError(0xdeadbeef);
1596 lstrcpy(path1, "C:\\");
1597 lstrcpy(out, "aaa");
1598 count = PathCommonPrefixA(path1, path2, out);
1599 ok(count == 0, "Expected 0, got %i\n", count);
1600 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1601 ok(lstrlen(path2) == 0, "Expected 0 length path2, got %i\n", lstrlen(path2));
1602 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1603 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1605 /* paths are legit, out is NULL */
1606 SetLastError(0xdeadbeef);
1607 lstrcpy(path1, "C:\\");
1608 lstrcpy(path2, "C:\\");
1609 count = PathCommonPrefixA(path1, path2, NULL);
1610 ok(count == 3, "Expected 3, got %i\n", count);
1611 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1612 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1613 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1615 /* all parameters legit */
1616 SetLastError(0xdeadbeef);
1617 lstrcpy(path1, "C:\\");
1618 lstrcpy(path2, "C:\\");
1619 lstrcpy(out, "aaa");
1620 count = PathCommonPrefixA(path1, path2, out);
1621 ok(count == 3, "Expected 3, got %i\n", count);
1622 ok(!lstrcmp(path1, "C:\\"), "Expected C:\\, got %s\n", path1);
1623 ok(!lstrcmp(path2, "C:\\"), "Expected C:\\, got %s\n", path2);
1624 ok(!lstrcmp(out, "C:\\"), "Expected C:\\, got %s\n", out);
1625 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1627 /* path1 and path2 not the same, but common prefix */
1628 SetLastError(0xdeadbeef);
1629 lstrcpy(path1, "C:\\one\\two");
1630 lstrcpy(path2, "C:\\one\\three");
1631 lstrcpy(out, "aaa");
1632 count = PathCommonPrefixA(path1, path2, out);
1633 ok(count == 6, "Expected 6, got %i\n", count);
1634 ok(!lstrcmp(path1, "C:\\one\\two"), "Expected C:\\one\\two, got %s\n", path1);
1635 ok(!lstrcmp(path2, "C:\\one\\three"), "Expected C:\\one\\three, got %s\n", path2);
1636 ok(!lstrcmp(out, "C:\\one"), "Expected C:\\one, got %s\n", out);
1637 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1640 SetLastError(0xdeadbeef);
1641 lstrcpy(path1, "one\\.two");
1642 lstrcpy(path2, "one\\.three");
1643 lstrcpy(out, "aaa");
1644 count = PathCommonPrefixA(path1, path2, out);
1645 ok(count == 3, "Expected 3, got %i\n", count);
1646 ok(!lstrcmp(path1, "one\\.two"), "Expected one\\.two, got %s\n", path1);
1647 ok(!lstrcmp(path2, "one\\.three"), "Expected one\\.three, got %s\n", path2);
1648 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1649 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1652 SetLastError(0xdeadbeef);
1653 lstrcpy(path1, "one\\..two");
1654 lstrcpy(path2, "one\\..three");
1655 lstrcpy(out, "aaa");
1656 count = PathCommonPrefixA(path1, path2, out);
1657 ok(count == 3, "Expected 3, got %i\n", count);
1658 ok(!lstrcmp(path1, "one\\..two"), "Expected one\\..two, got %s\n", path1);
1659 ok(!lstrcmp(path2, "one\\..three"), "Expected one\\..three, got %s\n", path2);
1660 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1661 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1663 /* try ... prefix */
1664 SetLastError(0xdeadbeef);
1665 lstrcpy(path1, "one\\...two");
1666 lstrcpy(path2, "one\\...three");
1667 lstrcpy(out, "aaa");
1668 count = PathCommonPrefixA(path1, path2, out);
1669 ok(count == 3, "Expected 3, got %i\n", count);
1670 ok(!lstrcmp(path1, "one\\...two"), "Expected one\\...two, got %s\n", path1);
1671 ok(!lstrcmp(path2, "one\\...three"), "Expected one\\...three, got %s\n", path2);
1672 ok(!lstrcmp(out, "one"), "Expected one, got %s\n", out);
1673 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1676 SetLastError(0xdeadbeef);
1677 lstrcpy(path1, "one\\.\\two");
1678 lstrcpy(path2, "one\\.\\three");
1679 lstrcpy(out, "aaa");
1680 count = PathCommonPrefixA(path1, path2, out);
1681 ok(count == 5, "Expected 5, got %i\n", count);
1682 ok(!lstrcmp(path1, "one\\.\\two"), "Expected one\\.\\two, got %s\n", path1);
1683 ok(!lstrcmp(path2, "one\\.\\three"), "Expected one\\.\\three, got %s\n", path2);
1684 ok(!lstrcmp(out, "one\\."), "Expected one\\., got %s\n", out);
1685 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1687 /* try ..\ prefix */
1688 SetLastError(0xdeadbeef);
1689 lstrcpy(path1, "one\\..\\two");
1690 lstrcpy(path2, "one\\..\\three");
1691 lstrcpy(out, "aaa");
1692 count = PathCommonPrefixA(path1, path2, out);
1693 ok(count == 6, "Expected 6, got %i\n", count);
1694 ok(!lstrcmp(path1, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1);
1695 ok(!lstrcmp(path2, "one\\..\\three"), "Expected one\\..\\three, got %s\n", path2);
1696 ok(!lstrcmp(out, "one\\.."), "Expected one\\.., got %s\n", out);
1697 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1699 /* try ...\\ prefix */
1700 SetLastError(0xdeadbeef);
1701 lstrcpy(path1, "one\\...\\two");
1702 lstrcpy(path2, "one\\...\\three");
1703 lstrcpy(out, "aaa");
1704 count = PathCommonPrefixA(path1, path2, out);
1705 ok(count == 7, "Expected 7, got %i\n", count);
1706 ok(!lstrcmp(path1, "one\\...\\two"), "Expected one\\...\\two, got %s\n", path1);
1707 ok(!lstrcmp(path2, "one\\...\\three"), "Expected one\\...\\three, got %s\n", path2);
1708 ok(!lstrcmp(out, "one\\..."), "Expected one\\..., got %s\n", out);
1709 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1711 /* try prefix that is not an msdn labeled prefix type */
1712 SetLastError(0xdeadbeef);
1713 lstrcpy(path1, "same");
1714 lstrcpy(path2, "same");
1715 lstrcpy(out, "aaa");
1716 count = PathCommonPrefixA(path1, path2, out);
1717 ok(count == 4, "Expected 4, got %i\n", count);
1718 ok(!lstrcmp(path1, "same"), "Expected same, got %s\n", path1);
1719 ok(!lstrcmp(path2, "same"), "Expected same, got %s\n", path2);
1720 ok(!lstrcmp(out, "same"), "Expected same, got %s\n", out);
1721 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1723 /* try . after directory */
1724 SetLastError(0xdeadbeef);
1725 lstrcpy(path1, "one\\mid.\\two");
1726 lstrcpy(path2, "one\\mid.\\three");
1727 lstrcpy(out, "aaa");
1728 count = PathCommonPrefixA(path1, path2, out);
1729 ok(count == 8, "Expected 8, got %i\n", count);
1730 ok(!lstrcmp(path1, "one\\mid.\\two"), "Expected one\\mid.\\two, got %s\n", path1);
1731 ok(!lstrcmp(path2, "one\\mid.\\three"), "Expected one\\mid.\\three, got %s\n", path2);
1732 ok(!lstrcmp(out, "one\\mid."), "Expected one\\mid., got %s\n", out);
1733 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1735 /* try . in the middle of a directory */
1736 SetLastError(0xdeadbeef);
1737 lstrcpy(path1, "one\\mid.end\\two");
1738 lstrcpy(path2, "one\\mid.end\\three");
1739 lstrcpy(out, "aaa");
1740 count = PathCommonPrefixA(path1, path2, out);
1741 ok(count == 11, "Expected 11, got %i\n", count);
1742 ok(!lstrcmp(path1, "one\\mid.end\\two"), "Expected one\\mid.end\\two, got %s\n", path1);
1743 ok(!lstrcmp(path2, "one\\mid.end\\three"), "Expected one\\mid.end\\three, got %s\n", path2);
1744 ok(!lstrcmp(out, "one\\mid.end"), "Expected one\\mid.end, got %s\n", out);
1745 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1747 /* try comparing a .. with the expanded path */
1748 SetLastError(0xdeadbeef);
1749 lstrcpy(path1, "one\\..\\two");
1750 lstrcpy(path2, "two");
1751 lstrcpy(out, "aaa");
1752 count = PathCommonPrefixA(path1, path2, out);
1753 ok(count == 0, "Expected 0, got %i\n", count);
1754 ok(!lstrcmp(path1, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1);
1755 ok(!lstrcmp(path2, "two"), "Expected two, got %s\n", path2);
1756 ok(lstrlen(out) == 0, "Expected 0 length out, got %i\n", lstrlen(out));
1757 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError());
1762 hShlwapi = LoadLibraryA("shlwapi.dll");
1763 if (!hShlwapi) return;
1767 test_UrlCanonicalize();
1770 test_UrlCreateFromPath();
1774 test_PathSearchAndQualify();
1775 test_PathCreateFromUrl();
1778 test_PathAddBackslash();
1779 test_PathMakePretty();
1780 test_PathMatchSpec();
1782 /* For whatever reason, PathIsValidCharA and PathAppendA share the same
1783 * ordinal number in some native versions. Check this to prevent a crash.
1785 pPathIsValidCharA = (void*)GetProcAddress(hShlwapi, (LPSTR)455);
1786 if (pPathIsValidCharA && pPathIsValidCharA != (void*)GetProcAddress(hShlwapi, "PathAppendA"))
1788 test_PathIsValidCharA();
1790 pPathIsValidCharW = (void*)GetProcAddress(hShlwapi, (LPSTR)456);
1791 if (pPathIsValidCharW) test_PathIsValidCharW();
1794 pPathCombineW = (void*)GetProcAddress(hShlwapi, "PathCombineW");
1796 test_PathCombineW();
1798 test_PathCombineA();
1800 test_PathCanonicalizeA();
1801 test_PathFindExtensionA();
1802 test_PathBuildRootA();
1803 test_PathCommonPrefixA();