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