wininet: Adapt tests to winehq changes.
[wine] / dlls / wininet / tests / url.c
1 /*
2  * Wininet - URL tests
3  *
4  * Copyright 2002 Aric Stewart
5  * Copyright 2004 Mike McCormack
6  * Copyright 2005 Hans Leidekker
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22
23 #include <stdarg.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26
27 #include "windef.h"
28 #include "winbase.h"
29 #include "wininet.h"
30
31 #include "wine/test.h"
32
33 #define TEST_URL "http://www.winehq.org/site/about"
34 #define TEST_URL_HOST "www.winehq.org"
35 #define TEST_URL_PATH "/site/about"
36 #define TEST_URL2 "http://www.myserver.com/myscript.php?arg=1"
37 #define TEST_URL2_SERVER "www.myserver.com"
38 #define TEST_URL2_PATH "/myscript.php"
39 #define TEST_URL2_PATHEXTRA "/myscript.php?arg=1"
40 #define TEST_URL2_EXTRA "?arg=1"
41 #define TEST_URL3 "file:///C:/Program%20Files/Atmel/AVR%20Tools/STK500/STK500.xml"
42
43 #define CREATE_URL1 "http://username:password@www.winehq.org/site/about"
44 #define CREATE_URL2 "http://username@www.winehq.org/site/about"
45 #define CREATE_URL3 "http://username:"
46 #define CREATE_URL4 "http://www.winehq.org/site/about"
47 #define CREATE_URL5 "http://"
48 #define CREATE_URL6 "nhttp://username:password@www.winehq.org:80/site/about"
49 #define CREATE_URL7 "http://username:password@www.winehq.org:42/site/about"
50 #define CREATE_URL8 "https://username:password@www.winehq.org/site/about"
51 #define CREATE_URL9 "about:blank"
52 #define CREATE_URL10 "about://host/blank"
53 #define CREATE_URL11 "about:"
54 #define CREATE_URL12 "http://www.winehq.org:65535"
55 #define CREATE_URL13 "http://localhost/?test=123"
56
57 static void copy_compsA(
58     URL_COMPONENTSA *src, 
59     URL_COMPONENTSA *dst, 
60     DWORD scheLen,
61     DWORD hostLen,
62     DWORD userLen,
63     DWORD passLen,
64     DWORD pathLen,
65     DWORD extrLen )
66 {
67     *dst = *src;
68     dst->dwSchemeLength    = scheLen;
69     dst->dwHostNameLength  = hostLen;
70     dst->dwUserNameLength  = userLen;
71     dst->dwPasswordLength  = passLen;
72     dst->dwUrlPathLength   = pathLen;
73     dst->dwExtraInfoLength = extrLen;
74     SetLastError(0xfaceabad);
75 }
76
77 static void zero_compsA(
78     URL_COMPONENTSA *dst, 
79     DWORD scheLen,
80     DWORD hostLen,
81     DWORD userLen,
82     DWORD passLen,
83     DWORD pathLen,
84     DWORD extrLen )
85 {
86     ZeroMemory(dst, sizeof(URL_COMPONENTSA));
87     dst->dwStructSize = sizeof(URL_COMPONENTSA);
88     dst->dwSchemeLength    = scheLen;
89     dst->dwHostNameLength  = hostLen;
90     dst->dwUserNameLength  = userLen;
91     dst->dwPasswordLength  = passLen;
92     dst->dwUrlPathLength   = pathLen;
93     dst->dwExtraInfoLength = extrLen;
94     SetLastError(0xfaceabad);
95 }
96
97 static void InternetCrackUrl_test(void)
98 {
99   URL_COMPONENTSA urlSrc, urlComponents;
100   char protocol[32], hostName[1024], userName[1024];
101   char password[1024], extra[1024], path[1024];
102   BOOL ret, firstret;
103   DWORD GLE, firstGLE;
104
105   ZeroMemory(&urlSrc, sizeof(urlSrc));
106   urlSrc.dwStructSize = sizeof(urlSrc);
107   urlSrc.lpszScheme = protocol;
108   urlSrc.lpszHostName = hostName;
109   urlSrc.lpszUserName = userName;
110   urlSrc.lpszPassword = password;
111   urlSrc.lpszUrlPath = path;
112   urlSrc.lpszExtraInfo = extra;
113
114   copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 1024, 2048, 1024);
115   ret = InternetCrackUrl(TEST_URL, 0,0,&urlComponents);
116   ok( ret, "InternetCrackUrl failed, error %d\n",GetLastError());
117   ok((strcmp(TEST_URL_PATH,path) == 0),"path cracked wrong\n");
118
119   /* Bug 1805: Confirm the returned lengths are correct:                     */
120   /* 1. When extra info split out explicitly */
121   zero_compsA(&urlComponents, 0, 1, 0, 0, 1, 1);
122   ok(InternetCrackUrlA(TEST_URL2, 0, 0, &urlComponents),"InternetCrackUrl failed, error %d\n", GetLastError());
123   ok(urlComponents.dwUrlPathLength == strlen(TEST_URL2_PATH),".dwUrlPathLength should be %d, but is %d\n", (DWORD)strlen(TEST_URL2_PATH), urlComponents.dwUrlPathLength);
124   ok(!strncmp(urlComponents.lpszUrlPath,TEST_URL2_PATH,strlen(TEST_URL2_PATH)),"lpszUrlPath should be %s but is %s\n", TEST_URL2_PATH, urlComponents.lpszUrlPath);
125   ok(urlComponents.dwHostNameLength == strlen(TEST_URL2_SERVER),".dwHostNameLength should be %d, but is %d\n", (DWORD)strlen(TEST_URL2_SERVER), urlComponents.dwHostNameLength);
126   ok(!strncmp(urlComponents.lpszHostName,TEST_URL2_SERVER,strlen(TEST_URL2_SERVER)),"lpszHostName should be %s but is %s\n", TEST_URL2_SERVER, urlComponents.lpszHostName);
127   ok(urlComponents.dwExtraInfoLength == strlen(TEST_URL2_EXTRA),".dwExtraInfoLength should be %d, but is %d\n", (DWORD)strlen(TEST_URL2_EXTRA), urlComponents.dwExtraInfoLength);
128   ok(!strncmp(urlComponents.lpszExtraInfo,TEST_URL2_EXTRA,strlen(TEST_URL2_EXTRA)),"lpszExtraInfo should be %s but is %s\n", TEST_URL2_EXTRA, urlComponents.lpszHostName);
129
130   /* 2. When extra info is not split out explicitly and is in url path */
131   zero_compsA(&urlComponents, 0, 1, 0, 0, 1, 0);
132   ok(InternetCrackUrlA(TEST_URL2, 0, 0, &urlComponents),"InternetCrackUrl failed with GLE %d\n",GetLastError());
133   ok(urlComponents.dwUrlPathLength == strlen(TEST_URL2_PATHEXTRA),".dwUrlPathLength should be %d, but is %d\n", (DWORD)strlen(TEST_URL2_PATHEXTRA), urlComponents.dwUrlPathLength);
134   ok(!strncmp(urlComponents.lpszUrlPath,TEST_URL2_PATHEXTRA,strlen(TEST_URL2_PATHEXTRA)),"lpszUrlPath should be %s but is %s\n", TEST_URL2_PATHEXTRA, urlComponents.lpszUrlPath);
135   ok(urlComponents.dwHostNameLength == strlen(TEST_URL2_SERVER),".dwHostNameLength should be %d, but is %d\n", (DWORD)strlen(TEST_URL2_SERVER), urlComponents.dwHostNameLength);
136   ok(!strncmp(urlComponents.lpszHostName,TEST_URL2_SERVER,strlen(TEST_URL2_SERVER)),"lpszHostName should be %s but is %s\n", TEST_URL2_SERVER, urlComponents.lpszHostName);
137   ok(urlComponents.nPort == INTERNET_DEFAULT_HTTP_PORT,"urlComponents->nPort should have been 80 instead of %d\n", urlComponents.nPort);
138   ok(urlComponents.nScheme == INTERNET_SCHEME_HTTP,"urlComponents->nScheme should have been INTERNET_SCHEME_HTTP instead of %d\n", urlComponents.nScheme);
139
140   zero_compsA(&urlComponents, 1, 1, 1, 1, 1, 1);
141   ok(InternetCrackUrlA(TEST_URL, strlen(TEST_URL), 0, &urlComponents),"InternetCrackUrl failed with GLE %d\n",GetLastError());
142   ok(urlComponents.dwUrlPathLength == strlen(TEST_URL_PATH),".dwUrlPathLength should be %d, but is %d\n", lstrlenA(TEST_URL_PATH), urlComponents.dwUrlPathLength);
143   ok(!strncmp(urlComponents.lpszUrlPath,TEST_URL_PATH,strlen(TEST_URL_PATH)),"lpszUrlPath should be %s but is %s\n", TEST_URL_PATH, urlComponents.lpszUrlPath);
144   ok(urlComponents.dwHostNameLength == strlen(TEST_URL_HOST),".dwHostNameLength should be %d, but is %d\n", lstrlenA(TEST_URL_HOST), urlComponents.dwHostNameLength);
145   ok(!strncmp(urlComponents.lpszHostName,TEST_URL_HOST,strlen(TEST_URL_HOST)),"lpszHostName should be %s but is %s\n", TEST_URL_HOST, urlComponents.lpszHostName);
146   ok(urlComponents.nPort == INTERNET_DEFAULT_HTTP_PORT,"urlComponents->nPort should have been 80 instead of %d\n", urlComponents.nPort);
147   ok(urlComponents.nScheme == INTERNET_SCHEME_HTTP,"urlComponents->nScheme should have been INTERNET_SCHEME_HTTP instead of %d\n", urlComponents.nScheme);
148   ok(!urlComponents.lpszUserName, ".lpszUserName should have been set to NULL\n");
149   ok(!urlComponents.lpszPassword, ".lpszPassword should have been set to NULL\n");
150   ok(!urlComponents.lpszExtraInfo, ".lpszExtraInfo should have been set to NULL\n");
151   ok(!urlComponents.dwUserNameLength,".dwUserNameLength should be 0, but is %d\n", urlComponents.dwUserNameLength);
152   ok(!urlComponents.dwPasswordLength,".dwPasswordLength should be 0, but is %d\n", urlComponents.dwPasswordLength);
153   ok(!urlComponents.dwExtraInfoLength,".dwExtraInfoLength should be 0, but is %d\n", urlComponents.dwExtraInfoLength);
154
155   /*3. Check for %20 */
156   copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 1024, 2048, 1024);
157   ok(InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents),"InternetCrackUrl failed with GLE %d\n",GetLastError());
158
159   /* Tests for lpsz* members pointing to real strings while 
160    * some corresponding length members are set to zero.
161    * As of IE7 (wininet 7.0*?) all members are checked. So we
162    * run the first test and expect the outcome to be the same
163    * for the first four (scheme, hostname, username and password).
164    * The last two (path and extrainfo) are the same for all versions
165    * of the wininet.dll.
166    */
167   copy_compsA(&urlSrc, &urlComponents, 0, 1024, 1024, 1024, 2048, 1024);
168   SetLastError(0xdeadbeef);
169   firstret = InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents);
170   firstGLE = GetLastError();
171
172   copy_compsA(&urlSrc, &urlComponents, 32, 0, 1024, 1024, 2048, 1024);
173   SetLastError(0xdeadbeef);
174   ret = InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents);
175   GLE = GetLastError();
176   ok(ret==firstret && (GLE==firstGLE), "InternetCrackUrl returned %d with GLE=%d (expected to return %d)\n",
177     ret, GetLastError(), firstret);
178
179   copy_compsA(&urlSrc, &urlComponents, 32, 1024, 0, 1024, 2048, 1024);
180   SetLastError(0xdeadbeef);
181   ret = InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents);
182   GLE = GetLastError();
183   ok(ret==firstret && (GLE==firstGLE), "InternetCrackUrl returned %d with GLE=%d (expected to return %d)\n",
184     ret, GetLastError(), firstret);
185
186   copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 0, 2048, 1024);
187   SetLastError(0xdeadbeef);
188   ret = InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents);
189   GLE = GetLastError();
190   ok(ret==firstret && (GLE==firstGLE), "InternetCrackUrl returned %d with GLE=%d (expected to return %d)\n",
191     ret, GetLastError(), firstret);
192
193   copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 1024, 0, 1024);
194   SetLastError(0xdeadbeef);
195   ret = InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents);
196   GLE = GetLastError();
197   todo_wine
198   ok(ret==0 && (GLE==ERROR_INVALID_HANDLE || GLE==ERROR_INSUFFICIENT_BUFFER),
199      "InternetCrackUrl returned %d with GLE=%d (expected to return 0 and ERROR_INVALID_HANDLE or ERROR_INSUFFICIENT_BUFFER)\n",
200     ret, GLE);
201
202   copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 1024, 2048, 0);
203   SetLastError(0xdeadbeef);
204   ret = InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents);
205   GLE = GetLastError();
206   todo_wine
207   ok(ret==0 && (GLE==ERROR_INVALID_HANDLE || GLE==ERROR_INSUFFICIENT_BUFFER),
208      "InternetCrackUrl returned %d with GLE=%d (expected to return 0 and ERROR_INVALID_HANDLE or ERROR_INSUFFICIENT_BUFFER)\n",
209     ret, GLE);
210
211   copy_compsA(&urlSrc, &urlComponents, 0, 0, 0, 0, 0, 0);
212   ret = InternetCrackUrlA(TEST_URL3, 0, ICU_DECODE, &urlComponents);
213   GLE = GetLastError();
214   todo_wine
215   ok(ret==0 && GLE==ERROR_INVALID_PARAMETER,
216      "InternetCrackUrl returned %d with GLE=%d (expected to return 0 and ERROR_INVALID_PARAMETER)\n",
217     ret, GLE);
218
219   copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 1024, 2048, 1024);
220   ret = InternetCrackUrl("about://host/blank", 0,0,&urlComponents);
221   ok(ret, "InternetCrackUrl failed with %d\n", GetLastError());
222   ok(!strcmp(urlComponents.lpszScheme, "about"), "lpszScheme was \"%s\" instead of \"about\"\n", urlComponents.lpszScheme);
223   ok(!strcmp(urlComponents.lpszHostName, "host"), "lpszHostName was \"%s\" instead of \"host\"\n", urlComponents.lpszHostName);
224   ok(!strcmp(urlComponents.lpszUrlPath, "/blank"), "lpszUrlPath was \"%s\" instead of \"/blank\"\n", urlComponents.lpszUrlPath);
225
226   /* try a NULL lpszUrl */
227   SetLastError(0xdeadbeef);
228   copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 1024, 2048, 1024);
229   ret = InternetCrackUrl(NULL, 0, 0, &urlComponents);
230   GLE = GetLastError();
231   ok(ret == FALSE, "Expected InternetCrackUrl to fail\n");
232   ok(GLE == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GLE);
233
234   /* try an empty lpszUrl, GetLastError returns 12006, whatever that means
235    * we just need to fail and not return success
236    */
237   SetLastError(0xdeadbeef);
238   copy_compsA(&urlSrc, &urlComponents, 32, 1024, 1024, 1024, 2048, 1024);
239   ret = InternetCrackUrl("", 0, 0, &urlComponents);
240   GLE = GetLastError();
241   ok(ret == FALSE, "Expected InternetCrackUrl to fail\n");
242   ok(GLE != 0xdeadbeef && GLE != ERROR_SUCCESS, "Expected GLE to represent a failure\n");
243
244   /* Invalid Call: must set size of components structure (Windows only
245    * enforces this on the InternetCrackUrlA version of the call) */
246   copy_compsA(&urlSrc, &urlComponents, 0, 1024, 1024, 1024, 2048, 1024);
247   SetLastError(0xdeadbeef);
248   urlComponents.dwStructSize = 0;
249   ret = InternetCrackUrlA(TEST_URL, 0, 0, &urlComponents);
250   ok(ret == FALSE, "Expected InternetCrackUrl to fail\n");
251   ok(GLE != 0xdeadbeef && GLE != ERROR_SUCCESS, "Expected GLE to represent a failure\n");
252
253   /* Invalid Call: size of dwStructSize must be one of the "standard" sizes
254    * of the URL_COMPONENTS structure (Windows only enforces this on the
255    * InternetCrackUrlA version of the call) */
256   copy_compsA(&urlSrc, &urlComponents, 0, 1024, 1024, 1024, 2048, 1024);
257   SetLastError(0xdeadbeef);
258   urlComponents.dwStructSize = sizeof(urlComponents) + 1;
259   ret = InternetCrackUrlA(TEST_URL, 0, 0, &urlComponents);
260   ok(ret == FALSE, "Expected InternetCrackUrl to fail\n");
261   ok(GLE != 0xdeadbeef && GLE != ERROR_SUCCESS, "Expected GLE to represent a failure\n");
262 }
263
264 static void InternetCrackUrlW_test(void)
265 {
266     WCHAR url[] = {
267         'h','t','t','p',':','/','/','1','9','2','.','1','6','8','.','0','.','2','2','/',
268         'C','F','I','D','E','/','m','a','i','n','.','c','f','m','?','C','F','S','V','R',
269         '=','I','D','E','&','A','C','T','I','O','N','=','I','D','E','_','D','E','F','A',
270         'U','L','T', 0 };
271     static const WCHAR url2[] = { '.','.','/','R','i','t','z','.','x','m','l',0 };
272     static const WCHAR url3[] = { 'h','t','t','p',':','/','/','x','.','o','r','g',0 };
273     URL_COMPONENTSW comp;
274     WCHAR scheme[20], host[20], user[20], pwd[20], urlpart[50], extra[50];
275     DWORD error;
276     BOOL r;
277
278     urlpart[0]=0;
279     scheme[0]=0;
280     extra[0]=0;
281     host[0]=0;
282     user[0]=0;
283     pwd[0]=0;
284     memset(&comp, 0, sizeof comp);
285     comp.dwStructSize = sizeof comp;
286     comp.lpszScheme = scheme;
287     comp.dwSchemeLength = sizeof scheme;
288     comp.lpszHostName = host;
289     comp.dwHostNameLength = sizeof host;
290     comp.lpszUserName = user;
291     comp.dwUserNameLength = sizeof user;
292     comp.lpszPassword = pwd;
293     comp.dwPasswordLength = sizeof pwd;
294     comp.lpszUrlPath = urlpart;
295     comp.dwUrlPathLength = sizeof urlpart;
296     comp.lpszExtraInfo = extra;
297     comp.dwExtraInfoLength = sizeof extra;
298
299     SetLastError(0xdeadbeef);
300     r = InternetCrackUrlW(NULL, 0, 0, &comp );
301     error = GetLastError();
302     ok( !r, "InternetCrackUrlW succeeded unexpectedly\n");
303     ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error);
304
305     SetLastError(0xdeadbeef);
306     r = InternetCrackUrlW(url, 0, 0, NULL );
307     error = GetLastError();
308     ok( !r, "InternetCrackUrlW succeeded unexpectedly\n");
309     ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error);
310
311     r = InternetCrackUrlW(url, 0, 0, &comp );
312     ok( r, "failed to crack url\n");
313     ok( comp.dwSchemeLength == 4, "scheme length wrong\n");
314     ok( comp.dwHostNameLength == 12, "host length wrong\n");
315     ok( comp.dwUserNameLength == 0, "user length wrong\n");
316     ok( comp.dwPasswordLength == 0, "password length wrong\n");
317     ok( comp.dwUrlPathLength == 15, "url length wrong\n");
318     ok( comp.dwExtraInfoLength == 29, "extra length wrong\n");
319  
320     urlpart[0]=0;
321     scheme[0]=0;
322     extra[0]=0;
323     host[0]=0;
324     user[0]=0;
325     pwd[0]=0;
326     memset(&comp, 0, sizeof comp);
327     comp.dwStructSize = sizeof comp;
328     comp.lpszHostName = host;
329     comp.dwHostNameLength = sizeof host;
330     comp.lpszUrlPath = urlpart;
331     comp.dwUrlPathLength = sizeof urlpart;
332
333     r = InternetCrackUrlW(url, 0, 0, &comp );
334     ok( r, "failed to crack url\n");
335     ok( comp.dwSchemeLength == 0, "scheme length wrong\n");
336     ok( comp.dwHostNameLength == 12, "host length wrong\n");
337     ok( comp.dwUserNameLength == 0, "user length wrong\n");
338     ok( comp.dwPasswordLength == 0, "password length wrong\n");
339     ok( comp.dwUrlPathLength == 44, "url length wrong\n");
340     ok( comp.dwExtraInfoLength == 0, "extra length wrong\n");
341
342     urlpart[0]=0;
343     scheme[0]=0;
344     extra[0]=0;
345     host[0]=0;
346     user[0]=0;
347     pwd[0]=0;
348     memset(&comp, 0, sizeof comp);
349     comp.dwStructSize = sizeof comp;
350     comp.lpszHostName = host;
351     comp.dwHostNameLength = sizeof host;
352     comp.lpszUrlPath = urlpart;
353     comp.dwUrlPathLength = sizeof urlpart;
354     comp.lpszExtraInfo = NULL;
355     comp.dwExtraInfoLength = sizeof extra;
356
357     r = InternetCrackUrlW(url, 0, 0, &comp );
358     ok( r, "failed to crack url\n");
359     ok( comp.dwSchemeLength == 0, "scheme length wrong\n");
360     ok( comp.dwHostNameLength == 12, "host length wrong\n");
361     ok( comp.dwUserNameLength == 0, "user length wrong\n");
362     ok( comp.dwPasswordLength == 0, "password length wrong\n");
363     ok( comp.dwUrlPathLength == 15, "url length wrong\n");
364     ok( comp.dwExtraInfoLength == 29, "extra length wrong\n");
365
366     urlpart[0]=0;
367     scheme[0]=0;
368     extra[0]=0;
369     host[0]=0;
370     user[0]=0;
371     pwd[0]=0;
372     memset(&comp, 0, sizeof(comp));
373     comp.dwStructSize = sizeof(comp);
374     comp.lpszScheme = scheme;
375     comp.dwSchemeLength = sizeof(scheme)/sizeof(scheme[0]);
376     comp.lpszHostName = host;
377     comp.dwHostNameLength = sizeof(host)/sizeof(host[0]);
378     comp.lpszUserName = user;
379     comp.dwUserNameLength = sizeof(user)/sizeof(user[0]);
380     comp.lpszPassword = pwd;
381     comp.dwPasswordLength = sizeof(pwd)/sizeof(pwd[0]);
382     comp.lpszUrlPath = urlpart;
383     comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]);
384     comp.lpszExtraInfo = extra;
385     comp.dwExtraInfoLength = sizeof(extra)/sizeof(extra[0]);
386
387     r = InternetCrackUrlW(url2, 0, 0, &comp);
388     todo_wine {
389     ok(!r, "InternetCrackUrl should have failed\n");
390     ok(GetLastError() == ERROR_INTERNET_UNRECOGNIZED_SCHEME,
391         "InternetCrackUrl should have failed with error ERROR_INTERNET_UNRECOGNIZED_SCHEME instead of error %d\n",
392         GetLastError());
393     }
394
395     /* Test to see whether cracking a URL without a filename initializes urlpart */
396     urlpart[0]=0xba;
397     scheme[0]=0;
398     extra[0]=0;
399     host[0]=0;
400     user[0]=0;
401     pwd[0]=0;
402     memset(&comp, 0, sizeof comp);
403     comp.dwStructSize = sizeof comp;
404     comp.lpszScheme = scheme;
405     comp.dwSchemeLength = sizeof scheme;
406     comp.lpszHostName = host;
407     comp.dwHostNameLength = sizeof host;
408     comp.lpszUserName = user;
409     comp.dwUserNameLength = sizeof user;
410     comp.lpszPassword = pwd;
411     comp.dwPasswordLength = sizeof pwd;
412     comp.lpszUrlPath = urlpart;
413     comp.dwUrlPathLength = sizeof urlpart;
414     comp.lpszExtraInfo = extra;
415     comp.dwExtraInfoLength = sizeof extra;
416     r = InternetCrackUrlW(url3, 0, 0, &comp );
417     ok( r, "InternetCrackUrlW failed unexpectedly\n");
418     ok( host[0] == 'x', "host should be x.org\n");
419     ok( urlpart[0] == 0, "urlpart should be empty\n");
420 }
421
422 static void fill_url_components(LPURL_COMPONENTS lpUrlComponents)
423 {
424     static CHAR http[]       = "http",
425                 winehq[]     = "www.winehq.org",
426                 username[]   = "username",
427                 password[]   = "password",
428                 site_about[] = "/site/about",
429                 empty[]      = "";
430
431     lpUrlComponents->dwStructSize = sizeof(URL_COMPONENTS);
432     lpUrlComponents->lpszScheme = http;
433     lpUrlComponents->dwSchemeLength = strlen(lpUrlComponents->lpszScheme);
434     lpUrlComponents->nScheme = INTERNET_SCHEME_HTTP;
435     lpUrlComponents->lpszHostName = winehq;
436     lpUrlComponents->dwHostNameLength = strlen(lpUrlComponents->lpszHostName);
437     lpUrlComponents->nPort = 80;
438     lpUrlComponents->lpszUserName = username;
439     lpUrlComponents->dwUserNameLength = strlen(lpUrlComponents->lpszUserName);
440     lpUrlComponents->lpszPassword = password;
441     lpUrlComponents->dwPasswordLength = strlen(lpUrlComponents->lpszPassword);
442     lpUrlComponents->lpszUrlPath = site_about;
443     lpUrlComponents->dwUrlPathLength = strlen(lpUrlComponents->lpszUrlPath);
444     lpUrlComponents->lpszExtraInfo = empty;
445     lpUrlComponents->dwExtraInfoLength = strlen(lpUrlComponents->lpszExtraInfo);
446 }
447
448 static void InternetCreateUrlA_test(void)
449 {
450         URL_COMPONENTS urlComp;
451         LPSTR szUrl;
452         DWORD len = -1;
453         BOOL ret;
454         static CHAR empty[]      = "",
455                     nhttp[]      = "nhttp",
456                     http[]       = "http",
457                     https[]      = "https",
458                     winehq[]     = "www.winehq.org",
459                     localhost[]  = "localhost",
460                     username[]   = "username",
461                     password[]   = "password",
462                     root[]       = "/",
463                     site_about[] = "/site/about",
464                     extra_info[] = "?test=123",
465                     about[]      = "about",
466                     blank[]      = "blank",
467                     host[]       = "host";
468
469         /* test NULL lpUrlComponents */
470         SetLastError(0xdeadbeef);
471         ret = InternetCreateUrlA(NULL, 0, NULL, &len);
472         ok(!ret, "Expected failure\n");
473         ok(GetLastError() == ERROR_INVALID_PARAMETER,
474                 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
475         ok(len == -1, "Expected len -1, got %d\n", len);
476
477         /* test zero'ed lpUrlComponents */
478         ZeroMemory(&urlComp, sizeof(URL_COMPONENTS));
479         SetLastError(0xdeadbeef);
480         ret = InternetCreateUrlA(&urlComp, 0, NULL, &len);
481         ok(!ret, "Expected failure\n");
482         ok(GetLastError() == ERROR_INVALID_PARAMETER,
483                 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
484         ok(len == -1, "Expected len -1, got %d\n", len);
485
486         /* test valid lpUrlComponents, NULL lpdwUrlLength */
487         fill_url_components(&urlComp);
488         SetLastError(0xdeadbeef);
489         ret = InternetCreateUrlA(&urlComp, 0, NULL, NULL);
490         ok(!ret, "Expected failure\n");
491         ok(GetLastError() == ERROR_INVALID_PARAMETER,
492                 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
493         ok(len == -1, "Expected len -1, got %d\n", len);
494
495         /* test valid lpUrlComponents, empty szUrl
496          * lpdwUrlLength is size of buffer required on exit, including
497          * the terminating null when GLE == ERROR_INSUFFICIENT_BUFFER
498          */
499         SetLastError(0xdeadbeef);
500         ret = InternetCreateUrlA(&urlComp, 0, NULL, &len);
501         ok(!ret, "Expected failure\n");
502         ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
503                 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
504         ok(len == 51, "Expected len 51, got %d\n", len);
505
506         /* test correct size, NULL szUrl */
507         fill_url_components(&urlComp);
508         SetLastError(0xdeadbeef);
509         ret = InternetCreateUrlA(&urlComp, 0, NULL, &len);
510         ok(!ret, "Expected failure\n");
511         ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
512                 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
513         ok(len == 51, "Expected len 51, got %d\n", len);
514
515         /* test valid lpUrlComponents, alloc-ed szUrl, small size */
516         SetLastError(0xdeadbeef);
517         szUrl = HeapAlloc(GetProcessHeap(), 0, len);
518         len -= 2;
519         ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len);
520         ok(!ret, "Expected failure\n");
521         ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
522                 "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
523         ok(len == 51, "Expected len 51, got %d\n", len);
524
525         /* alloc-ed szUrl, NULL lpszScheme
526          * shows that it uses nScheme instead
527          */
528         SetLastError(0xdeadbeef);
529         urlComp.lpszScheme = NULL;
530         ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len);
531         ok(ret, "Expected success\n");
532         ok(GetLastError() == 0xdeadbeef,
533                 "Expected 0xdeadbeef, got %d\n", GetLastError());
534         ok(len == 50, "Expected len 50, got %d\n", len);
535         ok(!strcmp(szUrl, CREATE_URL1), "Expected %s, got %s\n", CREATE_URL1, szUrl);
536
537         /* alloc-ed szUrl, invalid nScheme
538          * any nScheme out of range seems ignored
539          */
540         fill_url_components(&urlComp);
541         SetLastError(0xdeadbeef);
542         urlComp.nScheme = -3;
543         len++;
544         ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len);
545         ok(ret, "Expected success\n");
546         ok(GetLastError() == 0xdeadbeef,
547                 "Expected 0xdeadbeef, got %d\n", GetLastError());
548         ok(len == 50, "Expected len 50, got %d\n", len);
549
550         /* test valid lpUrlComponents, alloc-ed szUrl */
551         fill_url_components(&urlComp);
552         SetLastError(0xdeadbeef);
553         len = 51;
554         ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len);
555         ok(ret, "Expected success\n");
556         ok(GetLastError() == 0xdeadbeef,
557                 "Expected 0xdeadbeef, got %d\n", GetLastError());
558         ok(len == 50, "Expected len 50, got %d\n", len);
559         ok(strstr(szUrl, "80") == NULL, "Didn't expect to find 80 in szUrl\n");
560         ok(!strcmp(szUrl, CREATE_URL1), "Expected %s, got %s\n", CREATE_URL1, szUrl);
561
562         /* valid username, NULL password */
563         fill_url_components(&urlComp);
564         SetLastError(0xdeadbeef);
565         urlComp.lpszPassword = NULL;
566         len = 42;
567         ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len);
568         ok(ret, "Expected success\n");
569         ok(GetLastError() == 0xdeadbeef,
570                 "Expected 0xdeadbeef, got %d\n", GetLastError());
571         ok(len == 41, "Expected len 41, got %d\n", len);
572         ok(!strcmp(szUrl, CREATE_URL2), "Expected %s, got %s\n", CREATE_URL2, szUrl);
573
574         /* valid username, empty password */
575         fill_url_components(&urlComp);
576         SetLastError(0xdeadbeef);
577         urlComp.lpszPassword = empty;
578         len = 51;
579         ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len);
580         ok(ret, "Expected success\n");
581         ok(GetLastError() == 0xdeadbeef,
582                 "Expected 0xdeadbeef, got %d\n", GetLastError());
583         ok(len == 50, "Expected len 50, got %d\n", len);
584         ok(!strcmp(szUrl, CREATE_URL3), "Expected %s, got %s\n", CREATE_URL3, szUrl);
585
586         /* valid password, NULL username
587          * if password is provided, username has to exist
588          */
589         fill_url_components(&urlComp);
590         SetLastError(0xdeadbeef);
591         urlComp.lpszUserName = NULL;
592         len = 42;
593         ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len);
594         ok(!ret, "Expected failure\n");
595         ok(GetLastError() == ERROR_INVALID_PARAMETER,
596                 "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
597         ok(len == 42, "Expected len 42, got %d\n", len);
598         ok(!strcmp(szUrl, CREATE_URL3), "Expected %s, got %s\n", CREATE_URL3, szUrl);
599
600         /* valid password, empty username
601          * if password is provided, username has to exist
602          */
603         fill_url_components(&urlComp);
604         SetLastError(0xdeadbeef);
605         urlComp.lpszUserName = empty;
606         len = 51;
607         ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len);
608         ok(ret, "Expected success\n");
609         ok(GetLastError() == 0xdeadbeef,
610                 "Expected 0xdeadbeef, got %d\n", GetLastError());
611         ok(len == 50, "Expected len 50, got %d\n", len);
612         ok(!strcmp(szUrl, CREATE_URL5), "Expected %s, got %s\n", CREATE_URL5, szUrl);
613
614         /* NULL username, NULL password */
615         fill_url_components(&urlComp);
616         SetLastError(0xdeadbeef);
617         urlComp.lpszUserName = NULL;
618         urlComp.lpszPassword = NULL;
619         len = 42;
620         ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len);
621         ok(ret, "Expected success\n");
622         ok(GetLastError() == 0xdeadbeef,
623                 "Expected 0xdeadbeef, got %d\n", GetLastError());
624         ok(len == 32, "Expected len 32, got %d\n", len);
625         ok(!strcmp(szUrl, CREATE_URL4), "Expected %s, got %s\n", CREATE_URL4, szUrl);
626
627         /* empty username, empty password */
628         fill_url_components(&urlComp);
629         SetLastError(0xdeadbeef);
630         urlComp.lpszUserName = empty;
631         urlComp.lpszPassword = empty;
632         len = 51;
633         ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len);
634         ok(ret, "Expected success\n");
635         ok(GetLastError() == 0xdeadbeef,
636                 "Expected 0xdeadbeef, got %d\n", GetLastError());
637         ok(len == 50, "Expected len 50, got %d\n", len);
638         ok(!strcmp(szUrl, CREATE_URL5), "Expected %s, got %s\n", CREATE_URL5, szUrl);
639
640         /* shows that nScheme is ignored, as the appearance of the port number
641          * depends on lpszScheme and the string copied depends on lpszScheme.
642          */
643         fill_url_components(&urlComp);
644         HeapFree(GetProcessHeap(), 0, szUrl);
645         urlComp.lpszScheme = nhttp;
646         urlComp.dwSchemeLength = strlen(urlComp.lpszScheme);
647         len = strlen(CREATE_URL6) + 1;
648         szUrl = HeapAlloc(GetProcessHeap(), 0, len);
649         ret = InternetCreateUrlA(&urlComp, ICU_ESCAPE, szUrl, &len);
650         ok(ret, "Expected success\n");
651         ok(len == strlen(CREATE_URL6), "Expected len %d, got %d\n", lstrlenA(CREATE_URL6) + 1, len);
652         ok(!strcmp(szUrl, CREATE_URL6), "Expected %s, got %s\n", CREATE_URL6, szUrl);
653
654         /* if lpszScheme != "http" or nPort != 80, display nPort */
655         HeapFree(GetProcessHeap(), 0, szUrl);
656         urlComp.lpszScheme = http;
657         urlComp.dwSchemeLength = strlen(urlComp.lpszScheme);
658         urlComp.nPort = 42;
659         szUrl = HeapAlloc(GetProcessHeap(), 0, ++len);
660         ret = InternetCreateUrlA(&urlComp, ICU_ESCAPE, szUrl, &len);
661         ok(ret, "Expected success\n");
662         ok(len == 53, "Expected len 53, got %d\n", len);
663         ok(strstr(szUrl, "42") != NULL, "Expected to find 42 in szUrl\n");
664         ok(!strcmp(szUrl, CREATE_URL7), "Expected %s, got %s\n", CREATE_URL7, szUrl);
665
666         HeapFree(GetProcessHeap(), 0, szUrl);
667
668         memset(&urlComp, 0, sizeof(urlComp));
669         urlComp.dwStructSize = sizeof(URL_COMPONENTS);
670         urlComp.lpszScheme = http;
671         urlComp.dwSchemeLength = 0;
672         urlComp.nScheme = INTERNET_SCHEME_HTTP;
673         urlComp.lpszHostName = winehq;
674         urlComp.dwHostNameLength = 0;
675         urlComp.nPort = 80;
676         urlComp.lpszUserName = username;
677         urlComp.dwUserNameLength = 0;
678         urlComp.lpszPassword = password;
679         urlComp.dwPasswordLength = 0;
680         urlComp.lpszUrlPath = site_about;
681         urlComp.dwUrlPathLength = 0;
682         urlComp.lpszExtraInfo = empty;
683         urlComp.dwExtraInfoLength = 0;
684         len = strlen(CREATE_URL1);
685         szUrl = HeapAlloc(GetProcessHeap(), 0, ++len);
686         ret = InternetCreateUrlA(&urlComp, ICU_ESCAPE, szUrl, &len);
687         ok(ret, "Expected success\n");
688         ok(len == strlen(CREATE_URL1), "Expected len %d, got %d\n", lstrlenA(CREATE_URL1), len);
689         ok(!strcmp(szUrl, CREATE_URL1), "Expected %s, got %s\n", CREATE_URL1, szUrl);
690
691         HeapFree(GetProcessHeap(), 0, szUrl);
692
693         memset(&urlComp, 0, sizeof(urlComp));
694         urlComp.dwStructSize = sizeof(URL_COMPONENTS);
695         urlComp.lpszScheme = https;
696         urlComp.dwSchemeLength = 0;
697         urlComp.nScheme = INTERNET_SCHEME_HTTP;
698         urlComp.lpszHostName = winehq;
699         urlComp.dwHostNameLength = 0;
700         urlComp.nPort = 443;
701         urlComp.lpszUserName = username;
702         urlComp.dwUserNameLength = 0;
703         urlComp.lpszPassword = password;
704         urlComp.dwPasswordLength = 0;
705         urlComp.lpszUrlPath = site_about;
706         urlComp.dwUrlPathLength = 0;
707         urlComp.lpszExtraInfo = empty;
708         urlComp.dwExtraInfoLength = 0;
709         len = strlen(CREATE_URL8);
710         szUrl = HeapAlloc(GetProcessHeap(), 0, ++len);
711         ret = InternetCreateUrlA(&urlComp, ICU_ESCAPE, szUrl, &len);
712         ok(ret, "Expected success\n");
713         ok(len == strlen(CREATE_URL8), "Expected len %d, got %d\n", lstrlenA(CREATE_URL8), len);
714         ok(!strcmp(szUrl, CREATE_URL8), "Expected %s, got %s\n", CREATE_URL8, szUrl);
715
716         HeapFree(GetProcessHeap(), 0, szUrl);
717
718         memset(&urlComp, 0, sizeof(urlComp));
719         urlComp.dwStructSize = sizeof(URL_COMPONENTS);
720         urlComp.lpszScheme = about;
721         urlComp.dwSchemeLength = 5;
722         urlComp.lpszUrlPath = blank;
723         urlComp.dwUrlPathLength = 5;
724         len = strlen(CREATE_URL9);
725         len++; /* work around bug in native wininet */
726         szUrl = HeapAlloc(GetProcessHeap(), 0, ++len);
727         ret = InternetCreateUrlA(&urlComp, ICU_ESCAPE, szUrl, &len);
728         ok(ret, "Expected success\n");
729         ok(len == strlen(CREATE_URL9), "Expected len %d, got %d\n", lstrlenA(CREATE_URL9), len);
730         ok(!strcmp(szUrl, CREATE_URL9), "Expected %s, got %s\n", CREATE_URL9, szUrl);
731
732         HeapFree(GetProcessHeap(), 0, szUrl);
733
734         memset(&urlComp, 0, sizeof(urlComp));
735         urlComp.dwStructSize = sizeof(URL_COMPONENTS);
736         urlComp.lpszScheme = about;
737         urlComp.lpszHostName = host;
738         urlComp.lpszUrlPath = blank;
739         len = strlen(CREATE_URL10);
740         len++; /* work around bug in native wininet */
741         szUrl = HeapAlloc(GetProcessHeap(), 0, ++len);
742         ret = InternetCreateUrlA(&urlComp, ICU_ESCAPE, szUrl, &len);
743         ok(ret, "Expected success\n");
744         ok(len == strlen(CREATE_URL10), "Expected len %d, got %d\n", lstrlenA(CREATE_URL10), len);
745         ok(!strcmp(szUrl, CREATE_URL10), "Expected %s, got %s\n", CREATE_URL10, szUrl);
746
747         HeapFree(GetProcessHeap(), 0, szUrl);
748
749         memset(&urlComp, 0, sizeof(urlComp));
750         urlComp.dwStructSize = sizeof(URL_COMPONENTS);
751         urlComp.nPort = 8080;
752         urlComp.lpszScheme = about;
753         len = strlen(CREATE_URL11);
754         szUrl = HeapAlloc(GetProcessHeap(), 0, ++len);
755         ret = InternetCreateUrlA(&urlComp, ICU_ESCAPE, szUrl, &len);
756         ok(ret, "Expected success\n");
757         ok(len == strlen(CREATE_URL11), "Expected len %d, got %d\n", lstrlenA(CREATE_URL11), len);
758         ok(!strcmp(szUrl, CREATE_URL11), "Expected %s, got %s\n", CREATE_URL11, szUrl);
759
760         HeapFree(GetProcessHeap(), 0, szUrl);
761
762         memset(&urlComp, 0, sizeof(urlComp));
763         urlComp.dwStructSize = sizeof(URL_COMPONENTS);
764         urlComp.lpszScheme = http;
765         urlComp.dwSchemeLength = 0;
766         urlComp.nScheme = INTERNET_SCHEME_HTTP;
767         urlComp.lpszHostName = winehq;
768         urlComp.dwHostNameLength = 0;
769         urlComp.nPort = 65535;
770         len = strlen(CREATE_URL12);
771         szUrl = HeapAlloc(GetProcessHeap(), 0, ++len);
772         ret = InternetCreateUrlA(&urlComp, ICU_ESCAPE, szUrl, &len);
773         ok(ret, "Expected success\n");
774         ok(len == strlen(CREATE_URL12), "Expected len %d, got %d\n", lstrlenA(CREATE_URL12), len);
775         ok(!strcmp(szUrl, CREATE_URL12), "Expected %s, got %s\n", CREATE_URL12, szUrl);
776
777         HeapFree(GetProcessHeap(), 0, szUrl);
778
779     memset(&urlComp, 0, sizeof(urlComp));
780     urlComp.dwStructSize = sizeof(URL_COMPONENTS);
781     urlComp.lpszScheme = http;
782     urlComp.dwSchemeLength = strlen(urlComp.lpszScheme);
783     urlComp.lpszHostName = localhost;
784     urlComp.dwHostNameLength = strlen(urlComp.lpszHostName);
785     urlComp.nPort = 80;
786     urlComp.lpszUrlPath = root;
787     urlComp.dwUrlPathLength = strlen(urlComp.lpszUrlPath);
788     urlComp.lpszExtraInfo = extra_info;
789     urlComp.dwExtraInfoLength = strlen(urlComp.lpszExtraInfo);
790     len = 256;
791     szUrl = HeapAlloc(GetProcessHeap(), 0, len);
792     InternetCreateUrlA(&urlComp, ICU_ESCAPE, szUrl, &len);
793     ok(ret, "Expected success\n");
794     ok(len == strlen(CREATE_URL13), "Got len %u\n", len);
795     ok(!strcmp(szUrl, CREATE_URL13), "Expected \"%s\", got \"%s\"\n", CREATE_URL13, szUrl);
796
797     HeapFree(GetProcessHeap(), 0, szUrl);
798 }
799
800 START_TEST(url)
801 {
802     InternetCrackUrl_test();
803     InternetCrackUrlW_test();
804     InternetCreateUrlA_test();
805 }