kernel32: GetModuleHandleEx already clears the module handle on failure.
[wine] / dlls / urlmon / tests / url.c
1 /*
2  * UrlMon URL tests
3  *
4  * Copyright 2004 Kevin Koltzau
5  * Copyright 2004-2007 Jacek Caban for CodeWeavers
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include <stdarg.h>
23 #include <stdio.h>
24
25 #define COBJMACROS
26 #define NONAMELESSUNION
27 #define CONST_VTABLE
28
29 #include "windef.h"
30 #include "winbase.h"
31 #include "initguid.h"
32 #include "urlmon.h"
33 #include "wininet.h"
34 #include "mshtml.h"
35
36 #include "wine/test.h"
37
38 static HRESULT (WINAPI *pCreateAsyncBindCtxEx)(IBindCtx *, DWORD,
39                 IBindStatusCallback *, IEnumFORMATETC *, IBindCtx **, DWORD);
40 static HRESULT (WINAPI *pCreateUri)(LPCWSTR, DWORD, DWORD_PTR, IUri**);
41
42 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
43 DEFINE_GUID(CLSID_IdentityUnmarshal,0x0000001b,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
44 DEFINE_GUID(IID_IBindStatusCallbackHolder,0x79eac9cc,0xbaf9,0x11ce,0x8c,0x82,0x00,0xaa,0x00,0x4b,0xa9,0x0b);
45 extern CLSID CLSID_AboutProtocol;
46
47 #define DEFINE_EXPECT(func) \
48     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
49
50 #define SET_EXPECT(func) \
51     do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0)
52
53 #define CHECK_EXPECT2(func) \
54     do { \
55         ok(expect_ ##func, "unexpected call " #func "\n"); \
56         called_ ## func = TRUE; \
57     }while(0)
58
59 #define CHECK_EXPECT(func) \
60     do { \
61         CHECK_EXPECT2(func); \
62         expect_ ## func = FALSE; \
63     }while(0)
64
65 #define CHECK_CALLED(func) \
66     do { \
67         ok(called_ ## func, "expected " #func "\n"); \
68         expect_ ## func = called_ ## func = FALSE; \
69     }while(0)
70
71 #define CHECK_NOT_CALLED(func) \
72     do { \
73         ok(!called_ ## func, "unexpected " #func "\n"); \
74         expect_ ## func = called_ ## func = FALSE; \
75     }while(0)
76
77 #define CHECK_CALLED_BROKEN(func) \
78     do { \
79         ok(called_ ## func || broken(!called_ ## func), "expected " #func "\n"); \
80         expect_ ## func = called_ ## func = FALSE; \
81     }while(0)
82
83 #define CLEAR_CALLED(func) \
84     expect_ ## func = called_ ## func = FALSE
85
86 DEFINE_EXPECT(QueryInterface_IServiceProvider);
87 DEFINE_EXPECT(QueryInterface_IHttpNegotiate);
88 DEFINE_EXPECT(QueryInterface_IBindStatusCallback);
89 DEFINE_EXPECT(QueryInterface_IBindStatusCallbackEx);
90 DEFINE_EXPECT(QueryInterface_IBindStatusCallbackHolder);
91 DEFINE_EXPECT(QueryInterface_IInternetBindInfo);
92 DEFINE_EXPECT(QueryInterface_IAuthenticate);
93 DEFINE_EXPECT(QueryInterface_IInternetProtocol);
94 DEFINE_EXPECT(QueryInterface_IWindowForBindingUI);
95 DEFINE_EXPECT(QueryInterface_IHttpSecurity);
96 DEFINE_EXPECT(QueryService_IAuthenticate);
97 DEFINE_EXPECT(QueryService_IInternetProtocol);
98 DEFINE_EXPECT(QueryService_IInternetBindInfo);
99 DEFINE_EXPECT(QueryService_IWindowForBindingUI);
100 DEFINE_EXPECT(QueryService_IHttpSecurity);
101 DEFINE_EXPECT(BeginningTransaction);
102 DEFINE_EXPECT(OnResponse);
103 DEFINE_EXPECT(QueryInterface_IHttpNegotiate2);
104 DEFINE_EXPECT(GetRootSecurityId);
105 DEFINE_EXPECT(GetBindInfo);
106 DEFINE_EXPECT(GetBindInfoEx);
107 DEFINE_EXPECT(OnStartBinding);
108 DEFINE_EXPECT(OnProgress_FINDINGRESOURCE);
109 DEFINE_EXPECT(OnProgress_CONNECTING);
110 DEFINE_EXPECT(OnProgress_REDIRECTING);
111 DEFINE_EXPECT(OnProgress_SENDINGREQUEST);
112 DEFINE_EXPECT(OnProgress_MIMETYPEAVAILABLE);
113 DEFINE_EXPECT(OnProgress_BEGINDOWNLOADDATA);
114 DEFINE_EXPECT(OnProgress_DOWNLOADINGDATA);
115 DEFINE_EXPECT(OnProgress_ENDDOWNLOADDATA);
116 DEFINE_EXPECT(OnProgress_CACHEFILENAMEAVAILABLE);
117 DEFINE_EXPECT(OnStopBinding);
118 DEFINE_EXPECT(OnDataAvailable);
119 DEFINE_EXPECT(OnObjectAvailable);
120 DEFINE_EXPECT(Obj_OnStartBinding);
121 DEFINE_EXPECT(Obj_OnStopBinding);
122 DEFINE_EXPECT(Obj_GetBindInfo);
123 DEFINE_EXPECT(Obj_OnProgress_BEGINDOWNLOADDATA);
124 DEFINE_EXPECT(Obj_OnProgress_ENDDOWNLOADDATA);
125 DEFINE_EXPECT(Obj_OnProgress_SENDINGREQUEST);
126 DEFINE_EXPECT(Obj_OnProgress_MIMETYPEAVAILABLE);
127 DEFINE_EXPECT(Obj_OnProgress_CLASSIDAVAILABLE);
128 DEFINE_EXPECT(Obj_OnProgress_BEGINSYNCOPERATION);
129 DEFINE_EXPECT(Obj_OnProgress_ENDSYNCOPERATION);
130 DEFINE_EXPECT(Obj_OnProgress_FINDINGRESOURCE);
131 DEFINE_EXPECT(Obj_OnProgress_CONNECTING);
132 DEFINE_EXPECT(Obj_OnProgress_REDIRECTING);
133 DEFINE_EXPECT(Obj_OnProgress_CACHEFILENAMEAVAILABLE);
134 DEFINE_EXPECT(Start);
135 DEFINE_EXPECT(Read);
136 DEFINE_EXPECT(LockRequest);
137 DEFINE_EXPECT(Terminate);
138 DEFINE_EXPECT(UnlockRequest);
139 DEFINE_EXPECT(Continue);
140 DEFINE_EXPECT(Abort);
141 DEFINE_EXPECT(CreateInstance);
142 DEFINE_EXPECT(Load);
143 DEFINE_EXPECT(PutProperty_MIMETYPEPROP);
144 DEFINE_EXPECT(PutProperty_CLASSIDPROP);
145 DEFINE_EXPECT(SetPriority);
146 DEFINE_EXPECT(GetWindow_IHttpSecurity);
147 DEFINE_EXPECT(GetWindow_IWindowForBindingUI);
148 DEFINE_EXPECT(OnSecurityProblem);
149
150 static const WCHAR winetest_data_urlW[] =
151     {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
152      't','e','s','t','s','/','d','a','t','a','.','p','h','p',0};
153
154 static const WCHAR TEST_PART_URL_1[] = {'/','t','e','s','t','s','/','d','a','t','a','.','p','h','p','\0'};
155
156 static const WCHAR winetest_post_urlW[] =
157         {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',
158          't','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
159 static const WCHAR ABOUT_BLANK[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
160 static WCHAR INDEX_HTML[MAX_PATH];
161 static const WCHAR ITS_URL[] =
162     {'i','t','s',':','t','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l',0};
163 static const WCHAR MK_URL[] = {'m','k',':','@','M','S','I','T','S','t','o','r','e',':',
164     't','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l',0};
165 static const WCHAR https_urlW[] =
166     {'h','t','t','p','s',':','/','/','w','w','w','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',
167      '/','t','e','s','t','.','h','t','m','l',0};
168 static const WCHAR https_invalid_cn_urlW[] =
169     {'h','t','t','p','s',':','/','/','2','0','9','.','4','6','.','2','5','.','1','3','2',
170      '/','t','e','s','t','.','h','t','m','l',0};
171 static const WCHAR ftp_urlW[] = {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g',
172     '/','p','u','b','/','o','t','h','e','r','/',
173     'w','i','n','e','l','o','g','o','.','x','c','f','.','t','a','r','.','b','z','2',0};
174 static const WCHAR winetest_urlW[] = {'w','i','n','e','t','e','s','t',':','t','e','s','t',0};
175
176
177 static const WCHAR wszTextHtml[] = {'t','e','x','t','/','h','t','m','l',0};
178
179 static WCHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
180
181 static const WCHAR wszWineHQSite[] =
182     {'w','w','w','.','w','i','n','e','h','q','.','o','r','g',0};
183 static const WCHAR wszWineHQIP[] =
184     {'2','0','9','.','3','2','.','1','4','1','.','3',0};
185 static const CHAR wszIndexHtmlA[] = "index.html";
186 static const WCHAR wszIndexHtml[] = {'i','n','d','e','x','.','h','t','m','l',0};
187 static const WCHAR cache_fileW[] = {'c',':','\\','c','a','c','h','e','.','h','t','m',0};
188 static const CHAR dwl_htmlA[] = "dwl.html";
189 static const WCHAR dwl_htmlW[] = {'d','w','l','.','h','t','m','l',0};
190 static const CHAR test_txtA[] = "test.txt";
191 static const WCHAR emptyW[] = {0};
192
193 static BOOL stopped_binding = FALSE, stopped_obj_binding = FALSE, emulate_protocol = FALSE,
194     data_available = FALSE, http_is_first = TRUE, bind_to_object = FALSE, filedwl_api;
195 static DWORD read = 0, bindf = 0, prot_state = 0, thread_id, tymed, security_problem;
196 static const WCHAR *reported_url;
197 static CHAR mime_type[512];
198 static IInternetProtocolSink *protocol_sink = NULL;
199 static IBinding *current_binding;
200 static HANDLE complete_event, complete_event2;
201 static HRESULT binding_hres;
202 static HRESULT onsecurityproblem_hres;
203 static HRESULT abort_hres;
204 static BOOL have_IHttpNegotiate2, use_bscex, is_async_prot;
205 static BOOL test_redirect, use_cache_file, callback_read, no_callback, test_abort;
206 static WCHAR cache_file_name[MAX_PATH];
207 static BOOL only_check_prot_args = FALSE;
208 static BOOL invalid_cn_accepted = FALSE;
209 static BOOL abort_start = FALSE;
210 static BOOL abort_progress = FALSE;
211 static BOOL async_switch = FALSE;
212
213 static LPCWSTR urls[] = {
214     winetest_data_urlW,
215     ABOUT_BLANK,
216     INDEX_HTML,
217     ITS_URL,
218     MK_URL,
219     https_urlW,
220     ftp_urlW,
221     winetest_urlW
222 };
223
224 static WCHAR file_url[INTERNET_MAX_URL_LENGTH];
225
226 static enum {
227     HTTP_TEST,
228     ABOUT_TEST,
229     FILE_TEST,
230     ITS_TEST,
231     MK_TEST,
232     HTTPS_TEST,
233     FTP_TEST,
234     WINETEST_TEST
235 } test_protocol;
236
237 static enum {
238     BEFORE_DOWNLOAD,
239     DOWNLOADING,
240     END_DOWNLOAD
241 } download_state;
242
243 static const char *debugstr_guid(REFIID riid)
244 {
245     static char buf[50];
246
247     sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
248             riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
249             riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
250             riid->Data4[5], riid->Data4[6], riid->Data4[7]);
251
252     return buf;
253 }
254
255 static BOOL proxy_active(void)
256 {
257     HKEY internet_settings;
258     DWORD proxy_enable;
259     DWORD size;
260
261     if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
262                       0, KEY_QUERY_VALUE, &internet_settings) != ERROR_SUCCESS)
263         return FALSE;
264
265     size = sizeof(DWORD);
266     if (RegQueryValueExA(internet_settings, "ProxyEnable", NULL, NULL, (LPBYTE) &proxy_enable, &size) != ERROR_SUCCESS)
267         proxy_enable = 0;
268
269     RegCloseKey(internet_settings);
270
271     return proxy_enable != 0;
272 }
273
274 static BOOL is_urlmon_protocol(int prot)
275 {
276     return prot == FILE_TEST || prot == HTTP_TEST || prot == HTTPS_TEST || prot == FTP_TEST || prot == MK_TEST;
277 }
278
279 static void test_CreateURLMoniker(LPCWSTR url1, LPCWSTR url2)
280 {
281     HRESULT hr;
282     IMoniker *mon1 = NULL;
283     IMoniker *mon2 = NULL;
284
285     hr = CreateURLMoniker(NULL, NULL, NULL);
286     ok(hr == E_INVALIDARG,
287        "Expected CreateURLMoniker to return E_INVALIDARG, got 0x%08x\n", hr);
288
289     mon1 = (IMoniker *)0xdeadbeef;
290     hr = CreateURLMoniker(NULL, NULL, &mon1);
291     ok(hr == E_INVALIDARG,
292        "Expected CreateURLMoniker to return E_INVALIDARG, got 0x%08x\n", hr);
293     ok(mon1 == NULL, "Expected the output pointer to be NULL, got %p\n", mon1);
294
295     hr = CreateURLMoniker(NULL, emptyW, NULL);
296     ok(hr == E_INVALIDARG,
297        "Expected CreateURLMoniker to return E_INVALIDARG, got 0x%08x\n", hr);
298
299     hr = CreateURLMoniker(NULL, emptyW, &mon1);
300     ok(hr == S_OK ||
301        broken(hr == MK_E_SYNTAX), /* IE5/IE5.01/IE6 SP2 */
302        "Expected CreateURLMoniker to return S_OK, got 0x%08x\n", hr);
303     if(mon1) IMoniker_Release(mon1);
304
305     hr = CreateURLMoniker(NULL, url1, &mon1);
306     ok(hr == S_OK, "failed to create moniker: 0x%08x\n", hr);
307     if(hr == S_OK) {
308         hr = CreateURLMoniker(mon1, url2, &mon2);
309         ok(hr == S_OK, "failed to create moniker: 0x%08x\n", hr);
310     }
311     if(mon1) IMoniker_Release(mon1);
312     if(mon2) IMoniker_Release(mon2);
313 }
314
315 static void test_create(void)
316 {
317     static const WCHAR relativeW[] = {'a','/','b','.','t','x','t',0};
318     IStream *stream;
319     IMoniker *mon;
320     IBindCtx *bctx;
321     HRESULT hr;
322
323     test_CreateURLMoniker(winetest_data_urlW, TEST_PART_URL_1);
324
325     mon = (void*)0xdeadbeef;
326     hr = CreateURLMoniker(NULL, relativeW, &mon);
327     ok(hr == S_OK, "got 0x%08x\n", hr);
328
329     hr = CreateBindCtx(0, &bctx);
330     ok(hr == S_OK, "got 0x%08x\n", hr);
331
332     stream = (void*)0xdeadbeef;
333     hr = IMoniker_BindToStorage(mon, bctx, NULL, &IID_IStream, (void**)&stream);
334     todo_wine ok(hr == INET_E_UNKNOWN_PROTOCOL, "got 0x%08x\n", hr);
335     ok(stream == NULL, "got %p\n", stream);
336
337     hr = IMoniker_BindToStorage(mon, bctx, NULL, &IID_IStream, NULL);
338     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
339
340     stream = (void*)0xdeadbeef;
341     hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IStream, (void**)&stream);
342     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
343     ok(stream == NULL || broken(stream == (void*)0xdeadbeef) /* starting XP SP3 it's set to null */,
344         "got %p\n", stream);
345
346     IMoniker_Release(mon);
347
348     mon = (void*)0xdaedbeef;
349     hr = CreateURLMoniker(NULL, winetest_data_urlW, &mon);
350     ok(hr == S_OK, "got 0x%08x\n", hr);
351
352     stream = (void*)0xdeadbeef;
353     hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IStream, (void**)&stream);
354     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
355     ok(stream == NULL || broken(stream == (void*)0xdeadbeef) /* starting XP SP3 it's set to null */,
356         "got %p\n", stream);
357
358     hr = IMoniker_BindToStorage(mon, bctx, NULL, &IID_IStream, NULL);
359     ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
360
361     IMoniker_Release(mon);
362     IBindCtx_Release(bctx);
363 }
364
365 static HRESULT WINAPI Priority_QueryInterface(IInternetPriority *iface, REFIID riid, void **ppv)
366 {
367     ok(0, "unexpected call\n");
368     return E_NOINTERFACE;
369 }
370
371 static ULONG WINAPI Priority_AddRef(IInternetPriority *iface)
372 {
373     return 2;
374 }
375
376 static ULONG WINAPI Priority_Release(IInternetPriority *iface)
377 {
378     return 1;
379 }
380
381 static HRESULT WINAPI Priority_SetPriority(IInternetPriority *iface, LONG nPriority)
382 {
383     CHECK_EXPECT(SetPriority);
384     ok(!nPriority, "nPriority = %d\n", nPriority);
385     return S_OK;
386 }
387
388 static HRESULT WINAPI Priority_GetPriority(IInternetPriority *iface, LONG *pnPriority)
389 {
390     ok(0, "unexpected call\n");
391     return S_OK;
392 }
393
394 static const IInternetPriorityVtbl InternetPriorityVtbl = {
395     Priority_QueryInterface,
396     Priority_AddRef,
397     Priority_Release,
398     Priority_SetPriority,
399     Priority_GetPriority
400 };
401
402 static IInternetPriority InternetPriority = { &InternetPriorityVtbl };
403
404 static HRESULT WINAPI Protocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
405 {
406     *ppv = NULL;
407
408     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
409         *ppv = iface;
410         return S_OK;
411     }
412
413     if(IsEqualGUID(&IID_IInternetPriority, riid)) {
414         if(!is_urlmon_protocol(test_protocol))
415             return E_NOINTERFACE;
416
417         *ppv = &InternetPriority;
418         return S_OK;
419     }
420
421     if(IsEqualGUID(&IID_IInternetProtocolEx, riid))
422         return E_NOINTERFACE; /* TODO */
423
424     ok(0, "unexpected call %s\n", debugstr_guid(riid));
425     return E_NOINTERFACE;
426 }
427
428 static ULONG WINAPI Protocol_AddRef(IInternetProtocol *iface)
429 {
430     return 2;
431 }
432
433 static ULONG WINAPI Protocol_Release(IInternetProtocol *iface)
434 {
435     return 1;
436 }
437
438 static void test_switch_fail(void)
439 {
440     IInternetProtocolSink *binding_sink;
441     PROTOCOLDATA protocoldata = {0};
442     HRESULT hres;
443
444     static BOOL tested_switch_fail;
445
446     if(tested_switch_fail)
447         return;
448
449     tested_switch_fail = TRUE;
450
451     hres = IBinding_QueryInterface(current_binding, &IID_IInternetProtocolSink, (void**)&binding_sink);
452     ok(hres == S_OK, "Could not get IInternetProtocolSink iface: %08x\n", hres);
453     if(SUCCEEDED(hres)) {
454         hres = IInternetProtocolSink_Switch(binding_sink, &protocoldata);
455         ok(hres == E_FAIL, "Switch failed: %08x, expected E_FAIL\n", hres);
456         IInternetProtocolSink_Release(binding_sink);
457     }
458 }
459
460 static DWORD WINAPI thread_proc(PVOID arg)
461 {
462     PROTOCOLDATA protocoldata = {0};
463     HRESULT hres;
464
465     if(!no_callback) {
466         if(bind_to_object)
467             SET_EXPECT(Obj_OnProgress_FINDINGRESOURCE);
468         else
469             SET_EXPECT(OnProgress_FINDINGRESOURCE);
470     }
471     hres = IInternetProtocolSink_ReportProgress(protocol_sink,
472             BINDSTATUS_FINDINGRESOURCE, wszWineHQSite);
473     ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
474     if(!no_callback) {
475         WaitForSingleObject(complete_event, INFINITE);
476         if(bind_to_object)
477             CHECK_CALLED(Obj_OnProgress_FINDINGRESOURCE);
478         else
479             CHECK_CALLED(OnProgress_FINDINGRESOURCE);
480     }
481
482     if(!no_callback) {
483         if(bind_to_object)
484             SET_EXPECT(Obj_OnProgress_CONNECTING);
485         else
486             SET_EXPECT(OnProgress_CONNECTING);
487     }
488     hres = IInternetProtocolSink_ReportProgress(protocol_sink,
489             BINDSTATUS_CONNECTING, wszWineHQIP);
490     ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
491     if(!no_callback) {
492         WaitForSingleObject(complete_event, INFINITE);
493         if(bind_to_object)
494             CHECK_CALLED(Obj_OnProgress_CONNECTING);
495         else
496             CHECK_CALLED(OnProgress_CONNECTING);
497     }
498
499     if(!no_callback) {
500         if(bind_to_object)
501             SET_EXPECT(Obj_OnProgress_SENDINGREQUEST);
502         else
503             SET_EXPECT(OnProgress_SENDINGREQUEST);
504     }
505     hres = IInternetProtocolSink_ReportProgress(protocol_sink,
506             BINDSTATUS_SENDINGREQUEST, NULL);
507     ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
508     if(!no_callback) {
509         WaitForSingleObject(complete_event, INFINITE);
510         if(bind_to_object)
511             CHECK_CALLED(Obj_OnProgress_SENDINGREQUEST);
512         else
513             CHECK_CALLED(OnProgress_SENDINGREQUEST);
514     }
515
516     if(test_redirect) {
517         if(bind_to_object)
518             SET_EXPECT(Obj_OnProgress_REDIRECTING);
519         else
520             SET_EXPECT(OnProgress_REDIRECTING);
521         hres = IInternetProtocolSink_ReportProgress(protocol_sink, BINDSTATUS_REDIRECTING, winetest_data_urlW);
522         ok(hres == S_OK, "ReportProgress(BINDSTATUS_REFIRECTING) failed: %08x\n", hres);
523         WaitForSingleObject(complete_event, INFINITE);
524         if(bind_to_object)
525             CHECK_CALLED(Obj_OnProgress_REDIRECTING);
526         else
527             CHECK_CALLED(OnProgress_REDIRECTING);
528     }
529
530     test_switch_fail();
531
532     SET_EXPECT(Continue);
533     prot_state = 1;
534     hres = IInternetProtocolSink_Switch(protocol_sink, &protocoldata);
535     ok(hres == S_OK, "Switch failed: %08x\n", hres);
536     WaitForSingleObject(complete_event, INFINITE);
537
538     CHECK_CALLED(Continue);
539     CHECK_CALLED(Read);
540     if(bind_to_object) {
541         CHECK_CALLED(Obj_OnProgress_MIMETYPEAVAILABLE);
542         CHECK_CALLED(Obj_OnProgress_BEGINDOWNLOADDATA);
543         CHECK_CALLED(Obj_OnProgress_CLASSIDAVAILABLE);
544         CHECK_CALLED(Obj_OnProgress_BEGINSYNCOPERATION);
545         CHECK_CALLED(CreateInstance);
546         CHECK_CALLED(PutProperty_MIMETYPEPROP);
547         CHECK_CALLED_BROKEN(PutProperty_CLASSIDPROP);
548         CHECK_CALLED(Load);
549         CHECK_CALLED(Obj_OnProgress_ENDSYNCOPERATION);
550         CHECK_CALLED(OnObjectAvailable);
551         CHECK_CALLED(Obj_OnStopBinding);
552     }else if(!no_callback) {
553         CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
554         CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
555         CHECK_CALLED(OnDataAvailable);
556     }else {
557         CHECK_CALLED(LockRequest);
558     }
559
560     SET_EXPECT(Continue);
561     prot_state = 2;
562     hres = IInternetProtocolSink_Switch(protocol_sink, &protocoldata);
563     ok(hres == S_OK, "Switch failed: %08x\n", hres);
564     WaitForSingleObject(complete_event, INFINITE);
565     CHECK_CALLED(Continue);
566     if(test_abort) {
567         CHECK_CALLED(OnProgress_DOWNLOADINGDATA);
568         CHECK_CALLED(OnStopBinding);
569         SetEvent(complete_event2);
570         return 0;
571     }else {
572         CHECK_CALLED(Read);
573         if(!no_callback) {
574             CHECK_CALLED(OnProgress_DOWNLOADINGDATA);
575             CHECK_CALLED(OnDataAvailable);
576         }
577     }
578
579     SET_EXPECT(Continue);
580     prot_state = 2;
581     hres = IInternetProtocolSink_Switch(protocol_sink, &protocoldata);
582     ok(hres == S_OK, "Switch failed: %08x\n", hres);
583     WaitForSingleObject(complete_event, INFINITE);
584     CHECK_CALLED(Continue);
585     CHECK_CALLED(Read);
586     if(!no_callback) {
587         CHECK_CALLED(OnProgress_DOWNLOADINGDATA);
588         CHECK_CALLED(OnDataAvailable);
589     }
590
591     SET_EXPECT(Continue);
592     prot_state = 3;
593     hres = IInternetProtocolSink_Switch(protocol_sink, &protocoldata);
594     ok(hres == S_OK, "Switch failed: %08x\n", hres);
595     WaitForSingleObject(complete_event, INFINITE);
596     CHECK_CALLED(Continue);
597     CHECK_CALLED(Read);
598     if(!no_callback) {
599         CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
600         CHECK_CALLED(OnDataAvailable);
601         CHECK_CALLED(OnStopBinding);
602     }
603
604     SET_EXPECT(Read);
605
606     SetEvent(complete_event2);
607     return 0;
608 }
609
610 static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
611         IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
612         DWORD grfPI, HANDLE_PTR dwReserved)
613 {
614     BINDINFO bindinfo;
615     DWORD bind_info, bscf = BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION;
616     HRESULT hres;
617
618     static const STGMEDIUM stgmed_zero = {0};
619     static const SECURITY_ATTRIBUTES sa_zero = {0};
620
621     CHECK_EXPECT(Start);
622
623     read = 0;
624
625     reported_url = szUrl;
626     if(!filedwl_api) /* FIXME */
627         ok(szUrl && !lstrcmpW(szUrl, urls[test_protocol]), "wrong url %s\n", wine_dbgstr_w(szUrl));
628     ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
629     ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
630     ok(grfPI == 0, "grfPI=%d, expected 0\n", grfPI);
631     ok(dwReserved == 0, "dwReserved=%lx, expected 0\n", dwReserved);
632
633     if(!filedwl_api && binding_hres != S_OK) {
634         SET_EXPECT(OnStopBinding);
635         SET_EXPECT(Terminate);
636         hres = IInternetProtocolSink_ReportResult(pOIProtSink, binding_hres, 0, NULL);
637         ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
638         CHECK_CALLED(OnStopBinding);
639         CHECK_CALLED(Terminate);
640
641         return S_OK;
642     }
643
644     memset(&bindinfo, 0, sizeof(bindinfo));
645     bindinfo.cbSize = 0;
646     hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &bind_info, &bindinfo);
647     ok(hres == E_INVALIDARG, "GetBindInfo returned: %08x, expected E_INVALIDARG\n", hres);
648
649     memset(&bindinfo, 0, sizeof(bindinfo));
650     bindinfo.cbSize = sizeof(bindinfo);
651     hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &bind_info, &bindinfo);
652     ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
653
654     ok(bind_info & BINDF_FROMURLMON, "BINDF_FROMURLMON is not set\n");
655
656     if(filedwl_api || !is_urlmon_protocol(test_protocol) || tymed != TYMED_ISTREAM ||
657        !(bindf&BINDF_ASYNCSTORAGE) || !(bindf&BINDF_PULLDATA))
658         ok(bind_info & BINDF_NEEDFILE, "BINDF_NEEDFILE is not set\n");
659     else
660         ok(!(bind_info & BINDF_NEEDFILE), "BINDF_NEEDFILE is set\n");
661
662     bind_info &= ~(BINDF_NEEDFILE|BINDF_FROMURLMON);
663     if(filedwl_api || no_callback)
664         ok(bind_info == BINDF_PULLDATA, "bind_info = %x, expected BINDF_PULLDATA\n", bind_info);
665     else
666         ok(bind_info == (bindf & ~(BINDF_NEEDFILE|BINDF_FROMURLMON)), "bind_info = %x, expected %x\n",
667            bind_info, (bindf & ~(BINDF_NEEDFILE|BINDF_FROMURLMON)));
668
669     ok(bindinfo.cbSize == sizeof(bindinfo), "bindinfo.cbSize = %d\n", bindinfo.cbSize);
670     ok(!bindinfo.szExtraInfo, "bindinfo.szExtraInfo = %p\n", bindinfo.szExtraInfo);
671     ok(!memcmp(&bindinfo.stgmedData, &stgmed_zero, sizeof(STGMEDIUM)), "wrong stgmedData\n");
672     ok(!bindinfo.grfBindInfoF, "bindinfo.grfBindInfoF = %d\n", bindinfo.grfBindInfoF);
673     ok(!bindinfo.dwBindVerb, "bindinfo.dwBindVerb = %d\n", bindinfo.dwBindVerb);
674     ok(!bindinfo.szCustomVerb, "bindinfo.szCustomVerb = %p\n", bindinfo.szCustomVerb);
675     ok(!bindinfo.cbstgmedData, "bindinfo.cbstgmedData = %d\n", bindinfo.cbstgmedData);
676     ok(bindinfo.dwOptions == (bind_to_object ? 0x100000 : 0), "bindinfo.dwOptions = %x\n", bindinfo.dwOptions);
677     ok(!bindinfo.dwOptionsFlags, "bindinfo.dwOptionsFlags = %d\n", bindinfo.dwOptionsFlags);
678     ok(!bindinfo.dwCodePage, "bindinfo.dwCodePage = %d\n", bindinfo.dwCodePage);
679     ok(!memcmp(&bindinfo.securityAttributes, &sa_zero, sizeof(sa_zero)), "wrong bindinfo.securityAttributes\n");
680     ok(IsEqualGUID(&bindinfo.iid, &IID_NULL), "wrong bindinfo.iid\n");
681     ok(!bindinfo.pUnk, "bindinfo.pUnk = %p\n", bindinfo.pUnk);
682     ok(!bindinfo.dwReserved, "bindinfo.dwReserved = %d\n", bindinfo.dwReserved);
683
684     if(only_check_prot_args)
685         return E_FAIL;
686
687     switch(test_protocol) {
688     case MK_TEST:
689         hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
690                 BINDSTATUS_DIRECTBIND, NULL);
691         ok(hres == S_OK,
692            "ReportProgress(BINDSTATUS_SENDINGREQUEST) failed: %08x\n", hres);
693
694     case FILE_TEST:
695     case ITS_TEST:
696         if(bind_to_object)
697             SET_EXPECT(Obj_OnProgress_SENDINGREQUEST);
698         else
699             SET_EXPECT(OnProgress_SENDINGREQUEST);
700         hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
701                 BINDSTATUS_SENDINGREQUEST, emptyW);
702         ok(hres == S_OK,
703            "ReportProgress(BINDSTATUS_SENDINGREQUEST) failed: %08x\n", hres);
704         if(bind_to_object)
705             CHECK_CALLED(Obj_OnProgress_SENDINGREQUEST);
706         else
707             CHECK_CALLED(OnProgress_SENDINGREQUEST);
708     default:
709         break;
710     }
711
712     if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST) {
713         IServiceProvider *service_provider;
714         IHttpNegotiate *http_negotiate;
715         IHttpNegotiate2 *http_negotiate2;
716         IHttpSecurity *http_security;
717         LPWSTR ua = (LPWSTR)0xdeadbeef, accept_mimes[256];
718         LPWSTR additional_headers = (LPWSTR)0xdeadbeef;
719         BYTE sec_id[100];
720         DWORD fetched = 256, size = 100;
721         DWORD tid;
722
723         static const WCHAR wszMimes[] = {'*','/','*',0};
724
725         SET_EXPECT(QueryInterface_IInternetBindInfo);
726         SET_EXPECT(QueryService_IInternetBindInfo);
727         hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_USER_AGENT,
728                                                &ua, 1, &fetched);
729         CLEAR_CALLED(QueryInterface_IInternetBindInfo); /* IE <8 */
730         CLEAR_CALLED(QueryService_IInternetBindInfo); /* IE <8 */
731
732         ok(hres == E_NOINTERFACE,
733            "GetBindString(BINDSTRING_USER_AGETNT) failed: %08x\n", hres);
734         ok(fetched == 256, "fetched = %d, expected 254\n", fetched);
735         ok(ua == (LPWSTR)0xdeadbeef, "ua =  %p\n", ua);
736
737         hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_ACCEPT_MIMES,
738                                                accept_mimes, 256, &fetched);
739         ok(hres == S_OK,
740            "GetBindString(BINDSTRING_ACCEPT_MIMES) failed: %08x\n", hres);
741         ok(fetched == 1, "fetched = %d, expected 1\n", fetched);
742         ok(!lstrcmpW(wszMimes, accept_mimes[0]), "unexpected mimes\n");
743         CoTaskMemFree(accept_mimes[0]);
744
745         hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_ACCEPT_MIMES,
746                                                NULL, 256, &fetched);
747         ok(hres == E_INVALIDARG,
748            "GetBindString(BINDSTRING_ACCEPT_MIMES) failed: %08x\n", hres);
749
750         hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_ACCEPT_MIMES,
751                                                accept_mimes, 256, NULL);
752         ok(hres == E_INVALIDARG,
753            "GetBindString(BINDSTRING_ACCEPT_MIMES) failed: %08x\n", hres);
754
755         hres = IInternetBindInfo_QueryInterface(pOIBindInfo, &IID_IServiceProvider,
756                                                 (void**)&service_provider);
757         ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
758
759         SET_EXPECT(QueryInterface_IHttpNegotiate);
760         hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
761                 &IID_IHttpNegotiate, (void**)&http_negotiate);
762         CLEAR_CALLED(QueryInterface_IHttpNegotiate); /* IE <8 */
763         ok(hres == S_OK, "QueryService failed: %08x\n", hres);
764
765         if(!no_callback) {
766             SET_EXPECT(BeginningTransaction);
767             SET_EXPECT(QueryInterface_IHttpNegotiate);
768         }
769         hres = IHttpNegotiate_BeginningTransaction(http_negotiate, urls[test_protocol],
770                                                    NULL, 0, &additional_headers);
771         if(!no_callback) {
772             CHECK_CALLED_BROKEN(QueryInterface_IHttpNegotiate);
773             CHECK_CALLED(BeginningTransaction);
774         }
775         IHttpNegotiate_Release(http_negotiate);
776         ok(hres == S_OK, "BeginningTransction failed: %08x\n", hres);
777         ok(additional_headers == NULL, "additional_headers=%p\n", additional_headers);
778
779         SET_EXPECT(QueryInterface_IHttpNegotiate2);
780         hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate2,
781                 &IID_IHttpNegotiate2, (void**)&http_negotiate2);
782         CLEAR_CALLED(QueryInterface_IHttpNegotiate2); /* IE <8 */
783         ok(hres == S_OK, "QueryService failed: %08x\n", hres);
784
785         size = 512;
786         if(!no_callback) {
787             SET_EXPECT(QueryInterface_IHttpNegotiate2);
788             SET_EXPECT(GetRootSecurityId);
789         }
790         hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, sec_id, &size, 0);
791         if(!no_callback) {
792             CHECK_CALLED_BROKEN(QueryInterface_IHttpNegotiate2);
793             CHECK_CALLED(GetRootSecurityId);
794         }
795         IHttpNegotiate2_Release(http_negotiate2);
796         ok(hres == E_FAIL, "GetRootSecurityId failed: %08x, expected E_FAIL\n", hres);
797         ok(size == no_callback ? 512 : 13, "size=%d\n", size);
798
799         if(!no_callback) {
800             SET_EXPECT(QueryService_IHttpSecurity);
801             SET_EXPECT(QueryInterface_IHttpSecurity);
802         }
803         hres = IServiceProvider_QueryService(service_provider, &IID_IHttpSecurity,
804                 &IID_IHttpSecurity, (void**)&http_security);
805         ok(hres == (no_callback ? E_NOINTERFACE : S_OK), "QueryService failed: 0x%08x\n", hres);
806         if(!no_callback) {
807             CHECK_CALLED(QueryService_IHttpSecurity);
808             CHECK_CALLED(QueryInterface_IHttpSecurity);
809         }
810
811         IServiceProvider_Release(service_provider);
812
813         IInternetProtocolSink_AddRef(pOIProtSink);
814         protocol_sink = pOIProtSink;
815
816         if(async_switch) {
817             PROTOCOLDATA data;
818
819             memset(&data, 0, sizeof(data));
820             data.grfFlags = PI_FORCE_ASYNC;
821             prot_state = 0;
822             hres = IInternetProtocolSink_Switch(pOIProtSink, &data);
823             ok(hres == S_OK, "Switch failed: %08x\n", hres);
824             SET_EXPECT(Continue);
825             SetEvent(complete_event2);
826             return E_PENDING;
827         } else {
828             CreateThread(NULL, 0, thread_proc, NULL, 0, &tid);
829             return S_OK;
830         }
831     }
832
833     if(test_protocol == FILE_TEST) {
834         hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
835                 BINDSTATUS_CACHEFILENAMEAVAILABLE, file_url+8);
836         ok(hres == S_OK,
837            "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
838
839         if(bind_to_object)
840             SET_EXPECT(Obj_OnProgress_MIMETYPEAVAILABLE);
841         else
842             SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
843         hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
844                 BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE, wszTextHtml);
845         ok(hres == S_OK,
846            "ReportProgress(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE) failed: %08x\n", hres);
847         if(bind_to_object)
848             CHECK_CALLED(Obj_OnProgress_MIMETYPEAVAILABLE);
849         else
850             CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
851     }else {
852         hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
853                 BINDSTATUS_MIMETYPEAVAILABLE, wszTextHtml);
854         ok(hres == S_OK,
855            "ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE) failed: %08x\n", hres);
856     }
857
858     if(test_protocol == ABOUT_TEST)
859         bscf |= BSCF_DATAFULLYAVAILABLE;
860     if(test_protocol == ITS_TEST)
861         bscf = BSCF_FIRSTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE;
862
863     SET_EXPECT(Read);
864     if(bind_to_object) {
865         if(test_protocol != FILE_TEST && test_protocol != MK_TEST)
866             SET_EXPECT(Obj_OnProgress_MIMETYPEAVAILABLE);
867         SET_EXPECT(Obj_OnProgress_BEGINDOWNLOADDATA);
868         if(test_protocol == FILE_TEST)
869             SET_EXPECT(Obj_OnProgress_CACHEFILENAMEAVAILABLE);
870         SET_EXPECT(Obj_OnProgress_ENDDOWNLOADDATA);
871         SET_EXPECT(Obj_OnProgress_CLASSIDAVAILABLE);
872         SET_EXPECT(Obj_OnProgress_BEGINSYNCOPERATION);
873         SET_EXPECT(CreateInstance);
874         SET_EXPECT(PutProperty_MIMETYPEPROP);
875         SET_EXPECT(PutProperty_CLASSIDPROP);
876         SET_EXPECT(Load);
877         SET_EXPECT(Obj_OnProgress_ENDSYNCOPERATION);
878         SET_EXPECT(OnObjectAvailable);
879         SET_EXPECT(Obj_OnStopBinding);
880     }else {
881         if(test_protocol != FILE_TEST && test_protocol != MK_TEST)
882             SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
883         SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
884         if(test_protocol == FILE_TEST)
885             SET_EXPECT(OnProgress_CACHEFILENAMEAVAILABLE);
886         SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
887         SET_EXPECT(LockRequest);
888         if(!filedwl_api)
889             SET_EXPECT(OnDataAvailable);
890         SET_EXPECT(OnStopBinding);
891     }
892
893     hres = IInternetProtocolSink_ReportData(pOIProtSink, bscf, 13, 13);
894     ok(hres == S_OK, "ReportData failed: %08x\n", hres);
895
896     CHECK_CALLED(Read);
897     if(bind_to_object) {
898         if(test_protocol != FILE_TEST && test_protocol != MK_TEST)
899             CHECK_CALLED(Obj_OnProgress_MIMETYPEAVAILABLE);
900         CHECK_CALLED(Obj_OnProgress_BEGINDOWNLOADDATA);
901         if(test_protocol == FILE_TEST)
902             CHECK_CALLED(Obj_OnProgress_CACHEFILENAMEAVAILABLE);
903         CHECK_CALLED(Obj_OnProgress_ENDDOWNLOADDATA);
904         CHECK_CALLED(Obj_OnProgress_CLASSIDAVAILABLE);
905         CHECK_CALLED(Obj_OnProgress_BEGINSYNCOPERATION);
906         CHECK_CALLED(CreateInstance);
907         CHECK_CALLED(PutProperty_MIMETYPEPROP);
908         CHECK_CALLED_BROKEN(PutProperty_CLASSIDPROP);
909         CHECK_CALLED(Load);
910         CHECK_CALLED(Obj_OnProgress_ENDSYNCOPERATION);
911         CHECK_CALLED(OnObjectAvailable);
912         CHECK_CALLED(Obj_OnStopBinding);
913     }else {
914         if(test_protocol != FILE_TEST && test_protocol != MK_TEST)
915             CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
916         CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
917         if(test_protocol == FILE_TEST)
918             CHECK_CALLED(OnProgress_CACHEFILENAMEAVAILABLE);
919         CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
920         CHECK_CALLED(LockRequest);
921         if(!filedwl_api)
922             CHECK_CALLED(OnDataAvailable);
923         CHECK_CALLED(OnStopBinding);
924     }
925
926     if(test_protocol == ITS_TEST) {
927         SET_EXPECT(Read);
928         hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_BEGINDOWNLOADDATA, NULL);
929         ok(hres == S_OK, "ReportProgress(BINDSTATUS_BEGINDOWNLOADDATA) failed: %08x\n", hres);
930         CHECK_CALLED(Read);
931     }else if(!bind_to_object && test_protocol == ABOUT_TEST) {
932         SET_EXPECT(Read);
933         hres = IInternetProtocolSink_ReportData(pOIProtSink, bscf, 13, 13);
934         ok(hres == S_OK, "ReportData failed: %08x\n", hres);
935         CHECK_CALLED(Read);
936     }
937
938     SET_EXPECT(Terminate);
939     hres = IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);
940     ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
941     CHECK_CALLED(Terminate);
942
943     return S_OK;
944 }
945
946 static HRESULT WINAPI Protocol_Continue(IInternetProtocol *iface,
947         PROTOCOLDATA *pProtocolData)
948 {
949     DWORD bscf = 0;
950     HRESULT hres;
951
952     CHECK_EXPECT(Continue);
953
954     ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
955     ok(reported_url && !lstrcmpW(reported_url, urls[test_protocol]), "wrong url %s\n", wine_dbgstr_w(reported_url));
956
957     ok(pProtocolData != NULL, "pProtocolData == NULL\n");
958     if(!pProtocolData)
959         return S_OK;
960
961     switch(prot_state) {
962     case 0:
963         hres = IInternetProtocolSink_ReportProgress(protocol_sink,
964                     BINDSTATUS_SENDINGREQUEST, NULL);
965         ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
966
967         hres = IInternetProtocolSink_ReportProgress(protocol_sink,
968                 BINDSTATUS_MIMETYPEAVAILABLE, wszTextHtml);
969         ok(hres == S_OK,
970                 "ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE) failed: %08x\n", hres);
971
972         bscf |= BSCF_FIRSTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION;
973         break;
974     case 1: {
975         IServiceProvider *service_provider;
976         IHttpNegotiate *http_negotiate;
977         static WCHAR header[] = {'?',0};
978
979         hres = IInternetProtocolSink_QueryInterface(protocol_sink, &IID_IServiceProvider,
980                                                     (void**)&service_provider);
981         ok(hres == S_OK, "Could not get IServiceProvicder\n");
982
983         hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
984                                              &IID_IHttpNegotiate, (void**)&http_negotiate);
985         ok(hres == S_OK, "Could not get IHttpNegotiate\n");
986
987         if(!no_callback) {
988             SET_EXPECT(QueryInterface_IHttpNegotiate);
989             SET_EXPECT(OnResponse);
990         }
991         hres = IHttpNegotiate_OnResponse(http_negotiate, 200, header, NULL, NULL);
992         if(!no_callback) {
993             CHECK_CALLED_BROKEN(QueryInterface_IHttpNegotiate);
994             CHECK_CALLED(OnResponse);
995         }
996         IHttpNegotiate_Release(http_negotiate);
997         ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
998
999         if(test_protocol == HTTPS_TEST || test_redirect) {
1000             hres = IInternetProtocolSink_ReportProgress(protocol_sink, BINDSTATUS_ACCEPTRANGES, NULL);
1001             ok(hres == S_OK, "ReportProgress(BINDSTATUS_ACCEPTRANGES) failed: %08x\n", hres);
1002         }
1003
1004         hres = IInternetProtocolSink_ReportProgress(protocol_sink,
1005                 BINDSTATUS_MIMETYPEAVAILABLE, wszTextHtml);
1006         ok(hres == S_OK,
1007            "ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE) failed: %08x\n", hres);
1008
1009         hres = IInternetProtocolSink_ReportProgress(protocol_sink,
1010             BINDSTATUS_CACHEFILENAMEAVAILABLE, use_cache_file ? cache_file_name : cache_fileW);
1011         ok(hres == S_OK, "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
1012
1013         bscf |= BSCF_FIRSTDATANOTIFICATION;
1014         break;
1015     }
1016     case 2:
1017     case 3:
1018         bscf = BSCF_INTERMEDIATEDATANOTIFICATION;
1019         break;
1020     }
1021
1022     hres = IInternetProtocolSink_ReportData(protocol_sink, bscf, 100, 400);
1023     ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1024
1025     if(prot_state != 2 || !test_abort)
1026         SET_EXPECT(Read);
1027     switch(prot_state) {
1028     case 0:
1029         hres = IInternetProtocolSink_ReportResult(protocol_sink, S_OK, 0, NULL);
1030         ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1031         SET_EXPECT(OnProgress_SENDINGREQUEST);
1032         SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
1033         SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
1034         SET_EXPECT(LockRequest);
1035         SET_EXPECT(OnStopBinding);
1036         break;
1037     case 1:
1038         if(bind_to_object) {
1039             SET_EXPECT(Obj_OnProgress_MIMETYPEAVAILABLE);
1040             SET_EXPECT(Obj_OnProgress_BEGINDOWNLOADDATA);
1041             SET_EXPECT(Obj_OnProgress_CLASSIDAVAILABLE);
1042             SET_EXPECT(Obj_OnProgress_BEGINSYNCOPERATION);
1043             SET_EXPECT(CreateInstance);
1044             SET_EXPECT(PutProperty_MIMETYPEPROP);
1045             SET_EXPECT(PutProperty_CLASSIDPROP);
1046             SET_EXPECT(Load);
1047             SET_EXPECT(Obj_OnProgress_ENDSYNCOPERATION);
1048             SET_EXPECT(OnObjectAvailable);
1049             SET_EXPECT(Obj_OnStopBinding);
1050         }else if(!no_callback) {
1051             SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
1052             SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
1053             SET_EXPECT(LockRequest);
1054         }else {
1055             SET_EXPECT(LockRequest);
1056         }
1057         break;
1058     case 2:
1059         if(!no_callback)
1060             SET_EXPECT(OnProgress_DOWNLOADINGDATA);
1061         break;
1062     case 3:
1063         SET_EXPECT(OnProgress_DOWNLOADINGDATA);
1064         SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
1065     }
1066     if(!no_callback) {
1067         if((!bind_to_object || prot_state >= 2) && (!test_abort || prot_state != 2))
1068             SET_EXPECT(OnDataAvailable);
1069         if(prot_state == 3 || (test_abort && prot_state == 2))
1070             SET_EXPECT(OnStopBinding);
1071     }
1072     return S_OK;
1073 }
1074
1075 static HRESULT WINAPI Protocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
1076         DWORD dwOptions)
1077 {
1078     HRESULT hres;
1079
1080     CHECK_EXPECT(Abort);
1081
1082     ok(hrReason == E_ABORT, "hrReason = %08x\n", hrReason);
1083     ok(!dwOptions, "dwOptions = %x\n", dwOptions);
1084
1085     hres = IInternetProtocolSink_ReportResult(protocol_sink, E_ABORT, ERROR_SUCCESS, NULL);
1086     ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1087
1088     return S_OK;
1089 }
1090
1091 static HRESULT WINAPI Protocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
1092 {
1093     CHECK_EXPECT(Terminate);
1094
1095     ok(dwOptions == 0, "dwOptions=%d, expected 0\n", dwOptions);
1096
1097     if(protocol_sink) {
1098         IInternetProtocolSink_Release(protocol_sink);
1099         protocol_sink = NULL;
1100     }
1101
1102     if(no_callback)
1103         SetEvent(complete_event);
1104     return S_OK;
1105 }
1106
1107 static HRESULT WINAPI Protocol_Suspend(IInternetProtocol *iface)
1108 {
1109     ok(0, "unexpected call\n");
1110     return E_NOTIMPL;
1111 }
1112
1113 static HRESULT WINAPI Protocol_Resume(IInternetProtocol *iface)
1114 {
1115     ok(0, "unexpected call\n");
1116     return E_NOTIMPL;
1117 }
1118
1119 static HRESULT WINAPI Protocol_Read(IInternetProtocol *iface, void *pv,
1120         ULONG cb, ULONG *pcbRead)
1121 {
1122     static const char data[] = "<HTML></HTML>";
1123
1124     CHECK_EXPECT2(Read);
1125
1126     ok(pv != NULL, "pv == NULL\n");
1127     ok(cb != 0, "cb == 0\n");
1128     ok(pcbRead != NULL, "pcbRead == NULL\n");
1129
1130     if(async_switch) {
1131         if(prot_state++ > 1) {
1132             *pcbRead = 0;
1133             return S_FALSE;
1134         } else {
1135             memset(pv, '?', cb);
1136             *pcbRead = cb;
1137             return S_OK;
1138         }
1139     }
1140
1141     if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST) {
1142         HRESULT hres;
1143
1144         static int pending = TRUE;
1145
1146         pending = !pending;
1147
1148         switch(prot_state) {
1149         case 1:
1150         case 2:
1151             if(pending) {
1152                 *pcbRead = 10;
1153                 memset(pv, '?', 10);
1154                 if(prot_state == 2 && no_callback)
1155                     SetEvent(complete_event);
1156                 return E_PENDING;
1157             }else {
1158                 memset(pv, '?', cb);
1159                 *pcbRead = cb;
1160                 read++;
1161                 return S_OK;
1162             }
1163         case 3:
1164             prot_state++;
1165
1166             *pcbRead = 0;
1167
1168             hres = IInternetProtocolSink_ReportData(protocol_sink,
1169                     BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION, 2000, 2000);
1170             ok(hres == S_OK, "ReportData failed: %08x\n", hres);
1171
1172             hres = IInternetProtocolSink_ReportResult(protocol_sink, S_OK, 0, NULL);
1173             ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
1174
1175             return S_FALSE;
1176         case 4:
1177             *pcbRead = 0;
1178             return S_FALSE;
1179         }
1180     }
1181
1182     if(read) {
1183         *pcbRead = 0;
1184         return S_FALSE;
1185     }
1186
1187     ok(*pcbRead == 0, "*pcbRead=%d, expected 0\n", *pcbRead);
1188     read += *pcbRead = sizeof(data)-1;
1189     memcpy(pv, data, sizeof(data));
1190     return S_OK;
1191 }
1192
1193 static HRESULT WINAPI Protocol_Seek(IInternetProtocol *iface,
1194         LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
1195 {
1196     ok(0, "unexpected call\n");
1197     return E_NOTIMPL;
1198 }
1199
1200 static HRESULT WINAPI Protocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
1201 {
1202     CHECK_EXPECT(LockRequest);
1203     if(no_callback)
1204         SetEvent(complete_event);
1205     return S_OK;
1206 }
1207
1208 static HRESULT WINAPI Protocol_UnlockRequest(IInternetProtocol *iface)
1209 {
1210     CHECK_EXPECT(UnlockRequest);
1211     return S_OK;
1212 }
1213
1214 static const IInternetProtocolVtbl ProtocolVtbl = {
1215     Protocol_QueryInterface,
1216     Protocol_AddRef,
1217     Protocol_Release,
1218     Protocol_Start,
1219     Protocol_Continue,
1220     Protocol_Abort,
1221     Protocol_Terminate,
1222     Protocol_Suspend,
1223     Protocol_Resume,
1224     Protocol_Read,
1225     Protocol_Seek,
1226     Protocol_LockRequest,
1227     Protocol_UnlockRequest
1228 };
1229
1230 static IInternetProtocol Protocol = { &ProtocolVtbl };
1231
1232 static HRESULT WINAPI HttpNegotiate_QueryInterface(IHttpNegotiate2 *iface, REFIID riid, void **ppv)
1233 {
1234     if(IsEqualGUID(&IID_IUnknown, riid)
1235             || IsEqualGUID(&IID_IHttpNegotiate, riid)
1236             || IsEqualGUID(&IID_IHttpNegotiate2, riid)) {
1237         *ppv = iface;
1238         return S_OK;
1239     }
1240
1241     ok(0, "unexpected call\n");
1242     return E_NOINTERFACE;
1243 }
1244
1245 static ULONG WINAPI HttpNegotiate_AddRef(IHttpNegotiate2 *iface)
1246 {
1247     return 2;
1248 }
1249
1250 static ULONG WINAPI HttpNegotiate_Release(IHttpNegotiate2 *iface)
1251 {
1252     return 1;
1253 }
1254
1255 static HRESULT WINAPI HttpNegotiate_BeginningTransaction(IHttpNegotiate2 *iface, LPCWSTR szURL,
1256         LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
1257 {
1258     if(onsecurityproblem_hres == S_OK)
1259         CHECK_EXPECT2(BeginningTransaction);
1260     else
1261         CHECK_EXPECT(BeginningTransaction);
1262
1263     ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
1264
1265     ok(!lstrcmpW(szURL, urls[test_protocol]), "szURL != urls[test_protocol]\n");
1266     ok(!dwReserved, "dwReserved=%d, expected 0\n", dwReserved);
1267     ok(pszAdditionalHeaders != NULL, "pszAdditionalHeaders == NULL\n");
1268     if(pszAdditionalHeaders)
1269         ok(*pszAdditionalHeaders == NULL, "*pszAdditionalHeaders != NULL\n");
1270
1271     return S_OK;
1272 }
1273
1274 static HRESULT WINAPI HttpNegotiate_OnResponse(IHttpNegotiate2 *iface, DWORD dwResponseCode,
1275         LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders)
1276 {
1277     CHECK_EXPECT(OnResponse);
1278
1279     ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
1280
1281     ok(dwResponseCode == 200, "dwResponseCode=%d, expected 200\n", dwResponseCode);
1282     ok(szResponseHeaders != NULL, "szResponseHeaders == NULL\n");
1283     ok(szRequestHeaders == NULL, "szRequestHeaders != NULL\n");
1284     /* Note: in protocol.c tests, OnResponse pszAdditionalRequestHeaders _is_ NULL */
1285     ok(pszAdditionalRequestHeaders != NULL, "pszAdditionalHeaders == NULL\n");
1286     if(pszAdditionalRequestHeaders)
1287         ok(*pszAdditionalRequestHeaders == NULL, "*pszAdditionalHeaders != NULL\n");
1288
1289     return S_OK;
1290 }
1291
1292 static HRESULT WINAPI HttpNegotiate_GetRootSecurityId(IHttpNegotiate2 *iface,
1293         BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
1294 {
1295     static const BYTE sec_id[] = {'h','t','t','p',':','t','e','s','t',1,0,0,0};
1296
1297     CHECK_EXPECT(GetRootSecurityId);
1298
1299     ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
1300
1301     ok(!dwReserved, "dwReserved=%ld, expected 0\n", dwReserved);
1302     ok(pbSecurityId != NULL, "pbSecurityId == NULL\n");
1303     ok(pcbSecurityId != NULL, "pcbSecurityId == NULL\n");
1304
1305     if(pbSecurityId == (void*)0xdeadbeef)
1306         return E_NOTIMPL;
1307
1308     if(pcbSecurityId) {
1309         ok(*pcbSecurityId == 512, "*pcbSecurityId=%d, expected 512\n", *pcbSecurityId);
1310         *pcbSecurityId = sizeof(sec_id);
1311     }
1312
1313     if(pbSecurityId)
1314         memcpy(pbSecurityId, sec_id, sizeof(sec_id));
1315
1316     return E_FAIL;
1317 }
1318
1319 static IHttpNegotiate2Vtbl HttpNegotiateVtbl = {
1320     HttpNegotiate_QueryInterface,
1321     HttpNegotiate_AddRef,
1322     HttpNegotiate_Release,
1323     HttpNegotiate_BeginningTransaction,
1324     HttpNegotiate_OnResponse,
1325     HttpNegotiate_GetRootSecurityId
1326 };
1327
1328 static IHttpNegotiate2 HttpNegotiate = { &HttpNegotiateVtbl };
1329
1330 static HRESULT WINAPI HttpSecurity_QueryInterface(IHttpSecurity *iface, REFIID riid, void **ppv)
1331 {
1332     ok(0, "Unexpected call\n");
1333     *ppv = NULL;
1334     if(IsEqualGUID(&IID_IHttpSecurity, riid) ||
1335        IsEqualGUID(&IID_IWindowForBindingUI, riid) ||
1336        IsEqualGUID(&IID_IUnknown, riid))
1337     {
1338         *ppv = iface;
1339         return S_OK;
1340     }
1341
1342     ok(0, "Unexpected interface requested.\n");
1343
1344     return E_NOINTERFACE;
1345 }
1346
1347 static ULONG WINAPI HttpSecurity_AddRef(IHttpSecurity *iface)
1348 {
1349     return 2;
1350 }
1351
1352 static ULONG WINAPI HttpSecurity_Release(IHttpSecurity *iface)
1353 {
1354     return 1;
1355 }
1356
1357 static HRESULT WINAPI HttpSecurity_GetWindow(IHttpSecurity *iface, REFGUID rguidReason, HWND *phwnd)
1358 {
1359     if(IsEqualGUID(rguidReason, &IID_IHttpSecurity))
1360         CHECK_EXPECT(GetWindow_IHttpSecurity);
1361     else if(IsEqualGUID(rguidReason, &IID_IWindowForBindingUI))
1362         CHECK_EXPECT2(GetWindow_IWindowForBindingUI);
1363     else
1364         ok(0, "Unexpected rguidReason: %s\n", debugstr_guid(rguidReason));
1365
1366     *phwnd = NULL;
1367     return S_OK;
1368 }
1369
1370 static HRESULT WINAPI HttpSecurity_OnSecurityProblem(IHttpSecurity *iface, DWORD dwProblem)
1371 {
1372     CHECK_EXPECT(OnSecurityProblem);
1373     if(!security_problem) {
1374         ok(dwProblem == ERROR_INTERNET_SEC_CERT_CN_INVALID ||
1375            broken(dwProblem == ERROR_INTERNET_SEC_CERT_ERRORS) /* Some versions of IE6 */,
1376            "Got problem: %d\n", dwProblem);
1377         security_problem = dwProblem;
1378
1379         if(dwProblem == ERROR_INTERNET_SEC_CERT_ERRORS)
1380             binding_hres = INET_E_SECURITY_PROBLEM;
1381     }else
1382         ok(dwProblem == security_problem, "Got problem: %d\n", dwProblem);
1383
1384     return onsecurityproblem_hres;
1385 }
1386
1387 static const IHttpSecurityVtbl HttpSecurityVtbl = {
1388     HttpSecurity_QueryInterface,
1389     HttpSecurity_AddRef,
1390     HttpSecurity_Release,
1391     HttpSecurity_GetWindow,
1392     HttpSecurity_OnSecurityProblem
1393 };
1394
1395 static IHttpSecurity HttpSecurity = { &HttpSecurityVtbl };
1396
1397 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
1398 {
1399     ok(0, "unexpected call\n");
1400     return E_NOINTERFACE;
1401 }
1402
1403 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
1404 {
1405     return 2;
1406 }
1407
1408 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
1409 {
1410     return 1;
1411 }
1412
1413 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface,
1414         REFGUID guidService, REFIID riid, void **ppv)
1415 {
1416     if(IsEqualGUID(&IID_IAuthenticate, guidService)) {
1417         CHECK_EXPECT(QueryService_IAuthenticate);
1418         return E_NOTIMPL;
1419     }
1420
1421     if(IsEqualGUID(&IID_IInternetProtocol, guidService)) {
1422         CHECK_EXPECT2(QueryService_IInternetProtocol);
1423         return E_NOTIMPL;
1424     }
1425
1426     if(IsEqualGUID(&IID_IInternetBindInfo, guidService)) {
1427         CHECK_EXPECT(QueryService_IInternetBindInfo);
1428         return E_NOTIMPL;
1429     }
1430
1431     if(IsEqualGUID(&IID_IWindowForBindingUI, guidService)) {
1432         CHECK_EXPECT2(QueryService_IWindowForBindingUI);
1433         *ppv = &HttpSecurity;
1434         return S_OK;
1435     }
1436
1437     if(IsEqualGUID(&IID_IHttpSecurity, guidService)) {
1438         CHECK_EXPECT(QueryService_IHttpSecurity);
1439         *ppv = &HttpSecurity;
1440         return S_OK;
1441     }
1442
1443     ok(0, "unexpected service %s\n", debugstr_guid(guidService));
1444     return E_NOINTERFACE;
1445 }
1446
1447 static IServiceProviderVtbl ServiceProviderVtbl = {
1448     ServiceProvider_QueryInterface,
1449     ServiceProvider_AddRef,
1450     ServiceProvider_Release,
1451     ServiceProvider_QueryService
1452 };
1453
1454 static IServiceProvider ServiceProvider = { &ServiceProviderVtbl };
1455
1456 static IBindStatusCallbackEx objbsc;
1457
1458 static void test_WinInetHttpInfo(IWinInetHttpInfo *http_info, DWORD progress)
1459 {
1460     DWORD status, size;
1461     HRESULT hres, expect;
1462
1463     /* QueryInfo changes it's behavior during this request */
1464     if(progress == BINDSTATUS_SENDINGREQUEST)
1465         return;
1466
1467     if(test_protocol==FTP_TEST && download_state==BEFORE_DOWNLOAD
1468             && progress!=BINDSTATUS_MIMETYPEAVAILABLE)
1469         expect = E_FAIL;
1470     else if(test_protocol == FTP_TEST)
1471         expect = S_FALSE;
1472     else
1473         expect = S_OK;
1474
1475     size = sizeof(DWORD);
1476     hres = IWinInetHttpInfo_QueryInfo(http_info, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER,
1477             &status, &size, NULL, NULL);
1478     ok(hres == expect, "hres = %x, expected %x\n", hres, expect);
1479     if(hres == S_OK) {
1480         if(download_state==BEFORE_DOWNLOAD && progress!=BINDSTATUS_MIMETYPEAVAILABLE)
1481             ok(status == 0, "status = %d\n", status);
1482         else
1483             ok(status == HTTP_STATUS_OK, "status = %d\n", status);
1484         ok(size == sizeof(DWORD), "size = %d\n", size);
1485     }
1486
1487     size = sizeof(DWORD);
1488     hres = IWinInetHttpInfo_QueryOption(http_info, INTERNET_OPTION_HANDLE_TYPE, &status, &size);
1489     if(test_protocol == FTP_TEST) {
1490         if(download_state==BEFORE_DOWNLOAD && progress!=BINDSTATUS_MIMETYPEAVAILABLE)
1491             ok(hres == E_FAIL, "hres = %x\n", hres);
1492         else
1493             ok(hres == S_OK, "hres = %x\n", hres);
1494
1495         if(hres == S_OK)
1496             ok(status == INTERNET_HANDLE_TYPE_FTP_FILE, "status = %d\n", status);
1497     } else {
1498         ok(hres == S_OK, "hres = %x\n", hres);
1499         ok(status == INTERNET_HANDLE_TYPE_HTTP_REQUEST, "status = %d\n", status);
1500     }
1501 }
1502
1503 static HRESULT WINAPI statusclb_QueryInterface(IBindStatusCallbackEx *iface, REFIID riid, void **ppv)
1504 {
1505     ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
1506
1507     if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
1508         CHECK_EXPECT2(QueryInterface_IInternetProtocol);
1509         if(emulate_protocol) {
1510             *ppv = &Protocol;
1511             return S_OK;
1512         }else {
1513             return E_NOINTERFACE;
1514         }
1515     }
1516     else if (IsEqualGUID(&IID_IServiceProvider, riid))
1517     {
1518         CHECK_EXPECT2(QueryInterface_IServiceProvider);
1519         *ppv = &ServiceProvider;
1520         return S_OK;
1521     }
1522     else if (IsEqualGUID(&IID_IHttpNegotiate, riid))
1523     {
1524         CHECK_EXPECT2(QueryInterface_IHttpNegotiate);
1525         *ppv = &HttpNegotiate;
1526         return S_OK;
1527     }
1528     else if (IsEqualGUID(&IID_IHttpNegotiate2, riid))
1529     {
1530         CHECK_EXPECT(QueryInterface_IHttpNegotiate2);
1531         *ppv = &HttpNegotiate;
1532         return S_OK;
1533     }
1534     else if (IsEqualGUID(&IID_IAuthenticate, riid))
1535     {
1536         CHECK_EXPECT(QueryInterface_IAuthenticate);
1537         return E_NOINTERFACE;
1538     }
1539     else if(IsEqualGUID(&IID_IBindStatusCallback, riid))
1540     {
1541         CHECK_EXPECT2(QueryInterface_IBindStatusCallback);
1542         *ppv = iface;
1543         return S_OK;
1544     }
1545     else if(IsEqualGUID(&IID_IBindStatusCallbackHolder, riid))
1546     {
1547         CHECK_EXPECT2(QueryInterface_IBindStatusCallbackHolder);
1548         return E_NOINTERFACE;
1549     }
1550     else if(IsEqualGUID(&IID_IBindStatusCallbackEx, riid))
1551     {
1552         CHECK_EXPECT(QueryInterface_IBindStatusCallbackEx);
1553         if(!use_bscex)
1554             return E_NOINTERFACE;
1555         *ppv = iface;
1556         return S_OK;
1557     }
1558     else if(IsEqualGUID(&IID_IInternetBindInfo, riid))
1559     {
1560         /* TODO */
1561         CHECK_EXPECT2(QueryInterface_IInternetBindInfo);
1562     }
1563     else if(IsEqualGUID(&IID_IWindowForBindingUI, riid))
1564     {
1565         CHECK_EXPECT2(QueryInterface_IWindowForBindingUI);
1566         return E_NOINTERFACE;
1567     }
1568     else if(IsEqualGUID(&IID_IHttpSecurity, riid))
1569     {
1570         CHECK_EXPECT2(QueryInterface_IHttpSecurity);
1571         return E_NOINTERFACE;
1572     }
1573     else
1574     {
1575         ok(0, "unexpected interface %s\n", debugstr_guid(riid));
1576     }
1577
1578     return E_NOINTERFACE;
1579 }
1580
1581 static ULONG WINAPI statusclb_AddRef(IBindStatusCallbackEx *iface)
1582 {
1583     return 2;
1584 }
1585
1586 static ULONG WINAPI statusclb_Release(IBindStatusCallbackEx *iface)
1587 {
1588     return 1;
1589 }
1590
1591 static HRESULT WINAPI statusclb_OnStartBinding(IBindStatusCallbackEx *iface, DWORD dwReserved,
1592         IBinding *pib)
1593 {
1594     IWinInetHttpInfo *http_info;
1595     HRESULT hres;
1596     IMoniker *mon;
1597     DWORD res;
1598     CLSID clsid;
1599     LPOLESTR res_str;
1600
1601     if(iface == &objbsc)
1602         CHECK_EXPECT(Obj_OnStartBinding);
1603     else
1604         CHECK_EXPECT(OnStartBinding);
1605
1606     ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
1607
1608     ok(pib != NULL, "pib should not be NULL\n");
1609     ok(dwReserved == 0xff, "dwReserved=%x\n", dwReserved);
1610
1611     if(pib == (void*)0xdeadbeef)
1612         return S_OK;
1613
1614     current_binding = pib;
1615
1616     hres = IBinding_QueryInterface(pib, &IID_IMoniker, (void**)&mon);
1617     ok(hres == E_NOINTERFACE, "IBinding should not have IMoniker interface\n");
1618     if(SUCCEEDED(hres))
1619         IMoniker_Release(mon);
1620
1621     hres = IBinding_QueryInterface(pib, &IID_IWinInetHttpInfo, (void**)&http_info);
1622     ok(hres == E_NOINTERFACE, "Could not get IID_IWinInetHttpInfo: %08x\n", hres);
1623
1624     if(0) { /* crashes with native urlmon */
1625         hres = IBinding_GetBindResult(pib, NULL, &res, &res_str, NULL);
1626         ok(hres == E_INVALIDARG, "GetBindResult failed: %08x\n", hres);
1627     }
1628     hres = IBinding_GetBindResult(pib, &clsid, NULL, &res_str, NULL);
1629     ok(hres == E_INVALIDARG, "GetBindResult failed: %08x\n", hres);
1630     hres = IBinding_GetBindResult(pib, &clsid, &res, NULL, NULL);
1631     ok(hres == E_INVALIDARG, "GetBindResult failed: %08x\n", hres);
1632     hres = IBinding_GetBindResult(pib, &clsid, &res, &res_str, (void*)0xdeadbeef);
1633     ok(hres == E_INVALIDARG, "GetBindResult failed: %08x\n", hres);
1634
1635     hres = IBinding_GetBindResult(pib, &clsid, &res, &res_str, NULL);
1636     ok(hres == S_OK, "GetBindResult failed: %08x, expected S_OK\n", hres);
1637     ok(IsEqualCLSID(&clsid, &CLSID_NULL), "incorrect clsid: %s\n", debugstr_guid(&clsid));
1638     ok(!res, "incorrect res: %x\n", res);
1639     ok(!res_str, "incorrect res_str: %s\n", wine_dbgstr_w(res_str));
1640
1641     if(abort_start) {
1642         binding_hres = abort_hres;
1643         return abort_hres;
1644     }
1645
1646     return S_OK;
1647 }
1648
1649 static HRESULT WINAPI statusclb_GetPriority(IBindStatusCallbackEx *iface, LONG *pnPriority)
1650 {
1651     ok(0, "unexpected call\n");
1652     return E_NOTIMPL;
1653 }
1654
1655 static HRESULT WINAPI statusclb_OnLowResource(IBindStatusCallbackEx *iface, DWORD reserved)
1656 {
1657     ok(0, "unexpected call\n");
1658     return E_NOTIMPL;
1659 }
1660
1661 static HRESULT WINAPI statusclb_OnProgress(IBindStatusCallbackEx *iface, ULONG ulProgress,
1662         ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
1663 {
1664     ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
1665
1666     switch(ulStatusCode) {
1667     case BINDSTATUS_FINDINGRESOURCE:
1668         if(iface == &objbsc)
1669             CHECK_EXPECT(Obj_OnProgress_FINDINGRESOURCE);
1670         else if(test_protocol == FTP_TEST)
1671             todo_wine CHECK_EXPECT(OnProgress_FINDINGRESOURCE);
1672         else
1673             CHECK_EXPECT(OnProgress_FINDINGRESOURCE);
1674         if(emulate_protocol && (test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST))
1675             SetEvent(complete_event);
1676         break;
1677     case BINDSTATUS_CONNECTING:
1678         if(iface == &objbsc)
1679             CHECK_EXPECT(Obj_OnProgress_CONNECTING);
1680         else if(test_protocol == FTP_TEST)
1681             todo_wine CHECK_EXPECT(OnProgress_CONNECTING);
1682         else if(onsecurityproblem_hres == S_OK)
1683             CHECK_EXPECT2(OnProgress_CONNECTING);
1684         else
1685             CHECK_EXPECT(OnProgress_CONNECTING);
1686         if(emulate_protocol && (test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST))
1687             SetEvent(complete_event);
1688         break;
1689     case BINDSTATUS_REDIRECTING:
1690         if(iface == &objbsc)
1691             CHECK_EXPECT(Obj_OnProgress_REDIRECTING);
1692         else
1693             CHECK_EXPECT(OnProgress_REDIRECTING);
1694         ok(!lstrcmpW(szStatusText, winetest_data_urlW), "unexpected status text %s\n",
1695            wine_dbgstr_w(szStatusText));
1696         if(emulate_protocol && (test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST)
1697                 && (!bind_to_object || iface == &objbsc))
1698             SetEvent(complete_event);
1699         break;
1700     case BINDSTATUS_SENDINGREQUEST:
1701         if(iface == &objbsc)
1702             CHECK_EXPECT(Obj_OnProgress_SENDINGREQUEST);
1703         else if(test_protocol == FTP_TEST)
1704             CHECK_EXPECT2(OnProgress_SENDINGREQUEST);
1705         else
1706             CHECK_EXPECT(OnProgress_SENDINGREQUEST);
1707         if(emulate_protocol && (test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST))
1708             SetEvent(complete_event);
1709
1710         if(abort_progress) {
1711             if(filedwl_api)
1712                 binding_hres = E_ABORT;
1713             return E_ABORT;
1714         }
1715
1716         break;
1717     case BINDSTATUS_MIMETYPEAVAILABLE:
1718         if(iface == &objbsc)
1719             CHECK_EXPECT(Obj_OnProgress_MIMETYPEAVAILABLE);
1720         else
1721             CHECK_EXPECT(OnProgress_MIMETYPEAVAILABLE);
1722         if(!bind_to_object)
1723             ok(download_state == BEFORE_DOWNLOAD, "Download state was %d, expected BEFORE_DOWNLOAD\n",
1724                download_state);
1725         WideCharToMultiByte(CP_ACP, 0, szStatusText, -1, mime_type, sizeof(mime_type)-1, NULL, NULL);
1726         break;
1727     case BINDSTATUS_BEGINDOWNLOADDATA:
1728         if(iface == &objbsc)
1729             CHECK_EXPECT(Obj_OnProgress_BEGINDOWNLOADDATA);
1730         else
1731             CHECK_EXPECT(OnProgress_BEGINDOWNLOADDATA);
1732         ok(szStatusText != NULL, "szStatusText == NULL\n");
1733         if(szStatusText) {
1734             if(filedwl_api) {
1735                 /* FIXME */
1736             }else {
1737                 ok(!lstrcmpW(szStatusText, urls[test_protocol]), "wrong szStatusText %s\n", wine_dbgstr_w(szStatusText));
1738             }
1739         }
1740         if(!bind_to_object)
1741             ok(download_state == BEFORE_DOWNLOAD, "Download state was %d, expected BEFORE_DOWNLOAD\n",
1742                download_state);
1743         download_state = DOWNLOADING;
1744         break;
1745     case BINDSTATUS_DOWNLOADINGDATA:
1746         CHECK_EXPECT2(OnProgress_DOWNLOADINGDATA);
1747         ok(iface != &objbsc, "unexpected call\n");
1748         ok(download_state == DOWNLOADING, "Download state was %d, expected DOWNLOADING\n",
1749            download_state);
1750         if(test_abort) {
1751             HRESULT hres;
1752
1753             SET_EXPECT(Abort);
1754             hres = IBinding_Abort(current_binding);
1755             ok(hres == S_OK, "Abort failed: %08x\n", hres);
1756             CHECK_CALLED(Abort);
1757
1758             hres = IBinding_Abort(current_binding);
1759             ok(hres == E_FAIL, "Abort failed: %08x\n", hres);
1760
1761             binding_hres = E_ABORT;
1762         }
1763         break;
1764     case BINDSTATUS_ENDDOWNLOADDATA:
1765         if(iface == &objbsc)
1766             CHECK_EXPECT(Obj_OnProgress_ENDDOWNLOADDATA);
1767         else
1768             CHECK_EXPECT(OnProgress_ENDDOWNLOADDATA);
1769         ok(szStatusText != NULL, "szStatusText == NULL\n");
1770         if(szStatusText) {
1771             if(filedwl_api) {
1772                 /* FIXME */
1773             }else {
1774                 ok(!lstrcmpW(szStatusText, urls[test_protocol]), "wrong szStatusText %s\n", wine_dbgstr_w(szStatusText));
1775             }
1776         }
1777         ok(download_state == DOWNLOADING, "Download state was %d, expected DOWNLOADING\n",
1778            download_state);
1779         download_state = END_DOWNLOAD;
1780         break;
1781     case BINDSTATUS_CACHEFILENAMEAVAILABLE:
1782         if(test_protocol != HTTP_TEST && test_protocol != HTTPS_TEST && test_protocol != WINETEST_TEST) {
1783             if(iface == &objbsc)
1784                 CHECK_EXPECT(Obj_OnProgress_CACHEFILENAMEAVAILABLE);
1785             else
1786                 CHECK_EXPECT(OnProgress_CACHEFILENAMEAVAILABLE);
1787         }else {  /* FIXME */
1788             CLEAR_CALLED(OnProgress_CACHEFILENAMEAVAILABLE);
1789             CLEAR_CALLED(Obj_OnProgress_CACHEFILENAMEAVAILABLE);
1790         }
1791
1792         ok(szStatusText != NULL, "szStatusText == NULL\n");
1793         if(szStatusText && test_protocol == FILE_TEST)
1794             ok(!lstrcmpW(file_url+8, szStatusText), "wrong szStatusText %s\n", wine_dbgstr_w(szStatusText));
1795         break;
1796     case BINDSTATUS_CLASSIDAVAILABLE:
1797     {
1798         CLSID clsid;
1799         HRESULT hr;
1800         if(iface != &objbsc)
1801             ok(0, "unexpected call\n");
1802         else
1803             CHECK_EXPECT(Obj_OnProgress_CLASSIDAVAILABLE);
1804         hr = CLSIDFromString((LPCOLESTR)szStatusText, &clsid);
1805         ok(hr == S_OK, "CLSIDFromString failed with error 0x%08x\n", hr);
1806         ok(IsEqualCLSID(&clsid, &CLSID_HTMLDocument),
1807             "Expected clsid to be CLSID_HTMLDocument instead of %s\n", debugstr_guid(&clsid));
1808         break;
1809     }
1810     case BINDSTATUS_BEGINSYNCOPERATION:
1811         CHECK_EXPECT(Obj_OnProgress_BEGINSYNCOPERATION);
1812         if(iface != &objbsc)
1813             ok(0, "unexpected call\n");
1814         ok(szStatusText == NULL, "Expected szStatusText to be NULL\n");
1815         break;
1816     case BINDSTATUS_ENDSYNCOPERATION:
1817         CHECK_EXPECT(Obj_OnProgress_ENDSYNCOPERATION);
1818         if(iface != &objbsc)
1819             ok(0, "unexpected call\n");
1820         ok(szStatusText == NULL, "Expected szStatusText to be NULL\n");
1821         break;
1822     case BINDSTATUS_PROXYDETECTING:
1823         trace("BINDSTATUS_PROXYDETECTING\n");
1824         break;
1825     case BINDSTATUS_COOKIE_SENT:
1826         trace("BINDSTATUS_COOKIE_SENT\n");
1827         break;
1828     default:
1829         ok(0, "unexpected code %d\n", ulStatusCode);
1830     };
1831
1832     if(current_binding) {
1833         IWinInetHttpInfo *http_info;
1834         HRESULT hres;
1835
1836         hres = IBinding_QueryInterface(current_binding, &IID_IWinInetHttpInfo, (void**)&http_info);
1837         if(!emulate_protocol && test_protocol != FILE_TEST && is_urlmon_protocol(test_protocol)) {
1838             ok(hres == S_OK, "Could not get IWinInetHttpInfo iface: %08x\n", hres);
1839             test_WinInetHttpInfo(http_info, ulStatusCode);
1840         } else
1841             ok(hres == E_NOINTERFACE,
1842                "QueryInterface(IID_IWinInetHttpInfo) returned: %08x, expected E_NOINTERFACE\n", hres);
1843         if(SUCCEEDED(hres))
1844             IWinInetHttpInfo_Release(http_info);
1845     }
1846
1847     return S_OK;
1848 }
1849
1850 static HRESULT WINAPI statusclb_OnStopBinding(IBindStatusCallbackEx *iface, HRESULT hresult, LPCWSTR szError)
1851 {
1852     if(iface == &objbsc) {
1853         CHECK_EXPECT(Obj_OnStopBinding);
1854         stopped_obj_binding = TRUE;
1855     }else {
1856         CHECK_EXPECT(OnStopBinding);
1857         stopped_binding = TRUE;
1858     }
1859
1860     ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
1861
1862     if(only_check_prot_args) {
1863         todo_wine ok(hresult == S_OK, "Got %08x\n", hresult);
1864         return S_OK;
1865     }
1866
1867     /* ignore DNS failure */
1868     if (hresult == HRESULT_FROM_WIN32(ERROR_INTERNET_NAME_NOT_RESOLVED))
1869         return S_OK;
1870
1871     if(filedwl_api) {
1872         if(!abort_progress && !abort_start)
1873             ok(SUCCEEDED(hresult), "binding failed: %08x\n", hresult);
1874         else if(abort_start && abort_hres == E_NOTIMPL)
1875             todo_wine ok(hresult == S_FALSE, "binding failed: %08x, expected S_FALSE\n", hresult);
1876         else
1877             ok(hresult == E_ABORT, "binding failed: %08x, expected E_ABORT\n", hresult);
1878     } else
1879         ok(hresult == binding_hres, "binding failed: %08x, expected %08x\n", hresult, binding_hres);
1880     ok(szError == NULL, "szError should be NULL\n");
1881
1882     if(current_binding) {
1883         CLSID clsid;
1884         DWORD res;
1885         LPOLESTR res_str;
1886         HRESULT hres;
1887
1888         hres = IBinding_GetBindResult(current_binding, &clsid, &res, &res_str, NULL);
1889         ok(hres == S_OK, "GetBindResult failed: %08x, expected S_OK\n", hres);
1890         ok(res == hresult, "res = %08x, expected %08x\n", res, binding_hres);
1891         ok(!res_str, "incorrect res_str = %s\n", wine_dbgstr_w(res_str));
1892
1893         if(hresult==S_OK || (abort_start && hresult!=S_FALSE)) {
1894             ok(IsEqualCLSID(&clsid, &CLSID_NULL),
1895                     "incorrect protocol CLSID: %s, expected CLSID_NULL\n",
1896                     debugstr_guid(&clsid));
1897         }else if(emulate_protocol) {
1898             todo_wine ok(IsEqualCLSID(&clsid, &CLSID_FtpProtocol),
1899                     "incorrect protocol CLSID: %s, expected CLSID_FtpProtocol\n",
1900                     debugstr_guid(&clsid));
1901         }else if(test_protocol == FTP_TEST) {
1902             ok(IsEqualCLSID(&clsid, &CLSID_FtpProtocol),
1903                     "incorrect protocol CLSID: %s, expected CLSID_FtpProtocol\n",
1904                     debugstr_guid(&clsid));
1905         }else if(test_protocol == FILE_TEST) {
1906             ok(IsEqualCLSID(&clsid, &CLSID_FileProtocol),
1907                     "incorrect protocol CLSID: %s, expected CLSID_FileProtocol\n",
1908                     debugstr_guid(&clsid));
1909         }else if(test_protocol == HTTP_TEST) {
1910             ok(IsEqualCLSID(&clsid, &CLSID_HttpProtocol),
1911                     "incorrect protocol CLSID: %s, expected CLSID_HttpProtocol\n",
1912                     debugstr_guid(&clsid));
1913         }else if(test_protocol == HTTPS_TEST) {
1914             ok(IsEqualCLSID(&clsid, &CLSID_HttpSProtocol),
1915                     "incorrect protocol CLSID: %s, expected CLSID_HttpSProtocol\n",
1916                     debugstr_guid(&clsid));
1917         }else if(test_protocol == ABOUT_TEST) {
1918             ok(IsEqualCLSID(&clsid, &CLSID_AboutProtocol),
1919                     "incorrect protocol CLSID: %s, expected CLSID_AboutProtocol\n",
1920                     debugstr_guid(&clsid));
1921         }else {
1922             ok(0, "unexpected (%d)\n", test_protocol);
1923         }
1924     }
1925
1926     if((test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST) && emulate_protocol) {
1927         SetEvent(complete_event);
1928         if(iface != &objbsc)
1929             WaitForSingleObject(complete_event2, INFINITE);
1930     }
1931
1932     return S_OK;
1933 }
1934
1935 static HRESULT WINAPI statusclb_GetBindInfo(IBindStatusCallbackEx *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
1936 {
1937     DWORD cbSize;
1938
1939     if(iface == &objbsc)
1940         CHECK_EXPECT(Obj_GetBindInfo);
1941     else
1942         CHECK_EXPECT(GetBindInfo);
1943
1944     ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
1945
1946     *grfBINDF = bindf;
1947     cbSize = pbindinfo->cbSize;
1948     memset(pbindinfo, 0, cbSize);
1949     pbindinfo->cbSize = cbSize;
1950
1951     return S_OK;
1952 }
1953
1954 static HRESULT WINAPI statusclb_OnDataAvailable(IBindStatusCallbackEx *iface, DWORD grfBSCF,
1955         DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
1956 {
1957     HRESULT hres;
1958     DWORD readed;
1959     BYTE buf[512];
1960     CHAR clipfmt[512];
1961
1962     if(iface == &objbsc)
1963         ok(0, "unexpected call\n");
1964
1965     CHECK_EXPECT2(OnDataAvailable);
1966
1967     ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
1968
1969     ok(download_state == DOWNLOADING || download_state == END_DOWNLOAD,
1970        "Download state was %d, expected DOWNLOADING or END_DOWNLOAD\n",
1971        download_state);
1972     data_available = TRUE;
1973
1974     if(bind_to_object && !is_async_prot)
1975         ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION), "grfBSCF = %x\n", grfBSCF);
1976
1977     ok(pformatetc != NULL, "pformatetx == NULL\n");
1978     if(pformatetc) {
1979         if (mime_type[0]) {
1980             INT ret;
1981             clipfmt[0] = 0;
1982             ret = GetClipboardFormatName(pformatetc->cfFormat, clipfmt, sizeof(clipfmt)-1);
1983             ok(ret, "GetClipboardFormatName failed, error %d\n", GetLastError());
1984             ok(!lstrcmp(clipfmt, mime_type), "clipformat %x != mime_type, \"%s\" != \"%s\"\n",
1985                pformatetc->cfFormat, clipfmt, mime_type);
1986         } else {
1987             ok(pformatetc->cfFormat == 0, "clipformat=%x\n", pformatetc->cfFormat);
1988         }
1989         ok(pformatetc->ptd == NULL, "ptd = %p\n", pformatetc->ptd);
1990         ok(pformatetc->dwAspect == 1, "dwAspect=%u\n", pformatetc->dwAspect);
1991         ok(pformatetc->lindex == -1, "lindex=%d\n", pformatetc->lindex);
1992         ok(pformatetc->tymed == tymed, "tymed=%u, expected %u\n", pformatetc->tymed, tymed);
1993     }
1994
1995     ok(pstgmed != NULL, "stgmeg == NULL\n");
1996     ok(pstgmed->tymed == tymed, "tymed=%u, expected %u\n", pstgmed->tymed, tymed);
1997     ok(pstgmed->pUnkForRelease != NULL, "pUnkForRelease == NULL\n");
1998
1999     switch(pstgmed->tymed) {
2000     case TYMED_ISTREAM:
2001         if(grfBSCF & BSCF_FIRSTDATANOTIFICATION) {
2002             STATSTG stat;
2003
2004             hres = IStream_Write(U(*pstgmed).pstm, buf, 10, NULL);
2005             ok(hres == STG_E_ACCESSDENIED,
2006                "Write failed: %08x, expected STG_E_ACCESSDENIED\n", hres);
2007
2008             hres = IStream_Commit(U(*pstgmed).pstm, 0);
2009             ok(hres == E_NOTIMPL, "Commit failed: %08x, expected E_NOTIMPL\n", hres);
2010
2011             hres = IStream_Revert(U(*pstgmed).pstm);
2012             ok(hres == E_NOTIMPL, "Revert failed: %08x, expected E_NOTIMPL\n", hres);
2013
2014             hres = IStream_Stat(U(*pstgmed).pstm, NULL, STATFLAG_NONAME);
2015             ok(hres == E_FAIL, "hres = %x\n", hres);
2016             if(use_cache_file && emulate_protocol) {
2017                 hres = IStream_Stat(U(*pstgmed).pstm, &stat, STATFLAG_DEFAULT);
2018                 ok(hres == S_OK, "hres = %x\n", hres);
2019                 ok(!lstrcmpW(stat.pwcsName, cache_file_name),
2020                         "stat.pwcsName = %s, cache_file_name = %s\n",
2021                         wine_dbgstr_w(stat.pwcsName), wine_dbgstr_w(cache_file_name));
2022                 CoTaskMemFree(stat.pwcsName);
2023                 ok(U(stat.cbSize).LowPart == (bindf&BINDF_ASYNCHRONOUS?0:6500),
2024                         "stat.cbSize.LowPart = %u\n", U(stat.cbSize).LowPart);
2025             } else {
2026                 hres = IStream_Stat(U(*pstgmed).pstm, &stat, STATFLAG_NONAME);
2027                 ok(hres == S_OK, "hres = %x\n", hres);
2028                 ok(!stat.pwcsName || broken(stat.pwcsName!=NULL),
2029                         "stat.pwcsName = %s\n", wine_dbgstr_w(stat.pwcsName));
2030             }
2031             ok(stat.type == STGTY_STREAM, "stat.type = %x\n", stat.type);
2032             ok(U(stat.cbSize).HighPart == 0, "stat.cbSize.HighPart != 0\n");
2033             ok(stat.grfMode == (U(stat.cbSize).LowPart?GENERIC_READ:0), "stat.grfMode = %x\n", stat.grfMode);
2034             ok(stat.grfLocksSupported == 0, "stat.grfLocksSupported = %x\n", stat.grfLocksSupported);
2035             ok(stat.grfStateBits == 0, "stat.grfStateBits = %x\n", stat.grfStateBits);
2036             ok(stat.reserved == 0, "stat.reserved = %x\n", stat.reserved);
2037         }
2038
2039         ok(U(*pstgmed).pstm != NULL, "U(*pstgmed).pstm == NULL\n");
2040         if(callback_read) {
2041             do {
2042                 hres = IStream_Read(U(*pstgmed).pstm, buf, 512, &readed);
2043                 if(test_protocol == HTTP_TEST && emulate_protocol && readed)
2044                     ok(buf[0] == (use_cache_file && !(bindf&BINDF_ASYNCHRONOUS) ? 'X' : '?'), "buf[0] = '%c'\n", buf[0]);
2045             }while(hres == S_OK);
2046             ok(hres == S_FALSE || hres == E_PENDING, "IStream_Read returned %08x\n", hres);
2047         }
2048         break;
2049
2050     case TYMED_FILE:
2051         if(test_protocol == FILE_TEST)
2052             ok(!lstrcmpW(pstgmed->u.lpszFileName, INDEX_HTML+7),
2053                "unexpected file name %s\n", wine_dbgstr_w(pstgmed->u.lpszFileName));
2054         else if(emulate_protocol)
2055             ok(!lstrcmpW(pstgmed->u.lpszFileName, cache_fileW),
2056                "unexpected file name %s\n", wine_dbgstr_w(pstgmed->u.lpszFileName));
2057         else
2058             ok(pstgmed->u.lpszFileName != NULL, "lpszFileName == NULL\n");
2059     }
2060
2061     if((test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST)
2062        && emulate_protocol && prot_state < 4 && (!bind_to_object || prot_state > 1))
2063         SetEvent(complete_event);
2064
2065     return S_OK;
2066 }
2067
2068 static HRESULT WINAPI statusclb_OnObjectAvailable(IBindStatusCallbackEx *iface, REFIID riid, IUnknown *punk)
2069 {
2070     CHECK_EXPECT(OnObjectAvailable);
2071
2072     if(iface != &objbsc)
2073         ok(0, "unexpected call\n");
2074
2075     ok(IsEqualGUID(&IID_IUnknown, riid), "riid = %s\n", debugstr_guid(riid));
2076     ok(punk != NULL, "punk == NULL\n");
2077
2078     return S_OK;
2079 }
2080
2081 static HRESULT WINAPI statusclb_GetBindInfoEx(IBindStatusCallbackEx *iface, DWORD *grfBINDF, BINDINFO *pbindinfo,
2082         DWORD *grfBINDF2, DWORD *pdwReserved)
2083 {
2084     CHECK_EXPECT(GetBindInfoEx);
2085
2086     ok(grfBINDF != NULL, "grfBINDF == NULL\n");
2087     ok(grfBINDF2 != NULL, "grfBINDF2 == NULL\n");
2088     ok(pbindinfo != NULL, "pbindinfo == NULL\n");
2089     ok(pdwReserved != NULL, "dwReserved == NULL\n");
2090
2091     return S_OK;
2092 }
2093
2094 static const IBindStatusCallbackExVtbl BindStatusCallbackVtbl = {
2095     statusclb_QueryInterface,
2096     statusclb_AddRef,
2097     statusclb_Release,
2098     statusclb_OnStartBinding,
2099     statusclb_GetPriority,
2100     statusclb_OnLowResource,
2101     statusclb_OnProgress,
2102     statusclb_OnStopBinding,
2103     statusclb_GetBindInfo,
2104     statusclb_OnDataAvailable,
2105     statusclb_OnObjectAvailable,
2106     statusclb_GetBindInfoEx
2107 };
2108
2109 static IBindStatusCallbackEx bsc = { &BindStatusCallbackVtbl };
2110 static IBindStatusCallbackEx bsc2 = { &BindStatusCallbackVtbl };
2111 static IBindStatusCallbackEx objbsc = { &BindStatusCallbackVtbl };
2112
2113 static HRESULT WINAPI MonikerProp_QueryInterface(IMonikerProp *iface, REFIID riid, void **ppv)
2114 {
2115     *ppv = NULL;
2116     ok(0, "unexpected riid %s\n", debugstr_guid(riid));
2117     return E_NOINTERFACE;
2118 }
2119
2120 static ULONG WINAPI MonikerProp_AddRef(IMonikerProp *iface)
2121 {
2122     return 2;
2123 }
2124
2125 static ULONG WINAPI MonikerProp_Release(IMonikerProp *iface)
2126 {
2127     return 1;
2128 }
2129
2130 static HRESULT WINAPI MonikerProp_PutProperty(IMonikerProp *iface, MONIKERPROPERTY mkp, LPCWSTR val)
2131 {
2132     switch(mkp) {
2133     case MIMETYPEPROP:
2134         CHECK_EXPECT(PutProperty_MIMETYPEPROP);
2135         ok(!lstrcmpW(val, wszTextHtml), "val = %s\n", wine_dbgstr_w(val));
2136         break;
2137     case CLASSIDPROP:
2138         CHECK_EXPECT(PutProperty_CLASSIDPROP);
2139         break;
2140     default:
2141         break;
2142     }
2143
2144     return S_OK;
2145 }
2146
2147 static const IMonikerPropVtbl MonikerPropVtbl = {
2148     MonikerProp_QueryInterface,
2149     MonikerProp_AddRef,
2150     MonikerProp_Release,
2151     MonikerProp_PutProperty
2152 };
2153
2154 static IMonikerProp MonikerProp = { &MonikerPropVtbl };
2155
2156 static HRESULT WINAPI PersistMoniker_QueryInterface(IPersistMoniker *iface, REFIID riid, void **ppv)
2157 {
2158     *ppv = NULL;
2159
2160     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IPersistMoniker, riid))
2161         *ppv = iface;
2162     else if(IsEqualGUID(&IID_IMonikerProp, riid))
2163         *ppv = &MonikerProp;
2164
2165     if(*ppv)
2166         return S_OK;
2167
2168     ok(0, "unexpected riid %s\n", debugstr_guid(riid));
2169     return E_NOINTERFACE;
2170 }
2171
2172 static ULONG WINAPI PersistMoniker_AddRef(IPersistMoniker *iface)
2173 {
2174     return 2;
2175 }
2176
2177 static ULONG WINAPI PersistMoniker_Release(IPersistMoniker *iface)
2178 {
2179     return 1;
2180 }
2181
2182 static HRESULT WINAPI PersistMoniker_GetClassID(IPersistMoniker *iface, CLSID *pClassID)
2183 {
2184     ok(0, "unexpected call\n");
2185     return E_NOTIMPL;
2186 }
2187
2188 static HRESULT WINAPI PersistMoniker_IsDirty(IPersistMoniker *iface)
2189 {
2190     ok(0, "unexpected call\n");
2191     return E_NOTIMPL;
2192 }
2193
2194 static HRESULT WINAPI PersistMoniker_Load(IPersistMoniker *iface, BOOL fFullyAvailable,
2195                                           IMoniker *pimkName, LPBC pibc, DWORD grfMode)
2196 {
2197     IUnknown *unk;
2198     HRESULT hres;
2199
2200     static WCHAR cbinding_contextW[] =
2201         {'C','B','i','n','d','i','n','g',' ','C','o','n','t','e','x','t',0};
2202
2203     CHECK_EXPECT(Load);
2204     ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
2205
2206     if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
2207         ok(!fFullyAvailable, "fFullyAvailable = %x\n", fFullyAvailable);
2208     else
2209         ok(fFullyAvailable, "fFullyAvailable = %x\n", fFullyAvailable);
2210     ok(pimkName != NULL, "pimkName == NULL\n");
2211     ok(pibc != NULL, "pibc == NULL\n");
2212     ok(grfMode == 0x12, "grfMode = %x\n", grfMode);
2213
2214     hres = IBindCtx_GetObjectParam(pibc, cbinding_contextW, &unk);
2215     ok(hres == S_OK, "GetObjectParam(CBinding Context) failed: %08x\n", hres);
2216     if(SUCCEEDED(hres)) {
2217         IBinding *binding;
2218
2219         hres = IUnknown_QueryInterface(unk, &IID_IBinding, (void**)&binding);
2220         ok(hres == S_OK, "Could not get IBinding: %08x\n", hres);
2221
2222         IBinding_Release(binding);
2223         IUnknown_Release(unk);
2224     }
2225
2226     SET_EXPECT(QueryInterface_IServiceProvider);
2227     hres = RegisterBindStatusCallback(pibc, (IBindStatusCallback*)&bsc, NULL, 0);
2228     ok(hres == S_OK, "RegisterBindStatusCallback failed: %08x\n", hres);
2229     CHECK_CALLED(QueryInterface_IServiceProvider);
2230
2231     SET_EXPECT(QueryInterface_IBindStatusCallbackEx);
2232     SET_EXPECT(GetBindInfo);
2233     SET_EXPECT(OnStartBinding);
2234     if(test_redirect)
2235         SET_EXPECT(OnProgress_REDIRECTING);
2236     SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
2237     if(test_protocol == FILE_TEST)
2238         SET_EXPECT(OnProgress_CACHEFILENAMEAVAILABLE);
2239     if(test_protocol != HTTP_TEST && test_protocol != HTTPS_TEST)
2240         SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
2241     SET_EXPECT(LockRequest);
2242     SET_EXPECT(OnDataAvailable);
2243     if(test_protocol != HTTP_TEST && test_protocol != HTTPS_TEST)
2244         SET_EXPECT(OnStopBinding);
2245
2246     hres = IMoniker_BindToStorage(pimkName, pibc, NULL, &IID_IStream, (void**)&unk);
2247     ok(hres == S_OK, "Load failed: %08x\n", hres);
2248
2249     CLEAR_CALLED(QueryInterface_IBindStatusCallbackEx); /* IE 8 */
2250     CHECK_CALLED(GetBindInfo);
2251     CHECK_CALLED(OnStartBinding);
2252     if(test_redirect)
2253         CHECK_CALLED(OnProgress_REDIRECTING);
2254     CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
2255     if(test_protocol == FILE_TEST)
2256         CHECK_CALLED(OnProgress_CACHEFILENAMEAVAILABLE);
2257     if(test_protocol != HTTP_TEST && test_protocol != HTTPS_TEST)
2258         CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
2259     CHECK_CALLED(LockRequest);
2260     CHECK_CALLED(OnDataAvailable);
2261     if(test_protocol != HTTP_TEST && test_protocol != HTTPS_TEST)
2262         CHECK_CALLED(OnStopBinding);
2263
2264     if(unk)
2265         IUnknown_Release(unk);
2266
2267     return S_OK;
2268 }
2269
2270 static HRESULT WINAPI PersistMoniker_Save(IPersistMoniker *iface, IMoniker *pimkName, LPBC pbc, BOOL fRemember)
2271 {
2272     ok(0, "unexpected call\n");
2273     return E_NOTIMPL;
2274 }
2275
2276 static HRESULT WINAPI PersistMoniker_SaveCompleted(IPersistMoniker *iface, IMoniker *pimkName, LPBC pibc)
2277 {
2278     ok(0, "unexpected call\n");
2279     return E_NOTIMPL;
2280 }
2281
2282 static HRESULT WINAPI PersistMoniker_GetCurMoniker(IPersistMoniker *iface, IMoniker **pimkName)
2283 {
2284     ok(0, "unexpected call\n");
2285     return E_NOTIMPL;
2286 }
2287
2288 static const IPersistMonikerVtbl PersistMonikerVtbl = {
2289     PersistMoniker_QueryInterface,
2290     PersistMoniker_AddRef,
2291     PersistMoniker_Release,
2292     PersistMoniker_GetClassID,
2293     PersistMoniker_IsDirty,
2294     PersistMoniker_Load,
2295     PersistMoniker_Save,
2296     PersistMoniker_SaveCompleted,
2297     PersistMoniker_GetCurMoniker
2298 };
2299
2300 static IPersistMoniker PersistMoniker = { &PersistMonikerVtbl };
2301
2302 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
2303 {
2304     *ppv = NULL;
2305
2306     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) {
2307         *ppv = iface;
2308         return S_OK;
2309     }
2310
2311     if(IsEqualGUID(&IID_IMarshal, riid))
2312         return E_NOINTERFACE;
2313     if(IsEqualGUID(&CLSID_IdentityUnmarshal, riid))
2314         return E_NOINTERFACE;
2315
2316     ok(0, "unexpected riid %s\n", debugstr_guid(riid));
2317     return E_NOTIMPL;
2318 }
2319
2320 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
2321 {
2322     return 2;
2323 }
2324
2325 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
2326 {
2327     return 1;
2328 }
2329
2330 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
2331 {
2332     CHECK_EXPECT(CreateInstance);
2333     ok(!outer, "outer = %p\n", outer);
2334     ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", debugstr_guid(riid));
2335     *ppv = &PersistMoniker;
2336     return S_OK;
2337 }
2338
2339 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
2340 {
2341     ok(0, "unexpected call\n");
2342     return S_OK;
2343 }
2344
2345 static const IClassFactoryVtbl ClassFactoryVtbl = {
2346     ClassFactory_QueryInterface,
2347     ClassFactory_AddRef,
2348     ClassFactory_Release,
2349     ClassFactory_CreateInstance,
2350     ClassFactory_LockServer
2351 };
2352
2353 static IClassFactory mime_cf = { &ClassFactoryVtbl };
2354
2355 static HRESULT WINAPI ProtocolCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
2356 {
2357     *ppv = NULL;
2358
2359     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) {
2360         *ppv = iface;
2361         return S_OK;
2362     }
2363
2364     if(IsEqualGUID(&IID_IInternetProtocolInfo, riid))
2365         return E_NOINTERFACE;
2366
2367     ok(0, "unexpected riid %s\n", debugstr_guid(riid));
2368     return E_NOTIMPL;
2369 }
2370
2371 static HRESULT WINAPI ProtocolCF_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
2372 {
2373     if(IsEqualGUID(&IID_IInternetProtocolInfo, riid))
2374         return E_NOINTERFACE;
2375
2376     todo_wine ok(outer != NULL, "outer == NULL\n");
2377     todo_wine ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", debugstr_guid(riid));
2378     *ppv = &Protocol;
2379     return S_OK;
2380 }
2381
2382 static const IClassFactoryVtbl ProtocolCFVtbl = {
2383     ProtocolCF_QueryInterface,
2384     ClassFactory_AddRef,
2385     ClassFactory_Release,
2386     ProtocolCF_CreateInstance,
2387     ClassFactory_LockServer
2388 };
2389
2390 static IClassFactory protocol_cf = { &ProtocolCFVtbl };
2391
2392 static void test_CreateAsyncBindCtx(void)
2393 {
2394     IBindCtx *bctx = (IBindCtx*)0x0ff00ff0;
2395     IUnknown *unk;
2396     HRESULT hres;
2397     ULONG ref;
2398     BIND_OPTS bindopts;
2399
2400     hres = CreateAsyncBindCtx(0, NULL, NULL, &bctx);
2401     ok(hres == E_INVALIDARG, "CreateAsyncBindCtx failed. expected: E_INVALIDARG, got: %08x\n", hres);
2402     ok(bctx == (IBindCtx*)0x0ff00ff0, "bctx should not be changed\n");
2403
2404     hres = CreateAsyncBindCtx(0, NULL, NULL, NULL);
2405     ok(hres == E_INVALIDARG, "CreateAsyncBindCtx failed. expected: E_INVALIDARG, got: %08x\n", hres);
2406
2407     SET_EXPECT(QueryInterface_IServiceProvider);
2408     hres = CreateAsyncBindCtx(0, (IBindStatusCallback*)&bsc, NULL, &bctx);
2409     ok(hres == S_OK, "CreateAsyncBindCtx failed: %08x\n", hres);
2410     CHECK_CALLED(QueryInterface_IServiceProvider);
2411
2412     bindopts.cbStruct = sizeof(bindopts);
2413     hres = IBindCtx_GetBindOptions(bctx, &bindopts);
2414     ok(hres == S_OK, "IBindCtx_GetBindOptions failed: %08x\n", hres);
2415     ok(bindopts.grfFlags == BIND_MAYBOTHERUSER,
2416                 "bindopts.grfFlags = %08x, expected: BIND_MAYBOTHERUSER\n", bindopts.grfFlags);
2417     ok(bindopts.grfMode == (STGM_READWRITE | STGM_SHARE_EXCLUSIVE),
2418                 "bindopts.grfMode = %08x, expected: STGM_READWRITE | STGM_SHARE_EXCLUSIVE\n",
2419                 bindopts.grfMode);
2420     ok(bindopts.dwTickCountDeadline == 0,
2421                 "bindopts.dwTickCountDeadline = %08x, expected: 0\n", bindopts.dwTickCountDeadline);
2422
2423     hres = IBindCtx_QueryInterface(bctx, &IID_IAsyncBindCtx, (void**)&unk);
2424     ok(hres == E_NOINTERFACE, "QueryInterface(IID_IAsyncBindCtx) failed: %08x, expected E_NOINTERFACE\n", hres);
2425     if(SUCCEEDED(hres))
2426         IUnknown_Release(unk);
2427
2428     ref = IBindCtx_Release(bctx);
2429     ok(ref == 0, "bctx should be destroyed here\n");
2430 }
2431
2432 static void test_CreateAsyncBindCtxEx(void)
2433 {
2434     IBindCtx *bctx = NULL, *bctx2 = NULL, *bctx_arg = NULL;
2435     IUnknown *unk;
2436     BIND_OPTS bindopts;
2437     HRESULT hres;
2438
2439     static WCHAR testW[] = {'t','e','s','t',0};
2440
2441     if (!pCreateAsyncBindCtxEx) {
2442         win_skip("CreateAsyncBindCtxEx not present\n");
2443         return;
2444     }
2445
2446     hres = pCreateAsyncBindCtxEx(NULL, 0, NULL, NULL, NULL, 0);
2447     ok(hres == E_INVALIDARG, "CreateAsyncBindCtx failed: %08x, expected E_INVALIDARG\n", hres);
2448
2449     hres = pCreateAsyncBindCtxEx(NULL, 0, NULL, NULL, &bctx, 0);
2450     ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08x\n", hres);
2451
2452     if(SUCCEEDED(hres)) {
2453         bindopts.cbStruct = sizeof(bindopts);
2454         hres = IBindCtx_GetBindOptions(bctx, &bindopts);
2455         ok(hres == S_OK, "IBindCtx_GetBindOptions failed: %08x\n", hres);
2456         ok(bindopts.grfFlags == BIND_MAYBOTHERUSER,
2457                 "bindopts.grfFlags = %08x, expected: BIND_MAYBOTHERUSER\n", bindopts.grfFlags);
2458         ok(bindopts.grfMode == (STGM_READWRITE | STGM_SHARE_EXCLUSIVE),
2459                 "bindopts.grfMode = %08x, expected: STGM_READWRITE | STGM_SHARE_EXCLUSIVE\n",
2460                 bindopts.grfMode);
2461         ok(bindopts.dwTickCountDeadline == 0,
2462                 "bindopts.dwTickCountDeadline = %08x, expected: 0\n", bindopts.dwTickCountDeadline);
2463
2464         IBindCtx_Release(bctx);
2465     }
2466
2467     CreateBindCtx(0, &bctx_arg);
2468     hres = pCreateAsyncBindCtxEx(NULL, 0, NULL, NULL, &bctx, 0);
2469     ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08x\n", hres);
2470
2471     if(SUCCEEDED(hres)) {
2472         bindopts.cbStruct = sizeof(bindopts);
2473         hres = IBindCtx_GetBindOptions(bctx, &bindopts);
2474         ok(hres == S_OK, "IBindCtx_GetBindOptions failed: %08x\n", hres);
2475         ok(bindopts.grfFlags == BIND_MAYBOTHERUSER,
2476                 "bindopts.grfFlags = %08x, expected: BIND_MAYBOTHERUSER\n", bindopts.grfFlags);
2477         ok(bindopts.grfMode == (STGM_READWRITE | STGM_SHARE_EXCLUSIVE),
2478                 "bindopts.grfMode = %08x, expected: STGM_READWRITE | STGM_SHARE_EXCLUSIVE\n",
2479                 bindopts.grfMode);
2480         ok(bindopts.dwTickCountDeadline == 0,
2481                 "bindopts.dwTickCountDeadline = %08x, expected: 0\n", bindopts.dwTickCountDeadline);
2482
2483         IBindCtx_Release(bctx);
2484     }
2485
2486     IBindCtx_Release(bctx_arg);
2487
2488     SET_EXPECT(QueryInterface_IServiceProvider);
2489     hres = pCreateAsyncBindCtxEx(NULL, 0, (IBindStatusCallback*)&bsc, NULL, &bctx, 0);
2490     ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08x\n", hres);
2491     CHECK_CALLED(QueryInterface_IServiceProvider);
2492
2493     hres = IBindCtx_QueryInterface(bctx, &IID_IAsyncBindCtx, (void**)&unk);
2494     ok(hres == S_OK, "QueryInterface(IID_IAsyncBindCtx) failed: %08x\n", hres);
2495     if(SUCCEEDED(hres))
2496         IUnknown_Release(unk);
2497
2498     IBindCtx_Release(bctx);
2499
2500     hres = CreateBindCtx(0, &bctx2);
2501     ok(hres == S_OK, "CreateBindCtx failed: %08x\n", hres);
2502
2503     hres = pCreateAsyncBindCtxEx(bctx2, 0, NULL, NULL, &bctx, 0);
2504     ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08x\n", hres);
2505
2506     hres = IBindCtx_RegisterObjectParam(bctx2, testW, (IUnknown*)&Protocol);
2507     ok(hres == S_OK, "RegisterObjectParam failed: %08x\n", hres);
2508
2509     hres = IBindCtx_GetObjectParam(bctx, testW, &unk);
2510     ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres);
2511     ok(unk == (IUnknown*)&Protocol, "unexpected unk %p\n", unk);
2512
2513     IBindCtx_Release(bctx);
2514     IBindCtx_Release(bctx2);
2515 }
2516
2517 static void test_GetBindInfoEx(IBindStatusCallback *holder)
2518 {
2519     IBindStatusCallbackEx *bscex;
2520     BINDINFO bindinfo = {sizeof(bindinfo)};
2521     DWORD bindf, bindf2, dw;
2522     HRESULT hres;
2523
2524     hres = IBindStatusCallback_QueryInterface(holder, &IID_IBindStatusCallbackEx, (void**)&bscex);
2525     if(FAILED(hres)) {
2526         win_skip("IBindStatusCallbackEx not supported\n");
2527         return;
2528     }
2529
2530     use_bscex = TRUE;
2531
2532     bindf = 0;
2533     SET_EXPECT(QueryInterface_IBindStatusCallbackEx);
2534     SET_EXPECT(GetBindInfoEx);
2535     hres = IBindStatusCallback_GetBindInfo(holder, &bindf, &bindinfo);
2536     ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2537     CHECK_CALLED(QueryInterface_IBindStatusCallbackEx);
2538     CHECK_CALLED(GetBindInfoEx);
2539
2540     bindf = bindf2 = dw = 0;
2541     SET_EXPECT(QueryInterface_IBindStatusCallbackEx);
2542     SET_EXPECT(GetBindInfoEx);
2543     hres = IBindStatusCallbackEx_GetBindInfoEx(bscex, &bindf, &bindinfo, &bindf2, &dw);
2544     ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2545     CHECK_CALLED(QueryInterface_IBindStatusCallbackEx);
2546     CHECK_CALLED(GetBindInfoEx);
2547
2548     use_bscex = FALSE;
2549
2550     bindf = bindf2 = dw = 0xdeadbeef;
2551     SET_EXPECT(QueryInterface_IBindStatusCallbackEx);
2552     SET_EXPECT(GetBindInfo);
2553     hres = IBindStatusCallbackEx_GetBindInfoEx(bscex, &bindf, &bindinfo, &bindf2, &dw);
2554     ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2555     CHECK_CALLED(QueryInterface_IBindStatusCallbackEx);
2556     CHECK_CALLED(GetBindInfo);
2557     ok(bindf2 == 0xdeadbeef, "bindf2 = %x\n", bindf2);
2558     ok(dw == 0xdeadbeef, "dw = %x\n", dw);
2559
2560     IBindStatusCallbackEx_Release(bscex);
2561 }
2562
2563 static BOOL test_bscholder(IBindStatusCallback *holder)
2564 {
2565     IServiceProvider *serv_prov;
2566     IHttpNegotiate *http_negotiate, *http_negotiate_serv;
2567     IHttpNegotiate2 *http_negotiate2, *http_negotiate2_serv;
2568     IAuthenticate *authenticate, *authenticate_serv;
2569     IInternetProtocol *protocol;
2570     BINDINFO bindinfo = {sizeof(bindinfo)};
2571     BOOL ret = TRUE;
2572     LPWSTR wstr;
2573     DWORD dw;
2574     HRESULT hres;
2575
2576     hres = IBindStatusCallback_QueryInterface(holder, &IID_IServiceProvider, (void**)&serv_prov);
2577     ok(hres == S_OK, "Could not get IServiceProvider interface: %08x\n", hres);
2578
2579     dw = 0xdeadbeef;
2580     SET_EXPECT(QueryInterface_IBindStatusCallbackEx);
2581     SET_EXPECT(GetBindInfo);
2582     hres = IBindStatusCallback_GetBindInfo(holder, &dw, &bindinfo);
2583     ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2584     CLEAR_CALLED(QueryInterface_IBindStatusCallbackEx); /* IE 8 */
2585     CHECK_CALLED(GetBindInfo);
2586
2587     test_GetBindInfoEx(holder);
2588
2589     SET_EXPECT(OnStartBinding);
2590     hres = IBindStatusCallback_OnStartBinding(holder, 0, (void*)0xdeadbeef);
2591     ok(hres == S_OK, "OnStartBinding failed: %08x\n", hres);
2592     CHECK_CALLED(OnStartBinding);
2593
2594     hres = IBindStatusCallback_QueryInterface(holder, &IID_IHttpNegotiate, (void**)&http_negotiate);
2595     ok(hres == S_OK, "Could not get IHttpNegotiate interface: %08x\n", hres);
2596
2597     SET_EXPECT(QueryInterface_IHttpNegotiate);
2598     hres = IServiceProvider_QueryService(serv_prov, &IID_IHttpNegotiate, &IID_IHttpNegotiate,
2599                                          (void**)&http_negotiate_serv);
2600     ok(hres == S_OK, "Could not get IHttpNegotiate service: %08x\n", hres);
2601     CLEAR_CALLED(QueryInterface_IHttpNegotiate); /* IE <8 */
2602
2603     ok(http_negotiate == http_negotiate_serv, "http_negotiate != http_negotiate_serv\n");
2604
2605     wstr = (void*)0xdeadbeef;
2606     SET_EXPECT(QueryInterface_IHttpNegotiate);
2607     SET_EXPECT(BeginningTransaction);
2608     hres = IHttpNegotiate_BeginningTransaction(http_negotiate_serv, urls[test_protocol], emptyW, 0, &wstr);
2609     CHECK_CALLED_BROKEN(QueryInterface_IHttpNegotiate); /* IE8 */
2610     CHECK_CALLED(BeginningTransaction);
2611     ok(hres == S_OK, "BeginningTransaction failed: %08x\n", hres);
2612     ok(wstr == NULL, "wstr = %p\n", wstr);
2613
2614     IHttpNegotiate_Release(http_negotiate_serv);
2615
2616     hres = IServiceProvider_QueryService(serv_prov, &IID_IHttpNegotiate, &IID_IHttpNegotiate,
2617                                          (void**)&http_negotiate_serv);
2618     ok(hres == S_OK, "Could not get IHttpNegotiate service: %08x\n", hres);
2619     ok(http_negotiate == http_negotiate_serv, "http_negotiate != http_negotiate_serv\n");
2620     IHttpNegotiate_Release(http_negotiate_serv);
2621
2622     hres = IBindStatusCallback_QueryInterface(holder, &IID_IHttpNegotiate2, (void**)&http_negotiate2);
2623     if(SUCCEEDED(hres)) {
2624         have_IHttpNegotiate2 = TRUE;
2625
2626         SET_EXPECT(QueryInterface_IHttpNegotiate2);
2627         hres = IServiceProvider_QueryService(serv_prov, &IID_IHttpNegotiate2, &IID_IHttpNegotiate2,
2628                                              (void**)&http_negotiate2_serv);
2629         ok(hres == S_OK, "Could not get IHttpNegotiate2 service: %08x\n", hres);
2630         CLEAR_CALLED(QueryInterface_IHttpNegotiate2); /* IE <8 */
2631         ok(http_negotiate2 == http_negotiate2_serv, "http_negotiate != http_negotiate_serv\n");
2632
2633         SET_EXPECT(QueryInterface_IHttpNegotiate2);
2634         SET_EXPECT(GetRootSecurityId);
2635         hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, (void*)0xdeadbeef, (void*)0xdeadbeef, 0);
2636         ok(hres == E_NOTIMPL, "GetRootSecurityId failed: %08x\n", hres);
2637         CHECK_CALLED_BROKEN(QueryInterface_IHttpNegotiate2); /* IE8 */
2638         CHECK_CALLED(GetRootSecurityId);
2639
2640         IHttpNegotiate_Release(http_negotiate2_serv);
2641         IHttpNegotiate_Release(http_negotiate2);
2642     }else {
2643         skip("Could not get IHttpNegotiate2\n");
2644         ret = FALSE;
2645     }
2646
2647     SET_EXPECT(OnProgress_FINDINGRESOURCE);
2648     hres = IBindStatusCallback_OnProgress(holder, 0, 0, BINDSTATUS_FINDINGRESOURCE, NULL);
2649     ok(hres == S_OK, "OnProgress failed: %08x\n", hres);
2650     CHECK_CALLED(OnProgress_FINDINGRESOURCE);
2651
2652     SET_EXPECT(QueryInterface_IHttpNegotiate);
2653     SET_EXPECT(OnResponse);
2654     wstr = (void*)0xdeadbeef;
2655     hres = IHttpNegotiate_OnResponse(http_negotiate, 200, emptyW, NULL, NULL);
2656     ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
2657     CHECK_CALLED_BROKEN(QueryInterface_IHttpNegotiate); /* IE8 */
2658     CHECK_CALLED(OnResponse);
2659
2660     IHttpNegotiate_Release(http_negotiate);
2661
2662     hres = IBindStatusCallback_QueryInterface(holder, &IID_IAuthenticate, (void**)&authenticate);
2663     ok(hres == S_OK, "Could not get IAuthenticate interface: %08x\n", hres);
2664
2665     SET_EXPECT(QueryInterface_IAuthenticate);
2666     SET_EXPECT(QueryService_IAuthenticate);
2667     hres = IServiceProvider_QueryService(serv_prov, &IID_IAuthenticate, &IID_IAuthenticate,
2668                                          (void**)&authenticate_serv);
2669     ok(hres == S_OK, "Could not get IAuthenticate service: %08x\n", hres);
2670     CLEAR_CALLED(QueryInterface_IAuthenticate); /* IE <8 */
2671     CLEAR_CALLED(QueryService_IAuthenticate); /* IE <8 */
2672     ok(authenticate == authenticate_serv, "authenticate != authenticate_serv\n");
2673     IAuthenticate_Release(authenticate_serv);
2674
2675     hres = IServiceProvider_QueryService(serv_prov, &IID_IAuthenticate, &IID_IAuthenticate,
2676                                          (void**)&authenticate_serv);
2677     ok(hres == S_OK, "Could not get IAuthenticate service: %08x\n", hres);
2678     ok(authenticate == authenticate_serv, "authenticate != authenticate_serv\n");
2679
2680     IAuthenticate_Release(authenticate);
2681     IAuthenticate_Release(authenticate_serv);
2682
2683     SET_EXPECT(OnStopBinding);
2684     hres = IBindStatusCallback_OnStopBinding(holder, S_OK, NULL);
2685     ok(hres == S_OK, "OnStopBinding failed: %08x\n", hres);
2686     CHECK_CALLED(OnStopBinding);
2687
2688     SET_EXPECT(QueryInterface_IInternetProtocol);
2689     SET_EXPECT(QueryService_IInternetProtocol);
2690     hres = IServiceProvider_QueryService(serv_prov, &IID_IInternetProtocol, &IID_IInternetProtocol,
2691                                          (void**)&protocol);
2692     ok(hres == E_NOINTERFACE, "QueryService(IInternetProtocol) failed: %08x\n", hres);
2693     CHECK_CALLED(QueryInterface_IInternetProtocol);
2694     CHECK_CALLED(QueryService_IInternetProtocol);
2695
2696     IServiceProvider_Release(serv_prov);
2697     return ret;
2698 }
2699
2700 static BOOL test_RegisterBindStatusCallback(void)
2701 {
2702     IBindStatusCallback *prevbsc, *clb, *prev_clb;
2703     IBindCtx *bindctx;
2704     BOOL ret = TRUE;
2705     IUnknown *unk;
2706     HRESULT hres;
2707
2708     hres = CreateBindCtx(0, &bindctx);
2709     ok(hres == S_OK, "BindCtx failed: %08x\n", hres);
2710
2711     SET_EXPECT(QueryInterface_IServiceProvider);
2712
2713     hres = IBindCtx_RegisterObjectParam(bindctx, BSCBHolder, (IUnknown*)&bsc);
2714     ok(hres == S_OK, "RegisterObjectParam failed: %08x\n", hres);
2715
2716     SET_EXPECT(QueryInterface_IBindStatusCallback);
2717     SET_EXPECT(QueryInterface_IBindStatusCallbackHolder);
2718     prevbsc = (void*)0xdeadbeef;
2719     hres = RegisterBindStatusCallback(bindctx, (IBindStatusCallback*)&bsc, &prevbsc, 0);
2720     ok(hres == S_OK, "RegisterBindStatusCallback failed: %08x\n", hres);
2721     ok(prevbsc == (IBindStatusCallback*)&bsc, "prevbsc=%p\n", prevbsc);
2722     CHECK_CALLED(QueryInterface_IBindStatusCallback);
2723     CHECK_CALLED(QueryInterface_IBindStatusCallbackHolder);
2724
2725     CHECK_CALLED(QueryInterface_IServiceProvider);
2726
2727     hres = IBindCtx_GetObjectParam(bindctx, BSCBHolder, &unk);
2728     ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres);
2729
2730     hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&clb);
2731     IUnknown_Release(unk);
2732     ok(hres == S_OK, "QueryInterface(IID_IBindStatusCallback) failed: %08x\n", hres);
2733     ok(clb != (IBindStatusCallback*)&bsc, "bsc == clb\n");
2734
2735     if(!test_bscholder(clb))
2736         ret = FALSE;
2737
2738     IBindStatusCallback_Release(clb);
2739
2740     hres = RevokeBindStatusCallback(bindctx, (IBindStatusCallback*)&bsc);
2741     ok(hres == S_OK, "RevokeBindStatusCallback failed: %08x\n", hres);
2742
2743     unk = (void*)0xdeadbeef;
2744     hres = IBindCtx_GetObjectParam(bindctx, BSCBHolder, &unk);
2745     ok(hres == E_FAIL, "GetObjectParam failed: %08x\n", hres);
2746     ok(unk == NULL, "unk != NULL\n");
2747
2748     if(unk)
2749         IUnknown_Release(unk);
2750
2751     hres = RevokeBindStatusCallback(bindctx, (void*)0xdeadbeef);
2752     ok(hres == S_OK, "RevokeBindStatusCallback failed: %08x\n", hres);
2753
2754     hres = RevokeBindStatusCallback(NULL, (void*)0xdeadbeef);
2755     ok(hres == E_INVALIDARG, "RevokeBindStatusCallback failed: %08x\n", hres);
2756
2757     hres = RevokeBindStatusCallback(bindctx, NULL);
2758     ok(hres == E_INVALIDARG, "RevokeBindStatusCallback failed: %08x\n", hres);
2759
2760     SET_EXPECT(QueryInterface_IServiceProvider);
2761     prevbsc = (void*)0xdeadbeef;
2762     hres = RegisterBindStatusCallback(bindctx, (IBindStatusCallback*)&bsc, &prevbsc, 0);
2763     ok(hres == S_OK, "RegisterBindStatusCallback failed: %08x\n", hres);
2764     ok(!prevbsc, "prevbsc=%p\n", prevbsc);
2765     CHECK_CALLED(QueryInterface_IServiceProvider);
2766
2767     hres = IBindCtx_GetObjectParam(bindctx, BSCBHolder, &unk);
2768     ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres);
2769
2770     hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&prev_clb);
2771     IUnknown_Release(unk);
2772     ok(hres == S_OK, "QueryInterface(IID_IBindStatusCallback) failed: %08x\n", hres);
2773     ok(prev_clb != (IBindStatusCallback*)&bsc, "bsc == clb\n");
2774
2775     SET_EXPECT(QueryInterface_IServiceProvider);
2776     prevbsc = (void*)0xdeadbeef;
2777     hres = RegisterBindStatusCallback(bindctx, (IBindStatusCallback*)&bsc2, &prevbsc, 0);
2778     ok(hres == S_OK, "RegisterBindStatusCallback failed: %08x\n", hres);
2779     ok(prevbsc == (IBindStatusCallback*)&bsc, "prevbsc != bsc\n");
2780     CHECK_CALLED(QueryInterface_IServiceProvider);
2781
2782     hres = IBindCtx_GetObjectParam(bindctx, BSCBHolder, &unk);
2783     ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres);
2784
2785     hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&clb);
2786     IUnknown_Release(unk);
2787     ok(hres == S_OK, "QueryInterface(IID_IBindStatusCallback) failed: %08x\n", hres);
2788     ok(prev_clb  == clb, "bsc != clb\n");
2789
2790     IBindStatusCallback_Release(clb);
2791     IBindStatusCallback_Release(prev_clb);
2792
2793     IBindCtx_Release(bindctx);
2794     return ret;
2795 }
2796
2797 #define BINDTEST_EMULATE            0x0001
2798 #define BINDTEST_TOOBJECT           0x0002
2799 #define BINDTEST_FILEDWLAPI         0x0004
2800 #define BINDTEST_HTTPRESPONSE       0x0008
2801 #define BINDTEST_REDIRECT           0x0010
2802 #define BINDTEST_USE_CACHE          0x0020
2803 #define BINDTEST_NO_CALLBACK_READ   0x0040
2804 #define BINDTEST_NO_CALLBACK        0x0080
2805 #define BINDTEST_ABORT              0x0100
2806 #define BINDTEST_INVALID_CN         0x0200
2807 #define BINDTEST_ABORT_START        0x0400
2808 #define BINDTEST_ABORT_PROGRESS     0x0800
2809 #define BINDTEST_ASYNC_SWITCH       0x1000
2810
2811 static void init_bind_test(int protocol, DWORD flags, DWORD t)
2812 {
2813     test_protocol = protocol;
2814     emulate_protocol = (flags & BINDTEST_EMULATE) != 0;
2815     download_state = BEFORE_DOWNLOAD;
2816     stopped_binding = FALSE;
2817     stopped_obj_binding = FALSE;
2818     data_available = FALSE;
2819     mime_type[0] = 0;
2820     binding_hres = S_OK;
2821     bind_to_object = (flags & BINDTEST_TOOBJECT) != 0;
2822     tymed = t;
2823     filedwl_api = (flags & BINDTEST_FILEDWLAPI) != 0;
2824     if(flags & BINDTEST_HTTPRESPONSE)
2825         urls[HTTP_TEST] = winetest_post_urlW;
2826     else
2827         urls[HTTP_TEST] = winetest_data_urlW;
2828     if(flags & BINDTEST_INVALID_CN)
2829         urls[HTTPS_TEST] = https_invalid_cn_urlW;
2830     else
2831         urls[HTTPS_TEST] = https_urlW;
2832     test_redirect = (flags & BINDTEST_REDIRECT) != 0;
2833     use_cache_file = (flags & BINDTEST_USE_CACHE) != 0;
2834     callback_read = !(flags & BINDTEST_NO_CALLBACK_READ);
2835     no_callback = (flags & BINDTEST_NO_CALLBACK) != 0;
2836     test_abort = (flags & BINDTEST_ABORT) != 0;
2837     abort_start = (flags & BINDTEST_ABORT_START) != 0;
2838     abort_progress = (flags & BINDTEST_ABORT_PROGRESS) != 0;
2839     async_switch = (flags & BINDTEST_ASYNC_SWITCH) != 0;
2840     is_async_prot = protocol == HTTP_TEST || protocol == HTTPS_TEST || protocol == FTP_TEST || protocol == WINETEST_TEST;
2841     prot_state = 0;
2842     ResetEvent(complete_event);
2843 }
2844
2845 static void test_BindToStorage(int protocol, DWORD flags, DWORD t)
2846 {
2847     IMoniker *mon;
2848     HRESULT hres;
2849     LPOLESTR display_name;
2850     IBindCtx *bctx = NULL;
2851     MSG msg;
2852     IBindStatusCallback *previousclb;
2853     IUnknown *unk = (IUnknown*)0x00ff00ff;
2854     IBinding *bind;
2855
2856     init_bind_test(protocol, flags, t);
2857
2858     if(no_callback) {
2859         hres = CreateBindCtx(0, &bctx);
2860         ok(hres == S_OK, "CreateBindCtx failed: %08x\n", hres);
2861     }else {
2862         SET_EXPECT(QueryInterface_IServiceProvider);
2863         hres = CreateAsyncBindCtx(0, (IBindStatusCallback*)&bsc, NULL, &bctx);
2864         ok(hres == S_OK, "CreateAsyncBindCtx failed: %08x\n\n", hres);
2865         CHECK_CALLED(QueryInterface_IServiceProvider);
2866         if(FAILED(hres))
2867             return;
2868
2869         SET_EXPECT(QueryInterface_IServiceProvider);
2870         hres = RegisterBindStatusCallback(bctx, (IBindStatusCallback*)&bsc, &previousclb, 0);
2871         ok(hres == S_OK, "RegisterBindStatusCallback failed: %08x\n", hres);
2872         ok(previousclb == (IBindStatusCallback*)&bsc, "previousclb(%p) != sclb(%p)\n", previousclb, &bsc);
2873         CHECK_CALLED(QueryInterface_IServiceProvider);
2874         if(previousclb)
2875             IBindStatusCallback_Release(previousclb);
2876     }
2877
2878     hres = CreateURLMoniker(NULL, test_protocol == FILE_TEST ? file_url : urls[test_protocol], &mon);
2879     ok(hres == S_OK, "failed to create moniker: %08x\n", hres);
2880     if(FAILED(hres))
2881         return;
2882
2883     hres = IMoniker_QueryInterface(mon, &IID_IBinding, (void**)&bind);
2884     ok(hres == E_NOINTERFACE, "IMoniker should not have IBinding interface\n");
2885     if(SUCCEEDED(hres))
2886         IBinding_Release(bind);
2887
2888     hres = IMoniker_GetDisplayName(mon, bctx, NULL, &display_name);
2889     ok(hres == S_OK, "GetDisplayName failed %08x\n", hres);
2890     ok(!lstrcmpW(display_name, urls[test_protocol]),
2891        "GetDisplayName got wrong name %s\n", wine_dbgstr_w(display_name));
2892     CoTaskMemFree(display_name);
2893
2894     if(tymed == TYMED_FILE && (test_protocol == ABOUT_TEST || test_protocol == ITS_TEST))
2895         binding_hres = INET_E_DATA_NOT_AVAILABLE;
2896     if((flags & BINDTEST_INVALID_CN) && !invalid_cn_accepted &&
2897        (onsecurityproblem_hres != S_OK || security_problem == ERROR_INTERNET_SEC_CERT_ERRORS)) {
2898         if(security_problem == ERROR_INTERNET_SEC_CERT_ERRORS)
2899             binding_hres = INET_E_SECURITY_PROBLEM;
2900         else
2901             binding_hres = INET_E_INVALID_CERTIFICATE;
2902     }
2903
2904
2905     if(only_check_prot_args)
2906         SET_EXPECT(OnStopBinding);
2907     if(!no_callback) {
2908         SET_EXPECT(QueryInterface_IBindStatusCallbackEx);
2909         SET_EXPECT(GetBindInfo);
2910         SET_EXPECT(QueryInterface_IInternetProtocol);
2911         if(!emulate_protocol)
2912             SET_EXPECT(QueryService_IInternetProtocol);
2913         SET_EXPECT(OnStartBinding);
2914     }
2915     if(emulate_protocol) {
2916         if(is_urlmon_protocol(test_protocol))
2917             SET_EXPECT(SetPriority);
2918         SET_EXPECT(Start);
2919         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST)
2920             SET_EXPECT(Terminate);
2921         if(tymed != TYMED_FILE || (test_protocol != ABOUT_TEST && test_protocol != ITS_TEST))
2922             SET_EXPECT(UnlockRequest);
2923     }else {
2924         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST) {
2925             SET_EXPECT(QueryInterface_IInternetBindInfo);
2926             SET_EXPECT(QueryService_IInternetBindInfo);
2927             if(!abort_start)
2928                 SET_EXPECT(QueryInterface_IHttpNegotiate);
2929             SET_EXPECT(QueryInterface_IWindowForBindingUI);
2930             SET_EXPECT(QueryService_IWindowForBindingUI);
2931             SET_EXPECT(GetWindow_IWindowForBindingUI);
2932             if(!abort_start) {
2933                 SET_EXPECT(BeginningTransaction);
2934                 SET_EXPECT(QueryInterface_IHttpNegotiate2);
2935                 SET_EXPECT(GetRootSecurityId);
2936                 if(http_is_first)
2937                     SET_EXPECT(OnProgress_FINDINGRESOURCE);
2938                 SET_EXPECT(OnProgress_CONNECTING);
2939             }
2940             if(flags & BINDTEST_INVALID_CN) {
2941                 SET_EXPECT(QueryInterface_IHttpSecurity);
2942                 SET_EXPECT(QueryService_IHttpSecurity);
2943                 SET_EXPECT(OnSecurityProblem);
2944                 if(SUCCEEDED(onsecurityproblem_hres))
2945                     SET_EXPECT(GetWindow_IHttpSecurity);
2946             }
2947         }
2948         if(!no_callback) {
2949             if((test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == FTP_TEST
2950                || test_protocol == FILE_TEST || test_protocol == WINETEST_TEST) && !abort_start)
2951                 SET_EXPECT(OnProgress_SENDINGREQUEST);
2952             if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST) {
2953                 SET_EXPECT(QueryInterface_IHttpNegotiate);
2954                 SET_EXPECT(OnResponse);
2955             }
2956             if(!abort_start) {
2957                 SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
2958                 SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
2959             }
2960             if(test_protocol == FILE_TEST)
2961                 SET_EXPECT(OnProgress_CACHEFILENAMEAVAILABLE);
2962             if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == FTP_TEST || test_protocol == WINETEST_TEST)
2963                 SET_EXPECT(OnProgress_DOWNLOADINGDATA);
2964             if(!abort_start)
2965                 SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
2966             if((tymed != TYMED_FILE || test_protocol != ABOUT_TEST) && !abort_start)
2967                 SET_EXPECT(OnDataAvailable);
2968             SET_EXPECT(OnStopBinding);
2969         }
2970     }
2971
2972     hres = IMoniker_BindToStorage(mon, bctx, NULL, tymed == TYMED_ISTREAM ? &IID_IStream : &IID_IUnknown, (void**)&unk);
2973     if ((test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
2974         && hres == HRESULT_FROM_WIN32(ERROR_INTERNET_NAME_NOT_RESOLVED))
2975     {
2976         skip("Network unreachable, skipping tests\n");
2977         return;
2978     }
2979
2980     if(only_check_prot_args) {
2981         ok(hres == E_FAIL, "Got %08x\n", hres);
2982         CHECK_CALLED(OnStopBinding);
2983     } else if(abort_start)
2984         ok(hres == abort_hres, "IMoniker_BindToStorage failed: %08x, expected %08x\n", hres, abort_hres);
2985     else if(abort_progress)
2986         ok(hres == MK_S_ASYNCHRONOUS, "IMoniker_BindToStorage failed: %08x\n", hres);
2987     else if(no_callback) {
2988         if(emulate_protocol)
2989             WaitForSingleObject(complete_event2, INFINITE);
2990         ok(hres == S_OK, "IMoniker_BindToStorage failed: %08x\n", hres);
2991         ok(unk != NULL, "unk == NULL\n");
2992     }else if(!(bindf & BINDF_ASYNCHRONOUS) && tymed == TYMED_FILE) {
2993         ok(hres == S_OK, "IMoniker_BindToStorage failed: %08x\n", hres);
2994         ok(unk == NULL, "unk != NULL\n");
2995     }else if(((bindf & BINDF_ASYNCHRONOUS) && !data_available)
2996        || (tymed == TYMED_FILE && test_protocol == FILE_TEST)) {
2997         ok(hres == MK_S_ASYNCHRONOUS, "IMoniker_BindToStorage failed: %08x\n", hres);
2998         ok(unk == NULL, "istr should be NULL\n");
2999     }else if(tymed == TYMED_FILE && test_protocol == ABOUT_TEST) {
3000         ok(hres == INET_E_DATA_NOT_AVAILABLE,
3001            "IMoniker_BindToStorage failed: %08x, expected INET_E_DATA_NOT_AVAILABLE\n", hres);
3002         ok(unk == NULL, "istr should be NULL\n");
3003     }else if((flags & BINDTEST_INVALID_CN) && binding_hres != S_OK) {
3004         ok(hres == binding_hres, "Got %08x\n", hres);
3005         ok(unk == NULL, "Got %p\n", unk);
3006     }else if((flags & BINDTEST_INVALID_CN) && invalid_cn_accepted) {
3007         ok(hres == S_OK, "IMoniker_BindToStorage failed: %08x\n", hres);
3008         ok(unk != NULL, "unk == NULL\n");
3009         if(unk == NULL) {
3010             ok(0, "Expected security problem to be ignored.\n");
3011             invalid_cn_accepted = FALSE;
3012             binding_hres = INET_E_INVALID_CERTIFICATE;
3013         }
3014     }else {
3015         ok(hres == S_OK, "IMoniker_BindToStorage failed: %08x\n", hres);
3016         ok(unk != NULL, "unk == NULL\n");
3017     }
3018     if(unk && callback_read && !no_callback) {
3019         IUnknown_Release(unk);
3020         unk = NULL;
3021     }
3022
3023     if(FAILED(hres) && !(flags & BINDTEST_INVALID_CN) && !(flags & BINDTEST_ABORT_START))
3024         return;
3025
3026     if((bindf & BINDF_ASYNCHRONOUS) && !no_callback) {
3027         while(!stopped_binding && GetMessage(&msg,NULL,0,0)) {
3028             TranslateMessage(&msg);
3029             DispatchMessage(&msg);
3030         }
3031     }
3032
3033     if(async_switch) {
3034         CHECK_CALLED(OnProgress_SENDINGREQUEST);
3035         CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
3036         CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
3037         CHECK_CALLED(LockRequest);
3038         CHECK_CALLED(OnStopBinding);
3039     }
3040     if(!no_callback) {
3041         CLEAR_CALLED(QueryInterface_IBindStatusCallbackEx); /* IE 8 */
3042         CHECK_CALLED(GetBindInfo);
3043         if(abort_start)
3044             todo_wine CHECK_CALLED(QueryInterface_IInternetProtocol);
3045         else
3046             CHECK_CALLED(QueryInterface_IInternetProtocol);
3047         if(!emulate_protocol) {
3048             if(abort_start)
3049                 todo_wine CHECK_CALLED(QueryService_IInternetProtocol);
3050             else
3051                 CHECK_CALLED(QueryService_IInternetProtocol);
3052         }
3053         CHECK_CALLED(OnStartBinding);
3054     }
3055     if(emulate_protocol) {
3056         if(is_urlmon_protocol(test_protocol))
3057             CHECK_CALLED(SetPriority);
3058         CHECK_CALLED(Start);
3059         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST) {
3060             if(tymed == TYMED_FILE)
3061                 CLEAR_CALLED(Read);
3062             CHECK_CALLED(Terminate);
3063         }
3064         if(tymed != TYMED_FILE || (test_protocol != ABOUT_TEST && test_protocol != ITS_TEST))
3065             CHECK_CALLED(UnlockRequest);
3066     }else {
3067         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST) {
3068             CLEAR_CALLED(QueryInterface_IInternetBindInfo);
3069             CLEAR_CALLED(QueryService_IInternetBindInfo);
3070             if(!abort_start)
3071                 CHECK_CALLED(QueryInterface_IHttpNegotiate);
3072             CLEAR_CALLED(QueryInterface_IWindowForBindingUI);
3073             CLEAR_CALLED(QueryService_IWindowForBindingUI);
3074             CLEAR_CALLED(GetWindow_IWindowForBindingUI);
3075             if(!abort_start)
3076                 CHECK_CALLED(BeginningTransaction);
3077             if (have_IHttpNegotiate2 && !abort_start)
3078             {
3079                 CHECK_CALLED(QueryInterface_IHttpNegotiate2);
3080                 CHECK_CALLED(GetRootSecurityId);
3081             }
3082             if(http_is_first) {
3083                 if (! proxy_active())
3084                 {
3085                     CHECK_CALLED(OnProgress_FINDINGRESOURCE);
3086                     CHECK_CALLED(OnProgress_CONNECTING);
3087                 }
3088                 else
3089                 {
3090                     CLEAR_CALLED(OnProgress_FINDINGRESOURCE);
3091                     CLEAR_CALLED(OnProgress_CONNECTING);
3092                 }
3093             }else if(!abort_start) {
3094                 /* IE7 does call this */
3095                 CLEAR_CALLED(OnProgress_CONNECTING);
3096             }
3097             if((flags & BINDTEST_INVALID_CN) && !invalid_cn_accepted)  {
3098                 CHECK_CALLED(QueryInterface_IHttpSecurity);
3099                 CHECK_CALLED(QueryService_IHttpSecurity);
3100                 CHECK_CALLED(OnSecurityProblem);
3101             }else {
3102                 CHECK_NOT_CALLED(QueryInterface_IHttpSecurity);
3103                 CHECK_NOT_CALLED(QueryService_IHttpSecurity);
3104                 CHECK_NOT_CALLED(OnSecurityProblem);
3105             }
3106         }
3107         if(!no_callback) {
3108             if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == FILE_TEST || test_protocol == WINETEST_TEST) {
3109                 if(flags & BINDTEST_INVALID_CN)
3110                     CLEAR_CALLED(OnProgress_SENDINGREQUEST);
3111                 else if(!abort_start)
3112                     CHECK_CALLED(OnProgress_SENDINGREQUEST);
3113             } else if(test_protocol == FTP_TEST)
3114                 todo_wine CHECK_CALLED(OnProgress_SENDINGREQUEST);
3115             if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST) {
3116                 CLEAR_CALLED(QueryInterface_IHttpNegotiate);
3117                 if((!(flags & BINDTEST_INVALID_CN) || (binding_hres == S_OK)) && !abort_start) {
3118                     CHECK_CALLED(OnResponse);
3119                 }
3120             }
3121             if((!(flags & BINDTEST_INVALID_CN) || binding_hres == S_OK) && !abort_start) {
3122                 CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
3123                 CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
3124                 CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
3125             }
3126             if(test_protocol == FILE_TEST)
3127                 CHECK_CALLED(OnProgress_CACHEFILENAMEAVAILABLE);
3128             if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == FTP_TEST  || test_protocol == WINETEST_TEST)
3129                 CLEAR_CALLED(OnProgress_DOWNLOADINGDATA);
3130             if((flags & BINDTEST_INVALID_CN)) {
3131                 if(binding_hres == S_OK)
3132                     CHECK_CALLED(OnDataAvailable);
3133                 else
3134                     CHECK_NOT_CALLED(OnDataAvailable);
3135             }else if((tymed != TYMED_FILE || test_protocol != ABOUT_TEST) && !abort_start)
3136                 CHECK_CALLED(OnDataAvailable);
3137             CHECK_CALLED(OnStopBinding);
3138         }
3139     }
3140
3141     ok(IMoniker_Release(mon) == 0, "mon should be destroyed here\n");
3142     if(bctx)
3143         ok(IBindCtx_Release(bctx) == 0, "bctx should be destroyed here\n");
3144
3145     if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
3146         http_is_first = FALSE;
3147
3148     if((flags & BINDTEST_INVALID_CN) && onsecurityproblem_hres == S_OK && security_problem != ERROR_INTERNET_SEC_CERT_ERRORS)
3149         invalid_cn_accepted = TRUE;
3150
3151     if(unk) {
3152         BYTE buf[512];
3153         DWORD readed;
3154         IStream *stream;
3155
3156         hres = IUnknown_QueryInterface(unk, &IID_IStream, (void**)&stream);
3157         ok(hres == S_OK, "Could not get IStream iface: %08x\n", hres);
3158         IUnknown_Release(unk);
3159
3160         do {
3161             readed = 0xdeadbeef;
3162             hres = IStream_Read(stream, buf, sizeof(buf), &readed);
3163             ok(readed != 0xdeadbeef, "readed = 0xdeadbeef\n");
3164             if(emulate_protocol && test_protocol == HTTP_TEST && readed)
3165                 ok(buf[0] == (use_cache_file && !(bindf&BINDF_ASYNCHRONOUS) ? 'X' : '?'), "buf[0] = '%c'\n", buf[0]);
3166         }while(hres == S_OK);
3167         ok(hres == S_FALSE, "IStream_Read returned %08x\n", hres);
3168         ok(!readed, "readed = %d\n", readed);
3169
3170         IStream_Release(stream);
3171     }
3172 }
3173
3174 static void test_BindToObject(int protocol, DWORD flags)
3175 {
3176     IMoniker *mon;
3177     HRESULT hres;
3178     LPOLESTR display_name;
3179     IBindCtx *bctx;
3180     DWORD regid;
3181     MSG msg;
3182     IUnknown *unk = (IUnknown*)0x00ff00ff;
3183     IBinding *bind;
3184
3185     init_bind_test(protocol, BINDTEST_TOOBJECT|flags, TYMED_ISTREAM);
3186
3187     if(emulate_protocol)
3188         CoRegisterClassObject(&CLSID_HTMLDocument, (IUnknown *)&mime_cf,
3189                               CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &regid);
3190
3191     SET_EXPECT(QueryInterface_IServiceProvider);
3192     hres = CreateAsyncBindCtx(0, (IBindStatusCallback*)&objbsc, NULL, &bctx);
3193     ok(hres == S_OK, "CreateAsyncBindCtx failed: %08x\n\n", hres);
3194     CHECK_CALLED(QueryInterface_IServiceProvider);
3195     if(FAILED(hres))
3196         return;
3197
3198     hres = CreateURLMoniker(NULL, test_protocol == FILE_TEST ? file_url : urls[test_protocol], &mon);
3199     ok(hres == S_OK, "failed to create moniker: %08x\n", hres);
3200     if(FAILED(hres)) {
3201         IBindCtx_Release(bctx);
3202         return;
3203     }
3204
3205     hres = IMoniker_QueryInterface(mon, &IID_IBinding, (void**)&bind);
3206     ok(hres == E_NOINTERFACE, "IMoniker should not have IBinding interface\n");
3207     if(SUCCEEDED(hres))
3208         IBinding_Release(bind);
3209
3210     hres = IMoniker_GetDisplayName(mon, bctx, NULL, &display_name);
3211     ok(hres == S_OK, "GetDisplayName failed %08x\n", hres);
3212     ok(!lstrcmpW(display_name, urls[test_protocol]), "GetDisplayName got wrong name\n");
3213     CoTaskMemFree(display_name);
3214
3215     SET_EXPECT(QueryInterface_IBindStatusCallbackEx);
3216     SET_EXPECT(Obj_GetBindInfo);
3217     SET_EXPECT(QueryInterface_IInternetProtocol);
3218     if(!emulate_protocol)
3219         SET_EXPECT(QueryService_IInternetProtocol);
3220     SET_EXPECT(Obj_OnStartBinding);
3221     if(emulate_protocol) {
3222         if(is_urlmon_protocol(test_protocol))
3223             SET_EXPECT(SetPriority);
3224         SET_EXPECT(Start);
3225         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
3226             SET_EXPECT(Terminate);
3227         if(test_protocol == FILE_TEST)
3228             SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
3229         SET_EXPECT(UnlockRequest);
3230     }else {
3231         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST) {
3232             SET_EXPECT(QueryInterface_IHttpNegotiate);
3233             SET_EXPECT(BeginningTransaction);
3234             SET_EXPECT(QueryInterface_IHttpNegotiate2);
3235             SET_EXPECT(GetRootSecurityId);
3236             if(http_is_first)
3237                 SET_EXPECT(Obj_OnProgress_FINDINGRESOURCE);
3238             SET_EXPECT(Obj_OnProgress_CONNECTING);
3239             SET_EXPECT(QueryInterface_IWindowForBindingUI);
3240             SET_EXPECT(QueryService_IWindowForBindingUI);
3241             SET_EXPECT(GetWindow_IWindowForBindingUI);
3242         }
3243         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == FILE_TEST)
3244             SET_EXPECT(Obj_OnProgress_SENDINGREQUEST);
3245         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST) {
3246             SET_EXPECT(QueryInterface_IHttpNegotiate);
3247             SET_EXPECT(OnResponse);
3248         }
3249         SET_EXPECT(Obj_OnProgress_MIMETYPEAVAILABLE);
3250         SET_EXPECT(Obj_OnProgress_BEGINDOWNLOADDATA);
3251         if(test_protocol == FILE_TEST)
3252             SET_EXPECT(Obj_OnProgress_CACHEFILENAMEAVAILABLE);
3253         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
3254             SET_EXPECT(OnProgress_DOWNLOADINGDATA);
3255         SET_EXPECT(Obj_OnProgress_ENDDOWNLOADDATA);
3256         SET_EXPECT(Obj_OnProgress_CLASSIDAVAILABLE);
3257         SET_EXPECT(Obj_OnProgress_BEGINSYNCOPERATION);
3258         SET_EXPECT(Obj_OnProgress_ENDSYNCOPERATION);
3259         SET_EXPECT(OnObjectAvailable);
3260         SET_EXPECT(Obj_OnStopBinding);
3261     }
3262
3263     hres = IMoniker_BindToObject(mon, bctx, NULL, &IID_IUnknown, (void**)&unk);
3264
3265     if ((test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
3266         && hres == HRESULT_FROM_WIN32(ERROR_INTERNET_NAME_NOT_RESOLVED))
3267     {
3268         skip( "Network unreachable, skipping tests\n" );
3269         return;
3270     }
3271
3272     /* no point testing the calls if binding didn't even work */
3273     if (FAILED(hres)) return;
3274
3275     if(bindf & BINDF_ASYNCHRONOUS) {
3276         ok(hres == MK_S_ASYNCHRONOUS, "IMoniker_BindToObject failed: %08x\n", hres);
3277         ok(unk == NULL, "istr should be NULL\n");
3278     }else {
3279         ok(hres == S_OK, "IMoniker_BindToStorage failed: %08x\n", hres);
3280         ok(unk != NULL, "unk == NULL\n");
3281         if(emulate_protocol)
3282             ok(unk == (IUnknown*)&PersistMoniker, "unk != PersistMoniker\n");
3283     }
3284     if(unk)
3285         IUnknown_Release(unk);
3286
3287     while((bindf & BINDF_ASYNCHRONOUS) &&
3288           !((!emulate_protocol || stopped_binding) && stopped_obj_binding) && GetMessage(&msg,NULL,0,0)) {
3289         TranslateMessage(&msg);
3290         DispatchMessage(&msg);
3291     }
3292
3293     CLEAR_CALLED(QueryInterface_IBindStatusCallbackEx);
3294     CHECK_CALLED(Obj_GetBindInfo);
3295     CHECK_CALLED(QueryInterface_IInternetProtocol);
3296     if(!emulate_protocol)
3297         CHECK_CALLED(QueryService_IInternetProtocol);
3298     CHECK_CALLED(Obj_OnStartBinding);
3299     if(emulate_protocol) {
3300         if(is_urlmon_protocol(test_protocol))
3301             CHECK_CALLED(SetPriority);
3302         CHECK_CALLED(Start);
3303         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
3304             CHECK_CALLED(Terminate);
3305         if(test_protocol == FILE_TEST)
3306             CLEAR_CALLED(OnProgress_MIMETYPEAVAILABLE); /* not called in IE7 */
3307         CHECK_CALLED(UnlockRequest);
3308     }else {
3309         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST) {
3310             CHECK_CALLED(QueryInterface_IHttpNegotiate);
3311             CHECK_CALLED(BeginningTransaction);
3312             if (have_IHttpNegotiate2)
3313             {
3314                 CHECK_CALLED(QueryInterface_IHttpNegotiate2);
3315                 CHECK_CALLED(GetRootSecurityId);
3316             }
3317             if(http_is_first) {
3318                 CHECK_CALLED(Obj_OnProgress_FINDINGRESOURCE);
3319                 CHECK_CALLED(Obj_OnProgress_CONNECTING);
3320             }else {
3321                 /* IE7 does call this */
3322                 CLEAR_CALLED(Obj_OnProgress_CONNECTING);
3323             }
3324             CLEAR_CALLED(QueryInterface_IWindowForBindingUI);
3325             CLEAR_CALLED(QueryService_IWindowForBindingUI);
3326             CLEAR_CALLED(GetWindow_IWindowForBindingUI);
3327         }
3328         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == FILE_TEST) {
3329             if(urls[test_protocol] == winetest_post_urlW)
3330                 CLEAR_CALLED(Obj_OnProgress_SENDINGREQUEST);
3331             else
3332                 CHECK_CALLED(Obj_OnProgress_SENDINGREQUEST);
3333         }
3334         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST) {
3335             CLEAR_CALLED(QueryInterface_IHttpNegotiate);
3336             CHECK_CALLED(OnResponse);
3337         }
3338         CHECK_CALLED(Obj_OnProgress_MIMETYPEAVAILABLE);
3339         CHECK_CALLED(Obj_OnProgress_BEGINDOWNLOADDATA);
3340         if(test_protocol == FILE_TEST)
3341             CHECK_CALLED(Obj_OnProgress_CACHEFILENAMEAVAILABLE);
3342         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
3343             CLEAR_CALLED(OnProgress_DOWNLOADINGDATA);
3344         CLEAR_CALLED(Obj_OnProgress_ENDDOWNLOADDATA);
3345         CHECK_CALLED(Obj_OnProgress_CLASSIDAVAILABLE);
3346         CHECK_CALLED(Obj_OnProgress_BEGINSYNCOPERATION);
3347         CHECK_CALLED(Obj_OnProgress_ENDSYNCOPERATION);
3348         CHECK_CALLED(OnObjectAvailable);
3349         CHECK_CALLED(Obj_OnStopBinding);
3350     }
3351
3352     ok(IMoniker_Release(mon) == 0, "mon should be destroyed here\n");
3353     if(test_protocol != HTTP_TEST || emulate_protocol || !(bindf & BINDF_ASYNCHRONOUS))
3354         ok(IBindCtx_Release(bctx) == 0, "bctx should be destroyed here\n");
3355     else
3356         IBindCtx_Release(bctx);
3357
3358     if(emulate_protocol)
3359         CoRevokeClassObject(regid);
3360
3361     if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
3362         http_is_first = FALSE;
3363 }
3364
3365 static void test_URLDownloadToFile(DWORD prot, BOOL emul)
3366 {
3367     BOOL res;
3368     HRESULT hres;
3369
3370     init_bind_test(prot, BINDTEST_FILEDWLAPI | (emul ? BINDTEST_EMULATE : 0), TYMED_FILE);
3371
3372     SET_EXPECT(GetBindInfo);
3373     SET_EXPECT(QueryInterface_IInternetProtocol);
3374     if(!emulate_protocol) {
3375         SET_EXPECT(QueryInterface_IServiceProvider);
3376         SET_EXPECT(QueryService_IInternetProtocol);
3377     }
3378     SET_EXPECT(OnStartBinding);
3379     if(emulate_protocol) {
3380         if(is_urlmon_protocol(test_protocol))
3381             SET_EXPECT(SetPriority);
3382         SET_EXPECT(Start);
3383         SET_EXPECT(UnlockRequest);
3384     }else {
3385         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST) {
3386             SET_EXPECT(QueryInterface_IHttpNegotiate);
3387             SET_EXPECT(BeginningTransaction);
3388             SET_EXPECT(QueryInterface_IHttpNegotiate2);
3389             SET_EXPECT(GetRootSecurityId);
3390             SET_EXPECT(QueryInterface_IWindowForBindingUI);
3391             SET_EXPECT(OnProgress_CONNECTING);
3392         }
3393         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == FILE_TEST)
3394             SET_EXPECT(OnProgress_SENDINGREQUEST);
3395         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST) {
3396             SET_EXPECT(QueryInterface_IHttpNegotiate);
3397             SET_EXPECT(OnResponse);
3398         }
3399         SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
3400         SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
3401         if(test_protocol == FILE_TEST)
3402             SET_EXPECT(OnProgress_CACHEFILENAMEAVAILABLE);
3403         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
3404             SET_EXPECT(OnProgress_DOWNLOADINGDATA);
3405         SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
3406         SET_EXPECT(OnStopBinding);
3407     }
3408
3409     hres = URLDownloadToFileW(NULL, test_protocol == FILE_TEST ? file_url : urls[test_protocol],
3410             dwl_htmlW, 0, (IBindStatusCallback*)&bsc);
3411     ok(hres == S_OK, "URLDownloadToFile failed: %08x\n", hres);
3412
3413     CHECK_CALLED(GetBindInfo);
3414     CHECK_CALLED(QueryInterface_IInternetProtocol);
3415     if(!emulate_protocol) {
3416         CHECK_CALLED(QueryInterface_IServiceProvider);
3417         CHECK_CALLED(QueryService_IInternetProtocol);
3418     }
3419     CHECK_CALLED(OnStartBinding);
3420     if(emulate_protocol) {
3421         if(is_urlmon_protocol(test_protocol))
3422             CHECK_CALLED(SetPriority);
3423         CHECK_CALLED(Start);
3424         CHECK_CALLED(UnlockRequest);
3425     }else {
3426         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST) {
3427             CHECK_CALLED(QueryInterface_IHttpNegotiate);
3428             CHECK_CALLED(BeginningTransaction);
3429             if (have_IHttpNegotiate2)
3430             {
3431                 CHECK_CALLED(QueryInterface_IHttpNegotiate2);
3432                 CHECK_CALLED(GetRootSecurityId);
3433             }
3434             CLEAR_CALLED(QueryInterface_IWindowForBindingUI);
3435             CLEAR_CALLED(OnProgress_CONNECTING);
3436         }
3437         if(test_protocol == FILE_TEST)
3438             CHECK_CALLED(OnProgress_SENDINGREQUEST);
3439         else if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
3440             CLEAR_CALLED(OnProgress_SENDINGREQUEST); /* not called by IE7 */
3441         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST) {
3442             CLEAR_CALLED(QueryInterface_IHttpNegotiate);
3443             CHECK_CALLED(OnResponse);
3444         }
3445         CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
3446         CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
3447         if(test_protocol == FILE_TEST)
3448             CHECK_CALLED(OnProgress_CACHEFILENAMEAVAILABLE);
3449         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
3450             CLEAR_CALLED(OnProgress_DOWNLOADINGDATA);
3451         CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
3452         CHECK_CALLED(OnStopBinding);
3453     }
3454
3455     res = DeleteFileA(dwl_htmlA);
3456     ok(res, "DeleteFile failed: %u\n", GetLastError());
3457
3458     if(prot != FILE_TEST || emul)
3459         return;
3460
3461     hres = URLDownloadToFileW(NULL, urls[test_protocol], dwl_htmlW, 0, NULL);
3462     ok(hres == S_OK, "URLDownloadToFile failed: %08x\n", hres);
3463
3464     res = DeleteFileA(dwl_htmlA);
3465     ok(res, "DeleteFile failed: %u\n", GetLastError());
3466 }
3467
3468 static void test_URLDownloadToFile_abort(void)
3469 {
3470     HRESULT hres;
3471
3472     init_bind_test(HTTP_TEST, BINDTEST_FILEDWLAPI|BINDTEST_ABORT_PROGRESS, TYMED_FILE);
3473
3474     SET_EXPECT(GetBindInfo);
3475     SET_EXPECT(QueryInterface_IInternetProtocol);
3476     SET_EXPECT(QueryInterface_IServiceProvider);
3477     SET_EXPECT(QueryService_IInternetProtocol);
3478     SET_EXPECT(OnStartBinding);
3479     SET_EXPECT(QueryInterface_IHttpNegotiate);
3480     SET_EXPECT(QueryInterface_IHttpNegotiate2);
3481     SET_EXPECT(BeginningTransaction);
3482     SET_EXPECT(GetRootSecurityId);
3483     SET_EXPECT(QueryInterface_IWindowForBindingUI);
3484     SET_EXPECT(OnProgress_CONNECTING);
3485     SET_EXPECT(OnProgress_SENDINGREQUEST);
3486     SET_EXPECT(OnStopBinding);
3487
3488     hres = URLDownloadToFileW(NULL, urls[HTTP_TEST], dwl_htmlW, 0, (IBindStatusCallback*)&bsc);
3489     ok(hres == E_ABORT, "URLDownloadToFile failed: %08x, expected E_ABORT\n", hres);
3490
3491     CHECK_CALLED(GetBindInfo);
3492     CHECK_CALLED(QueryInterface_IInternetProtocol);
3493     CHECK_CALLED(QueryInterface_IServiceProvider);
3494     CHECK_CALLED(QueryService_IInternetProtocol);
3495     CHECK_CALLED(OnStartBinding);
3496     CHECK_CALLED(QueryInterface_IHttpNegotiate);
3497     CHECK_CALLED(QueryInterface_IHttpNegotiate2);
3498     CHECK_CALLED(BeginningTransaction);
3499     CHECK_CALLED(GetRootSecurityId);
3500     CLEAR_CALLED(QueryInterface_IWindowForBindingUI);
3501     CHECK_CALLED(OnProgress_SENDINGREQUEST);
3502     CLEAR_CALLED(OnProgress_CONNECTING);
3503     CHECK_CALLED(OnStopBinding);
3504
3505     init_bind_test(HTTP_TEST, BINDTEST_FILEDWLAPI|BINDTEST_ABORT_START, TYMED_FILE);
3506
3507     SET_EXPECT(GetBindInfo);
3508     SET_EXPECT(QueryInterface_IInternetProtocol);
3509     SET_EXPECT(QueryInterface_IServiceProvider);
3510     SET_EXPECT(QueryService_IInternetProtocol);
3511     SET_EXPECT(OnStartBinding);
3512     SET_EXPECT(OnStopBinding);
3513
3514     abort_hres = E_ABORT;
3515     hres = URLDownloadToFileW(NULL, urls[HTTP_TEST], dwl_htmlW, 0, (IBindStatusCallback*)&bsc);
3516     ok(hres == E_ABORT, "URLDownloadToFile failed: %08x, expected E_ABORT\n", hres);
3517
3518     CHECK_CALLED(GetBindInfo);
3519     todo_wine CHECK_CALLED(QueryInterface_IInternetProtocol);
3520     todo_wine CHECK_CALLED(QueryInterface_IServiceProvider);
3521     todo_wine CHECK_CALLED(QueryService_IInternetProtocol);
3522     CHECK_CALLED(OnStartBinding);
3523     CHECK_CALLED(OnStopBinding);
3524
3525     init_bind_test(HTTP_TEST, BINDTEST_FILEDWLAPI|BINDTEST_ABORT_START, TYMED_FILE);
3526
3527     SET_EXPECT(GetBindInfo);
3528     SET_EXPECT(QueryInterface_IInternetProtocol);
3529     SET_EXPECT(QueryInterface_IServiceProvider);
3530     SET_EXPECT(QueryService_IInternetProtocol);
3531     SET_EXPECT(OnStartBinding);
3532     SET_EXPECT(QueryInterface_IHttpNegotiate);
3533     SET_EXPECT(QueryInterface_IHttpNegotiate2);
3534     SET_EXPECT(BeginningTransaction);
3535     SET_EXPECT(GetRootSecurityId);
3536     SET_EXPECT(QueryInterface_IWindowForBindingUI);
3537     SET_EXPECT(OnResponse);
3538     SET_EXPECT(OnProgress_CONNECTING);
3539     SET_EXPECT(OnProgress_SENDINGREQUEST);
3540     SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
3541     SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
3542     SET_EXPECT(OnProgress_DOWNLOADINGDATA);
3543     SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
3544     SET_EXPECT(OnStopBinding);
3545
3546     /* URLDownloadToFile doesn't abort if E_NOTIMPL is returned from the
3547      * IBindStatusCallback's OnStartBinding function.
3548      */
3549     abort_hres = E_NOTIMPL;
3550     hres = URLDownloadToFileW(NULL, urls[HTTP_TEST], dwl_htmlW, 0, (IBindStatusCallback*)&bsc);
3551     ok(hres == S_OK, "URLDownloadToFile failed: %08x\n", hres);
3552
3553     CHECK_CALLED(GetBindInfo);
3554     CHECK_CALLED(QueryInterface_IInternetProtocol);
3555     CHECK_CALLED(QueryInterface_IServiceProvider);
3556     CHECK_CALLED(QueryService_IInternetProtocol);
3557     CHECK_CALLED(OnStartBinding);
3558     CHECK_CALLED(QueryInterface_IHttpNegotiate);
3559     CHECK_CALLED(QueryInterface_IHttpNegotiate2);
3560     CHECK_CALLED(BeginningTransaction);
3561     CHECK_CALLED(GetRootSecurityId);
3562     CLEAR_CALLED(QueryInterface_IWindowForBindingUI);
3563     CHECK_CALLED(OnResponse);
3564     CLEAR_CALLED(OnProgress_CONNECTING);
3565     CHECK_CALLED(OnProgress_SENDINGREQUEST);
3566     CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
3567     CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
3568     CHECK_CALLED(OnProgress_DOWNLOADINGDATA);
3569     CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
3570     CHECK_CALLED(OnStopBinding);
3571
3572     DeleteFileA(dwl_htmlA);
3573 }
3574
3575 static void set_file_url(char *path)
3576 {
3577     CHAR file_urlA[INTERNET_MAX_URL_LENGTH];
3578     CHAR INDEX_HTMLA[MAX_PATH];
3579
3580     lstrcpyA(file_urlA, "file:///");
3581     lstrcatA(file_urlA, path);
3582     MultiByteToWideChar(CP_ACP, 0, file_urlA, -1, file_url, INTERNET_MAX_URL_LENGTH);
3583
3584     lstrcpyA(INDEX_HTMLA, "file://");
3585     lstrcatA(INDEX_HTMLA, path);
3586     MultiByteToWideChar(CP_ACP, 0, INDEX_HTMLA, -1, INDEX_HTML, MAX_PATH);
3587 }
3588
3589 static void create_file(void)
3590 {
3591     HANDLE file;
3592     DWORD size;
3593     CHAR path[MAX_PATH];
3594
3595     static const char html_doc[] = "<HTML></HTML>";
3596
3597     file = CreateFileA(wszIndexHtmlA, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
3598             FILE_ATTRIBUTE_NORMAL, NULL);
3599     ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
3600     if(file == INVALID_HANDLE_VALUE)
3601         return;
3602
3603     WriteFile(file, html_doc, sizeof(html_doc)-1, &size, NULL);
3604     CloseHandle(file);
3605
3606     GetCurrentDirectoryA(MAX_PATH, path);
3607     lstrcatA(path, "\\");
3608     lstrcatA(path, wszIndexHtmlA);
3609     set_file_url(path);
3610 }
3611
3612 static void create_cache_file(void)
3613 {
3614     char buf[6500], curdir[MAX_PATH];
3615     HANDLE file;
3616     DWORD size;
3617
3618     file = CreateFileA(test_txtA, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
3619             FILE_ATTRIBUTE_NORMAL, NULL);
3620     ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
3621     if(file == INVALID_HANDLE_VALUE)
3622         return;
3623
3624     memset(buf, 'X', sizeof(buf));
3625     WriteFile(file, buf, sizeof(buf), &size, NULL);
3626     CloseHandle(file);
3627
3628     memset(curdir, 0, sizeof(curdir));
3629     GetCurrentDirectoryA(MAX_PATH, curdir);
3630     lstrcatA(curdir, "\\");
3631     lstrcatA(curdir, test_txtA);
3632
3633     MultiByteToWideChar(CP_ACP, 0, curdir, -1, cache_file_name, MAX_PATH);
3634 }
3635
3636 static void test_ReportResult(HRESULT exhres)
3637 {
3638     IMoniker *mon = NULL;
3639     IBindCtx *bctx = NULL;
3640     IUnknown *unk = (void*)0xdeadbeef;
3641     HRESULT hres;
3642
3643     init_bind_test(ABOUT_TEST, BINDTEST_EMULATE, TYMED_ISTREAM);
3644     binding_hres = exhres;
3645
3646     hres = CreateURLMoniker(NULL, ABOUT_BLANK, &mon);
3647     ok(hres == S_OK, "CreateURLMoniker failed: %08x\n", hres);
3648
3649     SET_EXPECT(QueryInterface_IServiceProvider);
3650     hres = CreateAsyncBindCtx(0, (IBindStatusCallback*)&bsc, NULL, &bctx);
3651     ok(hres == S_OK, "CreateAsyncBindCtx failed: %08x\n\n", hres);
3652     CHECK_CALLED(QueryInterface_IServiceProvider);
3653
3654     SET_EXPECT(QueryInterface_IBindStatusCallbackEx);
3655     SET_EXPECT(GetBindInfo);
3656     SET_EXPECT(QueryInterface_IInternetProtocol);
3657     SET_EXPECT(OnStartBinding);
3658     if(is_urlmon_protocol(test_protocol))
3659         SET_EXPECT(SetPriority);
3660     SET_EXPECT(Start);
3661
3662     hres = IMoniker_BindToStorage(mon, bctx, NULL, &IID_IStream, (void**)&unk);
3663     if(SUCCEEDED(exhres))
3664         ok(hres == S_OK || hres == MK_S_ASYNCHRONOUS, "BindToStorage failed: %08x\n", hres);
3665     else
3666         ok(hres == exhres || hres == MK_S_ASYNCHRONOUS,
3667            "BindToStorage failed: %08x, expected %08x or MK_S_ASYNCHRONOUS\n", hres, exhres);
3668
3669     CLEAR_CALLED(QueryInterface_IBindStatusCallbackEx); /* IE 8 */
3670     CHECK_CALLED(GetBindInfo);
3671     CHECK_CALLED(QueryInterface_IInternetProtocol);
3672     CHECK_CALLED(OnStartBinding);
3673     if(is_urlmon_protocol(test_protocol))
3674         CHECK_CALLED(SetPriority);
3675     CHECK_CALLED(Start);
3676
3677     ok(unk == NULL, "unk=%p\n", unk);
3678
3679     IBindCtx_Release(bctx);
3680     IMoniker_Release(mon);
3681 }
3682
3683 static void test_BindToStorage_fail(void)
3684 {
3685     IMoniker *mon = NULL;
3686     IBindCtx *bctx = NULL;
3687     IUnknown *unk;
3688     HRESULT hres;
3689
3690     hres = CreateURLMoniker(NULL, ABOUT_BLANK, &mon);
3691     ok(hres == S_OK, "CreateURLMoniker failed: %08x\n", hres);
3692     if(FAILED(hres))
3693         return;
3694
3695     hres = pCreateAsyncBindCtxEx(NULL, 0, NULL, NULL, &bctx, 0);
3696     ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08x\n", hres);
3697
3698     unk = (void*)0xdeadbeef;
3699     hres = IMoniker_BindToStorage(mon, bctx, NULL, &IID_IStream, (void**)&unk);
3700     ok(hres == MK_E_SYNTAX || hres == INET_E_DATA_NOT_AVAILABLE,
3701        "hres=%08x, expected MK_E_SYNTAX or INET_E_DATA_NOT_AVAILABLE\n", hres);
3702     ok(unk == NULL, "got %p\n", unk);
3703
3704     IBindCtx_Release(bctx);
3705
3706     IMoniker_Release(mon);
3707
3708     test_ReportResult(E_NOTIMPL);
3709     test_ReportResult(S_FALSE);
3710 }
3711
3712 static void test_StdURLMoniker(void)
3713 {
3714     IMoniker *mon, *async_mon;
3715     LPOLESTR display_name;
3716     IBindCtx *bctx;
3717     IUnknown *unk;
3718     HRESULT hres;
3719
3720     hres = CoCreateInstance(&IID_IInternet, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
3721             &IID_IMoniker, (void**)&mon);
3722     ok(hres == S_OK, "Could not create IInternet instance: %08x\n", hres);
3723     if(FAILED(hres))
3724         return;
3725
3726     hres = IMoniker_QueryInterface(mon, &IID_IAsyncMoniker, (void**)&async_mon);
3727     ok(hres == S_OK, "Could not get IAsyncMoniker iface: %08x\n", hres);
3728     ok(mon == async_mon, "mon != async_mon\n");
3729     IMoniker_Release(async_mon);
3730
3731     hres = IMoniker_GetDisplayName(mon, NULL, NULL, &display_name);
3732     ok(hres == E_OUTOFMEMORY, "GetDisplayName failed: %08x, expected E_OUTOFMEMORY\n", hres);
3733
3734     if(pCreateUri) {
3735       IUriContainer *uri_container;
3736       IUri *uri;
3737
3738       hres = IMoniker_QueryInterface(mon, &IID_IUriContainer, (void**)&uri_container);
3739       ok(hres == S_OK, "Could not get IUriMoniker iface: %08x\n", hres);
3740
3741
3742       uri = (void*)0xdeadbeef;
3743       hres = IUriContainer_GetIUri(uri_container, &uri);
3744       ok(hres == S_FALSE, "GetIUri failed: %08x\n", hres);
3745       ok(!uri, "uri = %p, expected NULL\n", uri);
3746
3747       IUriContainer_Release(uri_container);
3748     }
3749
3750     SET_EXPECT(QueryInterface_IServiceProvider);
3751     hres = CreateAsyncBindCtx(0, (IBindStatusCallback*)&bsc, NULL, &bctx);
3752     ok(hres == S_OK, "CreateAsyncBindCtx failed: %08x\n\n", hres);
3753     CHECK_CALLED(QueryInterface_IServiceProvider);
3754
3755     if(pCreateUri) { /* Skip these tests on old IEs */
3756         unk = (void*)0xdeadbeef;
3757         hres = IMoniker_BindToStorage(mon, bctx, NULL, &IID_IStream, (void**)&unk);
3758         ok(hres == MK_E_SYNTAX, "BindToStorage failed: %08x, expected MK_E_SYNTAX\n", hres);
3759         ok(!unk, "unk = %p\n", unk);
3760
3761         unk = (void*)0xdeadbeef;
3762         hres = IMoniker_BindToObject(mon, bctx, NULL, &IID_IUnknown, (void**)&unk);
3763         ok(hres == MK_E_SYNTAX, "BindToStorage failed: %08x, expected MK_E_SYNTAX\n", hres);
3764         ok(!unk, "unk = %p\n", unk);
3765     }
3766
3767     IMoniker_Release(mon);
3768 }
3769
3770 static void register_protocols(void)
3771 {
3772     IInternetSession *session;
3773     HRESULT hres;
3774
3775     static const WCHAR winetestW[] = {'w','i','n','e','t','e','s','t',0};
3776
3777     hres = CoInternetGetSession(0, &session, 0);
3778     ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
3779     if(FAILED(hres))
3780         return;
3781
3782     hres = IInternetSession_RegisterNameSpace(session, &protocol_cf, &IID_NULL,
3783             winetestW, 0, NULL, 0);
3784     ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
3785
3786     IInternetSession_Release(session);
3787 }
3788
3789 START_TEST(url)
3790 {
3791     HMODULE hurlmon;
3792
3793     hurlmon = GetModuleHandle("urlmon.dll");
3794     pCreateAsyncBindCtxEx = (void*) GetProcAddress(hurlmon, "CreateAsyncBindCtxEx");
3795
3796     if(!GetProcAddress(hurlmon, "CompareSecurityIds")) {
3797         win_skip("Too old IE\n");
3798         return;
3799     }
3800
3801     pCreateUri = (void*) GetProcAddress(hurlmon, "CreateUri");
3802     if(!pCreateUri)
3803         win_skip("IUri not supported\n");
3804
3805     complete_event = CreateEvent(NULL, FALSE, FALSE, NULL);
3806     complete_event2 = CreateEvent(NULL, FALSE, FALSE, NULL);
3807     thread_id = GetCurrentThreadId();
3808     create_file();
3809     create_cache_file();
3810     register_protocols();
3811
3812     test_create();
3813
3814     trace("test CreateAsyncBindCtx...\n");
3815     test_CreateAsyncBindCtx();
3816
3817     trace("test CreateAsyncBindCtxEx...\n");
3818     test_CreateAsyncBindCtxEx();
3819
3820     trace("test RegisterBindStatusCallback...\n");
3821     if(test_RegisterBindStatusCallback()) {
3822         trace("test BindToStorage failures...\n");
3823         test_BindToStorage_fail();
3824
3825         trace("synchronous http test (COM not initialised)...\n");
3826         test_BindToStorage(HTTP_TEST, 0, TYMED_ISTREAM);
3827
3828         CoInitialize(NULL);
3829
3830         trace("test StdURLMoniker...\n");
3831         test_StdURLMoniker();
3832
3833         trace("synchronous http test...\n");
3834         test_BindToStorage(HTTP_TEST, 0, TYMED_ISTREAM);
3835
3836         trace("emulated synchronous http test (to file)...\n");
3837         test_BindToStorage(HTTP_TEST, BINDTEST_EMULATE, TYMED_FILE);
3838
3839         trace("synchronous http test (to object)...\n");
3840         test_BindToObject(HTTP_TEST, 0);
3841
3842         trace("emulated synchronous http test (with cache)...\n");
3843         test_BindToStorage(HTTP_TEST, BINDTEST_EMULATE|BINDTEST_USE_CACHE, TYMED_ISTREAM);
3844
3845         trace("emulated synchronous http test (with cache, no read)...\n");
3846         test_BindToStorage(HTTP_TEST, BINDTEST_EMULATE|BINDTEST_USE_CACHE|BINDTEST_NO_CALLBACK_READ, TYMED_ISTREAM);
3847
3848         trace("synchronous http test (with cache, no read)...\n");
3849         test_BindToStorage(HTTP_TEST, BINDTEST_USE_CACHE|BINDTEST_NO_CALLBACK_READ, TYMED_ISTREAM);
3850
3851         trace("synchronous file test...\n");
3852         test_BindToStorage(FILE_TEST, 0, TYMED_ISTREAM);
3853
3854         trace("emulated synchronous file test (to file)...\n");
3855         test_BindToStorage(FILE_TEST, BINDTEST_EMULATE, TYMED_FILE);
3856
3857         trace("synchronous file test (to object)...\n");
3858         test_BindToObject(FILE_TEST, 0);
3859
3860         trace("file test (no callback)...\n");
3861         test_BindToStorage(FILE_TEST, BINDTEST_NO_CALLBACK, TYMED_ISTREAM);
3862
3863         trace("synchronous https test (invalid CN, dialog)\n");
3864         onsecurityproblem_hres = S_FALSE;
3865         http_is_first = TRUE;
3866         test_BindToStorage(HTTPS_TEST, BINDTEST_INVALID_CN, TYMED_ISTREAM);
3867
3868         trace("synchronous https test (invalid CN, fail)\n");
3869         onsecurityproblem_hres = E_FAIL;
3870         test_BindToStorage(HTTPS_TEST, BINDTEST_INVALID_CN, TYMED_ISTREAM);
3871
3872         trace("synchronous https test (invalid CN, accept)\n");
3873         onsecurityproblem_hres = S_OK;
3874         test_BindToStorage(HTTPS_TEST, BINDTEST_INVALID_CN, TYMED_ISTREAM);
3875
3876         trace("asynchronous https test (invalid CN, dialog 2)\n");
3877         onsecurityproblem_hres = S_FALSE;
3878         test_BindToStorage(HTTPS_TEST, BINDTEST_INVALID_CN, TYMED_ISTREAM);
3879         invalid_cn_accepted = FALSE;
3880
3881         bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
3882
3883         trace("winetest test (async switch)...\n");
3884         test_BindToStorage(WINETEST_TEST, BINDTEST_EMULATE|BINDTEST_ASYNC_SWITCH, TYMED_ISTREAM);
3885
3886         trace("about test (no read)...\n");
3887         test_BindToStorage(ABOUT_TEST, BINDTEST_NO_CALLBACK_READ, TYMED_ISTREAM);
3888
3889         trace("http test...\n");
3890         test_BindToStorage(HTTP_TEST, 0, TYMED_ISTREAM);
3891
3892         trace("http test (to file)...\n");
3893         test_BindToStorage(HTTP_TEST, 0, TYMED_FILE);
3894
3895         trace("http test (to object)...\n");
3896         test_BindToObject(HTTP_TEST, 0);
3897
3898         trace("http test (short response)...\n");
3899         test_BindToStorage(HTTP_TEST, BINDTEST_HTTPRESPONSE, TYMED_ISTREAM);
3900
3901         trace("http test (short response, to object)...\n");
3902         test_BindToObject(HTTP_TEST, 0);
3903
3904         trace("http test (abort start binding E_NOTIMPL)...\n");
3905         abort_hres = E_NOTIMPL;
3906         test_BindToStorage(HTTP_TEST, BINDTEST_ABORT_START, TYMED_FILE);
3907
3908         trace("http test (abort start binding E_ABORT)...\n");
3909         abort_hres = E_ABORT;
3910         test_BindToStorage(HTTP_TEST, BINDTEST_ABORT_START, TYMED_FILE);
3911
3912         trace("http test (abort progress)...\n");
3913         test_BindToStorage(HTTP_TEST, BINDTEST_ABORT_PROGRESS, TYMED_FILE);
3914
3915         trace("emulated http test...\n");
3916         test_BindToStorage(HTTP_TEST, BINDTEST_EMULATE, TYMED_ISTREAM);
3917
3918         trace("emulated http test (to object)...\n");
3919         test_BindToObject(HTTP_TEST, BINDTEST_EMULATE);
3920
3921         trace("emulated http test (to object, redirect)...\n");
3922         test_BindToObject(HTTP_TEST, BINDTEST_EMULATE|BINDTEST_REDIRECT);
3923
3924         trace("emulated http test (to file)...\n");
3925         test_BindToStorage(HTTP_TEST, BINDTEST_EMULATE, TYMED_FILE);
3926
3927         trace("emulated http test (redirect)...\n");
3928         test_BindToStorage(HTTP_TEST, BINDTEST_EMULATE|BINDTEST_REDIRECT, TYMED_ISTREAM);
3929
3930         trace("emulated http test (with cache)...\n");
3931         test_BindToStorage(HTTP_TEST, BINDTEST_EMULATE|BINDTEST_USE_CACHE, TYMED_ISTREAM);
3932
3933         trace("winetest test (no callback)...\n");
3934         test_BindToStorage(WINETEST_TEST, BINDTEST_EMULATE|BINDTEST_NO_CALLBACK|BINDTEST_USE_CACHE, TYMED_ISTREAM);
3935
3936         trace("asynchronous https test...\n");
3937         http_is_first = TRUE;
3938         test_BindToStorage(HTTPS_TEST, 0, TYMED_ISTREAM);
3939
3940         trace("emulated https test...\n");
3941         test_BindToStorage(HTTPS_TEST, BINDTEST_EMULATE, TYMED_ISTREAM);
3942
3943         trace("about test...\n");
3944         test_BindToStorage(ABOUT_TEST, 0, TYMED_ISTREAM);
3945
3946         trace("about test (to file)...\n");
3947         test_BindToStorage(ABOUT_TEST, 0, TYMED_FILE);
3948
3949         trace("about test (to object)...\n");
3950         test_BindToObject(ABOUT_TEST, 0);
3951
3952         trace("emulated about test...\n");
3953         test_BindToStorage(ABOUT_TEST, BINDTEST_EMULATE, TYMED_ISTREAM);
3954
3955         trace("emulated about test (to file)...\n");
3956         test_BindToStorage(ABOUT_TEST, BINDTEST_EMULATE, TYMED_FILE);
3957
3958         trace("emulated about test (to object)...\n");
3959         test_BindToObject(ABOUT_TEST, BINDTEST_EMULATE);
3960
3961         trace("file test...\n");
3962         test_BindToStorage(FILE_TEST, 0, TYMED_ISTREAM);
3963
3964         trace("file test (to file)...\n");
3965         test_BindToStorage(FILE_TEST, 0, TYMED_FILE);
3966
3967         trace("file test (to object)...\n");
3968         test_BindToObject(FILE_TEST, 0);
3969
3970         trace("emulated file test...\n");
3971         test_BindToStorage(FILE_TEST, BINDTEST_EMULATE, TYMED_ISTREAM);
3972
3973         trace("emulated file test (to file)...\n");
3974         test_BindToStorage(FILE_TEST, BINDTEST_EMULATE, TYMED_FILE);
3975
3976         trace("emulated file test (to object)...\n");
3977         test_BindToObject(FILE_TEST, BINDTEST_EMULATE);
3978
3979         trace("emulated its test...\n");
3980         test_BindToStorage(ITS_TEST, BINDTEST_EMULATE, TYMED_ISTREAM);
3981
3982         trace("emulated its test (to file)...\n");
3983         test_BindToStorage(ITS_TEST, BINDTEST_EMULATE, TYMED_FILE);
3984
3985         trace("emulated mk test...\n");
3986         test_BindToStorage(MK_TEST, BINDTEST_EMULATE, TYMED_ISTREAM);
3987
3988         trace("test URLDownloadToFile for file protocol...\n");
3989         test_URLDownloadToFile(FILE_TEST, FALSE);
3990
3991         trace("test URLDownloadToFile for emulated file protocol...\n");
3992         test_URLDownloadToFile(FILE_TEST, TRUE);
3993
3994         trace("test URLDownloadToFile for http protocol...\n");
3995         test_URLDownloadToFile(HTTP_TEST, FALSE);
3996
3997         trace("test URLDownloadToFile abort...\n");
3998         test_URLDownloadToFile_abort();
3999
4000         trace("test emulated http abort...\n");
4001         test_BindToStorage(HTTP_TEST, BINDTEST_EMULATE|BINDTEST_ABORT, TYMED_ISTREAM);
4002
4003         bindf |= BINDF_NOWRITECACHE;
4004
4005         trace("ftp test...\n");
4006         test_BindToStorage(FTP_TEST, 0, TYMED_ISTREAM);
4007
4008         trace("test failures...\n");
4009         test_BindToStorage_fail();
4010
4011         bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE;
4012         only_check_prot_args = TRUE; /* Fail after checking arguments to Protocol_Start */
4013
4014         trace("check emulated http protocol arguments...\n");
4015         test_BindToStorage(HTTP_TEST, BINDTEST_EMULATE, TYMED_ISTREAM);
4016     }
4017
4018     DeleteFileA(wszIndexHtmlA);
4019     DeleteFileA(test_txtA);
4020     CloseHandle(complete_event);
4021     CloseHandle(complete_event2);
4022     CoUninitialize();
4023 }