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