comctl32/imagelist: Use proper color format for merged image lists.
[wine] / dlls / winhttp / tests / winhttp.c
1 /*
2  * WinHTTP - tests
3  *
4  * Copyright 2008 Google (Zac Brown)
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #define COBJMACROS
22 #include <stdarg.h>
23 #include <stdlib.h>
24 #include <windef.h>
25 #include <winbase.h>
26 #include <winhttp.h>
27 #include <wincrypt.h>
28 #include <winreg.h>
29 #include <winsock.h>
30 #include "initguid.h"
31 #include <httprequest.h>
32
33 #include "wine/test.h"
34
35 static const WCHAR test_useragent[] =
36     {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
37 static const WCHAR test_server[] = {'w','i','n','e','h','q','.','o','r','g',0};
38 static const WCHAR localhostW[] = {'l','o','c','a','l','h','o','s','t',0};
39
40 static BOOL proxy_active(void)
41 {
42     WINHTTP_PROXY_INFO proxy_info;
43     BOOL active = FALSE;
44
45     if (WinHttpGetDefaultProxyConfiguration(&proxy_info))
46     {
47         active = (proxy_info.lpszProxy != NULL);
48         if (active)
49             GlobalFree(proxy_info.lpszProxy);
50         if (proxy_info.lpszProxyBypass != NULL)
51             GlobalFree(proxy_info.lpszProxyBypass);
52     }
53     else
54        active = FALSE;
55
56     return active;
57 }
58
59 static void test_QueryOption(void)
60 {
61     BOOL ret;
62     HINTERNET session, request, connection;
63     DWORD feature, size;
64
65     SetLastError(0xdeadbeef);
66     session = WinHttpOpen(test_useragent, 0, 0, 0, 0);
67     ok(session != NULL, "WinHttpOpen failed to open session, error %u\n", GetLastError());
68
69     SetLastError(0xdeadbeef);
70     ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, NULL);
71     ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
72     ok(GetLastError() == ERROR_INVALID_PARAMETER,
73        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
74
75     size = 0xdeadbeef;
76     SetLastError(0xdeadbeef);
77     ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, &size);
78     ok(!ret, "should fail to query option\n");
79     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
80        "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
81     ok(size == 4, "expected 4, got %u\n", size);
82
83     feature = 0xdeadbeef;
84     size = sizeof(feature) - 1;
85     SetLastError(0xdeadbeef);
86     ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
87     ok(!ret, "should fail to query option\n");
88     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
89        "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
90     ok(size == 4, "expected 4, got %u\n", size);
91
92     feature = 0xdeadbeef;
93     size = sizeof(feature) + 1;
94     SetLastError(0xdeadbeef);
95     ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
96     ok(ret, "failed to query option %u\n", GetLastError());
97     ok(size == sizeof(feature), "WinHttpQueryOption should set the size: %u\n", size);
98     ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP,
99        "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature);
100
101     SetLastError(0xdeadbeef);
102     ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, sizeof(feature));
103     ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
104     ok(GetLastError() == ERROR_INVALID_PARAMETER,
105        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
106
107     feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
108     SetLastError(0xdeadbeef);
109     ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) - 1);
110     ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
111     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
112        "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
113
114     feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
115     SetLastError(0xdeadbeef);
116     ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) + 1);
117     ok(!ret, "should fail to set redirect policy %u\n", GetLastError());
118     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
119        "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
120
121     feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
122     SetLastError(0xdeadbeef);
123     ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature));
124     ok(ret, "failed to set redirect policy %u\n", GetLastError());
125
126     feature = 0xdeadbeef;
127     size = sizeof(feature);
128     SetLastError(0xdeadbeef);
129     ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size);
130     ok(ret, "failed to query option %u\n", GetLastError());
131     ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS,
132        "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature);
133
134     feature = WINHTTP_DISABLE_COOKIES;
135     SetLastError(0xdeadbeef);
136     ret = WinHttpSetOption(session, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
137     ok(!ret, "should fail to set disable feature for a session\n");
138     ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
139        "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
140
141     SetLastError(0xdeadbeef);
142     connection = WinHttpConnect(session, test_server, INTERNET_DEFAULT_HTTP_PORT, 0);
143     ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
144
145     feature = WINHTTP_DISABLE_COOKIES;
146     SetLastError(0xdeadbeef);
147     ret = WinHttpSetOption(connection, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
148     ok(!ret, "should fail to set disable feature for a connection\n");
149     ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
150        "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
151
152     SetLastError(0xdeadbeef);
153     request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
154                                  WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
155     if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
156     {
157         skip("Network unreachable, skipping the test\n");
158         goto done;
159     }
160
161     feature = 0xdeadbeef;
162     size = sizeof(feature);
163     SetLastError(0xdeadbeef);
164     ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, &size);
165     ok(!ret, "should fail to query disable feature for a request\n");
166     ok(GetLastError() == ERROR_INVALID_PARAMETER,
167        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
168
169     feature = 0;
170     size = sizeof(feature);
171     SetLastError(0xdeadbeef);
172     ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
173     ok(ret, "failed to set feature %u\n", GetLastError());
174
175     feature = 0xffffffff;
176     size = sizeof(feature);
177     SetLastError(0xdeadbeef);
178     ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
179     ok(ret, "failed to set feature %u\n", GetLastError());
180
181     feature = WINHTTP_DISABLE_COOKIES;
182     size = sizeof(feature);
183     SetLastError(0xdeadbeef);
184     ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature));
185     ok(ret, "failed to set feature %u\n", GetLastError());
186
187     size = 0;
188     SetLastError(0xdeadbeef);
189     ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, NULL, &size);
190     ok(!ret, "should fail to query disable feature for a request\n");
191     ok(GetLastError() == ERROR_INVALID_PARAMETER,
192        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
193
194     SetLastError(0xdeadbeef);
195     ret = WinHttpCloseHandle(request);
196     ok(ret, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
197
198 done:
199     SetLastError(0xdeadbeef);
200     ret = WinHttpCloseHandle(connection);
201     ok(ret, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
202     SetLastError(0xdeadbeef);
203     ret = WinHttpCloseHandle(session);
204     ok(ret, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
205 }
206
207 static void test_OpenRequest (void)
208 {
209     BOOL ret;
210     HINTERNET session, request, connection;
211
212     session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
213         WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
214     ok(session != NULL, "WinHttpOpen failed to open session.\n");
215
216     /* Test with a bad server name */
217     SetLastError(0xdeadbeef);
218     connection = WinHttpConnect(session, NULL, INTERNET_DEFAULT_HTTP_PORT, 0);
219     ok (connection == NULL, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
220     ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u.\n", GetLastError());
221
222     /* Test with a valid server name */
223     connection = WinHttpConnect (session, test_server, INTERNET_DEFAULT_HTTP_PORT, 0);
224     ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
225
226     request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
227         WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
228     if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
229     {
230         skip("Network unreachable, skipping.\n");
231         goto done;
232     }
233     ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
234
235     ret = WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, 0, 0);
236     if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
237     {
238         skip("Connection failed, skipping.\n");
239         goto done;
240     }
241     ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
242     ret = WinHttpCloseHandle(request);
243     ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
244
245  done:
246     ret = WinHttpCloseHandle(connection);
247     ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
248     ret = WinHttpCloseHandle(session);
249     ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
250
251 }
252
253 static void test_empty_headers_param(void)
254 {
255     static const WCHAR winehq[] = {'w','i','n','e','h','q','.','o','r','g',0};
256     static const WCHAR empty[]  = {0};
257     HINTERNET ses, con, req;
258     BOOL ret;
259
260     ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
261     ok(ses != NULL, "failed to open session %u\n", GetLastError());
262
263     con = WinHttpConnect(ses, winehq, 80, 0);
264     ok(con != NULL, "failed to open a connection %u\n", GetLastError());
265
266     req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
267     ok(req != NULL, "failed to open a request %u\n", GetLastError());
268
269     ret = WinHttpSendRequest(req, empty, 0, NULL, 0, 0, 0);
270     ok(ret, "failed to send request %u\n", GetLastError());
271
272     WinHttpCloseHandle(req);
273     WinHttpCloseHandle(con);
274     WinHttpCloseHandle(ses);
275 }
276
277 static void test_SendRequest (void)
278 {
279     HINTERNET session, request, connection;
280     DWORD header_len, optional_len, total_len, bytes_rw, size;
281     DWORD_PTR context;
282     BOOL ret;
283     CHAR buffer[256];
284     int i;
285
286     static const WCHAR test_site[] = {'c','r','o','s','s','o','v','e','r','.',
287                                 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
288     static const WCHAR content_type[] =
289         {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
290          '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
291     static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
292     static const WCHAR test_verb[] = {'P','O','S','T',0};
293     static CHAR post_data[] = "mode=Test";
294     static CHAR test_post[] = "mode => Test\\0\n";
295
296     header_len = -1L;
297     total_len = optional_len = sizeof(post_data);
298     memset(buffer, 0xff, sizeof(buffer));
299
300     session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
301         WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
302     ok(session != NULL, "WinHttpOpen failed to open session.\n");
303
304     connection = WinHttpConnect (session, test_site, INTERNET_DEFAULT_HTTP_PORT, 0);
305     ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
306
307     request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
308         WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
309     if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
310     {
311         skip("Network unreachable, skipping.\n");
312         goto done;
313     }
314     ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
315     if (!request) goto done;
316
317     context = 0xdeadbeef;
318     ret = WinHttpSetOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(context));
319     ok(ret, "WinHttpSetOption failed: %u\n", GetLastError());
320
321     context++;
322     ret = WinHttpSendRequest(request, content_type, header_len, post_data, optional_len, total_len, context);
323     ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
324
325     context = 0;
326     size = sizeof(context);
327     ret = WinHttpQueryOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, &size);
328     ok(ret, "WinHttpQueryOption failed: %u\n", GetLastError());
329     ok(context == 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context);
330
331     for (i = 3; post_data[i]; i++)
332     {
333         bytes_rw = -1;
334         ret = WinHttpWriteData(request, &post_data[i], 1, &bytes_rw);
335         if (ret)
336           ok(bytes_rw == 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw);
337         else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
338         {
339           ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
340           ok(bytes_rw == -1, "Expected bytes_rw to remain unchanged.\n");
341         }
342     }
343
344     ret = WinHttpReceiveResponse(request, NULL);
345     ok(ret == TRUE, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
346
347     bytes_rw = -1;
348     ret = WinHttpReadData(request, buffer, sizeof(buffer) - 1, &bytes_rw);
349     ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
350
351     ok(bytes_rw == strlen(test_post), "Read %u bytes instead of %d.\n", bytes_rw, lstrlen(test_post));
352     ok(strncmp(buffer, test_post, bytes_rw) == 0, "Data read did not match, got '%s'.\n", buffer);
353
354     ret = WinHttpCloseHandle(request);
355     ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
356  done:
357     ret = WinHttpCloseHandle(connection);
358     ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
359     ret = WinHttpCloseHandle(session);
360     ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
361 }
362
363 static void test_WinHttpTimeFromSystemTime(void)
364 {
365     BOOL ret;
366     static const SYSTEMTIME time = {2008, 7, 1, 28, 10, 5, 52, 0};
367     static const WCHAR expected_string[] =
368         {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
369          '1','0',':','0','5',':','5','2',' ','G','M','T',0};
370     WCHAR time_string[WINHTTP_TIME_FORMAT_BUFSIZE+1];
371
372     ret = WinHttpTimeFromSystemTime(&time, time_string);
373     ok(ret == TRUE, "WinHttpTimeFromSystemTime failed: %u\n", GetLastError());
374     ok(memcmp(time_string, expected_string, sizeof(expected_string)) == 0,
375         "Time string returned did not match expected time string.\n");
376 }
377
378 static void test_WinHttpTimeToSystemTime(void)
379 {
380     BOOL ret;
381     SYSTEMTIME time;
382     static const SYSTEMTIME expected_time = {2008, 7, 1, 28, 10, 5, 52, 0};
383     static const WCHAR time_string1[] =
384         {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
385          +          '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
386     static const WCHAR time_string2[] =
387         {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
388          '1','0',' ','0','5',' ','5','2','\n',0};
389
390     ret = WinHttpTimeToSystemTime(time_string1, &time);
391     ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
392     ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
393         "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
394
395     ret = WinHttpTimeToSystemTime(time_string2, &time);
396     ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
397     ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
398         "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
399 }
400
401 static void test_WinHttpAddHeaders(void)
402 {
403     HINTERNET session, request, connection;
404     BOOL ret, reverse;
405     WCHAR buffer[MAX_PATH];
406     WCHAR check_buffer[MAX_PATH];
407     DWORD index, len, oldlen;
408
409     static const WCHAR test_site[] = {'c','r','o','s','s','o','v','e','r','.',
410                                 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
411     static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
412     static const WCHAR test_verb[] = {'P','O','S','T',0};
413
414     static const WCHAR test_header_begin[] =
415         {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
416     static const WCHAR full_path_test_header_begin[] =
417         {'P','O','S','T',' ','h','t','t','p',':','/','/','c','r','o','s','s','o','v','e','r','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',':','8','0','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
418     static const WCHAR test_header_end[] = {'\r','\n','\r','\n',0};
419     static const WCHAR test_header_name[] = {'W','a','r','n','i','n','g',0};
420
421     static const WCHAR test_flag_coalesce[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
422     static const WCHAR test_flag_coalesce_reverse[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
423     static const WCHAR test_flag_coalesce_comma[] =
424         {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
425     static const WCHAR test_flag_coalesce_comma_reverse[] =
426         {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
427     static const WCHAR test_flag_coalesce_semicolon[] =
428         {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
429     static const WCHAR test_flag_coalesce_semicolon_reverse[] =
430         {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
431
432     static const WCHAR field[] = {'f','i','e','l','d',0};
433     static const WCHAR value[] = {'v','a','l','u','e',' ',0};
434     static const WCHAR value_nospace[] = {'v','a','l','u','e',0};
435
436     static const WCHAR test_headers[][14] =
437         {
438             {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
439             {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
440             {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
441             {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
442             {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
443             {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
444             {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
445             {0},
446             {':',0},
447             {'a',':',0},
448             {':','b',0},
449             {'c','d',0},
450             {' ','e',' ',':','f',0},
451             {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0}
452         };
453     static const WCHAR test_indices[][6] =
454         {
455             {'t','e','s','t','1',0},
456             {'t','e','s','t','2',0},
457             {'t','e','s','t','3',0},
458             {'t','e','s','t','4',0}
459         };
460
461     session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
462         WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
463     ok(session != NULL, "WinHttpOpen failed to open session.\n");
464
465     connection = WinHttpConnect (session, test_site, INTERNET_DEFAULT_HTTP_PORT, 0);
466     ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
467
468     request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
469         WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
470     if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
471     {
472         skip("Network unreachable, skipping.\n");
473         goto done;
474     }
475     ok(request != NULL, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
476
477     index = 0;
478     len = sizeof(buffer);
479     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
480         test_header_name, buffer, &len, &index);
481     ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
482     ret = WinHttpAddRequestHeaders(request, test_headers[0], -1L, WINHTTP_ADDREQ_FLAG_ADD);
483     ok(ret == TRUE, "WinHttpAddRequestHeader failed to add new header, got %d with error %u.\n", ret, GetLastError());
484
485     index = 0;
486     len = sizeof(buffer);
487     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
488         test_header_name, buffer, &len, &index);
489     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
490     ok(index == 1, "WinHttpQueryHeaders failed: header index not incremented\n");
491     ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
492     ok(len == 5*sizeof(WCHAR), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len);
493
494     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
495         test_header_name, buffer, &len, &index);
496     ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
497
498     /* Try to fetch the header info with a buffer that's big enough to fit the
499      * string but not the NULL terminator.
500      */
501     index = 0;
502     len = 5*sizeof(WCHAR);
503     memset(check_buffer, 0xab, sizeof(check_buffer));
504     memcpy(buffer, check_buffer, sizeof(buffer));
505     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
506         test_header_name, buffer, &len, &index);
507     ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
508     ok(memcmp(buffer, check_buffer, sizeof(buffer)) == 0,
509             "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
510     ok(len == 6*sizeof(WCHAR), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len);
511
512     /* Try with a NULL buffer */
513     index = 0;
514     len = sizeof(buffer);
515     SetLastError(0xdeadbeef);
516     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
517         test_header_name, NULL, &len, &index);
518     ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
519     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
520     ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
521     ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
522
523     /* Try with a NULL buffer and a length that's too small */
524     index = 0;
525     len = 10;
526     SetLastError(0xdeadbeef);
527     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
528         test_header_name, NULL, &len, &index);
529     ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
530     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
531         "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, go %u\n", GetLastError());
532     ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
533     ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
534
535     index = 0;
536     len = 0;
537     SetLastError(0xdeadbeef);
538     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
539         test_header_name, NULL, &len, &index);
540     ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
541     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
542         "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
543     ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
544     ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
545
546     /* valid query */
547     oldlen = len;
548     index = 0;
549     len = sizeof(buffer);
550     memset(buffer, 0xff, sizeof(buffer));
551     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
552         test_header_name, buffer, &len, &index);
553     ok(ret == TRUE, "WinHttpQueryHeaders failed: got %d\n", ret);
554     ok(len + sizeof(WCHAR) <= oldlen, "WinHttpQueryHeaders resulting length longer than advertized.\n");
555     ok((len < sizeof(buffer) - sizeof(WCHAR)) && buffer[len / sizeof(WCHAR)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
556     ok(len == lstrlenW(buffer) * sizeof(WCHAR), "WinHttpQueryHeaders returned incorrect length.\n");
557     ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
558         memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
559         "WinHttpQueryHeaders returned invalid beginning of header string.\n");
560     ok(memcmp(buffer + lstrlenW(buffer) - 4, test_header_end, sizeof(test_header_end)) == 0,
561         "WinHttpQueryHeaders returned invalid end of header string.\n");
562     ok(index == 0, "WinHttpQueryHeaders incremented header index.\n");
563
564     index = 0;
565     len = 0;
566     SetLastError(0xdeadbeef);
567     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
568         test_header_name, NULL, &len, &index);
569     ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
570     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
571         "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
572     ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
573     ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
574
575     oldlen = len;
576     index = 0;
577     len = sizeof(buffer);
578     memset(buffer, 0xff, sizeof(buffer));
579     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
580         test_header_name, buffer, &len, &index);
581     ok(ret == TRUE, "WinHttpQueryHeaders failed %u\n", GetLastError());
582     ok(len + sizeof(WCHAR) <= oldlen, "resulting length longer than advertized\n");
583     ok((len < sizeof(buffer) - sizeof(WCHAR)) && !buffer[len / sizeof(WCHAR)] && !buffer[len / sizeof(WCHAR) - 1],
584         "no double NULL terminator\n");
585     ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 ||
586         memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0,
587         "invalid beginning of header string.\n");
588     ok(index == 0, "header index was incremented\n");
589
590     /* tests for more indices */
591     ret = WinHttpAddRequestHeaders(request, test_headers[1], -1L, WINHTTP_ADDREQ_FLAG_ADD);
592     ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret);
593
594     index = 0;
595     len = sizeof(buffer);
596     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
597         test_header_name, buffer, &len, &index);
598     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
599     ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
600     ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
601
602     len = sizeof(buffer);
603     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
604         test_header_name, buffer, &len, &index);
605     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
606     ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
607     ok(memcmp(buffer, test_indices[1], sizeof(test_indices[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
608
609     ret = WinHttpAddRequestHeaders(request, test_headers[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE);
610     ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
611
612     index = 0;
613     len = sizeof(buffer);
614     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
615         test_header_name, buffer, &len, &index);
616     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
617     ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
618     reverse = (memcmp(buffer, test_indices[1], sizeof(test_indices[1])) != 0); /* Win7 returns values in reverse order of adding */
619     ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
620
621     len = sizeof(buffer);
622     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
623         test_header_name, buffer, &len, &index);
624     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
625     ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
626     ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
627
628     /* add if new flag */
629     ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW);
630     ok(ret == FALSE, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n");
631
632     index = 0;
633     len = sizeof(buffer);
634     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
635         test_header_name, buffer, &len, &index);
636     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
637     ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
638     ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
639
640     len = sizeof(buffer);
641     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
642         test_header_name, buffer, &len, &index);
643     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
644     ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
645     ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
646
647     len = sizeof(buffer);
648     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
649         test_header_name, buffer, &len, &index);
650     ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
651
652     /* coalesce flag */
653     ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE);
654     ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n");
655
656     index = 0;
657     len = sizeof(buffer);
658     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
659         test_header_name, buffer, &len, &index);
660     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
661     ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
662     ok(memcmp(buffer, reverse ? test_flag_coalesce_reverse : test_flag_coalesce,
663                       reverse ? sizeof(test_flag_coalesce_reverse) : sizeof(test_flag_coalesce)) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
664
665     len = sizeof(buffer);
666     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
667         test_header_name, buffer, &len, &index);
668     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
669     ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
670     ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
671
672     len = sizeof(buffer);
673     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
674         test_header_name, buffer, &len, &index);
675     ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
676
677     /* coalesce with comma flag */
678     ret = WinHttpAddRequestHeaders(request, test_headers[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA);
679     ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
680
681     index = 0;
682     len = sizeof(buffer);
683     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
684         test_header_name, buffer, &len, &index);
685     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
686     ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
687     ok(memcmp(buffer, reverse ? test_flag_coalesce_comma_reverse : test_flag_coalesce_comma,
688                       reverse ? sizeof(test_flag_coalesce_comma_reverse) : sizeof(test_flag_coalesce_comma)) == 0,
689         "WinHttpQueryHeaders returned incorrect string.\n");
690
691     len = sizeof(buffer);
692     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
693         test_header_name, buffer, &len, &index);
694     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
695     ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
696     ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
697
698     len = sizeof(buffer);
699     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
700         test_header_name, buffer, &len, &index);
701     ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
702
703
704     /* coalesce with semicolon flag */
705     ret = WinHttpAddRequestHeaders(request, test_headers[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON);
706     ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
707
708     index = 0;
709     len = sizeof(buffer);
710     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
711         test_header_name, buffer, &len, &index);
712     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
713     ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
714     ok(memcmp(buffer, reverse ? test_flag_coalesce_semicolon_reverse : test_flag_coalesce_semicolon,
715                       reverse ? sizeof(test_flag_coalesce_semicolon_reverse) : sizeof(test_flag_coalesce_semicolon)) == 0,
716             "WinHttpQueryHeaders returned incorrect string.\n");
717
718     len = sizeof(buffer);
719     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
720         test_header_name, buffer, &len, &index);
721     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
722     ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
723     ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
724
725     len = sizeof(buffer);
726     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
727         test_header_name, buffer, &len, &index);
728     ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
729
730     /* add and replace flags */
731     ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
732     ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n");
733
734     index = 0;
735     len = sizeof(buffer);
736     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
737         test_header_name, buffer, &len, &index);
738     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
739     ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
740     ok(memcmp(buffer, test_indices[reverse ? 3 : 2], sizeof(test_indices[reverse ? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
741
742     len = sizeof(buffer);
743     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
744         test_header_name, buffer, &len, &index);
745     ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
746     ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
747     ok(memcmp(buffer, test_indices[reverse ? 1 : 3], sizeof(test_indices[reverse ? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
748
749     len = sizeof(buffer);
750     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
751         test_header_name, buffer, &len, &index);
752     ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
753
754     ret = WinHttpAddRequestHeaders(request, test_headers[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
755     ok(!ret, "WinHttpAddRequestHeaders failed\n");
756
757     ret = WinHttpAddRequestHeaders(request, test_headers[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
758     ok(ret, "WinHttpAddRequestHeaders failed\n");
759
760     ret = WinHttpAddRequestHeaders(request, test_headers[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
761     ok(!ret, "WinHttpAddRequestHeaders failed\n");
762
763     ret = WinHttpAddRequestHeaders(request, test_headers[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
764     ok(!ret, "WinHttpAddRequestHeaders failed\n");
765
766     ret = WinHttpAddRequestHeaders(request, test_headers[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
767     ok(!ret, "WinHttpAddRequestHeaders failed\n");
768
769     ret = WinHttpAddRequestHeaders(request, test_headers[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD);
770     ok(ret, "WinHttpAddRequestHeaders failed\n");
771
772     index = 0;
773     buffer[0] = 0;
774     len = sizeof(buffer);
775     ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
776         field, buffer, &len, &index);
777     ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
778     ok(!memcmp(buffer, value, sizeof(value)) || ! memcmp(buffer, value_nospace, sizeof(value_nospace)), "unexpected result\n");
779
780     ret = WinHttpCloseHandle(request);
781     ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
782  done:
783     ret = WinHttpCloseHandle(connection);
784     ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
785     ret = WinHttpCloseHandle(session);
786     ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
787
788 }
789
790 static void test_secure_connection(void)
791 {
792     static const WCHAR google[] = {'w','w','w','.','g','o','o','g','l','e','.','c','o','m',0};
793
794     HINTERNET ses, con, req;
795     DWORD size, status, policy, bitness, read_size;
796     BOOL ret;
797     CERT_CONTEXT *cert;
798     WINHTTP_CERTIFICATE_INFO info;
799     char buffer[32];
800
801     ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
802     ok(ses != NULL, "failed to open session %u\n", GetLastError());
803
804     policy = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
805     ret = WinHttpSetOption(ses, WINHTTP_OPTION_REDIRECT_POLICY, &policy, sizeof(policy));
806     ok(ret, "failed to set redirect policy %u\n", GetLastError());
807
808     con = WinHttpConnect(ses, google, 443, 0);
809     ok(con != NULL, "failed to open a connection %u\n", GetLastError());
810
811     /* try without setting WINHTTP_FLAG_SECURE */
812     req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
813     ok(req != NULL, "failed to open a request %u\n", GetLastError());
814
815     ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
816     if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT)
817     {
818         skip("Connection failed, skipping.\n");
819         goto cleanup;
820     }
821     ok(ret, "failed to send request %u\n", GetLastError());
822
823     ret = WinHttpReceiveResponse(req, NULL);
824     ok(!ret || proxy_active(), "succeeded unexpectedly\n");
825
826     size = 0;
827     ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
828     ok(!ret, "succeeded unexpectedly\n");
829
830     WinHttpCloseHandle(req);
831
832     req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, WINHTTP_FLAG_SECURE);
833     ok(req != NULL, "failed to open a request %u\n", GetLastError());
834
835     ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
836     ok(ret, "failed to send request %u\n", GetLastError());
837     if (!ret)
838     {
839         skip("secure connection failed, skipping remaining secure tests\n");
840         goto cleanup;
841     }
842
843     size = sizeof(cert);
844     ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size );
845     ok(ret, "failed to retrieve certificate context %u\n", GetLastError());
846     if (ret)
847         CertFreeCertificateContext(cert);
848
849     size = sizeof(bitness);
850     ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_KEY_BITNESS, &bitness, &size );
851     ok(ret, "failed to retrieve key bitness %u\n", GetLastError());
852
853     size = sizeof(info);
854     ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT, &info, &size );
855     ok(ret, "failed to retrieve certificate info %u\n", GetLastError());
856
857     trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info.lpszSubjectInfo));
858     trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info.lpszIssuerInfo));
859     trace("lpszProtocolName %s\n", wine_dbgstr_w(info.lpszProtocolName));
860     trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info.lpszSignatureAlgName));
861     trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info.lpszEncryptionAlgName));
862     trace("dwKeySize %u\n", info.dwKeySize);
863
864     ret = WinHttpReceiveResponse(req, NULL);
865     ok(ret, "failed to receive response %u\n", GetLastError());
866
867     size = sizeof(status);
868     ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
869     ok(ret, "failed unexpectedly %u\n", GetLastError());
870     ok(status == 200, "request failed unexpectedly %u\n", status);
871
872     size = 0;
873     ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
874     ok(!ret, "succeeded unexpectedly\n");
875
876     read_size = 0;
877     for (;;)
878     {
879         size = 0;
880         ret = WinHttpReadData(req, buffer, sizeof(buffer), &size);
881         ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
882         if (!size) break;
883         read_size += size;
884     }
885     ok(read_size > 2014, "read_size = %u\n", read_size);
886
887 cleanup:
888     WinHttpCloseHandle(req);
889     WinHttpCloseHandle(con);
890     WinHttpCloseHandle(ses);
891 }
892
893 static void test_request_parameter_defaults(void)
894 {
895     static const WCHAR empty[] = {0};
896     static const WCHAR codeweavers[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
897
898     HINTERNET ses, con, req;
899     DWORD size, status, error;
900     WCHAR *version;
901     BOOL ret;
902
903     ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
904     ok(ses != NULL, "failed to open session %u\n", GetLastError());
905
906     con = WinHttpConnect(ses, codeweavers, 0, 0);
907     ok(con != NULL, "failed to open a connection %u\n", GetLastError());
908
909     req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
910     ok(req != NULL, "failed to open a request %u\n", GetLastError());
911
912     ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
913     ok(ret, "failed to send request %u\n", GetLastError());
914
915     ret = WinHttpReceiveResponse(req, NULL);
916     ok(ret, "failed to receive response %u\n", GetLastError());
917
918     size = sizeof(status);
919     ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
920     ok(ret, "failed unexpectedly %u\n", GetLastError());
921     ok(status == 200, "request failed unexpectedly %u\n", status);
922
923     WinHttpCloseHandle(req);
924
925     req = WinHttpOpenRequest(con, empty, empty, empty, NULL, NULL, 0);
926     ok(req != NULL, "failed to open a request %u\n", GetLastError());
927
928     ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
929     ok(ret, "failed to send request %u\n", GetLastError());
930
931     ret = WinHttpReceiveResponse(req, NULL);
932     ok(ret, "failed to receive response %u\n", GetLastError());
933
934     size = 0;
935     SetLastError(0xdeadbeef);
936     ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, NULL, &size, NULL);
937     error = GetLastError();
938     ok(!ret, "succeeded unexpectedly\n");
939     ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error);
940
941     version = HeapAlloc(GetProcessHeap(), 0, size);
942     ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, version, &size, NULL);
943     ok(ret, "failed unexpectedly %u\n", GetLastError());
944     ok(lstrlenW(version) == size / sizeof(WCHAR), "unexpected size %u\n", size);
945     HeapFree(GetProcessHeap(), 0, version);
946
947     size = sizeof(status);
948     ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
949     ok(ret, "failed unexpectedly %u\n", GetLastError());
950     ok(status == 200, "request failed unexpectedly %u\n", status);
951
952     WinHttpCloseHandle(req);
953     WinHttpCloseHandle(con);
954     WinHttpCloseHandle(ses);
955 }
956
957 static const WCHAR Connections[] = {
958     'S','o','f','t','w','a','r','e','\\',
959     'M','i','c','r','o','s','o','f','t','\\',
960     'W','i','n','d','o','w','s','\\',
961     'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
962     'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
963     'C','o','n','n','e','c','t','i','o','n','s',0 };
964 static const WCHAR WinHttpSettings[] = {
965     'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
966
967 static DWORD get_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD *type )
968 {
969     LONG l;
970     HKEY key;
971     DWORD ret = 0;
972
973     l = RegOpenKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, KEY_READ, &key );
974     if (!l)
975     {
976         DWORD size = 0;
977
978         l = RegQueryValueExW( key, WinHttpSettings, NULL, type, NULL, &size );
979         if (!l)
980         {
981             if (size <= len)
982                 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, buf,
983                     &size );
984             if (!l)
985                 ret = size;
986         }
987         RegCloseKey( key );
988     }
989     return ret;
990 }
991
992 static void set_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD type )
993 {
994     LONG l;
995     HKEY key;
996
997     l = RegCreateKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, NULL, 0,
998         KEY_WRITE, NULL, &key, NULL );
999     if (!l)
1000     {
1001         if (len)
1002             RegSetValueExW( key, WinHttpSettings, 0, type, buf, len );
1003         else
1004             RegDeleteValueW( key, WinHttpSettings );
1005         RegCloseKey( key );
1006     }
1007 }
1008
1009 static void test_set_default_proxy_config(void)
1010 {
1011     static WCHAR wideString[] = { 0x226f, 0x575b, 0 };
1012     static WCHAR normalString[] = { 'f','o','o',0 };
1013     DWORD type, len;
1014     BYTE *saved_proxy_settings = NULL;
1015     WINHTTP_PROXY_INFO info;
1016     BOOL ret;
1017
1018     /* FIXME: it would be simpler to read the current settings using
1019      * WinHttpGetDefaultProxyConfiguration and save them using
1020      * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
1021      *
1022      * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
1023      * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
1024      * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
1025      * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
1026      * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
1027      * the lpszProxy and lpszProxyBypass values are ignored.
1028      * Thus, if a proxy is set with proxycfg, then calling
1029      * WinHttpGetDefaultProxyConfiguration followed by
1030      * WinHttpSetDefaultProxyConfiguration results in the proxy settings
1031      * getting deleted from the registry.
1032      *
1033      * Instead I read the current registry value and restore it directly.
1034      */
1035     len = get_default_proxy_reg_value( NULL, 0, &type );
1036     if (len)
1037     {
1038         saved_proxy_settings = HeapAlloc( GetProcessHeap(), 0, len );
1039         len = get_default_proxy_reg_value( saved_proxy_settings, len, &type );
1040     }
1041
1042     if (0)
1043     {
1044         /* Crashes on Vista and higher */
1045         SetLastError(0xdeadbeef);
1046         ret = WinHttpSetDefaultProxyConfiguration(NULL);
1047         ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1048             "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1049     }
1050
1051     /* test with invalid access type */
1052     info.dwAccessType = 0xdeadbeef;
1053     info.lpszProxy = info.lpszProxyBypass = NULL;
1054     SetLastError(0xdeadbeef);
1055     ret = WinHttpSetDefaultProxyConfiguration(&info);
1056     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1057         "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1058
1059     /* at a minimum, the proxy server must be set */
1060     info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
1061     info.lpszProxy = info.lpszProxyBypass = NULL;
1062     SetLastError(0xdeadbeef);
1063     ret = WinHttpSetDefaultProxyConfiguration(&info);
1064     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1065         "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1066     info.lpszProxyBypass = normalString;
1067     SetLastError(0xdeadbeef);
1068     ret = WinHttpSetDefaultProxyConfiguration(&info);
1069     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1070         "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1071
1072     /* the proxy server can't have wide characters */
1073     info.lpszProxy = wideString;
1074     SetLastError(0xdeadbeef);
1075     ret = WinHttpSetDefaultProxyConfiguration(&info);
1076     if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
1077         skip("couldn't set default proxy configuration: access denied\n");
1078     else
1079         ok((!ret && GetLastError() == ERROR_INVALID_PARAMETER) ||
1080            broken(ret), /* Earlier winhttp versions on W2K/XP */
1081            "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1082
1083     info.lpszProxy = normalString;
1084     SetLastError(0xdeadbeef);
1085     ret = WinHttpSetDefaultProxyConfiguration(&info);
1086     if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
1087         skip("couldn't set default proxy configuration: access denied\n");
1088     else
1089         ok(ret, "WinHttpSetDefaultProxyConfiguration failed: %d\n",
1090            GetLastError());
1091
1092     set_default_proxy_reg_value( saved_proxy_settings, len, type );
1093 }
1094
1095 static void test_Timeouts (void)
1096 {
1097     BOOL ret;
1098     DWORD value, size;
1099     HINTERNET ses, req, con;
1100     static const WCHAR codeweavers[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1101
1102
1103     ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1104     ok(ses != NULL, "failed to open session %u\n", GetLastError());
1105
1106     SetLastError(0xdeadbeef);
1107     ret = WinHttpSetTimeouts(ses, -2, 0, 0, 0);
1108     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1109        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1110
1111     SetLastError(0xdeadbeef);
1112     ret = WinHttpSetTimeouts(ses, 0, -2, 0, 0);
1113     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1114        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1115
1116     SetLastError(0xdeadbeef);
1117     ret = WinHttpSetTimeouts(ses, 0, 0, -2, 0);
1118     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1119        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1120
1121     SetLastError(0xdeadbeef);
1122     ret = WinHttpSetTimeouts(ses, 0, 0, 0, -2);
1123     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1124        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1125
1126     SetLastError(0xdeadbeef);
1127     ret = WinHttpSetTimeouts(ses, -1, -1, -1, -1);
1128     ok(ret, "%u\n", GetLastError());
1129
1130     SetLastError(0xdeadbeef);
1131     ret = WinHttpSetTimeouts(ses, 0, 0, 0, 0);
1132     ok(ret, "%u\n", GetLastError());
1133
1134     SetLastError(0xdeadbeef);
1135     ret = WinHttpSetTimeouts(ses, 0x0123, 0x4567, 0x89ab, 0xcdef);
1136     ok(ret, "%u\n", GetLastError());
1137
1138     SetLastError(0xdeadbeef);
1139     value = 0xdeadbeef;
1140     size  = sizeof(DWORD);
1141     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1142     ok(ret, "%u\n", GetLastError());
1143     ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1144
1145     SetLastError(0xdeadbeef);
1146     value = 0xdeadbeef;
1147     size  = sizeof(DWORD);
1148     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1149     ok(ret, "%u\n", GetLastError());
1150     ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1151
1152     SetLastError(0xdeadbeef);
1153     value = 0xdeadbeef;
1154     size  = sizeof(DWORD);
1155     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1156     ok(ret, "%u\n", GetLastError());
1157     ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1158
1159     SetLastError(0xdeadbeef);
1160     value = 0xdeadbeef;
1161     size  = sizeof(DWORD);
1162     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1163     ok(ret, "%u\n", GetLastError());
1164     ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1165
1166     SetLastError(0xdeadbeef);
1167     value = 0;
1168     ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1169     ok(ret, "%u\n", GetLastError());
1170
1171     SetLastError(0xdeadbeef);
1172     value = 0xdeadbeef;
1173     size  = sizeof(DWORD);
1174     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1175     ok(ret, "%u\n", GetLastError());
1176     ok(value == 0, "Expected 0, got %u\n", value);
1177
1178     SetLastError(0xdeadbeef);
1179     value = 0;
1180     ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1181     ok(ret, "%u\n", GetLastError());
1182
1183     SetLastError(0xdeadbeef);
1184     value = 0xdeadbeef;
1185     size  = sizeof(DWORD);
1186     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1187     ok(ret, "%u\n", GetLastError());
1188     ok(value == 0, "Expected 0, got %u\n", value);
1189
1190     SetLastError(0xdeadbeef);
1191     value = 0;
1192     ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1193     ok(ret, "%u\n", GetLastError());
1194
1195     SetLastError(0xdeadbeef);
1196     value = 0xdeadbeef;
1197     size  = sizeof(DWORD);
1198     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1199     ok(ret, "%u\n", GetLastError());
1200     ok(value == 0, "Expected 0, got %u\n", value);
1201
1202     SetLastError(0xdeadbeef);
1203     value = 0;
1204     ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1205     ok(ret, "%u\n", GetLastError());
1206
1207     SetLastError(0xdeadbeef);
1208     value = 0xdeadbeef;
1209     size  = sizeof(DWORD);
1210     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1211     ok(ret, "%u\n", GetLastError());
1212     ok(value == 0, "Expected 0, got %u\n", value);
1213
1214     SetLastError(0xdeadbeef);
1215     value = 0xbeefdead;
1216     ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1217     ok(ret, "%u\n", GetLastError());
1218
1219     SetLastError(0xdeadbeef);
1220     value = 0xdeadbeef;
1221     size  = sizeof(DWORD);
1222     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1223     ok(ret, "%u\n", GetLastError());
1224     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1225
1226     SetLastError(0xdeadbeef);
1227     value = 0xbeefdead;
1228     ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1229     ok(ret, "%u\n", GetLastError());
1230
1231     SetLastError(0xdeadbeef);
1232     value = 0xdeadbeef;
1233     size  = sizeof(DWORD);
1234     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1235     ok(ret, "%u\n", GetLastError());
1236     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1237
1238     SetLastError(0xdeadbeef);
1239     value = 0xbeefdead;
1240     ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1241     ok(ret, "%u\n", GetLastError());
1242
1243     SetLastError(0xdeadbeef);
1244     value = 0xdeadbeef;
1245     size  = sizeof(DWORD);
1246     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1247     ok(ret, "%u\n", GetLastError());
1248     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1249
1250     SetLastError(0xdeadbeef);
1251     value = 0xbeefdead;
1252     ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1253     ok(ret, "%u\n", GetLastError());
1254
1255     SetLastError(0xdeadbeef);
1256     value = 0xdeadbeef;
1257     size  = sizeof(DWORD);
1258     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1259     ok(ret, "%u\n", GetLastError());
1260     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1261
1262     con = WinHttpConnect(ses, codeweavers, 0, 0);
1263     ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1264
1265     /* Timeout values should match the last one set for session */
1266     SetLastError(0xdeadbeef);
1267     value = 0xdeadbeef;
1268     size  = sizeof(DWORD);
1269     ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1270     ok(ret, "%u\n", GetLastError());
1271     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1272
1273     SetLastError(0xdeadbeef);
1274     value = 0xdeadbeef;
1275     size  = sizeof(DWORD);
1276     ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1277     ok(ret, "%u\n", GetLastError());
1278     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1279
1280     SetLastError(0xdeadbeef);
1281     value = 0xdeadbeef;
1282     size  = sizeof(DWORD);
1283     ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1284     ok(ret, "%u\n", GetLastError());
1285     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1286
1287     SetLastError(0xdeadbeef);
1288     value = 0xdeadbeef;
1289     size  = sizeof(DWORD);
1290     ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1291     ok(ret, "%u\n", GetLastError());
1292     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1293
1294     SetLastError(0xdeadbeef);
1295     ret = WinHttpSetTimeouts(con, -2, 0, 0, 0);
1296     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1297        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1298
1299     SetLastError(0xdeadbeef);
1300     ret = WinHttpSetTimeouts(con, 0, -2, 0, 0);
1301     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1302        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1303
1304     SetLastError(0xdeadbeef);
1305     ret = WinHttpSetTimeouts(con, 0, 0, -2, 0);
1306     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1307        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1308
1309     SetLastError(0xdeadbeef);
1310     ret = WinHttpSetTimeouts(con, 0, 0, 0, -2);
1311     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1312        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1313
1314     SetLastError(0xdeadbeef);
1315     ret = WinHttpSetTimeouts(con, -1, -1, -1, -1);
1316     ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1317        "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1318
1319     SetLastError(0xdeadbeef);
1320     ret = WinHttpSetTimeouts(con, 0, 0, 0, 0);
1321     ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1322        "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1323
1324     SetLastError(0xdeadbeef);
1325     value = 0;
1326     ret = WinHttpSetOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1327     ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1328        "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1329
1330     SetLastError(0xdeadbeef);
1331     value = 0;
1332     ret = WinHttpSetOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1333     ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1334        "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1335
1336     SetLastError(0xdeadbeef);
1337     value = 0;
1338     ret = WinHttpSetOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1339     ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1340        "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1341
1342     SetLastError(0xdeadbeef);
1343     value = 0;
1344     ret = WinHttpSetOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1345     ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
1346        "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1347
1348     /* Changing timeout values for session should affect the values for connection */
1349     SetLastError(0xdeadbeef);
1350     value = 0xdead;
1351     ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1352     ok(ret, "%u\n", GetLastError());
1353
1354     SetLastError(0xdeadbeef);
1355     value = 0xdeadbeef;
1356     size  = sizeof(DWORD);
1357     ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1358     ok(ret, "%u\n", GetLastError());
1359     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1360
1361     SetLastError(0xdeadbeef);
1362     value = 0xdead;
1363     ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1364     ok(ret, "%u\n", GetLastError());
1365
1366     SetLastError(0xdeadbeef);
1367     value = 0xdeadbeef;
1368     size  = sizeof(DWORD);
1369     ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1370     ok(ret, "%u\n", GetLastError());
1371     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1372
1373     SetLastError(0xdeadbeef);
1374     value = 0xdead;
1375     ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1376     ok(ret, "%u\n", GetLastError());
1377
1378     SetLastError(0xdeadbeef);
1379     value = 0xdeadbeef;
1380     size  = sizeof(DWORD);
1381     ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1382     ok(ret, "%u\n", GetLastError());
1383     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1384
1385     SetLastError(0xdeadbeef);
1386     value = 0xdead;
1387     ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1388     ok(ret, "%u\n", GetLastError());
1389
1390     SetLastError(0xdeadbeef);
1391     value = 0xdeadbeef;
1392     size  = sizeof(DWORD);
1393     ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1394     ok(ret, "%u\n", GetLastError());
1395     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1396
1397     req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1398     ok(req != NULL, "failed to open a request %u\n", GetLastError());
1399
1400     /* Timeout values should match the last one set for session */
1401     SetLastError(0xdeadbeef);
1402     value = 0xdeadbeef;
1403     size  = sizeof(DWORD);
1404     ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1405     ok(ret, "%u\n", GetLastError());
1406     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1407
1408     SetLastError(0xdeadbeef);
1409     value = 0xdeadbeef;
1410     size  = sizeof(DWORD);
1411     ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1412     ok(ret, "%u\n", GetLastError());
1413     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1414
1415     SetLastError(0xdeadbeef);
1416     value = 0xdeadbeef;
1417     size  = sizeof(DWORD);
1418     ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1419     ok(ret, "%u\n", GetLastError());
1420     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1421
1422     SetLastError(0xdeadbeef);
1423     value = 0xdeadbeef;
1424     size  = sizeof(DWORD);
1425     ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1426     ok(ret, "%u\n", GetLastError());
1427     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1428
1429     SetLastError(0xdeadbeef);
1430     ret = WinHttpSetTimeouts(req, -2, 0, 0, 0);
1431     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1432        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1433
1434     SetLastError(0xdeadbeef);
1435     ret = WinHttpSetTimeouts(req, 0, -2, 0, 0);
1436     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1437        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1438
1439     SetLastError(0xdeadbeef);
1440     ret = WinHttpSetTimeouts(req, 0, 0, -2, 0);
1441     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1442        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1443
1444     SetLastError(0xdeadbeef);
1445     ret = WinHttpSetTimeouts(req, 0, 0, 0, -2);
1446     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
1447        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1448
1449     SetLastError(0xdeadbeef);
1450     ret = WinHttpSetTimeouts(req, -1, -1, -1, -1);
1451     ok(ret, "%u\n", GetLastError());
1452
1453     SetLastError(0xdeadbeef);
1454     ret = WinHttpSetTimeouts(req, 0, 0, 0, 0);
1455     ok(ret, "%u\n", GetLastError());
1456
1457     SetLastError(0xdeadbeef);
1458     ret = WinHttpSetTimeouts(req, 0xcdef, 0x89ab, 0x4567, 0x0123);
1459     ok(ret, "%u\n", GetLastError());
1460
1461     SetLastError(0xdeadbeef);
1462     value = 0xdeadbeef;
1463     size  = sizeof(DWORD);
1464     ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1465     ok(ret, "%u\n", GetLastError());
1466     ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
1467
1468     SetLastError(0xdeadbeef);
1469     value = 0xdeadbeef;
1470     size  = sizeof(DWORD);
1471     ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1472     ok(ret, "%u\n", GetLastError());
1473     ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value);
1474
1475     SetLastError(0xdeadbeef);
1476     value = 0xdeadbeef;
1477     size  = sizeof(DWORD);
1478     ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1479     ok(ret, "%u\n", GetLastError());
1480     ok(value == 0x4567, "Expected 0x4567, got %u\n", value);
1481
1482     SetLastError(0xdeadbeef);
1483     value = 0xdeadbeef;
1484     size  = sizeof(DWORD);
1485     ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1486     ok(ret, "%u\n", GetLastError());
1487     ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
1488
1489     SetLastError(0xdeadbeef);
1490     value = 0;
1491     ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1492     ok(ret, "%u\n", GetLastError());
1493
1494     SetLastError(0xdeadbeef);
1495     value = 0xdeadbeef;
1496     size  = sizeof(DWORD);
1497     ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1498     ok(ret, "%u\n", GetLastError());
1499     ok(value == 0, "Expected 0, got %u\n", value);
1500
1501     SetLastError(0xdeadbeef);
1502     value = 0;
1503     ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1504     ok(ret, "%u\n", GetLastError());
1505
1506     SetLastError(0xdeadbeef);
1507     value = 0xdeadbeef;
1508     size  = sizeof(DWORD);
1509     ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1510     ok(ret, "%u\n", GetLastError());
1511     ok(value == 0, "Expected 0, got %u\n", value);
1512
1513     SetLastError(0xdeadbeef);
1514     value = 0;
1515     ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1516     ok(ret, "%u\n", GetLastError());
1517
1518     SetLastError(0xdeadbeef);
1519     value = 0xdeadbeef;
1520     size  = sizeof(DWORD);
1521     ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1522     ok(ret, "%u\n", GetLastError());
1523     ok(value == 0, "Expected 0, got %u\n", value);
1524
1525     SetLastError(0xdeadbeef);
1526     value = 0;
1527     ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1528     ok(ret, "%u\n", GetLastError());
1529
1530     SetLastError(0xdeadbeef);
1531     value = 0xdeadbeef;
1532     size  = sizeof(DWORD);
1533     ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1534     ok(ret, "%u\n", GetLastError());
1535     ok(value == 0, "Expected 0, got %u\n", value);
1536
1537     SetLastError(0xdeadbeef);
1538     value = 0xbeefdead;
1539     ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1540     ok(ret, "%u\n", GetLastError());
1541
1542     SetLastError(0xdeadbeef);
1543     value = 0xdeadbeef;
1544     size  = sizeof(DWORD);
1545     ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1546     ok(ret, "%u\n", GetLastError());
1547     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1548
1549     SetLastError(0xdeadbeef);
1550     value = 0xbeefdead;
1551     ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1552     ok(ret, "%u\n", GetLastError());
1553
1554     SetLastError(0xdeadbeef);
1555     value = 0xdeadbeef;
1556     size  = sizeof(DWORD);
1557     ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1558     ok(ret, "%u\n", GetLastError());
1559     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1560
1561     SetLastError(0xdeadbeef);
1562     value = 0xbeefdead;
1563     ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1564     ok(ret, "%u\n", GetLastError());
1565
1566     SetLastError(0xdeadbeef);
1567     value = 0xdeadbeef;
1568     size  = sizeof(DWORD);
1569     ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1570     ok(ret, "%u\n", GetLastError());
1571     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1572
1573     SetLastError(0xdeadbeef);
1574     value = 0xbeefdead;
1575     ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1576     ok(ret, "%u\n", GetLastError());
1577
1578     SetLastError(0xdeadbeef);
1579     value = 0xdeadbeef;
1580     size  = sizeof(DWORD);
1581     ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1582     ok(ret, "%u\n", GetLastError());
1583     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1584
1585     /* Changing timeout values for session should not affect the values for a request,
1586      * neither should the other way around.
1587      */
1588     SetLastError(0xdeadbeef);
1589     value = 0xbeefdead;
1590     ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1591     ok(ret, "%u\n", GetLastError());
1592
1593     SetLastError(0xdeadbeef);
1594     value = 0xdeadbeef;
1595     size  = sizeof(DWORD);
1596     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1597     ok(ret, "%u\n", GetLastError());
1598     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1599
1600     SetLastError(0xdeadbeef);
1601     value = 0xbeefdead;
1602     ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1603     ok(ret, "%u\n", GetLastError());
1604
1605     SetLastError(0xdeadbeef);
1606     value = 0xdeadbeef;
1607     size  = sizeof(DWORD);
1608     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1609     ok(ret, "%u\n", GetLastError());
1610     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1611
1612     SetLastError(0xdeadbeef);
1613     value = 0xbeefdead;
1614     ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1615     ok(ret, "%u\n", GetLastError());
1616
1617     SetLastError(0xdeadbeef);
1618     value = 0xdeadbeef;
1619     size  = sizeof(DWORD);
1620     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1621     ok(ret, "%u\n", GetLastError());
1622     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1623
1624     SetLastError(0xdeadbeef);
1625     value = 0xbeefdead;
1626     ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1627     ok(ret, "%u\n", GetLastError());
1628
1629     SetLastError(0xdeadbeef);
1630     value = 0xdeadbeef;
1631     size  = sizeof(DWORD);
1632     ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1633     ok(ret, "%u\n", GetLastError());
1634     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
1635
1636     SetLastError(0xdeadbeef);
1637     value = 0xbeef;
1638     ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
1639     ok(ret, "%u\n", GetLastError());
1640
1641     SetLastError(0xdeadbeef);
1642     value = 0xdeadbeef;
1643     size  = sizeof(DWORD);
1644     ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
1645     ok(ret, "%u\n", GetLastError());
1646     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1647
1648     SetLastError(0xdeadbeef);
1649     value = 0xbeef;
1650     ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
1651     ok(ret, "%u\n", GetLastError());
1652
1653     SetLastError(0xdeadbeef);
1654     value = 0xdeadbeef;
1655     size  = sizeof(DWORD);
1656     ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size);
1657     ok(ret, "%u\n", GetLastError());
1658     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1659
1660     SetLastError(0xdeadbeef);
1661     value = 0xbeef;
1662     ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value));
1663     ok(ret, "%u\n", GetLastError());
1664
1665     SetLastError(0xdeadbeef);
1666     value = 0xdeadbeef;
1667     size  = sizeof(DWORD);
1668     ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size);
1669     ok(ret, "%u\n", GetLastError());
1670     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1671
1672     SetLastError(0xdeadbeef);
1673     value = 0xbeef;
1674     ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value));
1675     ok(ret, "%u\n", GetLastError());
1676
1677     SetLastError(0xdeadbeef);
1678     value = 0xdeadbeef;
1679     size  = sizeof(DWORD);
1680     ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size);
1681     ok(ret, "%u\n", GetLastError());
1682     ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
1683
1684     WinHttpCloseHandle(req);
1685     WinHttpCloseHandle(con);
1686     WinHttpCloseHandle(ses);
1687 }
1688
1689 static void test_resolve_timeout(void)
1690 {
1691     static const WCHAR codeweavers[] =
1692         {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1693     static const WCHAR nxdomain[] =
1694         {'n','x','d','o','m','a','i','n','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
1695
1696     HINTERNET ses, con, req;
1697     DWORD timeout;
1698     BOOL ret;
1699
1700     if (! proxy_active())
1701     {
1702         ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1703         ok(ses != NULL, "failed to open session %u\n", GetLastError());
1704
1705         timeout = 10000;
1706         ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1707         ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1708
1709         con = WinHttpConnect(ses, nxdomain, 0, 0);
1710         ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1711
1712         req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1713         ok(req != NULL, "failed to open a request %u\n", GetLastError());
1714
1715         SetLastError(0xdeadbeef);
1716         ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1717         ok(!ret, "sent request\n");
1718         ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED,
1719            "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
1720
1721         WinHttpCloseHandle(req);
1722         WinHttpCloseHandle(con);
1723         WinHttpCloseHandle(ses);
1724     }
1725     else
1726        skip("Skipping host resolution tests, host resolution preformed by proxy\n");
1727
1728     ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1729     ok(ses != NULL, "failed to open session %u\n", GetLastError());
1730
1731     timeout = 10000;
1732     ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
1733     ok(ret, "failed to set resolve timeout %u\n", GetLastError());
1734
1735     con = WinHttpConnect(ses, codeweavers, 0, 0);
1736     ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1737
1738     req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
1739     ok(req != NULL, "failed to open a request %u\n", GetLastError());
1740
1741     ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1742     ok(ret, "failed to send request\n");
1743
1744     WinHttpCloseHandle(req);
1745     WinHttpCloseHandle(con);
1746     WinHttpCloseHandle(ses);
1747 }
1748
1749 static const char page1[] =
1750 "<HTML>\r\n"
1751 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
1752 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
1753 "</HTML>\r\n\r\n";
1754
1755 static const char okmsg[] =
1756 "HTTP/1.1 200 OK\r\n"
1757 "Server: winetest\r\n"
1758 "\r\n";
1759
1760 static const char noauthmsg[] =
1761 "HTTP/1.1 401 Unauthorized\r\n"
1762 "Server: winetest\r\n"
1763 "Connection: close\r\n"
1764 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
1765 "\r\n";
1766
1767 static const char proxymsg[] =
1768 "HTTP/1.1 407 Proxy Authentication Required\r\n"
1769 "Server: winetest\r\n"
1770 "Proxy-Connection: close\r\n"
1771 "Proxy-Authenticate: Basic realm=\"placebo\"\r\n"
1772 "\r\n";
1773
1774 struct server_info
1775 {
1776     HANDLE event;
1777     int port;
1778 };
1779
1780 static DWORD CALLBACK server_thread(LPVOID param)
1781 {
1782     struct server_info *si = param;
1783     int r, c, i, on;
1784     SOCKET s;
1785     struct sockaddr_in sa;
1786     char buffer[0x100];
1787     WSADATA wsaData;
1788     int last_request = 0;
1789
1790     WSAStartup(MAKEWORD(1,1), &wsaData);
1791
1792     s = socket(AF_INET, SOCK_STREAM, 0);
1793     if (s == INVALID_SOCKET)
1794         return 1;
1795
1796     on = 1;
1797     setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof on);
1798
1799     memset(&sa, 0, sizeof sa);
1800     sa.sin_family = AF_INET;
1801     sa.sin_port = htons(si->port);
1802     sa.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
1803
1804     r = bind(s, (struct sockaddr *)&sa, sizeof(sa));
1805     if (r < 0)
1806         return 1;
1807
1808     listen(s, 0);
1809     SetEvent(si->event);
1810     do
1811     {
1812         c = accept(s, NULL, NULL);
1813
1814         memset(buffer, 0, sizeof buffer);
1815         for(i = 0; i < sizeof buffer - 1; i++)
1816         {
1817             r = recv(c, &buffer[i], 1, 0);
1818             if (r != 1)
1819                 break;
1820             if (i < 4) continue;
1821             if (buffer[i - 2] == '\n' && buffer[i] == '\n' &&
1822                 buffer[i - 3] == '\r' && buffer[i - 1] == '\r')
1823                 break;
1824         }
1825         if (strstr(buffer, "GET /basic"))
1826         {
1827             send(c, okmsg, sizeof okmsg - 1, 0);
1828             send(c, page1, sizeof page1 - 1, 0);
1829         }
1830         if (strstr(buffer, "/auth"))
1831         {
1832             if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q="))
1833                 send(c, okmsg, sizeof okmsg - 1, 0);
1834             else
1835                 send(c, noauthmsg, sizeof noauthmsg - 1, 0);
1836         }
1837         if (strstr(buffer, "/no_headers"))
1838         {
1839             send(c, page1, sizeof page1 - 1, 0);
1840         }
1841         if (strstr(buffer, "GET /quit"))
1842         {
1843             send(c, okmsg, sizeof okmsg - 1, 0);
1844             send(c, page1, sizeof page1 - 1, 0);
1845             last_request = 1;
1846         }
1847         shutdown(c, 2);
1848         closesocket(c);
1849
1850     } while (!last_request);
1851
1852     closesocket(s);
1853     return 0;
1854 }
1855
1856 static void test_basic_request(int port, const WCHAR *verb, const WCHAR *path)
1857 {
1858     HINTERNET ses, con, req;
1859     char buffer[0x100];
1860     DWORD count, status, size;
1861     BOOL ret;
1862
1863     ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1864     ok(ses != NULL, "failed to open session %u\n", GetLastError());
1865
1866     con = WinHttpConnect(ses, localhostW, port, 0);
1867     ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1868
1869     req = WinHttpOpenRequest(con, verb, path, NULL, NULL, NULL, 0);
1870     ok(req != NULL, "failed to open a request %u\n", GetLastError());
1871
1872     ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1873     ok(ret, "failed to send request %u\n", GetLastError());
1874
1875     ret = WinHttpReceiveResponse(req, NULL);
1876     ok(ret, "failed to receive response %u\n", GetLastError());
1877
1878     size = sizeof(status);
1879     ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1880     ok(ret, "failed to query status code %u\n", GetLastError());
1881     ok(status == 200, "request failed unexpectedly %u\n", status);
1882
1883     count = 0;
1884     memset(buffer, 0, sizeof(buffer));
1885     ret = WinHttpReadData(req, buffer, sizeof buffer, &count);
1886     ok(ret, "failed to read data %u\n", GetLastError());
1887     ok(count == sizeof page1 - 1, "count was wrong\n");
1888     ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n");
1889
1890     WinHttpCloseHandle(req);
1891     WinHttpCloseHandle(con);
1892     WinHttpCloseHandle(ses);
1893 }
1894
1895 static void test_basic_authentication(int port)
1896 {
1897     static const WCHAR authW[] = {'/','a','u','t','h',0};
1898     static const WCHAR userW[] = {'u','s','e','r',0};
1899     static const WCHAR passW[] = {'p','w','d',0};
1900     HINTERNET ses, con, req;
1901     DWORD status, size, error;
1902     BOOL ret;
1903
1904     ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1905     ok(ses != NULL, "failed to open session %u\n", GetLastError());
1906
1907     con = WinHttpConnect(ses, localhostW, port, 0);
1908     ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1909
1910     req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0);
1911     ok(req != NULL, "failed to open a request %u\n", GetLastError());
1912
1913     ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1914     ok(ret, "failed to send request %u\n", GetLastError());
1915
1916     ret = WinHttpReceiveResponse(req, NULL);
1917     ok(ret, "failed to receive response %u\n", GetLastError());
1918
1919     size = sizeof(status);
1920     ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1921     ok(ret, "failed to query status code %u\n", GetLastError());
1922     ok(status == 401, "request failed unexpectedly %u\n", status);
1923
1924     SetLastError(0xdeadbeef);
1925     ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
1926     error = GetLastError();
1927     ok(!ret, "expected failure\n");
1928     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
1929
1930     SetLastError(0xdeadbeef);
1931     ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
1932     error = GetLastError();
1933     ok(!ret, "expected failure\n");
1934     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
1935
1936     ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
1937     ok(ret, "failed to set credentials %u\n", GetLastError());
1938
1939     ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1940     ok(ret, "failed to send request %u\n", GetLastError());
1941
1942     ret = WinHttpReceiveResponse(req, NULL);
1943     ok(ret, "failed to receive response %u\n", GetLastError());
1944
1945     size = sizeof(status);
1946     ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
1947     ok(ret, "failed to query status code %u\n", GetLastError());
1948     ok(status == 200, "request failed unexpectedly %u\n", status);
1949
1950     WinHttpCloseHandle(req);
1951     WinHttpCloseHandle(con);
1952     WinHttpCloseHandle(ses);
1953 }
1954
1955 static void test_no_headers(int port)
1956 {
1957     static const WCHAR no_headersW[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
1958     HINTERNET ses, con, req;
1959     DWORD error;
1960     BOOL ret;
1961
1962     ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
1963     ok(ses != NULL, "failed to open session %u\n", GetLastError());
1964
1965     con = WinHttpConnect(ses, localhostW, port, 0);
1966     ok(con != NULL, "failed to open a connection %u\n", GetLastError());
1967
1968     req = WinHttpOpenRequest(con, NULL, no_headersW, NULL, NULL, NULL, 0);
1969     ok(req != NULL, "failed to open a request %u\n", GetLastError());
1970
1971     ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
1972     ok(ret, "failed to send request %u\n", GetLastError());
1973
1974     SetLastError(0xdeadbeef);
1975     ret = WinHttpReceiveResponse(req, NULL);
1976     error = GetLastError();
1977     ok(!ret, "expected failure\n");
1978     ok(error == ERROR_WINHTTP_INVALID_SERVER_RESPONSE, "got %u\n", error);
1979
1980     WinHttpCloseHandle(req);
1981     WinHttpCloseHandle(con);
1982     WinHttpCloseHandle(ses);
1983 }
1984
1985 static void test_bad_header( int port )
1986 {
1987     static const WCHAR bad_headerW[] =
1988         {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ',
1989          't','e','x','t','/','h','t','m','l','\n','\r',0};
1990     static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
1991     static const WCHAR content_typeW[] = {'C','o','n','t','e','n','t','-','T','y','p','e',0};
1992     WCHAR buffer[32];
1993     HINTERNET ses, con, req;
1994     DWORD index, len;
1995     BOOL ret;
1996
1997     ses = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
1998     ok( ses != NULL, "failed to open session %u\n", GetLastError() );
1999
2000     con = WinHttpConnect( ses, localhostW, port, 0 );
2001     ok( con != NULL, "failed to open a connection %u\n", GetLastError() );
2002
2003     req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 );
2004     ok( req != NULL, "failed to open a request %u\n", GetLastError() );
2005
2006     ret = WinHttpAddRequestHeaders( req, bad_headerW, ~0u, WINHTTP_ADDREQ_FLAG_ADD );
2007     ok( ret, "failed to add header %u\n", GetLastError() );
2008
2009     index = 0;
2010     buffer[0] = 0;
2011     len = sizeof(buffer);
2012     ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_CUSTOM|WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
2013                                content_typeW, buffer, &len, &index );
2014     ok( ret, "failed to query headers %u\n", GetLastError() );
2015     ok( !lstrcmpW( buffer, text_htmlW ), "got %s\n", wine_dbgstr_w(buffer) );
2016
2017     WinHttpCloseHandle( req );
2018     WinHttpCloseHandle( con );
2019     WinHttpCloseHandle( ses );
2020 }
2021
2022 static void test_credentials(void)
2023 {
2024     static WCHAR userW[] = {'u','s','e','r',0};
2025     static WCHAR passW[] = {'p','a','s','s',0};
2026     static WCHAR proxy_userW[] = {'p','r','o','x','y','u','s','e','r',0};
2027     static WCHAR proxy_passW[] = {'p','r','o','x','y','p','a','s','s',0};
2028     HINTERNET ses, con, req;
2029     DWORD size, error;
2030     WCHAR buffer[32];
2031     BOOL ret;
2032
2033     ses = WinHttpOpen(test_useragent, 0, proxy_userW, proxy_passW, 0);
2034     ok(ses != NULL, "failed to open session %u\n", GetLastError());
2035
2036     con = WinHttpConnect(ses, localhostW, 0, 0);
2037     ok(con != NULL, "failed to open a connection %u\n", GetLastError());
2038
2039     req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
2040     ok(req != NULL, "failed to open a request %u\n", GetLastError());
2041
2042     size = sizeof(buffer)/sizeof(WCHAR);
2043     ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
2044     ok(ret, "failed to query proxy username %u\n", GetLastError());
2045     ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2046     ok(!size, "expected 0, got %u\n", size);
2047
2048     size = sizeof(buffer)/sizeof(WCHAR);
2049     ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
2050     ok(ret, "failed to query proxy password %u\n", GetLastError());
2051     ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2052     ok(!size, "expected 0, got %u\n", size);
2053
2054     ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_USERNAME, proxy_userW, lstrlenW(proxy_userW));
2055     ok(ret, "failed to set username %u\n", GetLastError());
2056
2057     size = sizeof(buffer)/sizeof(WCHAR);
2058     ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size);
2059     ok(ret, "failed to query proxy username %u\n", GetLastError());
2060     ok(!winetest_strcmpW(buffer, proxy_userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2061     ok(size == lstrlenW(proxy_userW) * sizeof(WCHAR), "unexpected result %u\n", size);
2062
2063     size = sizeof(buffer)/sizeof(WCHAR);
2064     ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2065     ok(ret, "failed to query username %u\n", GetLastError());
2066     ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2067     ok(!size, "expected 0, got %u\n", size);
2068
2069     size = sizeof(buffer)/sizeof(WCHAR);
2070     ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2071     ok(ret, "failed to query password %u\n", GetLastError());
2072     ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2073     ok(!size, "expected 0, got %u\n", size);
2074
2075     ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_PASSWORD, proxy_passW, lstrlenW(proxy_passW));
2076     ok(ret, "failed to set proxy password %u\n", GetLastError());
2077
2078     size = sizeof(buffer)/sizeof(WCHAR);
2079     ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size);
2080     ok(ret, "failed to query proxy password %u\n", GetLastError());
2081     ok(!winetest_strcmpW(buffer, proxy_passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2082     ok(size == lstrlenW(proxy_passW) * sizeof(WCHAR), "unexpected result %u\n", size);
2083
2084     ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW));
2085     ok(ret, "failed to set username %u\n", GetLastError());
2086
2087     size = sizeof(buffer)/sizeof(WCHAR);
2088     ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2089     ok(ret, "failed to query username %u\n", GetLastError());
2090     ok(!winetest_strcmpW(buffer, userW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2091     ok(size == lstrlenW(userW) * sizeof(WCHAR), "unexpected result %u\n", size);
2092
2093     ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, passW, lstrlenW(passW));
2094     ok(ret, "failed to set password %u\n", GetLastError());
2095
2096     size = sizeof(buffer)/sizeof(WCHAR);
2097     ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2098     ok(ret, "failed to query password %u\n", GetLastError());
2099     ok(!winetest_strcmpW(buffer, passW), "unexpected result %s\n", wine_dbgstr_w(buffer));
2100     ok(size == lstrlenW(passW) * sizeof(WCHAR), "unexpected result %u\n", size);
2101
2102     WinHttpCloseHandle(req);
2103
2104     req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
2105     ok(req != NULL, "failed to open a request %u\n", GetLastError());
2106
2107     SetLastError(0xdeadbeef);
2108     ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL);
2109     error = GetLastError();
2110     ok(!ret, "expected failure\n");
2111     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2112
2113     SetLastError(0xdeadbeef);
2114     ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL);
2115     error = GetLastError();
2116     ok(!ret, "expected failure\n");
2117     ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error);
2118
2119     ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL);
2120     ok(ret, "failed to set credentials %u\n", GetLastError());
2121
2122     size = sizeof(buffer)/sizeof(WCHAR);
2123     ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size);
2124     ok(ret, "failed to query username %u\n", GetLastError());
2125     todo_wine {
2126     ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2127     ok(!size, "expected 0, got %u\n", size);
2128     }
2129
2130     size = sizeof(buffer)/sizeof(WCHAR);
2131     ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size);
2132     ok(ret, "failed to query password %u\n", GetLastError());
2133     todo_wine {
2134     ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer));
2135     ok(!size, "expected 0, got %u\n", size);
2136     }
2137
2138     WinHttpCloseHandle(req);
2139     WinHttpCloseHandle(con);
2140     WinHttpCloseHandle(ses);
2141 }
2142
2143 static void test_IWinHttpRequest(void)
2144 {
2145     static const WCHAR usernameW[] = {'u','s','e','r','n','a','m','e',0};
2146     static const WCHAR passwordW[] = {'p','a','s','s','w','o','r','d',0};
2147     static const WCHAR url1W[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
2148     static const WCHAR url2W[] = {'w','i','n','e','h','q','.','o','r','g',0};
2149     static const WCHAR url3W[] = {'h','t','t','p',':','/','/','c','r','o','s','s','o','v','e','r','.',
2150                                   'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m','/',
2151                                   'p','o','s','t','t','e','s','t','.','p','h','p',0};
2152     static const WCHAR method1W[] = {'G','E','T',0};
2153     static const WCHAR method2W[] = {'I','N','V','A','L','I','D',0};
2154     static const WCHAR method3W[] = {'P','O','S','T',0};
2155     static const WCHAR proxy_serverW[] = {'p','r','o','x','y','s','e','r','v','e','r',0};
2156     static const WCHAR bypas_listW[] = {'b','y','p','a','s','s','l','i','s','t',0};
2157     static const WCHAR connectionW[] = {'C','o','n','n','e','c','t','i','o','n',0};
2158     static const WCHAR dateW[] = {'D','a','t','e',0};
2159     static const WCHAR test_dataW[] = {'t','e','s','t','d','a','t','a',128,0};
2160     HRESULT hr;
2161     IWinHttpRequest *req;
2162     BSTR method, url, username, password, response = NULL, status_text = NULL, headers = NULL;
2163     BSTR date, today, connection, value = NULL;
2164     VARIANT async, empty, timeout, body, proxy_server, bypass_list, data;
2165     VARIANT_BOOL succeeded;
2166     LONG status;
2167     WCHAR todayW[WINHTTP_TIME_FORMAT_BUFSIZE];
2168     SYSTEMTIME st;
2169
2170     GetSystemTime( &st );
2171     WinHttpTimeFromSystemTime( &st, todayW );
2172
2173     CoInitialize( NULL );
2174     hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
2175     ok( hr == S_OK, "got %08x\n", hr );
2176
2177     V_VT( &empty ) = VT_ERROR;
2178     V_ERROR( &empty ) = 0xdeadbeef;
2179
2180     V_VT( &async ) = VT_BOOL;
2181     V_BOOL( &async ) = VARIANT_FALSE;
2182
2183     method = SysAllocString( method3W );
2184     url = SysAllocString( url3W );
2185     hr = IWinHttpRequest_Open( req, method, url, async );
2186     ok( hr == S_OK, "got %08x\n", hr );
2187     SysFreeString( method );
2188     SysFreeString( url );
2189
2190     V_VT( &data ) = VT_BSTR;
2191     V_BSTR( &data ) = SysAllocString( test_dataW );
2192     hr = IWinHttpRequest_Send( req, data );
2193     ok( hr == S_OK || broken(hr == HRESULT_FROM_WIN32(ERROR_WINHTTP_INVALID_SERVER_RESPONSE)),
2194         "got %08x\n", hr );
2195     SysFreeString( V_BSTR( &data ) );
2196
2197     hr = IWinHttpRequest_Open( req, NULL, NULL, empty );
2198     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2199
2200     method = SysAllocString( method1W );
2201     hr = IWinHttpRequest_Open( req, method, NULL, empty );
2202     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2203
2204     hr = IWinHttpRequest_Open( req, method, NULL, async );
2205     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2206
2207     url = SysAllocString( url1W );
2208     hr = IWinHttpRequest_Open( req, NULL, url, empty );
2209     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2210
2211     hr = IWinHttpRequest_Abort( req );
2212     ok( hr == S_OK, "got %08x\n", hr );
2213
2214     hr = IWinHttpRequest_Open( req, method, url, empty );
2215     ok( hr == S_OK, "got %08x\n", hr );
2216
2217     hr = IWinHttpRequest_Abort( req );
2218     ok( hr == S_OK, "got %08x\n", hr );
2219
2220     hr = IWinHttpRequest_Release( req );
2221     ok( hr == S_OK, "got %08x\n", hr );
2222
2223     hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
2224     ok( hr == S_OK, "got %08x\n", hr );
2225
2226     SysFreeString( url );
2227     url = SysAllocString( url2W );
2228     hr = IWinHttpRequest_Open( req, method, url, async );
2229     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr );
2230
2231     SysFreeString( method );
2232     method = SysAllocString( method2W );
2233     hr = IWinHttpRequest_Open( req, method, url, async );
2234     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr );
2235
2236     SysFreeString( method );
2237     method = SysAllocString( method1W );
2238     SysFreeString( url );
2239     url = SysAllocString( url1W );
2240     hr = IWinHttpRequest_Open( req, method, url, async );
2241     ok( hr == S_OK, "got %08x\n", hr );
2242
2243     hr = IWinHttpRequest_Abort( req );
2244     ok( hr == S_OK, "got %08x\n", hr );
2245
2246     hr = IWinHttpRequest_Send( req, empty );
2247     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2248
2249     hr = IWinHttpRequest_Abort( req );
2250     ok( hr == S_OK, "got %08x\n", hr );
2251
2252     hr = IWinHttpRequest_Release( req );
2253     ok( hr == S_OK, "got %08x\n", hr );
2254
2255     hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req );
2256     ok( hr == S_OK, "got %08x\n", hr );
2257
2258     hr = IWinHttpRequest_get_ResponseText( req, NULL );
2259     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2260
2261     hr = IWinHttpRequest_get_ResponseText( req, &response );
2262     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2263
2264     hr = IWinHttpRequest_get_Status( req, NULL );
2265     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2266
2267     hr = IWinHttpRequest_get_Status( req, &status );
2268     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2269
2270     hr = IWinHttpRequest_get_StatusText( req, NULL );
2271     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2272
2273     hr = IWinHttpRequest_get_StatusText( req, &status_text );
2274     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2275
2276     hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2277     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2278
2279     hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 );
2280     ok( hr == S_OK, "got %08x\n", hr );
2281
2282     hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef );
2283     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2284
2285     VariantInit( &proxy_server );
2286     V_VT( &proxy_server ) = VT_ERROR;
2287     VariantInit( &bypass_list );
2288     V_VT( &bypass_list ) = VT_ERROR;
2289     hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2290     ok( hr == S_OK, "got %08x\n", hr );
2291
2292     hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2293     ok( hr == S_OK, "got %08x\n", hr );
2294
2295     hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2296     ok( hr == S_OK, "got %08x\n", hr );
2297
2298     hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL );
2299     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2300
2301     hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2302     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2303
2304     hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL );
2305     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2306
2307     connection = SysAllocString( connectionW );
2308     hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL );
2309     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2310
2311     hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2312     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2313
2314     hr = IWinHttpRequest_SetRequestHeader( req, NULL, NULL );
2315     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2316
2317     date = SysAllocString( dateW );
2318     hr = IWinHttpRequest_SetRequestHeader( req, date, NULL );
2319     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2320
2321     today = SysAllocString( todayW );
2322     hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2323     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr );
2324
2325     hr = IWinHttpRequest_SetAutoLogonPolicy( req, 0xdeadbeef );
2326     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2327
2328     hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2329     ok( hr == S_OK, "got %08x\n", hr );
2330
2331     SysFreeString( method );
2332     method = SysAllocString( method1W );
2333     SysFreeString( url );
2334     url = SysAllocString( url1W );
2335     hr = IWinHttpRequest_Open( req, method, url, async );
2336     ok( hr == S_OK, "got %08x\n", hr );
2337
2338     hr = IWinHttpRequest_get_ResponseText( req, NULL );
2339     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2340
2341     hr = IWinHttpRequest_get_ResponseText( req, &response );
2342     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2343
2344     hr = IWinHttpRequest_get_Status( req, &status );
2345     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2346
2347     hr = IWinHttpRequest_get_StatusText( req, &status_text );
2348     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2349
2350     hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2351     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2352
2353     hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 );
2354     ok( hr == S_OK, "got %08x\n", hr );
2355
2356     hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef );
2357     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2358
2359     username = SysAllocString( usernameW );
2360     hr = IWinHttpRequest_SetCredentials( req, username, NULL, 0xdeadbeef );
2361     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2362
2363     password = SysAllocString( passwordW );
2364     hr = IWinHttpRequest_SetCredentials( req, NULL, password, 0xdeadbeef );
2365     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2366
2367     hr = IWinHttpRequest_SetCredentials( req, username, password, 0xdeadbeef );
2368     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2369
2370     hr = IWinHttpRequest_SetCredentials( req, NULL, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2371     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2372
2373     hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2374     ok( hr == S_OK, "got %08x\n", hr );
2375
2376     V_VT( &proxy_server ) = VT_BSTR;
2377     V_BSTR( &proxy_server ) = SysAllocString( proxy_serverW );
2378     V_VT( &bypass_list ) = VT_BSTR;
2379     V_BSTR( &bypass_list ) = SysAllocString( bypas_listW );
2380     hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2381     ok( hr == S_OK, "got %08x\n", hr );
2382
2383     hr = IWinHttpRequest_SetProxy( req, 0xdeadbeef, proxy_server, bypass_list );
2384     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2385
2386     hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2387     ok( hr == S_OK, "got %08x\n", hr );
2388
2389     hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2390     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2391
2392     hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2393     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr );
2394
2395     hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2396     ok( hr == S_OK, "got %08x\n", hr );
2397
2398     hr = IWinHttpRequest_SetRequestHeader( req, date, NULL );
2399     ok( hr == S_OK, "got %08x\n", hr );
2400
2401     hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2402     ok( hr == S_OK, "got %08x\n", hr );
2403
2404     hr = IWinHttpRequest_Send( req, empty );
2405     ok( hr == S_OK, "got %08x\n", hr );
2406
2407     hr = IWinHttpRequest_Send( req, empty );
2408     ok( hr == S_OK, "got %08x\n", hr );
2409
2410     hr = IWinHttpRequest_get_ResponseText( req, NULL );
2411     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2412
2413     hr = IWinHttpRequest_get_ResponseText( req, &response );
2414     ok( hr == S_OK, "got %08x\n", hr );
2415     SysFreeString( response );
2416
2417     hr = IWinHttpRequest_get_Status( req, NULL );
2418     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2419
2420     status = 0;
2421     hr = IWinHttpRequest_get_Status( req, &status );
2422     ok( hr == S_OK, "got %08x\n", hr );
2423     trace("Status=%d\n", status);
2424
2425     hr = IWinHttpRequest_get_StatusText( req, NULL );
2426     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2427
2428     hr = IWinHttpRequest_get_StatusText( req, &status_text );
2429     ok( hr == S_OK, "got %08x\n", hr );
2430     trace("StatusText=%s\n", wine_dbgstr_w(status_text));
2431     SysFreeString( status_text );
2432
2433     hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2434     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2435
2436     hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2437     ok( hr == S_OK, "got %08x\n", hr );
2438
2439     hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2440     ok( hr == S_OK, "got %08x\n", hr );
2441
2442     hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2443     ok( hr == S_OK, "got %08x\n", hr );
2444
2445     hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL );
2446     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2447
2448     hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2449     ok( hr == S_OK, "got %08x\n", hr );
2450     SysFreeString( headers );
2451
2452     hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL );
2453     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2454
2455     hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL );
2456     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2457
2458     hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2459     ok( hr == S_OK, "got %08x\n", hr );
2460     SysFreeString( value );
2461
2462     hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2463     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr );
2464
2465     hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2466     ok( hr == S_OK, "got %08x\n", hr );
2467
2468     VariantInit( &timeout );
2469     V_VT( &timeout ) = VT_I4;
2470     V_I4( &timeout ) = 10;
2471     hr = IWinHttpRequest_WaitForResponse( req, timeout, &succeeded );
2472     ok( hr == S_OK, "got %08x\n", hr );
2473
2474     hr = IWinHttpRequest_get_Status( req, &status );
2475     ok( hr == S_OK, "got %08x\n", hr );
2476
2477     hr = IWinHttpRequest_get_StatusText( req, &status_text );
2478     ok( hr == S_OK, "got %08x\n", hr );
2479     SysFreeString( status_text );
2480
2481     hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER );
2482     ok( hr == S_OK, "got %08x\n", hr );
2483
2484     hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2485     ok( hr == S_OK, "got %08x\n", hr );
2486
2487     hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2488     ok( hr == S_OK, "got %08x\n", hr );
2489
2490     hr = IWinHttpRequest_Send( req, empty );
2491     ok( hr == S_OK, "got %08x\n", hr );
2492
2493     hr = IWinHttpRequest_get_ResponseText( req, NULL );
2494     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2495
2496     hr = IWinHttpRequest_get_ResponseText( req, &response );
2497     ok( hr == S_OK, "got %08x\n", hr );
2498     SysFreeString( response );
2499
2500     hr = IWinHttpRequest_get_ResponseBody( req, NULL );
2501     ok( hr == E_INVALIDARG, "got %08x\n", hr );
2502
2503     VariantInit( &body );
2504     V_VT( &body ) = VT_ERROR;
2505     hr = IWinHttpRequest_get_ResponseBody( req, &body );
2506     ok( hr == S_OK, "got %08x\n", hr );
2507     ok( V_VT( &body ) == (VT_ARRAY|VT_UI1), "got %08x\n", V_VT( &body ) );
2508
2509     hr = VariantClear( &body );
2510     ok( hr == S_OK, "got %08x\n", hr );
2511
2512     hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list );
2513     ok( hr == S_OK, "got %08x\n", hr );
2514
2515     hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list );
2516     ok( hr == S_OK, "got %08x\n", hr );
2517
2518     hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers );
2519     ok( hr == S_OK, "got %08x\n", hr );
2520     SysFreeString( headers );
2521
2522     hr = IWinHttpRequest_GetResponseHeader( req, connection, &value );
2523     ok( hr == S_OK, "got %08x\n", hr );
2524     SysFreeString( value );
2525
2526     hr = IWinHttpRequest_SetRequestHeader( req, date, today );
2527     ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr );
2528
2529     hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy );
2530     ok( hr == S_OK, "got %08x\n", hr );
2531
2532     hr = IWinHttpRequest_Send( req, empty );
2533     ok( hr == S_OK, "got %08x\n", hr );
2534
2535     hr = IWinHttpRequest_Abort( req );
2536     ok( hr == S_OK, "got %08x\n", hr );
2537
2538     hr = IWinHttpRequest_Abort( req );
2539     ok( hr == S_OK, "got %08x\n", hr );
2540
2541     hr = IWinHttpRequest_Release( req );
2542     ok( hr == S_OK, "got %08x\n", hr );
2543
2544     SysFreeString( method );
2545     SysFreeString( url );
2546     SysFreeString( username );
2547     SysFreeString( password );
2548     SysFreeString( connection );
2549     SysFreeString( date );
2550     SysFreeString( today );
2551     VariantClear( &proxy_server );
2552     VariantClear( &bypass_list );
2553     CoUninitialize();
2554 }
2555
2556 static void test_WinHttpDetectAutoProxyConfigUrl(void)
2557 {
2558     BOOL ret;
2559     WCHAR *url;
2560     DWORD error;
2561
2562 if (0) /* crashes on some win2k systems */
2563 {
2564     SetLastError(0xdeadbeef);
2565     ret = WinHttpDetectAutoProxyConfigUrl( 0, NULL );
2566     error = GetLastError();
2567     ok( !ret, "expected failure\n" );
2568     ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2569 }
2570     url = NULL;
2571     SetLastError(0xdeadbeef);
2572     ret = WinHttpDetectAutoProxyConfigUrl( 0, &url );
2573     error = GetLastError();
2574     ok( !ret, "expected failure\n" );
2575     ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2576
2577 if (0) /* crashes on some win2k systems */
2578 {
2579     SetLastError(0xdeadbeef);
2580     ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, NULL );
2581     error = GetLastError();
2582     ok( !ret, "expected failure\n" );
2583     ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2584 }
2585     url = NULL;
2586     SetLastError(0xdeadbeef);
2587     ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, &url );
2588     error = GetLastError();
2589     if (!ret)
2590         ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED, "got %u\n", error );
2591     else
2592     {
2593         trace("%s\n", wine_dbgstr_w(url));
2594         GlobalFree( url );
2595     }
2596 }
2597
2598 static void test_WinHttpGetIEProxyConfigForCurrentUser(void)
2599 {
2600     BOOL ret;
2601     DWORD error;
2602     WINHTTP_CURRENT_USER_IE_PROXY_CONFIG cfg;
2603
2604     memset( &cfg, 0, sizeof(cfg) );
2605
2606     SetLastError(0xdeadbeef);
2607     ret = WinHttpGetIEProxyConfigForCurrentUser( NULL );
2608     error = GetLastError();
2609     ok( !ret, "expected failure\n" );
2610     ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2611
2612     ret = WinHttpGetIEProxyConfigForCurrentUser( &cfg );
2613     ok( ret, "expected success\n" );
2614     trace("IEProxy.AutoDetect=%d\n", cfg.fAutoDetect);
2615     trace("IEProxy.AutoConfigUrl=%s\n", wine_dbgstr_w(cfg.lpszAutoConfigUrl));
2616     trace("IEProxy.Proxy=%s\n", wine_dbgstr_w(cfg.lpszProxy));
2617     trace("IEProxy.ProxyBypass=%s\n", wine_dbgstr_w(cfg.lpszProxyBypass));
2618     GlobalFree( cfg.lpszAutoConfigUrl );
2619     GlobalFree( cfg.lpszProxy );
2620     GlobalFree( cfg.lpszProxyBypass );
2621 }
2622
2623 static void test_WinHttpGetProxyForUrl(void)
2624 {
2625     static const WCHAR urlW[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
2626     static const WCHAR wpadW[] = {'h','t','t','p',':','/','/','w','p','a','d','/','w','p','a','d','.','d','a','t',0};
2627     static const WCHAR emptyW[] = {0};
2628     BOOL ret;
2629     DWORD error;
2630     HINTERNET session;
2631     WINHTTP_AUTOPROXY_OPTIONS options;
2632     WINHTTP_PROXY_INFO info;
2633
2634     memset( &options, 0, sizeof(options) );
2635
2636     SetLastError(0xdeadbeef);
2637     ret = WinHttpGetProxyForUrl( NULL, NULL, NULL, NULL );
2638     error = GetLastError();
2639     ok( !ret, "expected failure\n" );
2640     ok( error == ERROR_INVALID_HANDLE, "got %u\n", error );
2641
2642     session = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 );
2643     ok( session != NULL, "failed to open session %u\n", GetLastError() );
2644
2645     SetLastError(0xdeadbeef);
2646     ret = WinHttpGetProxyForUrl( session, NULL, NULL, NULL );
2647     error = GetLastError();
2648     ok( !ret, "expected failure\n" );
2649     ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2650
2651     SetLastError(0xdeadbeef);
2652     ret = WinHttpGetProxyForUrl( session, emptyW, NULL, NULL );
2653     error = GetLastError();
2654     ok( !ret, "expected failure\n" );
2655     ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2656
2657     SetLastError(0xdeadbeef);
2658     ret = WinHttpGetProxyForUrl( session, urlW, NULL, NULL );
2659     error = GetLastError();
2660     ok( !ret, "expected failure\n" );
2661     ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2662
2663     SetLastError(0xdeadbeef);
2664     ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
2665     error = GetLastError();
2666     ok( !ret, "expected failure\n" );
2667     ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2668
2669     options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
2670     options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
2671
2672     SetLastError(0xdeadbeef);
2673     ret = WinHttpGetProxyForUrl( session, urlW, &options, NULL );
2674     error = GetLastError();
2675     ok( !ret, "expected failure\n" );
2676     ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2677
2678     options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
2679     options.dwAutoDetectFlags = 0;
2680
2681     SetLastError(0xdeadbeef);
2682     ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
2683     error = GetLastError();
2684     ok( !ret, "expected failure\n" );
2685     ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2686
2687     options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT | WINHTTP_AUTOPROXY_CONFIG_URL;
2688     options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
2689
2690     SetLastError(0xdeadbeef);
2691     ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
2692     error = GetLastError();
2693     ok( !ret, "expected failure\n" );
2694     ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
2695
2696     options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
2697     options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
2698
2699     memset( &info, 0, sizeof(info) );
2700     SetLastError(0xdeadbeef);
2701     ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
2702     error = GetLastError();
2703     if (!ret) ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED ||
2704                   error == ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT, "got %u\n", error );
2705     else
2706     {
2707         trace("Proxy.AccessType=%u\n", info.dwAccessType);
2708         trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info.lpszProxy));
2709         trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info.lpszProxyBypass));
2710         GlobalFree( info.lpszProxy );
2711         GlobalFree( info.lpszProxyBypass );
2712     }
2713
2714     options.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
2715     options.dwAutoDetectFlags = 0;
2716     options.lpszAutoConfigUrl = wpadW;
2717
2718     memset( &info, 0, sizeof(info) );
2719     SetLastError(0xdeadbeef);
2720     ret = WinHttpGetProxyForUrl( session, urlW, &options, &info );
2721     error = GetLastError();
2722     if (!ret) ok( error == ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT, "got %u\n", error );
2723     else
2724     {
2725         trace("Proxy.AccessType=%u\n", info.dwAccessType);
2726         trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info.lpszProxy));
2727         trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info.lpszProxyBypass));
2728         GlobalFree( info.lpszProxy );
2729         GlobalFree( info.lpszProxyBypass );
2730     }
2731     WinHttpCloseHandle( session );
2732 }
2733
2734 START_TEST (winhttp)
2735 {
2736     static const WCHAR basicW[] = {'/','b','a','s','i','c',0};
2737     static const WCHAR quitW[] = {'/','q','u','i','t',0};
2738     struct server_info si;
2739     HANDLE thread;
2740     DWORD ret;
2741
2742     test_OpenRequest();
2743     test_SendRequest();
2744     test_WinHttpTimeFromSystemTime();
2745     test_WinHttpTimeToSystemTime();
2746     test_WinHttpAddHeaders();
2747     test_secure_connection();
2748     test_request_parameter_defaults();
2749     test_QueryOption();
2750     test_set_default_proxy_config();
2751     test_empty_headers_param();
2752     test_Timeouts();
2753     test_resolve_timeout();
2754     test_credentials();
2755     test_IWinHttpRequest();
2756     test_WinHttpDetectAutoProxyConfigUrl();
2757     test_WinHttpGetIEProxyConfigForCurrentUser();
2758     test_WinHttpGetProxyForUrl();
2759
2760     si.event = CreateEvent(NULL, 0, 0, NULL);
2761     si.port = 7532;
2762
2763     thread = CreateThread(NULL, 0, server_thread, (LPVOID)&si, 0, NULL);
2764     ok(thread != NULL, "failed to create thread %u\n", GetLastError());
2765
2766     ret = WaitForSingleObject(si.event, 10000);
2767     ok(ret == WAIT_OBJECT_0, "failed to start winhttp test server %u\n", GetLastError());
2768     if (ret != WAIT_OBJECT_0)
2769         return;
2770
2771     test_basic_request(si.port, NULL, basicW);
2772     test_no_headers(si.port);
2773     test_basic_authentication(si.port);
2774     test_bad_header(si.port);
2775
2776     /* send the basic request again to shutdown the server thread */
2777     test_basic_request(si.port, NULL, quitW);
2778
2779     WaitForSingleObject(thread, 3000);
2780 }