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", 0, S_OK
, "file:///c:/tests/foo%20bar"},
72 {"file:///c:/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\\../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%20bar", URL_FILE_USE_PATHURL
, S_OK
, "file://c:\\\\tests\\foo bar"},
77 {"file:///c:\\tests\\foo bar", 0, S_OK
, "file:///c:/tests/foo bar"},
78 {"file:///c:\\tests\\foo bar", URL_DONT_SIMPLIFY
, S_OK
, "file:///c:/tests/foo bar"},
79 {"http://www.winehq.org/site/about", URL_FILE_USE_PATHURL
, S_OK
, "http://www.winehq.org/site/about"},
80 {"file_://www.winehq.org/site/about", URL_FILE_USE_PATHURL
, S_OK
, "file_://www.winehq.org/site/about"},
81 {"c:\\dir\\file", 0, S_OK
, "file:///c:/dir/file"},
82 {"file:///c:\\dir\\file", 0, S_OK
, "file:///c:/dir/file"},
83 {"c:dir\\file", 0, S_OK
, "file:///c:dir/file"},
84 {"c:\\tests\\foo bar", URL_FILE_USE_PATHURL
, S_OK
, "file://c:\\tests\\foo bar"},
85 {"c:\\tests\\foo bar", 0, S_OK
, "file:///c:/tests/foo%20bar"},
90 typedef struct _TEST_URL_ESCAPE
{
95 const char *expecturl
;
98 const TEST_URL_ESCAPE TEST_ESCAPE
[] = {
99 {"http://www.winehq.org/tests0", 0, 0, S_OK
, "http://www.winehq.org/tests0"},
100 {"http://www.winehq.org/tests1\n", 0, 0, S_OK
, "http://www.winehq.org/tests1%0A"},
101 {"http://www.winehq.org/tests2\r", 0, 0, S_OK
, "http://www.winehq.org/tests2%0D"},
102 {"http://www.winehq.org/tests3\r", URL_ESCAPE_SPACES_ONLY
|URL_ESCAPE_UNSAFE
, 0, S_OK
, "http://www.winehq.org/tests3\r"},
103 {"http://www.winehq.org/tests4\r", URL_ESCAPE_SPACES_ONLY
, 0, S_OK
, "http://www.winehq.org/tests4\r"},
104 {"http://www.winehq.org/tests5\r", URL_WININET_COMPATIBILITY
|URL_ESCAPE_SPACES_ONLY
, 0, S_OK
, "http://www.winehq.org/tests5\r"},
105 {"/direct/swhelp/series6/6.2i_latestservicepack.dat\r", URL_ESCAPE_SPACES_ONLY
, 0, S_OK
, "/direct/swhelp/series6/6.2i_latestservicepack.dat\r"},
107 {"file://////foo/bar\\baz", 0, 0, S_OK
, "file://foo/bar/baz"},
108 {"file://///foo/bar\\baz", 0, 0, S_OK
, "file://foo/bar/baz"},
109 {"file:////foo/bar\\baz", 0, 0, S_OK
, "file://foo/bar/baz"},
110 {"file:///localhost/foo/bar\\baz", 0, 0, S_OK
, "file:///localhost/foo/bar/baz"},
111 {"file:///foo/bar\\baz", 0, 0, S_OK
, "file:///foo/bar/baz"},
112 {"file://loCalHost/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:/localhost/foo/bar\\baz", 0, 0, S_OK
, "file:///localhost/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:\\foo/bar\\baz", 0, 0, S_OK
, "file:///foo/bar/baz"},
118 {"file:\\\\foo/bar\\baz", 0, 0, S_OK
, "file://foo/bar/baz"},
119 {"file:\\\\\\foo/bar\\baz", 0, 0, S_OK
, "file:///foo/bar/baz"},
120 {"file:\\\\localhost\\foo/bar\\baz", 0, 0, S_OK
, "file:///foo/bar/baz"},
121 {"file:///f oo/b?a r\\baz", 0, 0, S_OK
, "file:///f%20oo/b?a r\\baz"},
122 {"file:///foo/b#a r\\baz", 0, 0, S_OK
, "file:///foo/b%23a%20r/baz"},
123 {"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"},
124 {"file:///f o%o/b?a r\\b%az", URL_ESCAPE_PERCENT
, 0, S_OK
, "file:///f%20o%25o/b?a r\\b%az"},
125 {"file:/foo/bar\\baz", URL_ESCAPE_SEGMENT_ONLY
, 0, S_OK
, "file:%2Ffoo%2Fbar%5Cbaz"},
127 {"foo/b%ar\\ba?z\\", URL_ESCAPE_SEGMENT_ONLY
, 0, S_OK
, "foo%2Fb%ar%5Cba%3Fz%5C"},
128 {"foo/b%ar\\ba?z\\", URL_ESCAPE_PERCENT
| URL_ESCAPE_SEGMENT_ONLY
, 0, S_OK
, "foo%2Fb%25ar%5Cba%3Fz%5C"},
129 {"foo/bar\\ba?z\\", 0, 0, S_OK
, "foo/bar%5Cba?z\\"},
130 {"/foo/bar\\ba?z\\", 0, 0, S_OK
, "/foo/bar%5Cba?z\\"},
131 {"/foo/bar\\ba#z\\", 0, 0, S_OK
, "/foo/bar%5Cba#z\\"},
132 {"/foo/%5C", 0, 0, S_OK
, "/foo/%5C"},
133 {"/foo/%5C", URL_ESCAPE_PERCENT
, 0, S_OK
, "/foo/%255C"},
135 {"http://////foo/bar\\baz", 0, 0, S_OK
, "http://////foo/bar/baz"},
136 {"http://///foo/bar\\baz", 0, 0, S_OK
, "http://///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://localhost/foo/bar\\baz", 0, 0, S_OK
, "http://localhost/foo/bar/baz"},
140 {"http://foo/bar\\baz", 0, 0, S_OK
, "http://foo/bar/baz"},
141 {"http:/foo/bar\\baz", 0, 0, S_OK
, "http:/foo/bar/baz"},
142 {"http:foo/bar\\ba?z\\", 0, 0, S_OK
, "http:foo%2Fbar%2Fba?z\\"},
143 {"http:foo/bar\\ba#z\\", 0, 0, S_OK
, "http:foo%2Fbar%2Fba#z\\"},
144 {"http:\\foo/bar\\baz", 0, 0, S_OK
, "http:/foo/bar/baz"},
145 {"http:\\\\foo/bar\\baz", 0, 0, S_OK
, "http://foo/bar/baz"},
146 {"http:\\\\\\foo/bar\\baz", 0, 0, S_OK
, "http:///foo/bar/baz"},
147 {"http:\\\\\\\\foo/bar\\baz", 0, 0, S_OK
, "http:////foo/bar/baz"},
148 {"http:/fo ?o/b ar\\baz", 0, 0, S_OK
, "http:/fo%20?o/b ar\\baz"},
149 {"http:fo ?o/b ar\\baz", 0, 0, S_OK
, "http:fo%20?o/b ar\\baz"},
150 {"http:/foo/bar\\baz", URL_ESCAPE_SEGMENT_ONLY
, 0, S_OK
, "http:%2Ffoo%2Fbar%5Cbaz"},
152 {"https://foo/bar\\baz", 0, 0, S_OK
, "https://foo/bar/baz"},
153 {"https:/foo/bar\\baz", 0, 0, S_OK
, "https:/foo/bar/baz"},
154 {"https:\\foo/bar\\baz", 0, 0, S_OK
, "https:/foo/bar/baz"},
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://localhost/foo/bar\\baz", 0, 0, S_OK
, "foo://localhost/foo/bar%5Cbaz"},
159 {"foo://foo/bar\\baz", 0, 0, S_OK
, "foo://foo/bar%5Cbaz"},
160 {"foo:/foo/bar\\baz", 0, 0, S_OK
, "foo:/foo/bar%5Cbaz"},
161 {"foo:foo/bar\\baz", 0, 0, S_OK
, "foo:foo%2Fbar%5Cbaz"},
162 {"foo:\\foo/bar\\baz", 0, 0, S_OK
, "foo:%5Cfoo%2Fbar%5Cbaz"},
163 {"foo:/foo/bar\\ba?\\z", 0, 0, S_OK
, "foo:/foo/bar%5Cba?\\z"},
164 {"foo:/foo/bar\\ba#\\z", 0, 0, S_OK
, "foo:/foo/bar%5Cba#\\z"},
166 {"mailto:/fo/o@b\\%a?\\r.b#\\az", 0, 0, S_OK
, "mailto:%2Ffo%2Fo@b%5C%a%3F%5Cr.b%23%5Caz"},
167 {"mailto:fo/o@b\\%a?\\r.b#\\az", 0, 0, S_OK
, "mailto:fo%2Fo@b%5C%a%3F%5Cr.b%23%5Caz"},
168 {"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"},
170 {"ftp:fo/o@bar.baz/foo/bar", 0, 0, S_OK
, "ftp:fo%2Fo@bar.baz%2Ffoo%2Fbar"},
171 {"ftp:/fo/o@bar.baz/foo/bar", 0, 0, S_OK
, "ftp:/fo/o@bar.baz/foo/bar"},
172 {"ftp://fo/o@bar.baz/fo?o\\bar", 0, 0, S_OK
, "ftp://fo/o@bar.baz/fo?o\\bar"},
173 {"ftp://fo/o@bar.baz/fo#o\\bar", 0, 0, S_OK
, "ftp://fo/o@bar.baz/fo#o\\bar"},
174 {"ftp://localhost/o@bar.baz/fo#o\\bar", 0, 0, S_OK
, "ftp://localhost/o@bar.baz/fo#o\\bar"},
175 {"ftp:///fo/o@bar.baz/foo/bar", 0, 0, S_OK
, "ftp:///fo/o@bar.baz/foo/bar"},
176 {"ftp:////fo/o@bar.baz/foo/bar", 0, 0, S_OK
, "ftp:////fo/o@bar.baz/foo/bar"}
179 typedef struct _TEST_URL_COMBINE
{
184 const char *expecturl
;
187 const TEST_URL_COMBINE TEST_COMBINE
[] = {
188 {"http://www.winehq.org/tests", "tests1", 0, S_OK
, "http://www.winehq.org/tests1"},
189 {"http://www.%77inehq.org/tests", "tests1", 0, S_OK
, "http://www.%77inehq.org/tests1"},
190 /*FIXME {"http://www.winehq.org/tests", "../tests2", 0, S_OK, "http://www.winehq.org/tests2"},*/
191 {"http://www.winehq.org/tests/", "../tests3", 0, S_OK
, "http://www.winehq.org/tests3"},
192 {"http://www.winehq.org/tests/test1", "test2", 0, S_OK
, "http://www.winehq.org/tests/test2"},
193 {"http://www.winehq.org/tests/../tests", "tests4", 0, S_OK
, "http://www.winehq.org/tests4"},
194 {"http://www.winehq.org/tests/../tests/", "tests5", 0, S_OK
, "http://www.winehq.org/tests/tests5"},
195 {"http://www.winehq.org/tests/../tests/", "/tests6/..", 0, S_OK
, "http://www.winehq.org/"},
196 {"http://www.winehq.org/tests/../tests/..", "tests7/..", 0, S_OK
, "http://www.winehq.org/"},
197 {"http://www.winehq.org/tests/?query=x&return=y", "tests8", 0, S_OK
, "http://www.winehq.org/tests/tests8"},
198 {"http://www.winehq.org/tests/#example", "tests9", 0, S_OK
, "http://www.winehq.org/tests/tests9"},
199 {"http://www.winehq.org/tests/../tests/", "/tests10/..", URL_DONT_SIMPLIFY
, S_OK
, "http://www.winehq.org/tests10/.."},
200 {"http://www.winehq.org/tests/../", "tests11", URL_DONT_SIMPLIFY
, S_OK
, "http://www.winehq.org/tests/../tests11"},
201 {"file:///C:\\dir\\file.txt", "test.txt", 0, S_OK
, "file:///C:/dir/test.txt"},
202 {"http://www.winehq.org/test/", "test%20file.txt", 0, S_OK
, "http://www.winehq.org/test/test%20file.txt"},
203 {"http://www.winehq.org/test/", "test%20file.txt", URL_FILE_USE_PATHURL
, S_OK
, "http://www.winehq.org/test/test%20file.txt"},
204 {"http://www.winehq.org%2ftest/", "test%20file.txt", URL_FILE_USE_PATHURL
, S_OK
, "http://www.winehq.org%2ftest/test%20file.txt"},
205 {"xxx:@MSITStore:file.chm/file.html", "dir/file", 0, S_OK
, "xxx:dir/file"},
206 {"mk:@MSITStore:file.chm::/file.html", "/dir/file", 0, S_OK
, "mk:@MSITStore:file.chm::/dir/file"},
207 {"mk:@MSITStore:file.chm::/file.html", "mk:@MSITStore:file.chm::/dir/file", 0, S_OK
, "mk:@MSITStore:file.chm::/dir/file"},
214 } TEST_URLFROMPATH
[] = {
215 {"foo", "file:foo", S_OK
},
216 {"foo\\bar", "file:foo/bar", S_OK
},
217 {"\\foo\\bar", "file:///foo/bar", S_OK
},
218 {"c:\\foo\\bar", "file:///c:/foo/bar", S_OK
},
219 {"c:foo\\bar", "file:///c:foo/bar", S_OK
},
220 {"c:\\foo/b a%r", "file:///c:/foo/b%20a%25r", S_OK
},
221 {"c:\\foo\\foo bar", "file:///c:/foo/foo%20bar", S_OK
},
223 /* The following test fails on native shlwapi as distributed with Win95/98.
224 * Wine matches the behaviour of later versions.
226 {"xx:c:\\foo\\bar", "xx:c:\\foo\\bar", S_FALSE
}
234 } TEST_PATHFROMURL
[] = {
235 {"file:///c:/foo/ba%5Cr", "c:\\foo\\ba\\r", S_OK
},
236 {"file:///c:/foo/../ba%5Cr", "c:\\foo\\..\\ba\\r", S_OK
},
237 {"file:///host/c:/foo/bar", "\\host\\c:\\foo\\bar", S_OK
},
238 {"file://host/c:/foo/bar", "\\\\hostc:\\foo\\bar", S_OK
},
239 {"file://host/c:/foo/bar", "\\\\hostc:\\foo\\bar", S_OK
},
240 {"file:\\\\host\\c:\\foo\\bar", "\\\\hostc:\\foo\\bar", S_OK
},
241 {"file:\\\\host\\ca\\foo\\bar", "\\\\host\\ca\\foo\\bar", S_OK
},
242 {"file:\\\\host\\c|\\foo\\bar", "\\\\hostc|\\foo\\bar", S_OK
},
243 {"file:\\%5Chost\\c:\\foo\\bar", "\\\\host\\c:\\foo\\bar", S_OK
},
244 {"file:\\\\host\\cx:\\foo\\bar", "\\\\host\\cx:\\foo\\bar", S_OK
},
245 {"file://c:/foo/bar", "c:\\foo\\bar", S_OK
},
246 {"file://c:/d:/foo/bar", "c:\\d:\\foo\\bar", S_OK
},
247 {"file://c|/d|/foo/bar", "c:\\d|\\foo\\bar", S_OK
},
248 {"file://host/foo/bar", "\\\\host\\foo\\bar", S_OK
},
249 {"file:/foo/bar", "\\foo\\bar", S_OK
},
250 {"file:/foo/bar/", "\\foo\\bar\\", S_OK
},
251 {"file:foo/bar", "foo\\bar", S_OK
},
252 {"file:c:/foo/bar", "c:\\foo\\bar", S_OK
},
253 {"file:c|/foo/bar", "c:\\foo\\bar", S_OK
},
254 {"file:cx|/foo/bar", "cx|\\foo\\bar", S_OK
},
255 {"file:////c:/foo/bar", "c:\\foo\\bar", S_OK
},
256 /* {"file:////c:/foo/foo%20bar", "c:\\foo\\foo%20bar", S_OK},*/
258 {"c:\\foo\\bar", NULL
, E_INVALIDARG
},
259 {"foo/bar", NULL
, E_INVALIDARG
},
260 {"http://foo/bar", NULL
, E_INVALIDARG
},
267 } TEST_URL_UNESCAPE
[] = {
268 {"file://foo/bar", "file://foo/bar"},
269 {"file://fo%20o%5Ca/bar", "file://fo o\\a/bar"}
276 } TEST_PATH_IS_URL
[] = {
277 {"http://foo/bar", TRUE
},
278 {"c:\\foo\\bar", FALSE
},
279 {"foo://foo/bar", TRUE
},
282 {"bogusscheme:", TRUE
},
283 {"http:partial", TRUE
}
290 } TEST_URLIS_ATTRIBS
[] = {
291 { "ftp:", FALSE
, FALSE
},
292 { "http:", FALSE
, FALSE
},
293 { "gopher:", FALSE
, FALSE
},
294 { "mailto:", TRUE
, FALSE
},
295 { "news:", FALSE
, FALSE
},
296 { "nntp:", FALSE
, FALSE
},
297 { "telnet:", FALSE
, FALSE
},
298 { "wais:", FALSE
, FALSE
},
299 { "file:", FALSE
, TRUE
},
300 { "mk:", FALSE
, FALSE
},
301 { "https:", FALSE
, FALSE
},
302 { "shell:", TRUE
, FALSE
},
303 { "https:", FALSE
, FALSE
},
304 { "snews:", FALSE
, FALSE
},
305 { "local:", FALSE
, FALSE
},
306 { "javascript:", TRUE
, FALSE
},
307 { "vbscript:", TRUE
, FALSE
},
308 { "about:", TRUE
, FALSE
},
309 { "res:", FALSE
, FALSE
},
310 { "bogusscheme:", FALSE
, FALSE
},
311 { "file:\\\\e:\\b\\c", FALSE
, TRUE
},
312 { "file://e:/b/c", FALSE
, TRUE
},
313 { "http:partial", FALSE
, FALSE
},
314 { "mailto://www.winehq.org/test.html", TRUE
, FALSE
},
315 { "file:partial", FALSE
, TRUE
}
321 } TEST_PATH_UNQUOTE_SPACES
[] = {
322 { "abcdef", "abcdef" },
323 { "\"abcdef\"", "abcdef" },
324 { "\"abcdef", "\"abcdef" },
325 { "abcdef\"", "abcdef\"" },
326 { "\"\"abcdef\"\"", "\"abcdef\"" },
327 { "abc\"def", "abc\"def" },
328 { "\"abc\"def", "\"abc\"def" },
329 { "\"abc\"def\"", "abc\"def" },
330 { "\'abcdef\'", "\'abcdef\'" },
335 static LPWSTR
GetWideString(const char* szString
)
337 LPWSTR wszString
= HeapAlloc(GetProcessHeap(), 0, (2*INTERNET_MAX_URL_LENGTH
) * sizeof(WCHAR
));
339 MultiByteToWideChar(0, 0, szString
, -1, wszString
, INTERNET_MAX_URL_LENGTH
);
344 static void FreeWideString(LPWSTR wszString
)
346 HeapFree(GetProcessHeap(), 0, wszString
);
349 static LPSTR
strdupA(LPCSTR p
)
352 DWORD len
= (strlen(p
) + 1);
353 ret
= HeapAlloc(GetProcessHeap(), 0, len
);
358 static void hash_url(const char* szUrl
)
360 LPCSTR szTestUrl
= szUrl
;
361 LPWSTR wszTestUrl
= GetWideString(szTestUrl
);
363 DWORD cbSize
= sizeof(DWORD
);
364 DWORD dwHash1
, dwHash2
;
365 ok(UrlHashA(szTestUrl
, (LPBYTE
)&dwHash1
, cbSize
) == S_OK
, "UrlHashA didn't return S_OK\n");
366 ok(UrlHashW(wszTestUrl
, (LPBYTE
)&dwHash2
, cbSize
) == S_OK
, "UrlHashW didn't return S_OK\n");
368 FreeWideString(wszTestUrl
);
370 ok(dwHash1
== dwHash2
, "Hashes didn't compare\n");
373 static void test_UrlHash(void)
375 hash_url(TEST_URL_1
);
376 hash_url(TEST_URL_2
);
377 hash_url(TEST_URL_3
);
380 static void test_url_part(const char* szUrl
, DWORD dwPart
, DWORD dwFlags
, const char* szExpected
)
382 CHAR szPart
[INTERNET_MAX_URL_LENGTH
];
383 WCHAR wszPart
[INTERNET_MAX_URL_LENGTH
];
384 LPWSTR wszUrl
= GetWideString(szUrl
);
385 LPWSTR wszConvertedPart
;
389 dwSize
= INTERNET_MAX_URL_LENGTH
;
390 ok( UrlGetPartA(szUrl
, szPart
, &dwSize
, dwPart
, dwFlags
) == S_OK
, "UrlGetPartA for \"%s\" part 0x%08x didn't return S_OK but \"%s\"\n", szUrl
, dwPart
, szPart
);
391 dwSize
= INTERNET_MAX_URL_LENGTH
;
392 ok( UrlGetPartW(wszUrl
, wszPart
, &dwSize
, dwPart
, dwFlags
) == S_OK
, "UrlGetPartW didn't return S_OK\n" );
394 wszConvertedPart
= GetWideString(szPart
);
396 ok(lstrcmpW(wszPart
,wszConvertedPart
)==0, "Strings didn't match between ascii and unicode UrlGetPart!\n");
398 FreeWideString(wszUrl
);
399 FreeWideString(wszConvertedPart
);
401 /* Note that v6.0 and later don't return '?' with the query */
402 ok(strcmp(szPart
,szExpected
)==0 ||
403 (*szExpected
=='?' && !strcmp(szPart
,szExpected
+1)),
404 "Expected %s, but got %s\n", szExpected
, szPart
);
407 static void test_UrlGetPart(void)
409 CHAR szPart
[INTERNET_MAX_URL_LENGTH
];
413 dwSize
= sizeof szPart
;
414 szPart
[0]='x'; szPart
[1]=0;
415 res
= UrlGetPartA("hi", szPart
, &dwSize
, URL_PART_SCHEME
, 0);
417 ok (res
==S_FALSE
, "UrlGetPartA(\"hi\") returned %08X\n", res
);
418 ok(szPart
[0]==0, "UrlGetPartA(\"hi\") return \"%s\" instead of \"\"\n", szPart
);
420 dwSize
= sizeof szPart
;
421 szPart
[0]='x'; szPart
[1]=0;
422 res
= UrlGetPartA("hi", szPart
, &dwSize
, URL_PART_QUERY
, 0);
424 ok (res
==S_FALSE
, "UrlGetPartA(\"hi\") returned %08X\n", res
);
425 ok(szPart
[0]==0, "UrlGetPartA(\"hi\") return \"%s\" instead of \"\"\n", szPart
);
428 test_url_part(TEST_URL_3
, URL_PART_HOSTNAME
, 0, "localhost");
429 test_url_part(TEST_URL_3
, URL_PART_PORT
, 0, "21");
430 test_url_part(TEST_URL_3
, URL_PART_USERNAME
, 0, "foo");
431 test_url_part(TEST_URL_3
, URL_PART_PASSWORD
, 0, "bar");
432 test_url_part(TEST_URL_3
, URL_PART_SCHEME
, 0, "http");
433 test_url_part(TEST_URL_3
, URL_PART_QUERY
, 0, "?query=x&return=y");
436 static void test_url_escape(const char *szUrl
, DWORD dwFlags
, HRESULT dwExpectReturn
, const char *szExpectUrl
)
438 CHAR szReturnUrl
[INTERNET_MAX_URL_LENGTH
];
440 WCHAR ret_urlW
[INTERNET_MAX_URL_LENGTH
];
441 WCHAR
*urlW
, *expected_urlW
;
442 dwEscaped
=INTERNET_MAX_URL_LENGTH
;
444 ok(UrlEscapeA(szUrl
, szReturnUrl
, &dwEscaped
, dwFlags
) == dwExpectReturn
, "UrlEscapeA didn't return 0x%08x from \"%s\"\n", dwExpectReturn
, szUrl
);
445 ok(strcmp(szReturnUrl
,szExpectUrl
)==0, "Expected \"%s\", but got \"%s\" from \"%s\"\n", szExpectUrl
, szReturnUrl
, szUrl
);
447 dwEscaped
= INTERNET_MAX_URL_LENGTH
;
448 urlW
= GetWideString(szUrl
);
449 expected_urlW
= GetWideString(szExpectUrl
);
450 ok(UrlEscapeW(urlW
, ret_urlW
, &dwEscaped
, dwFlags
) == dwExpectReturn
, "UrlEscapeW didn't return 0x%08x from \"%s\"\n", dwExpectReturn
, szUrl
);
451 WideCharToMultiByte(CP_ACP
,0,ret_urlW
,-1,szReturnUrl
,INTERNET_MAX_URL_LENGTH
,0,0);
452 ok(lstrcmpW(ret_urlW
, expected_urlW
)==0, "Expected \"%s\", but got \"%s\" from \"%s\" flags %08x\n", szExpectUrl
, szReturnUrl
, szUrl
, dwFlags
);
453 FreeWideString(urlW
);
454 FreeWideString(expected_urlW
);
458 static void test_url_canonicalize(const char *szUrl
, DWORD dwFlags
, HRESULT dwExpectReturn
, const char *szExpectUrl
)
460 CHAR szReturnUrl
[INTERNET_MAX_URL_LENGTH
];
461 WCHAR wszReturnUrl
[INTERNET_MAX_URL_LENGTH
];
462 LPWSTR wszUrl
= GetWideString(szUrl
);
463 LPWSTR wszExpectUrl
= GetWideString(szExpectUrl
);
464 LPWSTR wszConvertedUrl
;
468 dwSize
= INTERNET_MAX_URL_LENGTH
;
469 ok(UrlCanonicalizeA(szUrl
, NULL
, &dwSize
, dwFlags
) != dwExpectReturn
, "Unexpected return for NULL buffer\n");
470 ok(UrlCanonicalizeA(szUrl
, szReturnUrl
, &dwSize
, dwFlags
) == dwExpectReturn
, "UrlCanonicalizeA didn't return 0x%08x\n", dwExpectReturn
);
471 ok(strcmp(szReturnUrl
,szExpectUrl
)==0, "UrlCanonicalizeA dwFlags 0x%08x Expected \"%s\", but got \"%s\"\n", dwFlags
, szExpectUrl
, szReturnUrl
);
473 dwSize
= INTERNET_MAX_URL_LENGTH
;
474 ok(UrlCanonicalizeW(wszUrl
, NULL
, &dwSize
, dwFlags
) != dwExpectReturn
, "Unexpected return for NULL buffer\n");
475 ok(UrlCanonicalizeW(wszUrl
, wszReturnUrl
, &dwSize
, dwFlags
) == dwExpectReturn
, "UrlCanonicalizeW didn't return 0x%08x\n", dwExpectReturn
);
476 wszConvertedUrl
= GetWideString(szReturnUrl
);
477 ok(lstrcmpW(wszReturnUrl
, wszConvertedUrl
)==0, "Strings didn't match between ascii and unicode UrlCanonicalize!\n");
478 FreeWideString(wszConvertedUrl
);
481 FreeWideString(wszUrl
);
482 FreeWideString(wszExpectUrl
);
486 static void test_UrlEscape(void)
492 ret
= UrlEscapeA("/woningplan/woonkamer basis.swf", NULL
, &size
, URL_ESCAPE_SPACES_ONLY
);
493 ok(ret
== E_INVALIDARG
, "got %x, expected %x\n", ret
, E_INVALIDARG
);
495 for(i
=0; i
<sizeof(TEST_ESCAPE
)/sizeof(TEST_ESCAPE
[0]); i
++) {
496 test_url_escape(TEST_ESCAPE
[i
].url
, TEST_ESCAPE
[i
].flags
,
497 TEST_ESCAPE
[i
].expectret
, TEST_ESCAPE
[i
].expecturl
);
501 static void test_UrlCanonicalize(void)
504 CHAR szReturnUrl
[INTERNET_MAX_URL_LENGTH
];
508 for(i
=0; i
<sizeof(TEST_CANONICALIZE
)/sizeof(TEST_CANONICALIZE
[0]); i
++) {
509 test_url_canonicalize(TEST_CANONICALIZE
[i
].url
, TEST_CANONICALIZE
[i
].flags
,
510 TEST_CANONICALIZE
[i
].expectret
, TEST_CANONICALIZE
[i
].expecturl
);
513 /* move to TEST_CANONICALIZE when fixed */
514 dwSize
= sizeof szReturnUrl
;
515 /*LimeWire online installer calls this*/
516 hr
= UrlCanonicalizeA("/uri-res/N2R?urn:sha1:B3K", szReturnUrl
, &dwSize
,URL_DONT_ESCAPE_EXTRA_INFO
| URL_WININET_COMPATIBILITY
/*0x82000000*/);
517 ok(hr
==S_OK
,"UrlCanonicalizeA returned 0x%08x instead of S_OK\n", hr
);
519 ok(strcmp(szReturnUrl
,"/uri-res/N2R?urn:sha1:B3K")==0, "UrlCanonicalizeA got \"%s\" instead of \"/uri-res/N2R?urn:sha1:B3K\"\n", szReturnUrl
);
523 static void test_url_combine(const char *szUrl1
, const char *szUrl2
, DWORD dwFlags
, HRESULT dwExpectReturn
, const char *szExpectUrl
)
526 CHAR szReturnUrl
[INTERNET_MAX_URL_LENGTH
];
527 WCHAR wszReturnUrl
[INTERNET_MAX_URL_LENGTH
];
528 LPWSTR wszUrl1
= GetWideString(szUrl1
);
529 LPWSTR wszUrl2
= GetWideString(szUrl2
);
530 LPWSTR wszExpectUrl
= GetWideString(szExpectUrl
);
531 LPWSTR wszConvertedUrl
;
534 DWORD dwExpectLen
= lstrlen(szExpectUrl
);
536 hr
= UrlCombineA(szUrl1
, szUrl2
, NULL
, NULL
, dwFlags
);
537 ok(hr
== E_INVALIDARG
, "UrlCombineA returned 0x%08x, expected 0x%08x\n", hr
, E_INVALIDARG
);
540 hr
= UrlCombineA(szUrl1
, szUrl2
, NULL
, &dwSize
, dwFlags
);
541 ok(hr
== E_POINTER
, "Checking length of string, return was 0x%08x, expected 0x%08x\n", hr
, E_POINTER
);
542 ok(dwSize
== dwExpectLen
+1, "Got length %d, expected %d\n", dwSize
, dwExpectLen
+1);
545 hr
= UrlCombineA(szUrl1
, szUrl2
, szReturnUrl
, &dwSize
, dwFlags
);
546 ok(hr
== E_POINTER
, "UrlCombineA returned 0x%08x, expected 0x%08x\n", hr
, E_POINTER
);
547 ok(dwSize
== dwExpectLen
+1, "Got length %d, expected %d\n", dwSize
, dwExpectLen
+1);
549 hr
= UrlCombineA(szUrl1
, szUrl2
, szReturnUrl
, &dwSize
, dwFlags
);
550 ok(hr
== dwExpectReturn
, "UrlCombineA returned 0x%08x, expected 0x%08x\n", hr
, dwExpectReturn
);
551 ok(dwSize
== dwExpectLen
, "Got length %d, expected %d\n", dwSize
, dwExpectLen
);
553 ok(strcmp(szReturnUrl
,szExpectUrl
)==0, "Expected %s, but got %s\n", szExpectUrl
, szReturnUrl
);
557 hr
= UrlCombineW(wszUrl1
, wszUrl2
, NULL
, &dwSize
, dwFlags
);
558 ok(hr
== E_POINTER
, "Checking length of string, return was 0x%08x, expected 0x%08x\n", hr
, E_POINTER
);
559 ok(dwSize
== dwExpectLen
+1, "Got length %d, expected %d\n", dwSize
, dwExpectLen
+1);
562 hr
= UrlCombineW(wszUrl1
, wszUrl2
, wszReturnUrl
, &dwSize
, dwFlags
);
563 ok(hr
== E_POINTER
, "UrlCombineA returned 0x%08x, expected 0x%08x\n", hr
, E_POINTER
);
564 ok(dwSize
== dwExpectLen
+1, "Got length %d, expected %d\n", dwSize
, dwExpectLen
+1);
566 hr
= UrlCombineW(wszUrl1
, wszUrl2
, wszReturnUrl
, &dwSize
, dwFlags
);
567 ok(hr
== dwExpectReturn
, "UrlCombineW returned 0x%08x, expected 0x%08x\n", hr
, dwExpectReturn
);
568 ok(dwSize
== dwExpectLen
, "Got length %d, expected %d\n", dwSize
, dwExpectLen
);
570 wszConvertedUrl
= GetWideString(szReturnUrl
);
571 ok(lstrcmpW(wszReturnUrl
, wszConvertedUrl
)==0, "Strings didn't match between ascii and unicode UrlCombine!\n");
572 FreeWideString(wszConvertedUrl
);
575 FreeWideString(wszUrl1
);
576 FreeWideString(wszUrl2
);
577 FreeWideString(wszExpectUrl
);
580 static void test_UrlCombine(void)
583 for(i
=0; i
<sizeof(TEST_COMBINE
)/sizeof(TEST_COMBINE
[0]); i
++) {
584 test_url_combine(TEST_COMBINE
[i
].url1
, TEST_COMBINE
[i
].url2
, TEST_COMBINE
[i
].flags
,
585 TEST_COMBINE
[i
].expectret
, TEST_COMBINE
[i
].expecturl
);
589 static void test_UrlCreateFromPath(void)
592 char ret_url
[INTERNET_MAX_URL_LENGTH
];
594 WCHAR ret_urlW
[INTERNET_MAX_URL_LENGTH
];
597 for(i
= 0; i
< sizeof(TEST_URLFROMPATH
) / sizeof(TEST_URLFROMPATH
[0]); i
++) {
598 len
= INTERNET_MAX_URL_LENGTH
;
599 ret
= UrlCreateFromPathA(TEST_URLFROMPATH
[i
].path
, ret_url
, &len
, 0);
600 ok(ret
== TEST_URLFROMPATH
[i
].ret
, "ret %08x from path %s\n", ret
, TEST_URLFROMPATH
[i
].path
);
601 ok(!lstrcmpi(ret_url
, TEST_URLFROMPATH
[i
].url
), "url %s from path %s\n", ret_url
, TEST_URLFROMPATH
[i
].path
);
602 ok(len
== strlen(ret_url
), "ret len %d from path %s\n", len
, TEST_URLFROMPATH
[i
].path
);
604 len
= INTERNET_MAX_URL_LENGTH
;
605 pathW
= GetWideString(TEST_URLFROMPATH
[i
].path
);
606 urlW
= GetWideString(TEST_URLFROMPATH
[i
].url
);
607 ret
= UrlCreateFromPathW(pathW
, ret_urlW
, &len
, 0);
608 WideCharToMultiByte(CP_ACP
, 0, ret_urlW
, -1, ret_url
, sizeof(ret_url
),0,0);
609 ok(ret
== TEST_URLFROMPATH
[i
].ret
, "ret %08x from path L\"%s\", expected %08x\n",
610 ret
, TEST_URLFROMPATH
[i
].path
, TEST_URLFROMPATH
[i
].ret
);
611 ok(!lstrcmpiW(ret_urlW
, urlW
), "got %s expected %s from path L\"%s\"\n", ret_url
, TEST_URLFROMPATH
[i
].url
, TEST_URLFROMPATH
[i
].path
);
612 ok(len
== lstrlenW(ret_urlW
), "ret len %d from path L\"%s\"\n", len
, TEST_URLFROMPATH
[i
].path
);
613 FreeWideString(urlW
);
614 FreeWideString(pathW
);
618 static void test_UrlIs(void)
624 for(i
= 0; i
< sizeof(TEST_PATH_IS_URL
) / sizeof(TEST_PATH_IS_URL
[0]); i
++) {
625 MultiByteToWideChar(CP_ACP
, 0, TEST_PATH_IS_URL
[i
].path
, -1, wurl
, 80);
627 ret
= UrlIsA( TEST_PATH_IS_URL
[i
].path
, URLIS_URL
);
628 ok( ret
== TEST_PATH_IS_URL
[i
].expect
,
629 "returned %d from path %s, expected %d\n", ret
, TEST_PATH_IS_URL
[i
].path
,
630 TEST_PATH_IS_URL
[i
].expect
);
632 ret
= UrlIsW( wurl
, URLIS_URL
);
633 ok( ret
== TEST_PATH_IS_URL
[i
].expect
,
634 "returned %d from path (UrlIsW) %s, expected %d\n", ret
, TEST_PATH_IS_URL
[i
].path
,
635 TEST_PATH_IS_URL
[i
].expect
);
637 for(i
= 0; i
< sizeof(TEST_URLIS_ATTRIBS
) / sizeof(TEST_URLIS_ATTRIBS
[0]); i
++) {
638 MultiByteToWideChar(CP_ACP
, 0, TEST_URLIS_ATTRIBS
[i
].url
, -1, wurl
, 80);
640 ret
= UrlIsA( TEST_URLIS_ATTRIBS
[i
].url
, URLIS_OPAQUE
);
641 ok( ret
== TEST_URLIS_ATTRIBS
[i
].expectOpaque
,
642 "returned %d for URLIS_OPAQUE, url \"%s\", expected %d\n", ret
, TEST_URLIS_ATTRIBS
[i
].url
,
643 TEST_URLIS_ATTRIBS
[i
].expectOpaque
);
644 ret
= UrlIsA( TEST_URLIS_ATTRIBS
[i
].url
, URLIS_FILEURL
);
645 ok( ret
== TEST_URLIS_ATTRIBS
[i
].expectFile
,
646 "returned %d for URLIS_FILEURL, url \"%s\", expected %d\n", ret
, TEST_URLIS_ATTRIBS
[i
].url
,
647 TEST_URLIS_ATTRIBS
[i
].expectFile
);
649 ret
= UrlIsW( wurl
, URLIS_OPAQUE
);
650 ok( ret
== TEST_URLIS_ATTRIBS
[i
].expectOpaque
,
651 "returned %d for URLIS_OPAQUE (UrlIsW), url \"%s\", expected %d\n", ret
, TEST_URLIS_ATTRIBS
[i
].url
,
652 TEST_URLIS_ATTRIBS
[i
].expectOpaque
);
653 ret
= UrlIsW( wurl
, URLIS_FILEURL
);
654 ok( ret
== TEST_URLIS_ATTRIBS
[i
].expectFile
,
655 "returned %d for URLIS_FILEURL (UrlIsW), url \"%s\", expected %d\n", ret
, TEST_URLIS_ATTRIBS
[i
].url
,
656 TEST_URLIS_ATTRIBS
[i
].expectFile
);
660 static void test_UrlUnescape(void)
662 CHAR szReturnUrl
[INTERNET_MAX_URL_LENGTH
];
663 WCHAR ret_urlW
[INTERNET_MAX_URL_LENGTH
];
664 WCHAR
*urlW
, *expected_urlW
;
667 static char inplace
[] = "file:///C:/Program%20Files";
668 static WCHAR inplaceW
[] = {'f','i','l','e',':','/','/','/','C',':','/',
669 'P','r','o','g','r','a','m','%','2','0','F','i','l','e','s',0};
671 for(i
=0; i
<sizeof(TEST_URL_UNESCAPE
)/sizeof(TEST_URL_UNESCAPE
[0]); i
++) {
672 dwEscaped
=INTERNET_MAX_URL_LENGTH
;
673 ok(UrlUnescapeA(TEST_URL_UNESCAPE
[i
].url
, szReturnUrl
, &dwEscaped
, 0) == S_OK
, "UrlUnescapeA didn't return 0x%08x from \"%s\"\n", S_OK
, TEST_URL_UNESCAPE
[i
].url
);
674 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
);
676 dwEscaped
= INTERNET_MAX_URL_LENGTH
;
677 urlW
= GetWideString(TEST_URL_UNESCAPE
[i
].url
);
678 expected_urlW
= GetWideString(TEST_URL_UNESCAPE
[i
].expect
);
679 ok(UrlUnescapeW(urlW
, ret_urlW
, &dwEscaped
, 0) == S_OK
, "UrlUnescapeW didn't return 0x%08x from \"%s\"\n", S_OK
, TEST_URL_UNESCAPE
[i
].url
);
680 WideCharToMultiByte(CP_ACP
,0,ret_urlW
,-1,szReturnUrl
,INTERNET_MAX_URL_LENGTH
,0,0);
681 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);
682 FreeWideString(urlW
);
683 FreeWideString(expected_urlW
);
686 dwEscaped
= sizeof(inplace
);
687 ok(UrlUnescapeA(inplace
, NULL
, &dwEscaped
, URL_UNESCAPE_INPLACE
) == S_OK
, "UrlUnescapeA failed unexpectedly\n");
689 dwEscaped
= sizeof(inplaceW
);
690 ok(UrlUnescapeW(inplaceW
, NULL
, &dwEscaped
, URL_UNESCAPE_INPLACE
) == S_OK
, "UrlUnescapeW failed unexpectedly\n");
693 static void test_PathSearchAndQualify(void)
695 WCHAR path1
[] = {'c',':','\\','f','o','o',0};
696 WCHAR expect1
[] = {'c',':','\\','f','o','o',0};
697 WCHAR path2
[] = {'c',':','f','o','o',0};
698 WCHAR c_drive
[] = {'c',':',0};
699 WCHAR foo
[] = {'f','o','o',0};
700 WCHAR path3
[] = {'\\','f','o','o',0};
701 WCHAR winini
[] = {'w','i','n','.','i','n','i',0};
703 WCHAR cur_dir
[MAX_PATH
];
704 WCHAR dot
[] = {'.',0};
707 ok(PathSearchAndQualifyW(path1
, out
, MAX_PATH
) != 0,
708 "PathSearchAndQualify rets 0\n");
709 ok(!lstrcmpiW(out
, expect1
), "strings don't match\n");
712 ok(PathSearchAndQualifyW(path2
, out
, MAX_PATH
) != 0,
713 "PathSearchAndQualify rets 0\n");
714 GetFullPathNameW(c_drive
, MAX_PATH
, cur_dir
, NULL
);
715 PathAddBackslashW(cur_dir
);
716 lstrcatW(cur_dir
, foo
);
717 ok(!lstrcmpiW(out
, cur_dir
), "strings don't match\n");
720 ok(PathSearchAndQualifyW(foo
, out
, MAX_PATH
) != 0,
721 "PathSearchAndQualify rets 0\n");
722 GetFullPathNameW(dot
, MAX_PATH
, cur_dir
, NULL
);
723 PathAddBackslashW(cur_dir
);
724 lstrcatW(cur_dir
, foo
);
725 ok(!lstrcmpiW(out
, cur_dir
), "strings don't match\n");
728 ok(PathSearchAndQualifyW(path3
, out
, MAX_PATH
) != 0,
729 "PathSearchAndQualify rets 0\n");
730 GetFullPathNameW(dot
, MAX_PATH
, cur_dir
, NULL
);
731 lstrcpyW(cur_dir
+ 2, path3
);
732 ok(!lstrcmpiW(out
, cur_dir
), "strings don't match\n");
735 ok(PathSearchAndQualifyW(winini
, out
, MAX_PATH
) != 0,
736 "PathSearchAndQualify rets 0\n");
737 if(!SearchPathW(NULL
, winini
, NULL
, MAX_PATH
, cur_dir
, NULL
))
738 GetFullPathNameW(winini
, MAX_PATH
, cur_dir
, NULL
);
739 ok(!lstrcmpiW(out
, cur_dir
), "strings don't match\n");
743 static void test_PathCreateFromUrl(void)
746 char ret_path
[INTERNET_MAX_URL_LENGTH
];
748 WCHAR ret_pathW
[INTERNET_MAX_URL_LENGTH
];
750 static const char url
[] = "http://www.winehq.org";
752 /* Check ret_path = NULL */
754 ret
= PathCreateFromUrlA(url
, NULL
, &len
, 0);
755 ok ( ret
== E_INVALIDARG
, "got 0x%08x expected E_INVALIDARG\n", ret
);
757 for(i
= 0; i
< sizeof(TEST_PATHFROMURL
) / sizeof(TEST_PATHFROMURL
[0]); i
++) {
758 len
= INTERNET_MAX_URL_LENGTH
;
759 ret
= PathCreateFromUrlA(TEST_PATHFROMURL
[i
].url
, ret_path
, &len
, 0);
760 ok(ret
== TEST_PATHFROMURL
[i
].ret
, "ret %08x from url %s\n", ret
, TEST_PATHFROMURL
[i
].url
);
761 if(TEST_PATHFROMURL
[i
].path
) {
762 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
);
763 ok(len
== strlen(ret_path
), "ret len %d from url %s\n", len
, TEST_PATHFROMURL
[i
].url
);
765 len
= INTERNET_MAX_URL_LENGTH
;
766 pathW
= GetWideString(TEST_PATHFROMURL
[i
].path
);
767 urlW
= GetWideString(TEST_PATHFROMURL
[i
].url
);
768 ret
= PathCreateFromUrlW(urlW
, ret_pathW
, &len
, 0);
769 WideCharToMultiByte(CP_ACP
, 0, ret_pathW
, -1, ret_path
, sizeof(ret_path
),0,0);
770 ok(ret
== TEST_PATHFROMURL
[i
].ret
, "ret %08x from url L\"%s\"\n", ret
, TEST_PATHFROMURL
[i
].url
);
771 if(TEST_PATHFROMURL
[i
].path
) {
772 ok(!lstrcmpiW(ret_pathW
, pathW
), "got %s expected %s from url L\"%s\"\n", ret_path
, TEST_PATHFROMURL
[i
].path
, TEST_PATHFROMURL
[i
].url
);
773 ok(len
== lstrlenW(ret_pathW
), "ret len %d from url L\"%s\"\n", len
, TEST_PATHFROMURL
[i
].url
);
775 FreeWideString(urlW
);
776 FreeWideString(pathW
);
781 static void test_PathIsUrl(void)
786 for(i
= 0; i
< sizeof(TEST_PATH_IS_URL
)/sizeof(TEST_PATH_IS_URL
[0]); i
++) {
787 ret
= PathIsURLA(TEST_PATH_IS_URL
[i
].path
);
788 ok(ret
== TEST_PATH_IS_URL
[i
].expect
,
789 "returned %d from path %s, expected %d\n", ret
, TEST_PATH_IS_URL
[i
].path
,
790 TEST_PATH_IS_URL
[i
].expect
);
794 static const DWORD SHELL_charclass
[] =
796 0x00000000, 0x00000000, 0x00000000, 0x00000000,
797 0x00000000, 0x00000000, 0x00000000, 0x00000000,
798 0x00000000, 0x00000000, 0x00000000, 0x00000000,
799 0x00000000, 0x00000000, 0x00000000, 0x00000000,
800 0x00000000, 0x00000000, 0x00000000, 0x00000000,
801 0x00000000, 0x00000000, 0x00000000, 0x00000000,
802 0x00000000, 0x00000000, 0x00000000, 0x00000000,
803 0x00000000, 0x00000000, 0x00000000, 0x00000000,
804 0x00000080, 0x00000100, 0x00000200, 0x00000100,
805 0x00000100, 0x00000100, 0x00000100, 0x00000100,
806 0x00000100, 0x00000100, 0x00000002, 0x00000100,
807 0x00000040, 0x00000100, 0x00000004, 0x00000000,
808 0x00000100, 0x00000100, 0x00000100, 0x00000100,
809 0x00000100, 0x00000100, 0x00000100, 0x00000100,
810 0x00000100, 0x00000100, 0x00000010, 0x00000020,
811 0x00000000, 0x00000100, 0x00000000, 0x00000001,
812 0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
813 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
814 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
815 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
816 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
817 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
818 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
819 0x00000008, 0x00000100, 0x00000100, 0x00000100,
820 0x00000100, 0xffffffff, 0xffffffff, 0xffffffff,
821 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
822 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
823 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
824 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
825 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
826 0xffffffff, 0xffffffff, 0xffffffff, 0x00000100,
827 0x00000000, 0x00000100, 0x00000100
830 static void test_PathIsValidCharA(void)
835 ret
= pPathIsValidCharA( 0x7f, 0 );
836 ok ( !ret
, "PathIsValidCharA succeeded: 0x%08x\n", (DWORD
)ret
);
838 ret
= pPathIsValidCharA( 0x7f, 1 );
839 ok ( !ret
, "PathIsValidCharA succeeded: 0x%08x\n", (DWORD
)ret
);
841 for (c
= 0; c
< 0x7f; c
++)
843 ret
= pPathIsValidCharA( c
, ~0U );
844 ok ( ret
== SHELL_charclass
[c
] || (ret
== 1 && SHELL_charclass
[c
] == 0xffffffff),
845 "PathIsValidCharA failed: 0x%02x got 0x%08x expected 0x%08x\n",
846 c
, (DWORD
)ret
, SHELL_charclass
[c
] );
849 for (c
= 0x7f; c
<= 0xff; c
++)
851 ret
= pPathIsValidCharA( c
, ~0U );
852 ok ( ret
== 0x00000100,
853 "PathIsValidCharA failed: 0x%02x got 0x%08x expected 0x00000100\n",
858 static void test_PathIsValidCharW(void)
861 unsigned int c
, err_count
= 0;
863 ret
= pPathIsValidCharW( 0x7f, 0 );
864 ok ( !ret
, "PathIsValidCharW succeeded: 0x%08x\n", (DWORD
)ret
);
866 ret
= pPathIsValidCharW( 0x7f, 1 );
867 ok ( !ret
, "PathIsValidCharW succeeded: 0x%08x\n", (DWORD
)ret
);
869 for (c
= 0; c
< 0x7f; c
++)
871 ret
= pPathIsValidCharW( c
, ~0U );
872 ok ( ret
== SHELL_charclass
[c
] || (ret
== 1 && SHELL_charclass
[c
] == 0xffffffff),
873 "PathIsValidCharW failed: 0x%02x got 0x%08x expected 0x%08x\n",
874 c
, (DWORD
)ret
, SHELL_charclass
[c
] );
877 for (c
= 0x007f; c
<= 0xffff; c
++)
879 ret
= pPathIsValidCharW( c
, ~0U );
880 ok ( ret
== 0x00000100,
881 "PathIsValidCharW failed: 0x%02x got 0x%08x expected 0x00000100\n",
883 if (ret
!= 0x00000100)
885 if(++err_count
> 100 ) {
886 trace("skipping rest of PathIsValidCharW tests "
887 "because of the current number of errors\n");
894 static void test_PathMakePretty(void)
898 ok (PathMakePrettyA(NULL
) == FALSE
, "PathMakePretty: NULL path succeeded\n");
900 ok (PathMakePrettyA(buff
) == TRUE
, "PathMakePretty: Empty path failed\n");
902 strcpy(buff
, "C:\\A LONG FILE NAME WITH \\SPACES.TXT");
903 ok (PathMakePrettyA(buff
) == TRUE
, "PathMakePretty: Long UC name failed\n");
904 ok (strcmp(buff
, "C:\\a long file name with \\spaces.txt") == 0,
905 "PathMakePretty: Long UC name not changed\n");
907 strcpy(buff
, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT");
908 ok (PathMakePrettyA(buff
) == FALSE
, "PathMakePretty: Long MC name succeeded\n");
909 ok (strcmp(buff
, "C:\\A LONG FILE NAME WITH \\MixedCase.TXT") == 0,
910 "PathMakePretty: Failed but modified path\n");
912 strcpy(buff
, "TEST");
913 ok (PathMakePrettyA(buff
) == TRUE
, "PathMakePretty: Short name failed\n");
914 ok (strcmp(buff
, "Test") == 0, "PathMakePretty: 1st char lowercased %s\n", buff
);
917 static void test_PathMatchSpec(void)
919 static const char file
[] = "c:\\foo\\bar\\filename.ext";
920 static const char spec1
[] = ".ext";
921 static const char spec2
[] = "*.ext";
922 static const char spec3
[] = "*.ext ";
923 static const char spec4
[] = " *.ext";
924 static const char spec5
[] = "* .ext";
925 static const char spec6
[] = "*. ext";
926 static const char spec7
[] = "* . ext";
927 static const char spec8
[] = "*.e?t";
928 static const char spec9
[] = "filename.ext";
929 static const char spec10
[] = "*bar\\filename.ext";
930 static const char spec11
[] = " foo; *.ext";
931 static const char spec12
[] = "*.ext;*.bar";
932 static const char spec13
[] = "*bar*";
934 ok (PathMatchSpecA(file
, spec1
) == FALSE
, "PathMatchSpec: Spec1 failed\n");
935 ok (PathMatchSpecA(file
, spec2
) == TRUE
, "PathMatchSpec: Spec2 failed\n");
936 ok (PathMatchSpecA(file
, spec3
) == FALSE
, "PathMatchSpec: Spec3 failed\n");
937 ok (PathMatchSpecA(file
, spec4
) == TRUE
, "PathMatchSpec: Spec4 failed\n");
938 todo_wine
ok (PathMatchSpecA(file
, spec5
) == TRUE
, "PathMatchSpec: Spec5 failed\n");
939 todo_wine
ok (PathMatchSpecA(file
, spec6
) == TRUE
, "PathMatchSpec: Spec6 failed\n");
940 ok (PathMatchSpecA(file
, spec7
) == FALSE
, "PathMatchSpec: Spec7 failed\n");
941 ok (PathMatchSpecA(file
, spec8
) == TRUE
, "PathMatchSpec: Spec8 failed\n");
942 ok (PathMatchSpecA(file
, spec9
) == FALSE
, "PathMatchSpec: Spec9 failed\n");
943 ok (PathMatchSpecA(file
, spec10
) == TRUE
, "PathMatchSpec: Spec10 failed\n");
944 ok (PathMatchSpecA(file
, spec11
) == TRUE
, "PathMatchSpec: Spec11 failed\n");
945 ok (PathMatchSpecA(file
, spec12
) == TRUE
, "PathMatchSpec: Spec12 failed\n");
946 ok (PathMatchSpecA(file
, spec13
) == TRUE
, "PathMatchSpec: Spec13 failed\n");
949 static void test_PathCombineW(void)
951 LPWSTR wszString
, wszString2
;
952 WCHAR wbuf
[MAX_PATH
+1], wstr1
[MAX_PATH
] = {'C',':','\\',0}, wstr2
[MAX_PATH
];
953 static const WCHAR expout
[] = {'C',':','\\','A','A',0};
956 wszString2
= HeapAlloc(GetProcessHeap(), 0, MAX_PATH
* sizeof(WCHAR
));
959 wszString
= pPathCombineW(NULL
, NULL
, NULL
);
960 ok (wszString
== NULL
, "Expected a NULL return\n");
964 wszString
= pPathCombineW(wszString2
, NULL
, NULL
);
965 ok (wszString
== NULL
, "Expected a NULL return\n");
966 ok (wszString2
[0] == 0, "Destination string not empty\n");
968 HeapFree(GetProcessHeap(), 0, wszString2
);
971 wstr2
[0] = wstr2
[1] = wstr2
[2] = 'A';
972 for (i
=3; i
<MAX_PATH
/2; i
++)
973 wstr1
[i
] = wstr2
[i
] = 'A';
974 wstr1
[(MAX_PATH
/2) - 1] = wstr2
[MAX_PATH
/2] = 0;
975 memset(wbuf
, 0xbf, sizeof(wbuf
));
977 wszString
= pPathCombineW(wbuf
, wstr1
, wstr2
);
978 ok(wszString
== NULL
, "Expected a NULL return\n");
979 ok(wbuf
[0] == 0, "Buffer contains data\n");
981 /* PathCombineW can be used in place */
984 ok(PathCombineW(wstr1
, wstr1
, wstr2
) == wstr1
, "Expected a wstr1 return\n");
985 ok(StrCmpW(wstr1
, expout
) == 0, "Unexpected PathCombine output\n");
989 #define LONG_LEN (MAX_PATH * 2)
990 #define HALF_LEN (MAX_PATH / 2 + 1)
992 static void test_PathCombineA(void)
996 char too_long
[LONG_LEN
];
997 char one
[HALF_LEN
], two
[HALF_LEN
];
1000 SetLastError(0xdeadbeef);
1001 str
= PathCombineA(NULL
, "C:\\", "one\\two\\three");
1002 ok(str
== NULL
, "Expected NULL, got %p\n", str
);
1003 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1005 /* try NULL dest and NULL directory */
1006 SetLastError(0xdeadbeef);
1007 str
= PathCombineA(NULL
, NULL
, "one\\two\\three");
1008 ok(str
== NULL
, "Expected NULL, got %p\n", str
);
1009 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1012 SetLastError(0xdeadbeef);
1013 str
= PathCombineA(NULL
, NULL
, NULL
);
1014 ok(str
== NULL
, "Expected NULL, got %p\n", str
);
1015 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1017 /* try NULL file part */
1018 SetLastError(0xdeadbeef);
1019 lstrcpyA(dest
, "control");
1020 str
= PathCombineA(dest
, "C:\\", NULL
);
1021 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
1022 ok(!lstrcmp(str
, "C:\\"), "Expected C:\\, got %s\n", str
);
1023 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1025 /* try empty file part */
1026 SetLastError(0xdeadbeef);
1027 lstrcpyA(dest
, "control");
1028 str
= PathCombineA(dest
, "C:\\", "");
1029 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
1030 ok(!lstrcmp(str
, "C:\\"), "Expected C:\\, got %s\n", str
);
1031 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1033 /* try empty directory and file part */
1034 SetLastError(0xdeadbeef);
1035 lstrcpyA(dest
, "control");
1036 str
= PathCombineA(dest
, "", "");
1037 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
1038 ok(!lstrcmp(str
, "\\"), "Expected \\, got %s\n", str
);
1039 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1041 /* try NULL directory */
1042 SetLastError(0xdeadbeef);
1043 lstrcpyA(dest
, "control");
1044 str
= PathCombineA(dest
, NULL
, "one\\two\\three");
1045 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
1046 ok(!lstrcmp(str
, "one\\two\\three"), "Expected one\\two\\three, got %s\n", str
);
1047 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1049 /* try NULL directory and empty file part */
1050 SetLastError(0xdeadbeef);
1051 lstrcpyA(dest
, "control");
1052 str
= PathCombineA(dest
, NULL
, "");
1053 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
1054 ok(!lstrcmp(str
, "\\"), "Expected \\, got %s\n", str
);
1055 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1057 /* try NULL directory and file part */
1058 SetLastError(0xdeadbeef);
1059 lstrcpyA(dest
, "control");
1060 str
= PathCombineA(dest
, NULL
, NULL
);
1061 ok(str
== NULL
, "Expected str == NULL, got %p\n", str
);
1062 ok(lstrlenA(dest
) == 0, "Expected 0 length, got %i\n", lstrlenA(dest
));
1063 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1065 /* try directory without backslash */
1066 SetLastError(0xdeadbeef);
1067 lstrcpyA(dest
, "control");
1068 str
= PathCombineA(dest
, "C:", "one\\two\\three");
1069 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
1070 ok(!lstrcmp(str
, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str
);
1071 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1073 /* try directory with backslash */
1074 SetLastError(0xdeadbeef);
1075 lstrcpyA(dest
, "control");
1076 str
= PathCombineA(dest
, "C:\\", "one\\two\\three");
1077 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
1078 ok(!lstrcmp(str
, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str
);
1079 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1081 /* try directory with backslash and file with prepended backslash */
1082 SetLastError(0xdeadbeef);
1083 lstrcpyA(dest
, "control");
1084 str
= PathCombineA(dest
, "C:\\", "\\one\\two\\three");
1085 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
1086 ok(!lstrcmp(str
, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str
);
1087 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1089 /* try previous test, with backslash appended as well */
1090 SetLastError(0xdeadbeef);
1091 lstrcpyA(dest
, "control");
1092 str
= PathCombineA(dest
, "C:\\", "\\one\\two\\three\\");
1093 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
1094 ok(!lstrcmp(str
, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str
);
1095 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1097 /* try a relative directory */
1098 SetLastError(0xdeadbeef);
1099 lstrcpyA(dest
, "control");
1100 str
= PathCombineA(dest
, "relative\\dir", "\\one\\two\\three\\");
1101 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
1102 ok(!lstrcmp(str
, "one\\two\\three\\"), "Expected one\\two\\three\\, got %s\n", str
);
1103 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1105 /* try forward slashes */
1106 SetLastError(0xdeadbeef);
1107 lstrcpyA(dest
, "control");
1108 str
= PathCombineA(dest
, "C:\\", "one/two/three\\");
1109 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
1110 ok(!lstrcmp(str
, "C:\\one/two/three\\"), "Expected one/two/three\\, got %s\n", str
);
1111 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1113 /* try a really weird directory */
1114 SetLastError(0xdeadbeef);
1115 lstrcpyA(dest
, "control");
1116 str
= PathCombineA(dest
, "C:\\/\\/", "\\one\\two\\three\\");
1117 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
1118 ok(!lstrcmp(str
, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str
);
1119 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1122 SetLastError(0xdeadbeef);
1123 lstrcpyA(dest
, "control");
1124 str
= PathCombineA(dest
, "C:\\", "one\\..\\two\\.\\three");
1125 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
1126 ok(!lstrcmp(str
, "C:\\two\\three"), "Expected C:\\two\\three, got %s\n", str
);
1127 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1129 /* try .. as file */
1130 /* try forward slashes */
1131 SetLastError(0xdeadbeef);
1132 lstrcpyA(dest
, "control");
1133 str
= PathCombineA(dest
, "C:\\", "..");
1134 ok(str
== dest
, "Expected str == dest, got %p\n", str
);
1135 ok(!lstrcmp(str
, "C:\\"), "Expected C:\\, got %s\n", str
);
1136 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1138 memset(too_long
, 'a', LONG_LEN
);
1139 too_long
[LONG_LEN
- 1] = '\0';
1141 /* try a file longer than MAX_PATH */
1142 SetLastError(0xdeadbeef);
1143 lstrcpyA(dest
, "control");
1144 str
= PathCombineA(dest
, "C:\\", too_long
);
1145 ok(str
== NULL
, "Expected str == NULL, got %p\n", str
);
1146 ok(lstrlenA(dest
) == 0, "Expected 0 length, got %i\n", lstrlenA(dest
));
1147 todo_wine
ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1149 /* try a directory longer than MAX_PATH */
1150 SetLastError(0xdeadbeef);
1151 lstrcpyA(dest
, "control");
1152 str
= PathCombineA(dest
, too_long
, "one\\two\\three");
1153 ok(str
== NULL
, "Expected str == NULL, got %p\n", str
);
1154 ok(lstrlenA(dest
) == 0, "Expected 0 length, got %i\n", lstrlenA(dest
));
1155 todo_wine
ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1157 memset(one
, 'b', HALF_LEN
);
1158 memset(two
, 'c', HALF_LEN
);
1159 one
[HALF_LEN
- 1] = '\0';
1160 two
[HALF_LEN
- 1] = '\0';
1162 /* destination string is longer than MAX_PATH, but not the constituent parts */
1163 SetLastError(0xdeadbeef);
1164 lstrcpyA(dest
, "control");
1165 str
= PathCombineA(dest
, one
, two
);
1166 ok(str
== NULL
, "Expected str == NULL, got %p\n", str
);
1167 ok(lstrlenA(dest
) == 0, "Expected 0 length, got %i\n", lstrlenA(dest
));
1168 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1171 static void test_PathAddBackslash(void)
1174 char path
[MAX_PATH
];
1175 char too_long
[LONG_LEN
];
1177 /* try a NULL path */
1178 SetLastError(0xdeadbeef);
1179 str
= PathAddBackslashA(NULL
);
1180 ok(str
== NULL
, "Expected str == NULL, got %p\n", str
);
1181 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1183 /* try an empty path */
1185 SetLastError(0xdeadbeef);
1186 str
= PathAddBackslashA(path
);
1187 ok(str
== (path
+ lstrlenA(path
)), "Expected str to point to end of path, got %p\n", str
);
1188 ok(lstrlenA(path
) == 0, "Expected empty string, got %i\n", lstrlenA(path
));
1189 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1191 /* try a relative path */
1192 lstrcpyA(path
, "one\\two");
1193 SetLastError(0xdeadbeef);
1194 str
= PathAddBackslashA(path
);
1195 ok(str
== (path
+ lstrlenA(path
)), "Expected str to point to end of path, got %p\n", str
);
1196 ok(!lstrcmp(path
, "one\\two\\"), "Expected one\\two\\, got %s\n", path
);
1197 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1200 lstrcpyA(path
, "one\\..\\two");
1201 SetLastError(0xdeadbeef);
1202 str
= PathAddBackslashA(path
);
1203 ok(str
== (path
+ lstrlenA(path
)), "Expected str to point to end of path, got %p\n", str
);
1204 ok(!lstrcmp(path
, "one\\..\\two\\"), "Expected one\\..\\two\\, got %s\n", path
);
1205 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1207 /* try just a space */
1208 lstrcpyA(path
, " ");
1209 SetLastError(0xdeadbeef);
1210 str
= PathAddBackslashA(path
);
1211 ok(str
== (path
+ lstrlenA(path
)), "Expected str to point to end of path, got %p\n", str
);
1212 ok(!lstrcmp(path
, " \\"), "Expected \\, got %s\n", path
);
1213 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1215 /* path already has backslash */
1216 lstrcpyA(path
, "C:\\one\\");
1217 SetLastError(0xdeadbeef);
1218 str
= PathAddBackslashA(path
);
1219 ok(str
== (path
+ lstrlenA(path
)), "Expected str to point to end of path, got %p\n", str
);
1220 ok(!lstrcmp(path
, "C:\\one\\"), "Expected C:\\one\\, got %s\n", path
);
1221 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1223 memset(too_long
, 'a', LONG_LEN
);
1224 too_long
[LONG_LEN
- 1] = '\0';
1226 /* path is longer than MAX_PATH */
1227 SetLastError(0xdeadbeef);
1228 str
= PathAddBackslashA(too_long
);
1229 ok(str
== NULL
, "Expected str == NULL, got %p\n", str
);
1230 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1233 static void test_PathAppendA(void)
1235 char path
[MAX_PATH
];
1236 char too_long
[LONG_LEN
];
1237 char one
[HALF_LEN
], two
[HALF_LEN
];
1240 lstrcpy(path
, "C:\\one");
1242 /* try NULL pszMore */
1243 SetLastError(0xdeadbeef);
1244 res
= PathAppendA(path
, NULL
);
1245 ok(!res
, "Expected failure\n");
1246 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1247 ok(!lstrcmp(path
, "C:\\one"), "Expected C:\\one, got %s\n", path
);
1249 /* try empty pszMore */
1250 SetLastError(0xdeadbeef);
1251 res
= PathAppendA(path
, "");
1252 ok(res
, "Expected success\n");
1253 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1254 ok(!lstrcmp(path
, "C:\\one"), "Expected C:\\one, got %s\n", path
);
1256 /* try NULL pszPath */
1257 SetLastError(0xdeadbeef);
1258 res
= PathAppendA(NULL
, "two\\three");
1259 ok(!res
, "Expected failure\n");
1260 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1262 /* try empty pszPath */
1264 SetLastError(0xdeadbeef);
1265 res
= PathAppendA(path
, "two\\three");
1266 ok(res
, "Expected success\n");
1267 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1268 ok(!lstrcmp(path
, "two\\three"), "Expected \\two\\three, got %s\n", path
);
1270 /* try empty pszPath and empty pszMore */
1272 SetLastError(0xdeadbeef);
1273 res
= PathAppendA(path
, "");
1274 ok(res
, "Expected success\n");
1275 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1276 ok(!lstrcmp(path
, "\\"), "Expected \\, got %s\n", path
);
1278 /* try legit params */
1279 lstrcpy(path
, "C:\\one");
1280 SetLastError(0xdeadbeef);
1281 res
= PathAppendA(path
, "two\\three");
1282 ok(res
, "Expected success\n");
1283 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1284 ok(!lstrcmp(path
, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path
);
1286 /* try pszPath with backslash after it */
1287 lstrcpy(path
, "C:\\one\\");
1288 SetLastError(0xdeadbeef);
1289 res
= PathAppendA(path
, "two\\three");
1290 ok(res
, "Expected success\n");
1291 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1292 ok(!lstrcmp(path
, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path
);
1294 /* try pszMore with backslash before it */
1295 lstrcpy(path
, "C:\\one");
1296 SetLastError(0xdeadbeef);
1297 res
= PathAppendA(path
, "\\two\\three");
1298 ok(res
, "Expected success\n");
1299 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1300 ok(!lstrcmp(path
, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path
);
1302 /* try pszMore with backslash after it */
1303 lstrcpy(path
, "C:\\one");
1304 SetLastError(0xdeadbeef);
1305 res
= PathAppendA(path
, "two\\three\\");
1306 ok(res
, "Expected success\n");
1307 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1308 ok(!lstrcmp(path
, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", path
);
1310 /* try spaces in pszPath */
1311 lstrcpy(path
, "C: \\ one ");
1312 SetLastError(0xdeadbeef);
1313 res
= PathAppendA(path
, "two\\three");
1314 ok(res
, "Expected success\n");
1315 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1316 ok(!lstrcmp(path
, "C: \\ one \\two\\three"), "Expected C: \\ one \\two\\three, got %s\n", path
);
1318 /* try spaces in pszMore */
1319 lstrcpy(path
, "C:\\one");
1320 SetLastError(0xdeadbeef);
1321 res
= PathAppendA(path
, " two \\ three ");
1322 ok(res
, "Expected success\n");
1323 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1324 ok(!lstrcmp(path
, "C:\\one\\ two \\ three "), "Expected 'C:\\one\\ two \\ three ', got %s\n", path
);
1326 /* pszPath is too long */
1327 memset(too_long
, 'a', LONG_LEN
);
1328 too_long
[LONG_LEN
- 1] = '\0';
1329 SetLastError(0xdeadbeef);
1330 res
= PathAppendA(too_long
, "two\\three");
1331 ok(!res
, "Expected failure\n");
1332 todo_wine
ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1333 ok(lstrlen(too_long
) == 0, "Expected length of too_long to be zero, got %i\n", lstrlen(too_long
));
1335 /* pszMore is too long */
1336 lstrcpy(path
, "C:\\one");
1337 memset(too_long
, 'a', LONG_LEN
);
1338 too_long
[LONG_LEN
- 1] = '\0';
1339 SetLastError(0xdeadbeef);
1340 res
= PathAppendA(path
, too_long
);
1341 ok(!res
, "Expected failure\n");
1342 todo_wine
ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1343 ok(lstrlen(path
) == 0, "Expected length of path to be zero, got %i\n", lstrlen(path
));
1345 /* both params combined are too long */
1346 memset(one
, 'a', HALF_LEN
);
1347 one
[HALF_LEN
- 1] = '\0';
1348 memset(two
, 'b', HALF_LEN
);
1349 two
[HALF_LEN
- 1] = '\0';
1350 SetLastError(0xdeadbeef);
1351 res
= PathAppendA(one
, two
);
1352 ok(!res
, "Expected failure\n");
1353 ok(lstrlen(one
) == 0, "Expected length of one to be zero, got %i\n", lstrlen(one
));
1354 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1357 static void test_PathCanonicalizeA(void)
1359 char dest
[MAX_PATH
];
1360 char too_long
[LONG_LEN
];
1363 /* try a NULL source */
1364 lstrcpy(dest
, "test");
1365 SetLastError(0xdeadbeef);
1366 res
= PathCanonicalizeA(dest
, NULL
);
1367 ok(!res
, "Expected failure\n");
1368 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1369 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1372 ok(!lstrcmp(dest
, "test"), "Expected test, got %s\n", dest
);
1375 /* try an empty source */
1376 lstrcpy(dest
, "test");
1377 SetLastError(0xdeadbeef);
1378 res
= PathCanonicalizeA(dest
, "");
1379 ok(res
, "Expected success\n");
1380 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1381 ok(!lstrcmp(dest
, "\\"), "Expected \\, got %s\n", dest
);
1383 /* try a NULL dest */
1384 SetLastError(0xdeadbeef);
1385 res
= PathCanonicalizeA(NULL
, "C:\\");
1386 ok(!res
, "Expected failure\n");
1387 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1388 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1390 /* try empty dest */
1392 SetLastError(0xdeadbeef);
1393 res
= PathCanonicalizeA(dest
, "C:\\");
1394 ok(res
, "Expected success\n");
1395 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1396 ok(!lstrcmp(dest
, "C:\\"), "Expected C:\\, got %s\n", dest
);
1398 /* try non-empty dest */
1399 lstrcpy(dest
, "test");
1400 SetLastError(0xdeadbeef);
1401 res
= PathCanonicalizeA(dest
, "C:\\");
1402 ok(res
, "Expected success\n");
1403 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1404 ok(!lstrcmp(dest
, "C:\\"), "Expected C:\\, got %s\n", dest
);
1406 /* try a space for source */
1407 lstrcpy(dest
, "test");
1408 SetLastError(0xdeadbeef);
1409 res
= PathCanonicalizeA(dest
, " ");
1410 ok(res
, "Expected success\n");
1411 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1412 ok(!lstrcmp(dest
, " "), "Expected ' ', got %s\n", dest
);
1414 /* try a relative path */
1415 lstrcpy(dest
, "test");
1416 SetLastError(0xdeadbeef);
1417 res
= PathCanonicalizeA(dest
, "one\\two");
1418 ok(res
, "Expected success\n");
1419 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1420 ok(!lstrcmp(dest
, "one\\two"), "Expected one\\two, got %s\n", dest
);
1422 /* try current dir and previous dir */
1423 lstrcpy(dest
, "test");
1424 SetLastError(0xdeadbeef);
1425 res
= PathCanonicalizeA(dest
, "C:\\one\\.\\..\\two\\three\\..");
1426 ok(res
, "Expected success\n");
1427 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1428 ok(!lstrcmp(dest
, "C:\\two"), "Expected C:\\two, got %s\n", dest
);
1430 /* try simple forward slashes */
1431 lstrcpy(dest
, "test");
1432 SetLastError(0xdeadbeef);
1433 res
= PathCanonicalizeA(dest
, "C:\\one/two/three\\four/five\\six");
1434 ok(res
, "Expected success\n");
1435 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1436 ok(!lstrcmp(dest
, "C:\\one/two/three\\four/five\\six"),
1437 "Expected C:\\one/two/three\\four/five\\six, got %s\n", dest
);
1439 /* try simple forward slashes with same dir */
1440 lstrcpy(dest
, "test");
1441 SetLastError(0xdeadbeef);
1442 res
= PathCanonicalizeA(dest
, "C:\\one/.\\two");
1443 ok(res
, "Expected success\n");
1444 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1445 ok(!lstrcmp(dest
, "C:\\one/.\\two"), "Expected C:\\one/.\\two, got %s\n", dest
);
1447 /* try simple forward slashes with change dir */
1448 lstrcpy(dest
, "test");
1449 SetLastError(0xdeadbeef);
1450 res
= PathCanonicalizeA(dest
, "C:\\one/.\\two\\..");
1451 ok(res
, "Expected success\n");
1452 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1453 ok(!lstrcmp(dest
, "C:\\one/."), "Expected C:\\one/., got %s\n", dest
);
1455 /* try forward slashes with change dirs
1456 * NOTE: if there is a forward slash in between two backslashes,
1457 * everything in between the two backslashes is considered on dir
1459 lstrcpy(dest
, "test");
1460 SetLastError(0xdeadbeef);
1461 res
= PathCanonicalizeA(dest
, "C:\\one/.\\..\\two/three\\..\\four/.five");
1462 ok(res
, "Expected success\n");
1463 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1464 ok(!lstrcmp(dest
, "C:\\four/.five"), "Expected C:\\four/.five, got %s\n", dest
);
1466 /* try src is too long */
1467 memset(too_long
, 'a', LONG_LEN
);
1468 too_long
[LONG_LEN
- 1] = '\0';
1469 lstrcpy(dest
, "test");
1470 SetLastError(0xdeadbeef);
1471 res
= PathCanonicalizeA(dest
, too_long
);
1474 ok(!res
, "Expected failure\n");
1475 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1477 ok(lstrlen(too_long
) == LONG_LEN
- 1, "Expected length LONG_LEN - 1, got %i\n", lstrlen(too_long
));
1480 static void test_PathFindExtensionA(void)
1483 char path
[MAX_PATH
];
1484 char too_long
[LONG_LEN
];
1486 /* try a NULL path */
1487 SetLastError(0xdeadbeef);
1488 ext
= PathFindExtensionA(NULL
);
1489 ok(ext
== NULL
, "Expected NULL, got %p\n", ext
);
1490 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1492 /* try an empty path */
1494 SetLastError(0xdeadbeef);
1495 ext
= PathFindExtensionA(path
);
1496 ok(ext
== path
, "Expected ext == path, got %p\n", ext
);
1497 ok(lstrlen(ext
) == 0, "Expected length 0, got %i\n", lstrlen(ext
));
1498 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1500 /* try a path without an extension */
1501 lstrcpy(path
, "file");
1502 SetLastError(0xdeadbeef);
1503 ext
= PathFindExtensionA(path
);
1504 ok(ext
== path
+ lstrlen(path
), "Expected ext == path, got %p\n", ext
);
1505 ok(lstrlen(ext
) == 0, "Expected length 0, got %i\n", lstrlen(ext
));
1506 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1508 /* try a path with an extension */
1509 lstrcpy(path
, "file.txt");
1510 SetLastError(0xdeadbeef);
1511 ext
= PathFindExtensionA(path
);
1512 ok(ext
== path
+ lstrlen("file"),
1513 "Expected ext == path + lstrlen(\"file\"), got %p\n", ext
);
1514 ok(!lstrcmp(ext
, ".txt"), "Expected .txt, got %s\n", ext
);
1515 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1517 /* try a path with two extensions */
1518 lstrcpy(path
, "file.txt.doc");
1519 SetLastError(0xdeadbeef);
1520 ext
= PathFindExtensionA(path
);
1521 ok(ext
== path
+ lstrlen("file.txt"),
1522 "Expected ext == path + lstrlen(\"file.txt\"), got %p\n", ext
);
1523 ok(!lstrcmp(ext
, ".doc"), "Expected .txt, got %s\n", ext
);
1524 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1526 /* try a path longer than MAX_PATH without an extension*/
1527 memset(too_long
, 'a', LONG_LEN
);
1528 too_long
[LONG_LEN
- 1] = '\0';
1529 SetLastError(0xdeadbeef);
1530 ext
= PathFindExtensionA(too_long
);
1531 ok(ext
== too_long
+ LONG_LEN
- 1, "Expected ext == too_long + LONG_LEN - 1, got %p\n", ext
);
1532 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1534 /* try a path longer than MAX_PATH with an extension*/
1535 memset(too_long
, 'a', LONG_LEN
);
1536 too_long
[LONG_LEN
- 1] = '\0';
1537 lstrcpy(too_long
+ 300, ".abcde");
1538 too_long
[lstrlen(too_long
)] = 'a';
1539 SetLastError(0xdeadbeef);
1540 ext
= PathFindExtensionA(too_long
);
1541 ok(ext
== too_long
+ 300, "Expected ext == too_long + 300, got %p\n", ext
);
1542 ok(lstrlen(ext
) == LONG_LEN
- 301, "Expected LONG_LEN - 301, got %i\n", lstrlen(ext
));
1543 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1546 static void test_PathBuildRootA(void)
1550 char root_expected
[26][4];
1554 /* set up the expected paths */
1555 for (drive
= 'A'; drive
<= 'Z'; drive
++)
1556 sprintf(root_expected
[drive
- 'A'], "%c:\\", drive
);
1558 /* test the expected values */
1559 for (j
= 0; j
< 26; j
++)
1561 SetLastError(0xdeadbeef);
1562 lstrcpy(path
, "aaaaaaaaa");
1563 root
= PathBuildRootA(path
, j
);
1564 ok(root
== path
, "Expected root == path, got %p\n", root
);
1565 ok(!lstrcmp(root
, root_expected
[j
]), "Expected %s, got %s\n", root_expected
[j
], root
);
1566 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1569 /* test a negative drive number */
1570 SetLastError(0xdeadbeef);
1571 lstrcpy(path
, "aaaaaaaaa");
1572 root
= PathBuildRootA(path
, -1);
1573 ok(root
== path
, "Expected root == path, got %p\n", root
);
1574 ok(!lstrcmp(path
, "aaaaaaaaa"), "Expected aaaaaaaaa, got %s\n", path
);
1575 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1577 /* test a drive number greater than 25 */
1578 SetLastError(0xdeadbeef);
1579 lstrcpy(path
, "aaaaaaaaa");
1580 root
= PathBuildRootA(path
, 26);
1581 ok(root
== path
, "Expected root == path, got %p\n", root
);
1582 ok(!lstrcmp(path
, "aaaaaaaaa"), "Expected aaaaaaaaa, got %s\n", path
);
1583 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1585 /* length of path is less than 4 */
1586 SetLastError(0xdeadbeef);
1587 lstrcpy(path
, "aa");
1588 root
= PathBuildRootA(path
, 0);
1589 ok(root
== path
, "Expected root == path, got %p\n", root
);
1590 ok(!lstrcmp(path
, "A:\\"), "Expected A:\\, got %s\n", path
);
1591 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1594 SetLastError(0xdeadbeef);
1595 root
= PathBuildRootA(NULL
, 0);
1596 ok(root
== NULL
, "Expected root == NULL, got %p\n", root
);
1597 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1600 static void test_PathCommonPrefixA(void)
1602 char path1
[MAX_PATH
], path2
[MAX_PATH
];
1606 /* test NULL path1 */
1607 SetLastError(0xdeadbeef);
1608 lstrcpy(path2
, "C:\\");
1609 lstrcpy(out
, "aaa");
1610 count
= PathCommonPrefixA(NULL
, path2
, out
);
1611 ok(count
== 0, "Expected 0, got %i\n", count
);
1614 ok(!lstrcmp(out
, "aaa"), "Expected aaa, got %s\n", out
);
1616 ok(!lstrcmp(path2
, "C:\\"), "Expected C:\\, got %s\n", path2
);
1617 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1619 /* test NULL path2 */
1620 SetLastError(0xdeadbeef);
1621 lstrcpy(path1
, "C:\\");
1622 lstrcpy(out
, "aaa");
1623 count
= PathCommonPrefixA(path1
, NULL
, out
);
1624 ok(count
== 0, "Expected 0, got %i\n", count
);
1627 ok(!lstrcmp(out
, "aaa"), "Expected aaa, got %s\n", out
);
1629 ok(!lstrcmp(path1
, "C:\\"), "Expected C:\\, got %s\n", path1
);
1630 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1632 /* test empty path1 */
1633 SetLastError(0xdeadbeef);
1635 lstrcpy(path2
, "C:\\");
1636 lstrcpy(out
, "aaa");
1637 count
= PathCommonPrefixA(path1
, path2
, out
);
1638 ok(count
== 0, "Expected 0, got %i\n", count
);
1639 ok(lstrlen(out
) == 0, "Expected 0 length out, got %i\n", lstrlen(out
));
1640 ok(lstrlen(path1
) == 0, "Expected 0 length path1, got %i\n", lstrlen(path1
));
1641 ok(!lstrcmp(path2
, "C:\\"), "Expected C:\\, got %s\n", path2
);
1642 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1644 /* test empty path1 */
1645 SetLastError(0xdeadbeef);
1647 lstrcpy(path1
, "C:\\");
1648 lstrcpy(out
, "aaa");
1649 count
= PathCommonPrefixA(path1
, path2
, out
);
1650 ok(count
== 0, "Expected 0, got %i\n", count
);
1651 ok(lstrlen(out
) == 0, "Expected 0 length out, got %i\n", lstrlen(out
));
1652 ok(lstrlen(path2
) == 0, "Expected 0 length path2, got %i\n", lstrlen(path2
));
1653 ok(!lstrcmp(path1
, "C:\\"), "Expected C:\\, got %s\n", path1
);
1654 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1656 /* paths are legit, out is NULL */
1657 SetLastError(0xdeadbeef);
1658 lstrcpy(path1
, "C:\\");
1659 lstrcpy(path2
, "C:\\");
1660 count
= PathCommonPrefixA(path1
, path2
, NULL
);
1661 ok(count
== 3, "Expected 3, got %i\n", count
);
1662 ok(!lstrcmp(path1
, "C:\\"), "Expected C:\\, got %s\n", path1
);
1663 ok(!lstrcmp(path2
, "C:\\"), "Expected C:\\, got %s\n", path2
);
1664 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1666 /* all parameters legit */
1667 SetLastError(0xdeadbeef);
1668 lstrcpy(path1
, "C:\\");
1669 lstrcpy(path2
, "C:\\");
1670 lstrcpy(out
, "aaa");
1671 count
= PathCommonPrefixA(path1
, path2
, out
);
1672 ok(count
== 3, "Expected 3, got %i\n", count
);
1673 ok(!lstrcmp(path1
, "C:\\"), "Expected C:\\, got %s\n", path1
);
1674 ok(!lstrcmp(path2
, "C:\\"), "Expected C:\\, got %s\n", path2
);
1675 ok(!lstrcmp(out
, "C:\\"), "Expected C:\\, got %s\n", out
);
1676 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1678 /* path1 and path2 not the same, but common prefix */
1679 SetLastError(0xdeadbeef);
1680 lstrcpy(path1
, "C:\\one\\two");
1681 lstrcpy(path2
, "C:\\one\\three");
1682 lstrcpy(out
, "aaa");
1683 count
= PathCommonPrefixA(path1
, path2
, out
);
1684 ok(count
== 6, "Expected 6, got %i\n", count
);
1685 ok(!lstrcmp(path1
, "C:\\one\\two"), "Expected C:\\one\\two, got %s\n", path1
);
1686 ok(!lstrcmp(path2
, "C:\\one\\three"), "Expected C:\\one\\three, got %s\n", path2
);
1687 ok(!lstrcmp(out
, "C:\\one"), "Expected C:\\one, got %s\n", out
);
1688 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1691 SetLastError(0xdeadbeef);
1692 lstrcpy(path1
, "one\\.two");
1693 lstrcpy(path2
, "one\\.three");
1694 lstrcpy(out
, "aaa");
1695 count
= PathCommonPrefixA(path1
, path2
, out
);
1696 ok(count
== 3, "Expected 3, got %i\n", count
);
1697 ok(!lstrcmp(path1
, "one\\.two"), "Expected one\\.two, got %s\n", path1
);
1698 ok(!lstrcmp(path2
, "one\\.three"), "Expected one\\.three, got %s\n", path2
);
1699 ok(!lstrcmp(out
, "one"), "Expected one, got %s\n", out
);
1700 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1703 SetLastError(0xdeadbeef);
1704 lstrcpy(path1
, "one\\..two");
1705 lstrcpy(path2
, "one\\..three");
1706 lstrcpy(out
, "aaa");
1707 count
= PathCommonPrefixA(path1
, path2
, out
);
1708 ok(count
== 3, "Expected 3, got %i\n", count
);
1709 ok(!lstrcmp(path1
, "one\\..two"), "Expected one\\..two, got %s\n", path1
);
1710 ok(!lstrcmp(path2
, "one\\..three"), "Expected one\\..three, got %s\n", path2
);
1711 ok(!lstrcmp(out
, "one"), "Expected one, got %s\n", out
);
1712 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1714 /* try ... prefix */
1715 SetLastError(0xdeadbeef);
1716 lstrcpy(path1
, "one\\...two");
1717 lstrcpy(path2
, "one\\...three");
1718 lstrcpy(out
, "aaa");
1719 count
= PathCommonPrefixA(path1
, path2
, out
);
1720 ok(count
== 3, "Expected 3, got %i\n", count
);
1721 ok(!lstrcmp(path1
, "one\\...two"), "Expected one\\...two, got %s\n", path1
);
1722 ok(!lstrcmp(path2
, "one\\...three"), "Expected one\\...three, got %s\n", path2
);
1723 ok(!lstrcmp(out
, "one"), "Expected one, got %s\n", out
);
1724 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1727 SetLastError(0xdeadbeef);
1728 lstrcpy(path1
, "one\\.\\two");
1729 lstrcpy(path2
, "one\\.\\three");
1730 lstrcpy(out
, "aaa");
1731 count
= PathCommonPrefixA(path1
, path2
, out
);
1732 ok(count
== 5, "Expected 5, got %i\n", count
);
1733 ok(!lstrcmp(path1
, "one\\.\\two"), "Expected one\\.\\two, got %s\n", path1
);
1734 ok(!lstrcmp(path2
, "one\\.\\three"), "Expected one\\.\\three, got %s\n", path2
);
1735 ok(!lstrcmp(out
, "one\\."), "Expected one\\., got %s\n", out
);
1736 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1738 /* try ..\ prefix */
1739 SetLastError(0xdeadbeef);
1740 lstrcpy(path1
, "one\\..\\two");
1741 lstrcpy(path2
, "one\\..\\three");
1742 lstrcpy(out
, "aaa");
1743 count
= PathCommonPrefixA(path1
, path2
, out
);
1744 ok(count
== 6, "Expected 6, got %i\n", count
);
1745 ok(!lstrcmp(path1
, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1
);
1746 ok(!lstrcmp(path2
, "one\\..\\three"), "Expected one\\..\\three, got %s\n", path2
);
1747 ok(!lstrcmp(out
, "one\\.."), "Expected one\\.., got %s\n", out
);
1748 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1750 /* try ...\\ prefix */
1751 SetLastError(0xdeadbeef);
1752 lstrcpy(path1
, "one\\...\\two");
1753 lstrcpy(path2
, "one\\...\\three");
1754 lstrcpy(out
, "aaa");
1755 count
= PathCommonPrefixA(path1
, path2
, out
);
1756 ok(count
== 7, "Expected 7, got %i\n", count
);
1757 ok(!lstrcmp(path1
, "one\\...\\two"), "Expected one\\...\\two, got %s\n", path1
);
1758 ok(!lstrcmp(path2
, "one\\...\\three"), "Expected one\\...\\three, got %s\n", path2
);
1759 ok(!lstrcmp(out
, "one\\..."), "Expected one\\..., got %s\n", out
);
1760 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1762 /* try prefix that is not an msdn labeled prefix type */
1763 SetLastError(0xdeadbeef);
1764 lstrcpy(path1
, "same");
1765 lstrcpy(path2
, "same");
1766 lstrcpy(out
, "aaa");
1767 count
= PathCommonPrefixA(path1
, path2
, out
);
1768 ok(count
== 4, "Expected 4, got %i\n", count
);
1769 ok(!lstrcmp(path1
, "same"), "Expected same, got %s\n", path1
);
1770 ok(!lstrcmp(path2
, "same"), "Expected same, got %s\n", path2
);
1771 ok(!lstrcmp(out
, "same"), "Expected same, got %s\n", out
);
1772 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1774 /* try . after directory */
1775 SetLastError(0xdeadbeef);
1776 lstrcpy(path1
, "one\\mid.\\two");
1777 lstrcpy(path2
, "one\\mid.\\three");
1778 lstrcpy(out
, "aaa");
1779 count
= PathCommonPrefixA(path1
, path2
, out
);
1780 ok(count
== 8, "Expected 8, got %i\n", count
);
1781 ok(!lstrcmp(path1
, "one\\mid.\\two"), "Expected one\\mid.\\two, got %s\n", path1
);
1782 ok(!lstrcmp(path2
, "one\\mid.\\three"), "Expected one\\mid.\\three, got %s\n", path2
);
1783 ok(!lstrcmp(out
, "one\\mid."), "Expected one\\mid., got %s\n", out
);
1784 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1786 /* try . in the middle of a directory */
1787 SetLastError(0xdeadbeef);
1788 lstrcpy(path1
, "one\\mid.end\\two");
1789 lstrcpy(path2
, "one\\mid.end\\three");
1790 lstrcpy(out
, "aaa");
1791 count
= PathCommonPrefixA(path1
, path2
, out
);
1792 ok(count
== 11, "Expected 11, got %i\n", count
);
1793 ok(!lstrcmp(path1
, "one\\mid.end\\two"), "Expected one\\mid.end\\two, got %s\n", path1
);
1794 ok(!lstrcmp(path2
, "one\\mid.end\\three"), "Expected one\\mid.end\\three, got %s\n", path2
);
1795 ok(!lstrcmp(out
, "one\\mid.end"), "Expected one\\mid.end, got %s\n", out
);
1796 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1798 /* try comparing a .. with the expanded path */
1799 SetLastError(0xdeadbeef);
1800 lstrcpy(path1
, "one\\..\\two");
1801 lstrcpy(path2
, "two");
1802 lstrcpy(out
, "aaa");
1803 count
= PathCommonPrefixA(path1
, path2
, out
);
1804 ok(count
== 0, "Expected 0, got %i\n", count
);
1805 ok(!lstrcmp(path1
, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1
);
1806 ok(!lstrcmp(path2
, "two"), "Expected two, got %s\n", path2
);
1807 ok(lstrlen(out
) == 0, "Expected 0 length out, got %i\n", lstrlen(out
));
1808 ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError());
1811 static void test_PathUnquoteSpaces(void)
1814 for(i
= 0; i
< sizeof(TEST_PATH_UNQUOTE_SPACES
) / sizeof(TEST_PATH_UNQUOTE_SPACES
[0]); i
++)
1816 char *path
= strdupA(TEST_PATH_UNQUOTE_SPACES
[i
].path
);
1817 WCHAR
*pathW
= GetWideString(TEST_PATH_UNQUOTE_SPACES
[i
].path
);
1818 WCHAR
*resultW
= GetWideString(TEST_PATH_UNQUOTE_SPACES
[i
].result
);
1820 PathUnquoteSpacesA(path
);
1821 ok(!strcmp(path
, TEST_PATH_UNQUOTE_SPACES
[i
].result
), "%s (A): got %s expected %s\n",
1822 TEST_PATH_UNQUOTE_SPACES
[i
].path
, path
,
1823 TEST_PATH_UNQUOTE_SPACES
[i
].result
);
1825 PathUnquoteSpacesW(pathW
);
1826 ok(!lstrcmpW(pathW
, resultW
), "%s (W): strings differ\n",
1827 TEST_PATH_UNQUOTE_SPACES
[i
].path
);
1828 FreeWideString(pathW
);
1829 FreeWideString(resultW
);
1830 HeapFree(GetProcessHeap(), 0, path
);
1836 hShlwapi
= LoadLibraryA("shlwapi.dll");
1837 if (!hShlwapi
) return;
1841 test_UrlCanonicalize();
1844 test_UrlCreateFromPath();
1848 test_PathSearchAndQualify();
1849 test_PathCreateFromUrl();
1852 test_PathAddBackslash();
1853 test_PathMakePretty();
1854 test_PathMatchSpec();
1856 /* For whatever reason, PathIsValidCharA and PathAppendA share the same
1857 * ordinal number in some native versions. Check this to prevent a crash.
1859 pPathIsValidCharA
= (void*)GetProcAddress(hShlwapi
, (LPSTR
)455);
1860 if (pPathIsValidCharA
&& pPathIsValidCharA
!= (void*)GetProcAddress(hShlwapi
, "PathAppendA"))
1862 test_PathIsValidCharA();
1864 pPathIsValidCharW
= (void*)GetProcAddress(hShlwapi
, (LPSTR
)456);
1865 if (pPathIsValidCharW
) test_PathIsValidCharW();
1868 pPathCombineW
= (void*)GetProcAddress(hShlwapi
, "PathCombineW");
1870 test_PathCombineW();
1872 test_PathCombineA();
1874 test_PathCanonicalizeA();
1875 test_PathFindExtensionA();
1876 test_PathBuildRootA();
1877 test_PathCommonPrefixA();
1878 test_PathUnquoteSpaces();