hlink: Use ifaces instead of vtbl pointers in ExtensionService.
[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             INT ret;
1621             clipfmt[0] = 0;
1622             ret = GetClipboardFormatName(pformatetc->cfFormat, clipfmt, sizeof(clipfmt)-1);
1623             ok(ret, "GetClipboardFormatName failed, error %d\n", GetLastError());
1624             ok(!lstrcmp(clipfmt, mime_type), "clipformat %x != mime_type, \"%s\" != \"%s\"\n",
1625                pformatetc->cfFormat, clipfmt, mime_type);
1626         } else {
1627             ok(pformatetc->cfFormat == 0, "clipformat=%x\n", pformatetc->cfFormat);
1628         }
1629         ok(pformatetc->ptd == NULL, "ptd = %p\n", pformatetc->ptd);
1630         ok(pformatetc->dwAspect == 1, "dwAspect=%u\n", pformatetc->dwAspect);
1631         ok(pformatetc->lindex == -1, "lindex=%d\n", pformatetc->lindex);
1632         ok(pformatetc->tymed == tymed, "tymed=%u, expected %u\n", pformatetc->tymed, tymed);
1633     }
1634
1635     ok(pstgmed != NULL, "stgmeg == NULL\n");
1636     ok(pstgmed->tymed == tymed, "tymed=%u, expected %u\n", pstgmed->tymed, tymed);
1637     ok(pstgmed->pUnkForRelease != NULL, "pUnkForRelease == NULL\n");
1638
1639     switch(pstgmed->tymed) {
1640     case TYMED_ISTREAM:
1641         if(grfBSCF & BSCF_FIRSTDATANOTIFICATION) {
1642             STATSTG stat;
1643
1644             hres = IStream_Write(U(*pstgmed).pstm, buf, 10, NULL);
1645             ok(hres == STG_E_ACCESSDENIED,
1646                "Write failed: %08x, expected STG_E_ACCESSDENIED\n", hres);
1647
1648             hres = IStream_Commit(U(*pstgmed).pstm, 0);
1649             ok(hres == E_NOTIMPL, "Commit failed: %08x, expected E_NOTIMPL\n", hres);
1650
1651             hres = IStream_Revert(U(*pstgmed).pstm);
1652             ok(hres == E_NOTIMPL, "Revert failed: %08x, expected E_NOTIMPL\n", hres);
1653
1654             hres = IStream_Stat(U(*pstgmed).pstm, NULL, STATFLAG_NONAME);
1655             ok(hres == E_FAIL, "hres = %x\n", hres);
1656             if(use_cache_file && emulate_protocol) {
1657                 hres = IStream_Stat(U(*pstgmed).pstm, &stat, STATFLAG_DEFAULT);
1658                 ok(hres == S_OK, "hres = %x\n", hres);
1659                 ok(!lstrcmpW(stat.pwcsName, cache_file_name),
1660                         "stat.pwcsName = %s, cache_file_name = %s\n",
1661                         wine_dbgstr_w(stat.pwcsName), wine_dbgstr_w(cache_file_name));
1662                 CoTaskMemFree(stat.pwcsName);
1663                 ok(U(stat.cbSize).LowPart == (bindf&BINDF_ASYNCHRONOUS?0:6500),
1664                         "stat.cbSize.LowPart = %u\n", U(stat.cbSize).LowPart);
1665             } else {
1666                 hres = IStream_Stat(U(*pstgmed).pstm, &stat, STATFLAG_NONAME);
1667                 ok(hres == S_OK, "hres = %x\n", hres);
1668                 ok(!stat.pwcsName || broken(stat.pwcsName!=NULL),
1669                         "stat.pwcsName = %s\n", wine_dbgstr_w(stat.pwcsName));
1670             }
1671             ok(stat.type == STGTY_STREAM, "stat.type = %x\n", stat.type);
1672             ok(U(stat.cbSize).HighPart == 0, "stat.cbSize.HighPart != 0\n");
1673             ok(stat.grfMode == (U(stat.cbSize).LowPart?GENERIC_READ:0), "stat.grfMode = %x\n", stat.grfMode);
1674             ok(stat.grfLocksSupported == 0, "stat.grfLocksSupported = %x\n", stat.grfLocksSupported);
1675             ok(stat.grfStateBits == 0, "stat.grfStateBits = %x\n", stat.grfStateBits);
1676             ok(stat.reserved == 0, "stat.reserved = %x\n", stat.reserved);
1677         }
1678
1679         ok(U(*pstgmed).pstm != NULL, "U(*pstgmed).pstm == NULL\n");
1680         if(callback_read) {
1681             do {
1682                 hres = IStream_Read(U(*pstgmed).pstm, buf, 512, &readed);
1683                 if(test_protocol == HTTP_TEST && emulate_protocol && readed)
1684                     ok(buf[0] == (use_cache_file && !(bindf&BINDF_ASYNCHRONOUS) ? 'X' : '?'), "buf[0] = '%c'\n", buf[0]);
1685             }while(hres == S_OK);
1686             ok(hres == S_FALSE || hres == E_PENDING, "IStream_Read returned %08x\n", hres);
1687         }
1688         break;
1689
1690     case TYMED_FILE:
1691         if(test_protocol == FILE_TEST)
1692             ok(!lstrcmpW(pstgmed->u.lpszFileName, INDEX_HTML+7),
1693                "unexpected file name %s\n", wine_dbgstr_w(pstgmed->u.lpszFileName));
1694         else if(emulate_protocol)
1695             ok(!lstrcmpW(pstgmed->u.lpszFileName, cache_fileW),
1696                "unexpected file name %s\n", wine_dbgstr_w(pstgmed->u.lpszFileName));
1697         else
1698             ok(pstgmed->u.lpszFileName != NULL, "lpszFileName == NULL\n");
1699     }
1700
1701     if((test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST)
1702        && emulate_protocol && prot_state < 4 && (!bind_to_object || prot_state > 1))
1703         SetEvent(complete_event);
1704
1705     return S_OK;
1706 }
1707
1708 static HRESULT WINAPI statusclb_OnObjectAvailable(IBindStatusCallbackEx *iface, REFIID riid, IUnknown *punk)
1709 {
1710     CHECK_EXPECT(OnObjectAvailable);
1711
1712     if(iface != &objbsc)
1713         ok(0, "unexpected call\n");
1714
1715     ok(IsEqualGUID(&IID_IUnknown, riid), "riid = %s\n", debugstr_guid(riid));
1716     ok(punk != NULL, "punk == NULL\n");
1717
1718     return S_OK;
1719 }
1720
1721 static HRESULT WINAPI statusclb_GetBindInfoEx(IBindStatusCallbackEx *iface, DWORD *grfBINDF, BINDINFO *pbindinfo,
1722         DWORD *grfBINDF2, DWORD *pdwReserved)
1723 {
1724     CHECK_EXPECT(GetBindInfoEx);
1725
1726     ok(grfBINDF != NULL, "grfBINDF == NULL\n");
1727     ok(grfBINDF2 != NULL, "grfBINDF2 == NULL\n");
1728     ok(pbindinfo != NULL, "pbindinfo == NULL\n");
1729     ok(pdwReserved != NULL, "dwReserved == NULL\n");
1730
1731     return S_OK;
1732 }
1733
1734 static const IBindStatusCallbackExVtbl BindStatusCallbackVtbl = {
1735     statusclb_QueryInterface,
1736     statusclb_AddRef,
1737     statusclb_Release,
1738     statusclb_OnStartBinding,
1739     statusclb_GetPriority,
1740     statusclb_OnLowResource,
1741     statusclb_OnProgress,
1742     statusclb_OnStopBinding,
1743     statusclb_GetBindInfo,
1744     statusclb_OnDataAvailable,
1745     statusclb_OnObjectAvailable,
1746     statusclb_GetBindInfoEx
1747 };
1748
1749 static IBindStatusCallbackEx bsc = { &BindStatusCallbackVtbl };
1750 static IBindStatusCallbackEx bsc2 = { &BindStatusCallbackVtbl };
1751 static IBindStatusCallbackEx objbsc = { &BindStatusCallbackVtbl };
1752
1753 static HRESULT WINAPI MonikerProp_QueryInterface(IMonikerProp *iface, REFIID riid, void **ppv)
1754 {
1755     *ppv = NULL;
1756     ok(0, "unexpected riid %s\n", debugstr_guid(riid));
1757     return E_NOINTERFACE;
1758 }
1759
1760 static ULONG WINAPI MonikerProp_AddRef(IMonikerProp *iface)
1761 {
1762     return 2;
1763 }
1764
1765 static ULONG WINAPI MonikerProp_Release(IMonikerProp *iface)
1766 {
1767     return 1;
1768 }
1769
1770 static HRESULT WINAPI MonikerProp_PutProperty(IMonikerProp *iface, MONIKERPROPERTY mkp, LPCWSTR val)
1771 {
1772     switch(mkp) {
1773     case MIMETYPEPROP:
1774         CHECK_EXPECT(PutProperty_MIMETYPEPROP);
1775         ok(!lstrcmpW(val, wszTextHtml), "val = %s\n", wine_dbgstr_w(val));
1776         break;
1777     case CLASSIDPROP:
1778         CHECK_EXPECT(PutProperty_CLASSIDPROP);
1779         break;
1780     default:
1781         break;
1782     }
1783
1784     return S_OK;
1785 }
1786
1787 static const IMonikerPropVtbl MonikerPropVtbl = {
1788     MonikerProp_QueryInterface,
1789     MonikerProp_AddRef,
1790     MonikerProp_Release,
1791     MonikerProp_PutProperty
1792 };
1793
1794 static IMonikerProp MonikerProp = { &MonikerPropVtbl };
1795
1796 static HRESULT WINAPI PersistMoniker_QueryInterface(IPersistMoniker *iface, REFIID riid, void **ppv)
1797 {
1798     *ppv = NULL;
1799
1800     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IPersistMoniker, riid))
1801         *ppv = iface;
1802     else if(IsEqualGUID(&IID_IMonikerProp, riid))
1803         *ppv = &MonikerProp;
1804
1805     if(*ppv)
1806         return S_OK;
1807
1808     ok(0, "unexpected riid %s\n", debugstr_guid(riid));
1809     return E_NOINTERFACE;
1810 }
1811
1812 static ULONG WINAPI PersistMoniker_AddRef(IPersistMoniker *iface)
1813 {
1814     return 2;
1815 }
1816
1817 static ULONG WINAPI PersistMoniker_Release(IPersistMoniker *iface)
1818 {
1819     return 1;
1820 }
1821
1822 static HRESULT WINAPI PersistMoniker_GetClassID(IPersistMoniker *iface, CLSID *pClassID)
1823 {
1824     ok(0, "unexpected call\n");
1825     return E_NOTIMPL;
1826 }
1827
1828 static HRESULT WINAPI PersistMoniker_IsDirty(IPersistMoniker *iface)
1829 {
1830     ok(0, "unexpected call\n");
1831     return E_NOTIMPL;
1832 }
1833
1834 static HRESULT WINAPI PersistMoniker_Load(IPersistMoniker *iface, BOOL fFullyAvailable,
1835                                           IMoniker *pimkName, LPBC pibc, DWORD grfMode)
1836 {
1837     IUnknown *unk;
1838     HRESULT hres;
1839
1840     static WCHAR cbinding_contextW[] =
1841         {'C','B','i','n','d','i','n','g',' ','C','o','n','t','e','x','t',0};
1842
1843     CHECK_EXPECT(Load);
1844     ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
1845
1846     if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
1847         ok(!fFullyAvailable, "fFulyAvailable = %x\n", fFullyAvailable);
1848     else
1849         ok(fFullyAvailable, "fFulyAvailable = %x\n", fFullyAvailable);
1850     ok(pimkName != NULL, "pimkName == NULL\n");
1851     ok(pibc != NULL, "pibc == NULL\n");
1852     ok(grfMode == 0x12, "grfMode = %x\n", grfMode);
1853
1854     hres = IBindCtx_GetObjectParam(pibc, cbinding_contextW, &unk);
1855     ok(hres == S_OK, "GetObjectParam(CBinding Context) failed: %08x\n", hres);
1856     if(SUCCEEDED(hres)) {
1857         IBinding *binding;
1858
1859         hres = IUnknown_QueryInterface(unk, &IID_IBinding, (void**)&binding);
1860         ok(hres == S_OK, "Could not get IBinding: %08x\n", hres);
1861
1862         IBinding_Release(binding);
1863         IUnknown_Release(unk);
1864     }
1865
1866     SET_EXPECT(QueryInterface_IServiceProvider);
1867     hres = RegisterBindStatusCallback(pibc, (IBindStatusCallback*)&bsc, NULL, 0);
1868     ok(hres == S_OK, "RegisterBindStatusCallback failed: %08x\n", hres);
1869     CHECK_CALLED(QueryInterface_IServiceProvider);
1870
1871     SET_EXPECT(QueryInterface_IBindStatusCallbackEx);
1872     SET_EXPECT(GetBindInfo);
1873     SET_EXPECT(OnStartBinding);
1874     if(test_redirect)
1875         SET_EXPECT(OnProgress_REDIRECTING);
1876     SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
1877     if(test_protocol == FILE_TEST)
1878         SET_EXPECT(OnProgress_CACHEFILENAMEAVAILABLE);
1879     if(test_protocol != HTTP_TEST && test_protocol != HTTPS_TEST)
1880         SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
1881     SET_EXPECT(LockRequest);
1882     SET_EXPECT(OnDataAvailable);
1883     if(test_protocol != HTTP_TEST && test_protocol != HTTPS_TEST)
1884         SET_EXPECT(OnStopBinding);
1885
1886     hres = IMoniker_BindToStorage(pimkName, pibc, NULL, &IID_IStream, (void**)&unk);
1887     ok(hres == S_OK, "Load failed: %08x\n", hres);
1888
1889     CLEAR_CALLED(QueryInterface_IBindStatusCallbackEx); /* IE 8 */
1890     CHECK_CALLED(GetBindInfo);
1891     CHECK_CALLED(OnStartBinding);
1892     if(test_redirect)
1893         CHECK_CALLED(OnProgress_REDIRECTING);
1894     CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
1895     if(test_protocol == FILE_TEST)
1896         CHECK_CALLED(OnProgress_CACHEFILENAMEAVAILABLE);
1897     if(test_protocol != HTTP_TEST && test_protocol != HTTPS_TEST)
1898         CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
1899     CHECK_CALLED(LockRequest);
1900     CHECK_CALLED(OnDataAvailable);
1901     if(test_protocol != HTTP_TEST && test_protocol != HTTPS_TEST)
1902         CHECK_CALLED(OnStopBinding);
1903
1904     if(unk)
1905         IUnknown_Release(unk);
1906
1907     return S_OK;
1908 }
1909
1910 static HRESULT WINAPI PersistMoniker_Save(IPersistMoniker *iface, IMoniker *pimkName, LPBC pbc, BOOL fRemember)
1911 {
1912     ok(0, "unexpected call\n");
1913     return E_NOTIMPL;
1914 }
1915
1916 static HRESULT WINAPI PersistMoniker_SaveCompleted(IPersistMoniker *iface, IMoniker *pimkName, LPBC pibc)
1917 {
1918     ok(0, "unexpected call\n");
1919     return E_NOTIMPL;
1920 }
1921
1922 static HRESULT WINAPI PersistMoniker_GetCurMoniker(IPersistMoniker *iface, IMoniker **pimkName)
1923 {
1924     ok(0, "unexpected call\n");
1925     return E_NOTIMPL;
1926 }
1927
1928 static const IPersistMonikerVtbl PersistMonikerVtbl = {
1929     PersistMoniker_QueryInterface,
1930     PersistMoniker_AddRef,
1931     PersistMoniker_Release,
1932     PersistMoniker_GetClassID,
1933     PersistMoniker_IsDirty,
1934     PersistMoniker_Load,
1935     PersistMoniker_Save,
1936     PersistMoniker_SaveCompleted,
1937     PersistMoniker_GetCurMoniker
1938 };
1939
1940 static IPersistMoniker PersistMoniker = { &PersistMonikerVtbl };
1941
1942 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
1943 {
1944     *ppv = NULL;
1945
1946     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) {
1947         *ppv = iface;
1948         return S_OK;
1949     }
1950
1951     if(IsEqualGUID(&IID_IMarshal, riid))
1952         return E_NOINTERFACE;
1953     if(IsEqualGUID(&CLSID_IdentityUnmarshal, riid))
1954         return E_NOINTERFACE;
1955
1956     ok(0, "unexpected riid %s\n", debugstr_guid(riid));
1957     return E_NOTIMPL;
1958 }
1959
1960 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
1961 {
1962     return 2;
1963 }
1964
1965 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
1966 {
1967     return 1;
1968 }
1969
1970 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
1971 {
1972     CHECK_EXPECT(CreateInstance);
1973     ok(!outer, "outer = %p\n", outer);
1974     ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", debugstr_guid(riid));
1975     *ppv = &PersistMoniker;
1976     return S_OK;
1977 }
1978
1979 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
1980 {
1981     ok(0, "unexpected call\n");
1982     return S_OK;
1983 }
1984
1985 static const IClassFactoryVtbl ClassFactoryVtbl = {
1986     ClassFactory_QueryInterface,
1987     ClassFactory_AddRef,
1988     ClassFactory_Release,
1989     ClassFactory_CreateInstance,
1990     ClassFactory_LockServer
1991 };
1992
1993 static IClassFactory mime_cf = { &ClassFactoryVtbl };
1994
1995 static HRESULT WINAPI ProtocolCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
1996 {
1997     *ppv = NULL;
1998
1999     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IClassFactory, riid)) {
2000         *ppv = iface;
2001         return S_OK;
2002     }
2003
2004     if(IsEqualGUID(&IID_IInternetProtocolInfo, riid))
2005         return E_NOINTERFACE;
2006
2007     ok(0, "unexpected riid %s\n", debugstr_guid(riid));
2008     return E_NOTIMPL;
2009 }
2010
2011 static HRESULT WINAPI ProtocolCF_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv)
2012 {
2013     if(IsEqualGUID(&IID_IInternetProtocolInfo, riid))
2014         return E_NOINTERFACE;
2015
2016     todo_wine ok(outer != NULL, "outer == NULL\n");
2017     todo_wine ok(IsEqualGUID(&IID_IUnknown, riid), "unexpected riid %s\n", debugstr_guid(riid));
2018     *ppv = &Protocol;
2019     return S_OK;
2020 }
2021
2022 static const IClassFactoryVtbl ProtocolCFVtbl = {
2023     ProtocolCF_QueryInterface,
2024     ClassFactory_AddRef,
2025     ClassFactory_Release,
2026     ProtocolCF_CreateInstance,
2027     ClassFactory_LockServer
2028 };
2029
2030 static IClassFactory protocol_cf = { &ProtocolCFVtbl };
2031
2032 static void test_CreateAsyncBindCtx(void)
2033 {
2034     IBindCtx *bctx = (IBindCtx*)0x0ff00ff0;
2035     IUnknown *unk;
2036     HRESULT hres;
2037     ULONG ref;
2038     BIND_OPTS bindopts;
2039
2040     hres = CreateAsyncBindCtx(0, NULL, NULL, &bctx);
2041     ok(hres == E_INVALIDARG, "CreateAsyncBindCtx failed. expected: E_INVALIDARG, got: %08x\n", hres);
2042     ok(bctx == (IBindCtx*)0x0ff00ff0, "bctx should not be changed\n");
2043
2044     hres = CreateAsyncBindCtx(0, NULL, NULL, NULL);
2045     ok(hres == E_INVALIDARG, "CreateAsyncBindCtx failed. expected: E_INVALIDARG, got: %08x\n", hres);
2046
2047     SET_EXPECT(QueryInterface_IServiceProvider);
2048     hres = CreateAsyncBindCtx(0, (IBindStatusCallback*)&bsc, NULL, &bctx);
2049     ok(hres == S_OK, "CreateAsyncBindCtx failed: %08x\n", hres);
2050     CHECK_CALLED(QueryInterface_IServiceProvider);
2051
2052     bindopts.cbStruct = sizeof(bindopts);
2053     hres = IBindCtx_GetBindOptions(bctx, &bindopts);
2054     ok(SUCCEEDED(hres), "IBindCtx_GetBindOptions failed: %08x\n", hres);
2055     ok(bindopts.grfFlags == BIND_MAYBOTHERUSER,
2056                 "bindopts.grfFlags = %08x, expected: BIND_MAYBOTHERUSER\n", bindopts.grfFlags);
2057     ok(bindopts.grfMode == (STGM_READWRITE | STGM_SHARE_EXCLUSIVE),
2058                 "bindopts.grfMode = %08x, expected: STGM_READWRITE | STGM_SHARE_EXCLUSIVE\n",
2059                 bindopts.grfMode);
2060     ok(bindopts.dwTickCountDeadline == 0,
2061                 "bindopts.dwTickCountDeadline = %08x, expected: 0\n", bindopts.dwTickCountDeadline);
2062
2063     hres = IBindCtx_QueryInterface(bctx, &IID_IAsyncBindCtx, (void**)&unk);
2064     ok(hres == E_NOINTERFACE, "QueryInterface(IID_IAsyncBindCtx) failed: %08x, expected E_NOINTERFACE\n", hres);
2065     if(SUCCEEDED(hres))
2066         IUnknown_Release(unk);
2067
2068     ref = IBindCtx_Release(bctx);
2069     ok(ref == 0, "bctx should be destroyed here\n");
2070 }
2071
2072 static void test_CreateAsyncBindCtxEx(void)
2073 {
2074     IBindCtx *bctx = NULL, *bctx2 = NULL, *bctx_arg = NULL;
2075     IUnknown *unk;
2076     BIND_OPTS bindopts;
2077     HRESULT hres;
2078
2079     static WCHAR testW[] = {'t','e','s','t',0};
2080
2081     if (!pCreateAsyncBindCtxEx) {
2082         win_skip("CreateAsyncBindCtxEx not present\n");
2083         return;
2084     }
2085
2086     hres = pCreateAsyncBindCtxEx(NULL, 0, NULL, NULL, NULL, 0);
2087     ok(hres == E_INVALIDARG, "CreateAsyncBindCtx failed: %08x, expected E_INVALIDARG\n", hres);
2088
2089     hres = pCreateAsyncBindCtxEx(NULL, 0, NULL, NULL, &bctx, 0);
2090     ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08x\n", hres);
2091
2092     if(SUCCEEDED(hres)) {
2093         bindopts.cbStruct = sizeof(bindopts);
2094         hres = IBindCtx_GetBindOptions(bctx, &bindopts);
2095         ok(SUCCEEDED(hres), "IBindCtx_GetBindOptions failed: %08x\n", hres);
2096         ok(bindopts.grfFlags == BIND_MAYBOTHERUSER,
2097                 "bindopts.grfFlags = %08x, expected: BIND_MAYBOTHERUSER\n", bindopts.grfFlags);
2098         ok(bindopts.grfMode == (STGM_READWRITE | STGM_SHARE_EXCLUSIVE),
2099                 "bindopts.grfMode = %08x, expected: STGM_READWRITE | STGM_SHARE_EXCLUSIVE\n",
2100                 bindopts.grfMode);
2101         ok(bindopts.dwTickCountDeadline == 0,
2102                 "bindopts.dwTickCountDeadline = %08x, expected: 0\n", bindopts.dwTickCountDeadline);
2103
2104         IBindCtx_Release(bctx);
2105     }
2106
2107     CreateBindCtx(0, &bctx_arg);
2108     hres = pCreateAsyncBindCtxEx(NULL, 0, NULL, NULL, &bctx, 0);
2109     ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08x\n", hres);
2110
2111     if(SUCCEEDED(hres)) {
2112         bindopts.cbStruct = sizeof(bindopts);
2113         hres = IBindCtx_GetBindOptions(bctx, &bindopts);
2114         ok(SUCCEEDED(hres), "IBindCtx_GetBindOptions failed: %08x\n", hres);
2115         ok(bindopts.grfFlags == BIND_MAYBOTHERUSER,
2116                 "bindopts.grfFlags = %08x, expected: BIND_MAYBOTHERUSER\n", bindopts.grfFlags);
2117         ok(bindopts.grfMode == (STGM_READWRITE | STGM_SHARE_EXCLUSIVE),
2118                 "bindopts.grfMode = %08x, expected: STGM_READWRITE | STGM_SHARE_EXCLUSIVE\n",
2119                 bindopts.grfMode);
2120         ok(bindopts.dwTickCountDeadline == 0,
2121                 "bindopts.dwTickCountDeadline = %08x, expected: 0\n", bindopts.dwTickCountDeadline);
2122
2123         IBindCtx_Release(bctx);
2124     }
2125
2126     IBindCtx_Release(bctx_arg);
2127
2128     SET_EXPECT(QueryInterface_IServiceProvider);
2129     hres = pCreateAsyncBindCtxEx(NULL, 0, (IBindStatusCallback*)&bsc, NULL, &bctx, 0);
2130     ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08x\n", hres);
2131     CHECK_CALLED(QueryInterface_IServiceProvider);
2132
2133     hres = IBindCtx_QueryInterface(bctx, &IID_IAsyncBindCtx, (void**)&unk);
2134     ok(hres == S_OK, "QueryInterface(IID_IAsyncBindCtx) failed: %08x\n", hres);
2135     if(SUCCEEDED(hres))
2136         IUnknown_Release(unk);
2137
2138     IBindCtx_Release(bctx);
2139
2140     hres = CreateBindCtx(0, &bctx2);
2141     ok(hres == S_OK, "CreateBindCtx failed: %08x\n", hres);
2142
2143     hres = pCreateAsyncBindCtxEx(bctx2, 0, NULL, NULL, &bctx, 0);
2144     ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08x\n", hres);
2145
2146     hres = IBindCtx_RegisterObjectParam(bctx2, testW, (IUnknown*)&Protocol);
2147     ok(hres == S_OK, "RegisterObjectParam failed: %08x\n", hres);
2148
2149     hres = IBindCtx_GetObjectParam(bctx, testW, &unk);
2150     ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres);
2151     ok(unk == (IUnknown*)&Protocol, "unexpected unk %p\n", unk);
2152
2153     IBindCtx_Release(bctx);
2154     IBindCtx_Release(bctx2);
2155 }
2156
2157 static void test_GetBindInfoEx(IBindStatusCallback *holder)
2158 {
2159     IBindStatusCallbackEx *bscex;
2160     BINDINFO bindinfo = {sizeof(bindinfo)};
2161     DWORD bindf, bindf2, dw;
2162     HRESULT hres;
2163
2164     hres = IBindStatusCallback_QueryInterface(holder, &IID_IBindStatusCallbackEx, (void**)&bscex);
2165     if(FAILED(hres)) {
2166         win_skip("IBindStatusCallbackEx not supported\n");
2167         return;
2168     }
2169
2170     use_bscex = TRUE;
2171
2172     bindf = 0;
2173     SET_EXPECT(QueryInterface_IBindStatusCallbackEx);
2174     SET_EXPECT(GetBindInfoEx);
2175     hres = IBindStatusCallback_GetBindInfo(holder, &bindf, &bindinfo);
2176     ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2177     CHECK_CALLED(QueryInterface_IBindStatusCallbackEx);
2178     CHECK_CALLED(GetBindInfoEx);
2179
2180     bindf = bindf2 = dw = 0;
2181     SET_EXPECT(QueryInterface_IBindStatusCallbackEx);
2182     SET_EXPECT(GetBindInfoEx);
2183     hres = IBindStatusCallbackEx_GetBindInfoEx(bscex, &bindf, &bindinfo, &bindf2, &dw);
2184     ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2185     CHECK_CALLED(QueryInterface_IBindStatusCallbackEx);
2186     CHECK_CALLED(GetBindInfoEx);
2187
2188     use_bscex = FALSE;
2189
2190     bindf = bindf2 = dw = 0xdeadbeef;
2191     SET_EXPECT(QueryInterface_IBindStatusCallbackEx);
2192     SET_EXPECT(GetBindInfo);
2193     hres = IBindStatusCallbackEx_GetBindInfoEx(bscex, &bindf, &bindinfo, &bindf2, &dw);
2194     ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2195     CHECK_CALLED(QueryInterface_IBindStatusCallbackEx);
2196     CHECK_CALLED(GetBindInfo);
2197     ok(bindf2 == 0xdeadbeef, "bindf2 = %x\n", bindf2);
2198     ok(dw == 0xdeadbeef, "dw = %x\n", dw);
2199
2200     IBindStatusCallbackEx_Release(bscex);
2201 }
2202
2203 static BOOL test_bscholder(IBindStatusCallback *holder)
2204 {
2205     IServiceProvider *serv_prov;
2206     IHttpNegotiate *http_negotiate, *http_negotiate_serv;
2207     IHttpNegotiate2 *http_negotiate2, *http_negotiate2_serv;
2208     IAuthenticate *authenticate, *authenticate_serv;
2209     IInternetProtocol *protocol;
2210     BINDINFO bindinfo = {sizeof(bindinfo)};
2211     BOOL ret = TRUE;
2212     LPWSTR wstr;
2213     DWORD dw;
2214     HRESULT hres;
2215
2216     hres = IBindStatusCallback_QueryInterface(holder, &IID_IServiceProvider, (void**)&serv_prov);
2217     ok(hres == S_OK, "Could not get IServiceProvider interface: %08x\n", hres);
2218
2219     dw = 0xdeadbeef;
2220     SET_EXPECT(QueryInterface_IBindStatusCallbackEx);
2221     SET_EXPECT(GetBindInfo);
2222     hres = IBindStatusCallback_GetBindInfo(holder, &dw, &bindinfo);
2223     ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
2224     CLEAR_CALLED(QueryInterface_IBindStatusCallbackEx); /* IE 8 */
2225     CHECK_CALLED(GetBindInfo);
2226
2227     test_GetBindInfoEx(holder);
2228
2229     SET_EXPECT(OnStartBinding);
2230     hres = IBindStatusCallback_OnStartBinding(holder, 0, (void*)0xdeadbeef);
2231     ok(hres == S_OK, "OnStartBinding failed: %08x\n", hres);
2232     CHECK_CALLED(OnStartBinding);
2233
2234     hres = IBindStatusCallback_QueryInterface(holder, &IID_IHttpNegotiate, (void**)&http_negotiate);
2235     ok(hres == S_OK, "Could not get IHttpNegotiate interface: %08x\n", hres);
2236
2237     SET_EXPECT(QueryInterface_IHttpNegotiate);
2238     hres = IServiceProvider_QueryService(serv_prov, &IID_IHttpNegotiate, &IID_IHttpNegotiate,
2239                                          (void**)&http_negotiate_serv);
2240     ok(hres == S_OK, "Could not get IHttpNegotiate service: %08x\n", hres);
2241     CLEAR_CALLED(QueryInterface_IHttpNegotiate); /* IE <8 */
2242
2243     ok(http_negotiate == http_negotiate_serv, "http_negotiate != http_negotiate_serv\n");
2244
2245     wstr = (void*)0xdeadbeef;
2246     SET_EXPECT(QueryInterface_IHttpNegotiate);
2247     SET_EXPECT(BeginningTransaction);
2248     hres = IHttpNegotiate_BeginningTransaction(http_negotiate_serv, urls[test_protocol], emptyW, 0, &wstr);
2249     CHECK_CALLED_BROKEN(QueryInterface_IHttpNegotiate); /* IE8 */
2250     CHECK_CALLED(BeginningTransaction);
2251     ok(hres == S_OK, "BeginningTransaction failed: %08x\n", hres);
2252     ok(wstr == NULL, "wstr = %p\n", wstr);
2253
2254     IHttpNegotiate_Release(http_negotiate_serv);
2255
2256     hres = IServiceProvider_QueryService(serv_prov, &IID_IHttpNegotiate, &IID_IHttpNegotiate,
2257                                          (void**)&http_negotiate_serv);
2258     ok(hres == S_OK, "Could not get IHttpNegotiate service: %08x\n", hres);
2259     ok(http_negotiate == http_negotiate_serv, "http_negotiate != http_negotiate_serv\n");
2260     IHttpNegotiate_Release(http_negotiate_serv);
2261
2262     hres = IBindStatusCallback_QueryInterface(holder, &IID_IHttpNegotiate2, (void**)&http_negotiate2);
2263     if(SUCCEEDED(hres)) {
2264         have_IHttpNegotiate2 = TRUE;
2265
2266         SET_EXPECT(QueryInterface_IHttpNegotiate2);
2267         hres = IServiceProvider_QueryService(serv_prov, &IID_IHttpNegotiate2, &IID_IHttpNegotiate2,
2268                                              (void**)&http_negotiate2_serv);
2269         ok(hres == S_OK, "Could not get IHttpNegotiate2 service: %08x\n", hres);
2270         CLEAR_CALLED(QueryInterface_IHttpNegotiate2); /* IE <8 */
2271         ok(http_negotiate2 == http_negotiate2_serv, "http_negotiate != http_negotiate_serv\n");
2272
2273         SET_EXPECT(QueryInterface_IHttpNegotiate2);
2274         SET_EXPECT(GetRootSecurityId);
2275         hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, (void*)0xdeadbeef, (void*)0xdeadbeef, 0);
2276         ok(hres == E_NOTIMPL, "GetRootSecurityId failed: %08x\n", hres);
2277         CHECK_CALLED_BROKEN(QueryInterface_IHttpNegotiate2); /* IE8 */
2278         CHECK_CALLED(GetRootSecurityId);
2279
2280         IHttpNegotiate_Release(http_negotiate2_serv);
2281         IHttpNegotiate_Release(http_negotiate2);
2282     }else {
2283         skip("Could not get IHttpNegotiate2\n");
2284         ret = FALSE;
2285     }
2286
2287     SET_EXPECT(OnProgress_FINDINGRESOURCE);
2288     hres = IBindStatusCallback_OnProgress(holder, 0, 0, BINDSTATUS_FINDINGRESOURCE, NULL);
2289     ok(hres == S_OK, "OnProgress failed: %08x\n", hres);
2290     CHECK_CALLED(OnProgress_FINDINGRESOURCE);
2291
2292     SET_EXPECT(QueryInterface_IHttpNegotiate);
2293     SET_EXPECT(OnResponse);
2294     wstr = (void*)0xdeadbeef;
2295     hres = IHttpNegotiate_OnResponse(http_negotiate, 200, emptyW, NULL, NULL);
2296     ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
2297     CHECK_CALLED_BROKEN(QueryInterface_IHttpNegotiate); /* IE8 */
2298     CHECK_CALLED(OnResponse);
2299
2300     IHttpNegotiate_Release(http_negotiate);
2301
2302     hres = IBindStatusCallback_QueryInterface(holder, &IID_IAuthenticate, (void**)&authenticate);
2303     ok(hres == S_OK, "Could not get IAuthenticate interface: %08x\n", hres);
2304
2305     SET_EXPECT(QueryInterface_IAuthenticate);
2306     SET_EXPECT(QueryService_IAuthenticate);
2307     hres = IServiceProvider_QueryService(serv_prov, &IID_IAuthenticate, &IID_IAuthenticate,
2308                                          (void**)&authenticate_serv);
2309     ok(hres == S_OK, "Could not get IAuthenticate service: %08x\n", hres);
2310     CLEAR_CALLED(QueryInterface_IAuthenticate); /* IE <8 */
2311     CLEAR_CALLED(QueryService_IAuthenticate); /* IE <8 */
2312     ok(authenticate == authenticate_serv, "authenticate != authenticate_serv\n");
2313     IAuthenticate_Release(authenticate_serv);
2314
2315     hres = IServiceProvider_QueryService(serv_prov, &IID_IAuthenticate, &IID_IAuthenticate,
2316                                          (void**)&authenticate_serv);
2317     ok(hres == S_OK, "Could not get IAuthenticate service: %08x\n", hres);
2318     ok(authenticate == authenticate_serv, "authenticate != authenticate_serv\n");
2319
2320     IAuthenticate_Release(authenticate);
2321     IAuthenticate_Release(authenticate_serv);
2322
2323     SET_EXPECT(OnStopBinding);
2324     hres = IBindStatusCallback_OnStopBinding(holder, S_OK, NULL);
2325     ok(hres == S_OK, "OnStopBinding failed: %08x\n", hres);
2326     CHECK_CALLED(OnStopBinding);
2327
2328     SET_EXPECT(QueryInterface_IInternetProtocol);
2329     SET_EXPECT(QueryService_IInternetProtocol);
2330     hres = IServiceProvider_QueryService(serv_prov, &IID_IInternetProtocol, &IID_IInternetProtocol,
2331                                          (void**)&protocol);
2332     ok(hres == E_NOINTERFACE, "QueryService(IInternetProtocol) failed: %08x\n", hres);
2333     CHECK_CALLED(QueryInterface_IInternetProtocol);
2334     CHECK_CALLED(QueryService_IInternetProtocol);
2335
2336     IServiceProvider_Release(serv_prov);
2337     return ret;
2338 }
2339
2340 static BOOL test_RegisterBindStatusCallback(void)
2341 {
2342     IBindStatusCallback *prevbsc, *clb, *prev_clb;
2343     IBindCtx *bindctx;
2344     BOOL ret = TRUE;
2345     IUnknown *unk;
2346     HRESULT hres;
2347
2348     hres = CreateBindCtx(0, &bindctx);
2349     ok(hres == S_OK, "BindCtx failed: %08x\n", hres);
2350
2351     SET_EXPECT(QueryInterface_IServiceProvider);
2352
2353     hres = IBindCtx_RegisterObjectParam(bindctx, BSCBHolder, (IUnknown*)&bsc);
2354     ok(hres == S_OK, "RegisterObjectParam failed: %08x\n", hres);
2355
2356     SET_EXPECT(QueryInterface_IBindStatusCallback);
2357     SET_EXPECT(QueryInterface_IBindStatusCallbackHolder);
2358     prevbsc = (void*)0xdeadbeef;
2359     hres = RegisterBindStatusCallback(bindctx, (IBindStatusCallback*)&bsc, &prevbsc, 0);
2360     ok(hres == S_OK, "RegisterBindStatusCallback failed: %08x\n", hres);
2361     ok(prevbsc == (IBindStatusCallback*)&bsc, "prevbsc=%p\n", prevbsc);
2362     CHECK_CALLED(QueryInterface_IBindStatusCallback);
2363     CHECK_CALLED(QueryInterface_IBindStatusCallbackHolder);
2364
2365     CHECK_CALLED(QueryInterface_IServiceProvider);
2366
2367     hres = IBindCtx_GetObjectParam(bindctx, BSCBHolder, &unk);
2368     ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres);
2369
2370     hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&clb);
2371     IUnknown_Release(unk);
2372     ok(hres == S_OK, "QueryInterface(IID_IBindStatusCallback) failed: %08x\n", hres);
2373     ok(clb != (IBindStatusCallback*)&bsc, "bsc == clb\n");
2374
2375     if(!test_bscholder(clb))
2376         ret = FALSE;
2377
2378     IBindStatusCallback_Release(clb);
2379
2380     hres = RevokeBindStatusCallback(bindctx, (IBindStatusCallback*)&bsc);
2381     ok(hres == S_OK, "RevokeBindStatusCallback failed: %08x\n", hres);
2382
2383     unk = (void*)0xdeadbeef;
2384     hres = IBindCtx_GetObjectParam(bindctx, BSCBHolder, &unk);
2385     ok(hres == E_FAIL, "GetObjectParam failed: %08x\n", hres);
2386     ok(unk == NULL, "unk != NULL\n");
2387
2388     if(unk)
2389         IUnknown_Release(unk);
2390
2391     hres = RevokeBindStatusCallback(bindctx, (void*)0xdeadbeef);
2392     ok(hres == S_OK, "RevokeBindStatusCallback failed: %08x\n", hres);
2393
2394     hres = RevokeBindStatusCallback(NULL, (void*)0xdeadbeef);
2395     ok(hres == E_INVALIDARG, "RevokeBindStatusCallback failed: %08x\n", hres);
2396
2397     hres = RevokeBindStatusCallback(bindctx, NULL);
2398     ok(hres == E_INVALIDARG, "RevokeBindStatusCallback failed: %08x\n", hres);
2399
2400     SET_EXPECT(QueryInterface_IServiceProvider);
2401     prevbsc = (void*)0xdeadbeef;
2402     hres = RegisterBindStatusCallback(bindctx, (IBindStatusCallback*)&bsc, &prevbsc, 0);
2403     ok(hres == S_OK, "RegisterBindStatusCallback failed: %08x\n", hres);
2404     ok(!prevbsc, "prevbsc=%p\n", prevbsc);
2405     CHECK_CALLED(QueryInterface_IServiceProvider);
2406
2407     hres = IBindCtx_GetObjectParam(bindctx, BSCBHolder, &unk);
2408     ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres);
2409
2410     hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&prev_clb);
2411     IUnknown_Release(unk);
2412     ok(hres == S_OK, "QueryInterface(IID_IBindStatusCallback) failed: %08x\n", hres);
2413     ok(prev_clb != (IBindStatusCallback*)&bsc, "bsc == clb\n");
2414
2415     SET_EXPECT(QueryInterface_IServiceProvider);
2416     prevbsc = (void*)0xdeadbeef;
2417     hres = RegisterBindStatusCallback(bindctx, (IBindStatusCallback*)&bsc2, &prevbsc, 0);
2418     ok(hres == S_OK, "RegisterBindStatusCallback failed: %08x\n", hres);
2419     ok(prevbsc == (IBindStatusCallback*)&bsc, "prevbsc != bsc\n");
2420     CHECK_CALLED(QueryInterface_IServiceProvider);
2421
2422     hres = IBindCtx_GetObjectParam(bindctx, BSCBHolder, &unk);
2423     ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres);
2424
2425     hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&clb);
2426     IUnknown_Release(unk);
2427     ok(hres == S_OK, "QueryInterface(IID_IBindStatusCallback) failed: %08x\n", hres);
2428     ok(prev_clb  == clb, "bsc != clb\n");
2429
2430     IBindStatusCallback_Release(clb);
2431     IBindStatusCallback_Release(prev_clb);
2432
2433     IBindCtx_Release(bindctx);
2434     return ret;
2435 }
2436
2437 #define BINDTEST_EMULATE       0x0001
2438 #define BINDTEST_TOOBJECT      0x0002
2439 #define BINDTEST_FILEDWLAPI    0x0004
2440 #define BINDTEST_HTTPRESPONSE  0x0008
2441 #define BINDTEST_REDIRECT      0x0010
2442 #define BINDTEST_USE_CACHE     0x0020
2443 #define BINDTEST_NO_CALLBACK_READ  0x0040
2444 #define BINDTEST_NO_CALLBACK   0x0080
2445 #define BINDTEST_ABORT         0x0100
2446
2447 static void init_bind_test(int protocol, DWORD flags, DWORD t)
2448 {
2449     test_protocol = protocol;
2450     emulate_protocol = (flags & BINDTEST_EMULATE) != 0;
2451     download_state = BEFORE_DOWNLOAD;
2452     stopped_binding = FALSE;
2453     stopped_obj_binding = FALSE;
2454     data_available = FALSE;
2455     mime_type[0] = 0;
2456     binding_hres = S_OK;
2457     bind_to_object = (flags & BINDTEST_TOOBJECT) != 0;
2458     tymed = t;
2459     filedwl_api = (flags & BINDTEST_FILEDWLAPI) != 0;
2460     if(flags & BINDTEST_HTTPRESPONSE)
2461         urls[HTTP_TEST] = SHORT_RESPONSE_URL;
2462     else
2463         urls[HTTP_TEST] = WINE_ABOUT_URL;
2464     test_redirect = (flags & BINDTEST_REDIRECT) != 0;
2465     use_cache_file = (flags & BINDTEST_USE_CACHE) != 0;
2466     callback_read = !(flags & BINDTEST_NO_CALLBACK_READ);
2467     no_callback = (flags & BINDTEST_NO_CALLBACK) != 0;
2468     test_abort = (flags & BINDTEST_ABORT) != 0;
2469     is_async_prot = protocol == HTTP_TEST || protocol == HTTPS_TEST || protocol == FTP_TEST || protocol == WINETEST_TEST;
2470 }
2471
2472 static void test_BindToStorage(int protocol, DWORD flags, DWORD t)
2473 {
2474     IMoniker *mon;
2475     HRESULT hres;
2476     LPOLESTR display_name;
2477     IBindCtx *bctx = NULL;
2478     MSG msg;
2479     IBindStatusCallback *previousclb;
2480     IUnknown *unk = (IUnknown*)0x00ff00ff;
2481     IBinding *bind;
2482
2483     init_bind_test(protocol, flags, t);
2484
2485     if(no_callback) {
2486         hres = CreateBindCtx(0, &bctx);
2487         ok(hres == S_OK, "CreateBindCtx failed: %08x\n", hres);
2488     }else {
2489         SET_EXPECT(QueryInterface_IServiceProvider);
2490         hres = CreateAsyncBindCtx(0, (IBindStatusCallback*)&bsc, NULL, &bctx);
2491         ok(hres == S_OK, "CreateAsyncBindCtx failed: %08x\n\n", hres);
2492         CHECK_CALLED(QueryInterface_IServiceProvider);
2493         if(FAILED(hres))
2494             return;
2495
2496         SET_EXPECT(QueryInterface_IServiceProvider);
2497         hres = RegisterBindStatusCallback(bctx, (IBindStatusCallback*)&bsc, &previousclb, 0);
2498         ok(hres == S_OK, "RegisterBindStatusCallback failed: %08x\n", hres);
2499         ok(previousclb == (IBindStatusCallback*)&bsc, "previousclb(%p) != sclb(%p)\n", previousclb, &bsc);
2500         CHECK_CALLED(QueryInterface_IServiceProvider);
2501         if(previousclb)
2502             IBindStatusCallback_Release(previousclb);
2503     }
2504
2505     hres = CreateURLMoniker(NULL, test_protocol == FILE_TEST ? file_url : urls[test_protocol], &mon);
2506     ok(hres == S_OK, "failed to create moniker: %08x\n", hres);
2507     if(FAILED(hres))
2508         return;
2509
2510     hres = IMoniker_QueryInterface(mon, &IID_IBinding, (void**)&bind);
2511     ok(hres == E_NOINTERFACE, "IMoniker should not have IBinding interface\n");
2512     if(SUCCEEDED(hres))
2513         IBinding_Release(bind);
2514
2515     hres = IMoniker_GetDisplayName(mon, bctx, NULL, &display_name);
2516     ok(hres == S_OK, "GetDisplayName failed %08x\n", hres);
2517     ok(!lstrcmpW(display_name, urls[test_protocol]),
2518        "GetDisplayName got wrong name %s\n", wine_dbgstr_w(display_name));
2519     CoTaskMemFree(display_name);
2520
2521     if(tymed == TYMED_FILE && (test_protocol == ABOUT_TEST || test_protocol == ITS_TEST))
2522         binding_hres = INET_E_DATA_NOT_AVAILABLE;
2523
2524     if(only_check_prot_args)
2525         SET_EXPECT(OnStopBinding);
2526     if(!no_callback) {
2527         SET_EXPECT(QueryInterface_IBindStatusCallbackEx);
2528         SET_EXPECT(GetBindInfo);
2529         SET_EXPECT(QueryInterface_IInternetProtocol);
2530         if(!emulate_protocol)
2531             SET_EXPECT(QueryService_IInternetProtocol);
2532         SET_EXPECT(OnStartBinding);
2533     }
2534     if(emulate_protocol) {
2535         if(is_urlmon_protocol(test_protocol))
2536             SET_EXPECT(SetPriority);
2537         SET_EXPECT(Start);
2538         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST)
2539             SET_EXPECT(Terminate);
2540         if(tymed != TYMED_FILE || (test_protocol != ABOUT_TEST && test_protocol != ITS_TEST))
2541             SET_EXPECT(UnlockRequest);
2542     }else {
2543         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST) {
2544             SET_EXPECT(QueryInterface_IInternetBindInfo);
2545             SET_EXPECT(QueryService_IInternetBindInfo);
2546             SET_EXPECT(QueryInterface_IHttpNegotiate);
2547             SET_EXPECT(QueryInterface_IWindowForBindingUI);
2548             SET_EXPECT(QueryService_IWindowForBindingUI);
2549             SET_EXPECT(BeginningTransaction);
2550             SET_EXPECT(QueryInterface_IHttpNegotiate2);
2551             SET_EXPECT(GetRootSecurityId);
2552             SET_EXPECT(OnProgress_FINDINGRESOURCE);
2553             SET_EXPECT(OnProgress_CONNECTING);
2554         }
2555         if(!no_callback) {
2556             if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == FTP_TEST
2557                || test_protocol == FILE_TEST || test_protocol == WINETEST_TEST)
2558                 SET_EXPECT(OnProgress_SENDINGREQUEST);
2559             if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST) {
2560                 SET_EXPECT(QueryInterface_IHttpNegotiate);
2561                 SET_EXPECT(OnResponse);
2562             }
2563             SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
2564             SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
2565             if(test_protocol == FILE_TEST)
2566                 SET_EXPECT(OnProgress_CACHEFILENAMEAVAILABLE);
2567             if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == FTP_TEST || test_protocol == WINETEST_TEST)
2568                 SET_EXPECT(OnProgress_DOWNLOADINGDATA);
2569             SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
2570             if(tymed != TYMED_FILE || test_protocol != ABOUT_TEST)
2571                 SET_EXPECT(OnDataAvailable);
2572             SET_EXPECT(OnStopBinding);
2573         }
2574     }
2575
2576     hres = IMoniker_BindToStorage(mon, bctx, NULL, tymed == TYMED_ISTREAM ? &IID_IStream : &IID_IUnknown, (void**)&unk);
2577     if ((test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
2578         && hres == HRESULT_FROM_WIN32(ERROR_INTERNET_NAME_NOT_RESOLVED))
2579     {
2580         skip("Network unreachable, skipping tests\n");
2581         return;
2582     }
2583
2584     if(only_check_prot_args) {
2585         ok(hres == E_FAIL, "Got %08x\n", hres);
2586         CHECK_CALLED(OnStopBinding);
2587     }else if(no_callback) {
2588         if(emulate_protocol)
2589             WaitForSingleObject(complete_event2, INFINITE);
2590         ok(hres == S_OK, "IMoniker_BindToStorage failed: %08x\n", hres);
2591         ok(unk != NULL, "unk == NULL\n");
2592     }else if(!(bindf & BINDF_ASYNCHRONOUS) && tymed == TYMED_FILE) {
2593         ok(hres == S_OK, "IMoniker_BindToStorage failed: %08x\n", hres);
2594         ok(unk == NULL, "unk != NULL\n");
2595     }else if(((bindf & BINDF_ASYNCHRONOUS) && !data_available)
2596        || (tymed == TYMED_FILE && test_protocol == FILE_TEST)) {
2597         ok(hres == MK_S_ASYNCHRONOUS, "IMoniker_BindToStorage failed: %08x\n", hres);
2598         ok(unk == NULL, "istr should be NULL\n");
2599     }else if(tymed == TYMED_FILE && test_protocol == ABOUT_TEST) {
2600         ok(hres == INET_E_DATA_NOT_AVAILABLE,
2601            "IMoniker_BindToStorage failed: %08x, expected INET_E_DATA_NOT_AVAILABLE\n", hres);
2602         ok(unk == NULL, "istr should be NULL\n");
2603     }else {
2604         ok(hres == S_OK, "IMoniker_BindToStorage failed: %08x\n", hres);
2605         ok(unk != NULL, "unk == NULL\n");
2606     }
2607     if(unk && callback_read && !no_callback) {
2608         IUnknown_Release(unk);
2609         unk = NULL;
2610     }
2611
2612     if(FAILED(hres))
2613         return;
2614
2615     if((bindf & BINDF_ASYNCHRONOUS) && !no_callback) {
2616         while(!stopped_binding && GetMessage(&msg,NULL,0,0)) {
2617             TranslateMessage(&msg);
2618             DispatchMessage(&msg);
2619         }
2620     }
2621
2622     if(!no_callback) {
2623         CLEAR_CALLED(QueryInterface_IBindStatusCallbackEx); /* IE 8 */
2624         CHECK_CALLED(GetBindInfo);
2625         CHECK_CALLED(QueryInterface_IInternetProtocol);
2626         if(!emulate_protocol)
2627             CHECK_CALLED(QueryService_IInternetProtocol);
2628         CHECK_CALLED(OnStartBinding);
2629     }
2630     if(emulate_protocol) {
2631         if(is_urlmon_protocol(test_protocol))
2632             CHECK_CALLED(SetPriority);
2633         CHECK_CALLED(Start);
2634         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST) {
2635             if(tymed == TYMED_FILE)
2636                 CLEAR_CALLED(Read);
2637             CHECK_CALLED(Terminate);
2638         }
2639         if(tymed != TYMED_FILE || (test_protocol != ABOUT_TEST && test_protocol != ITS_TEST))
2640             CHECK_CALLED(UnlockRequest);
2641     }else {
2642         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST) {
2643             CLEAR_CALLED(QueryInterface_IInternetBindInfo);
2644             CLEAR_CALLED(QueryService_IInternetBindInfo);
2645             CHECK_CALLED(QueryInterface_IHttpNegotiate);
2646             CLEAR_CALLED(QueryInterface_IWindowForBindingUI);
2647             CLEAR_CALLED(QueryService_IWindowForBindingUI);
2648             CHECK_CALLED(BeginningTransaction);
2649             if (have_IHttpNegotiate2)
2650             {
2651                 CHECK_CALLED(QueryInterface_IHttpNegotiate2);
2652                 CHECK_CALLED(GetRootSecurityId);
2653             }
2654             if(http_is_first || test_protocol == HTTPS_TEST) {
2655                 CHECK_CALLED(OnProgress_FINDINGRESOURCE);
2656                 CHECK_CALLED(OnProgress_CONNECTING);
2657             }else todo_wine {
2658                 CHECK_NOT_CALLED(OnProgress_FINDINGRESOURCE);
2659                 /* IE7 does call this */
2660                 CLEAR_CALLED(OnProgress_CONNECTING);
2661             }
2662         }
2663         if(!no_callback) {
2664             if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == FILE_TEST || test_protocol == WINETEST_TEST)
2665                 CHECK_CALLED(OnProgress_SENDINGREQUEST);
2666             else if(test_protocol == FTP_TEST)
2667                 todo_wine CHECK_CALLED(OnProgress_SENDINGREQUEST);
2668             if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST) {
2669                 CLEAR_CALLED(QueryInterface_IHttpNegotiate);
2670                 CHECK_CALLED(OnResponse);
2671             }
2672             CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
2673             CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
2674             if(test_protocol == FILE_TEST)
2675                 CHECK_CALLED(OnProgress_CACHEFILENAMEAVAILABLE);
2676             if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == FTP_TEST  || test_protocol == WINETEST_TEST)
2677                 CLEAR_CALLED(OnProgress_DOWNLOADINGDATA);
2678             CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
2679             if(tymed != TYMED_FILE || test_protocol != ABOUT_TEST)
2680                 CHECK_CALLED(OnDataAvailable);
2681             CHECK_CALLED(OnStopBinding);
2682         }
2683     }
2684
2685     ok(IMoniker_Release(mon) == 0, "mon should be destroyed here\n");
2686     if(bctx)
2687         ok(IBindCtx_Release(bctx) == 0, "bctx should be destroyed here\n");
2688
2689     if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
2690         http_is_first = FALSE;
2691
2692     if(unk) {
2693         BYTE buf[512];
2694         DWORD readed;
2695         IStream *stream;
2696
2697         hres = IUnknown_QueryInterface(unk, &IID_IStream, (void**)&stream);
2698         ok(hres == S_OK, "Could not get IStream iface: %08x\n", hres);
2699         IUnknown_Release(unk);
2700
2701         do {
2702             readed = 0xdeadbeef;
2703             hres = IStream_Read(stream, buf, sizeof(buf), &readed);
2704             ok(readed != 0xdeadbeef, "readed = 0xdeadbeef\n");
2705             if(emulate_protocol && test_protocol == HTTP_TEST && readed)
2706                 ok(buf[0] == (use_cache_file && !(bindf&BINDF_ASYNCHRONOUS) ? 'X' : '?'), "buf[0] = '%c'\n", buf[0]);
2707         }while(hres == S_OK);
2708         ok(hres == S_FALSE, "IStream_Read returned %08x\n", hres);
2709         ok(!readed, "readed = %d\n", readed);
2710
2711         IStream_Release(stream);
2712     }
2713 }
2714
2715 static void test_BindToObject(int protocol, DWORD flags)
2716 {
2717     IMoniker *mon;
2718     HRESULT hres;
2719     LPOLESTR display_name;
2720     IBindCtx *bctx;
2721     DWORD regid;
2722     MSG msg;
2723     IUnknown *unk = (IUnknown*)0x00ff00ff;
2724     IBinding *bind;
2725
2726     init_bind_test(protocol, BINDTEST_TOOBJECT|flags, TYMED_ISTREAM);
2727
2728     if(emulate_protocol)
2729         CoRegisterClassObject(&CLSID_HTMLDocument, (IUnknown *)&mime_cf,
2730                               CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &regid);
2731
2732     SET_EXPECT(QueryInterface_IServiceProvider);
2733     hres = CreateAsyncBindCtx(0, (IBindStatusCallback*)&objbsc, NULL, &bctx);
2734     ok(SUCCEEDED(hres), "CreateAsyncBindCtx failed: %08x\n\n", hres);
2735     CHECK_CALLED(QueryInterface_IServiceProvider);
2736     if(FAILED(hres))
2737         return;
2738
2739     hres = CreateURLMoniker(NULL, test_protocol == FILE_TEST ? file_url : urls[test_protocol], &mon);
2740     ok(SUCCEEDED(hres), "failed to create moniker: %08x\n", hres);
2741     if(FAILED(hres)) {
2742         IBindCtx_Release(bctx);
2743         return;
2744     }
2745
2746     hres = IMoniker_QueryInterface(mon, &IID_IBinding, (void**)&bind);
2747     ok(hres == E_NOINTERFACE, "IMoniker should not have IBinding interface\n");
2748     if(SUCCEEDED(hres))
2749         IBinding_Release(bind);
2750
2751     hres = IMoniker_GetDisplayName(mon, bctx, NULL, &display_name);
2752     ok(hres == S_OK, "GetDisplayName failed %08x\n", hres);
2753     ok(!lstrcmpW(display_name, urls[test_protocol]), "GetDisplayName got wrong name\n");
2754
2755     SET_EXPECT(QueryInterface_IBindStatusCallbackEx);
2756     SET_EXPECT(Obj_GetBindInfo);
2757     SET_EXPECT(QueryInterface_IInternetProtocol);
2758     if(!emulate_protocol)
2759         SET_EXPECT(QueryService_IInternetProtocol);
2760     SET_EXPECT(Obj_OnStartBinding);
2761     if(emulate_protocol) {
2762         if(is_urlmon_protocol(test_protocol))
2763             SET_EXPECT(SetPriority);
2764         SET_EXPECT(Start);
2765         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
2766             SET_EXPECT(Terminate);
2767         if(test_protocol == FILE_TEST)
2768             SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
2769         SET_EXPECT(UnlockRequest);
2770     }else {
2771         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST) {
2772             SET_EXPECT(QueryInterface_IHttpNegotiate);
2773             SET_EXPECT(BeginningTransaction);
2774             SET_EXPECT(QueryInterface_IHttpNegotiate2);
2775             SET_EXPECT(GetRootSecurityId);
2776             SET_EXPECT(Obj_OnProgress_FINDINGRESOURCE);
2777             SET_EXPECT(Obj_OnProgress_CONNECTING);
2778             SET_EXPECT(QueryInterface_IWindowForBindingUI);
2779             SET_EXPECT(QueryService_IWindowForBindingUI);
2780         }
2781         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == FILE_TEST)
2782             SET_EXPECT(Obj_OnProgress_SENDINGREQUEST);
2783         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST) {
2784             SET_EXPECT(QueryInterface_IHttpNegotiate);
2785             SET_EXPECT(OnResponse);
2786         }
2787         SET_EXPECT(Obj_OnProgress_MIMETYPEAVAILABLE);
2788         SET_EXPECT(Obj_OnProgress_BEGINDOWNLOADDATA);
2789         if(test_protocol == FILE_TEST)
2790             SET_EXPECT(Obj_OnProgress_CACHEFILENAMEAVAILABLE);
2791         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
2792             SET_EXPECT(OnProgress_DOWNLOADINGDATA);
2793         SET_EXPECT(Obj_OnProgress_ENDDOWNLOADDATA);
2794         SET_EXPECT(Obj_OnProgress_CLASSIDAVAILABLE);
2795         SET_EXPECT(Obj_OnProgress_BEGINSYNCOPERATION);
2796         SET_EXPECT(Obj_OnProgress_ENDSYNCOPERATION);
2797         SET_EXPECT(OnObjectAvailable);
2798         SET_EXPECT(Obj_OnStopBinding);
2799     }
2800
2801     hres = IMoniker_BindToObject(mon, bctx, NULL, &IID_IUnknown, (void**)&unk);
2802
2803     if ((test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
2804         && hres == HRESULT_FROM_WIN32(ERROR_INTERNET_NAME_NOT_RESOLVED))
2805     {
2806         skip( "Network unreachable, skipping tests\n" );
2807         return;
2808     }
2809
2810     /* no point testing the calls if binding didn't even work */
2811     if (FAILED(hres)) return;
2812
2813     if(bindf & BINDF_ASYNCHRONOUS) {
2814         ok(hres == MK_S_ASYNCHRONOUS, "IMoniker_BindToObject failed: %08x\n", hres);
2815         ok(unk == NULL, "istr should be NULL\n");
2816     }else {
2817         ok(hres == S_OK, "IMoniker_BindToStorage failed: %08x\n", hres);
2818         ok(unk != NULL, "unk == NULL\n");
2819         if(emulate_protocol)
2820             ok(unk == (IUnknown*)&PersistMoniker, "unk != PersistMoniker\n");
2821     }
2822     if(unk)
2823         IUnknown_Release(unk);
2824
2825     while((bindf & BINDF_ASYNCHRONOUS) &&
2826           !((!emulate_protocol || stopped_binding) && stopped_obj_binding) && GetMessage(&msg,NULL,0,0)) {
2827         TranslateMessage(&msg);
2828         DispatchMessage(&msg);
2829     }
2830
2831     CLEAR_CALLED(QueryInterface_IBindStatusCallbackEx);
2832     CHECK_CALLED(Obj_GetBindInfo);
2833     CHECK_CALLED(QueryInterface_IInternetProtocol);
2834     if(!emulate_protocol)
2835         CHECK_CALLED(QueryService_IInternetProtocol);
2836     CHECK_CALLED(Obj_OnStartBinding);
2837     if(emulate_protocol) {
2838         if(is_urlmon_protocol(test_protocol))
2839             CHECK_CALLED(SetPriority);
2840         CHECK_CALLED(Start);
2841         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
2842             CHECK_CALLED(Terminate);
2843         if(test_protocol == FILE_TEST)
2844             CLEAR_CALLED(OnProgress_MIMETYPEAVAILABLE); /* not called in IE7 */
2845         CHECK_CALLED(UnlockRequest);
2846     }else {
2847         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST) {
2848             CHECK_CALLED(QueryInterface_IHttpNegotiate);
2849             CHECK_CALLED(BeginningTransaction);
2850             if (have_IHttpNegotiate2)
2851             {
2852                 CHECK_CALLED(QueryInterface_IHttpNegotiate2);
2853                 CHECK_CALLED(GetRootSecurityId);
2854             }
2855             if(http_is_first) {
2856                 CHECK_CALLED(Obj_OnProgress_FINDINGRESOURCE);
2857                 CHECK_CALLED(Obj_OnProgress_CONNECTING);
2858             }else todo_wine {
2859                 CHECK_NOT_CALLED(Obj_OnProgress_FINDINGRESOURCE);
2860                 /* IE7 does call this */
2861                 CLEAR_CALLED(Obj_OnProgress_CONNECTING);
2862             }
2863             CLEAR_CALLED(QueryInterface_IWindowForBindingUI);
2864             CLEAR_CALLED(QueryService_IWindowForBindingUI);
2865         }
2866         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == FILE_TEST) {
2867             if(urls[test_protocol] == SHORT_RESPONSE_URL)
2868                 CLEAR_CALLED(Obj_OnProgress_SENDINGREQUEST);
2869             else
2870                 CHECK_CALLED(Obj_OnProgress_SENDINGREQUEST);
2871         }
2872         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST) {
2873             CLEAR_CALLED(QueryInterface_IHttpNegotiate);
2874             CHECK_CALLED(OnResponse);
2875         }
2876         CHECK_CALLED(Obj_OnProgress_MIMETYPEAVAILABLE);
2877         CHECK_CALLED(Obj_OnProgress_BEGINDOWNLOADDATA);
2878         if(test_protocol == FILE_TEST)
2879             CHECK_CALLED(Obj_OnProgress_CACHEFILENAMEAVAILABLE);
2880         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
2881             CLEAR_CALLED(OnProgress_DOWNLOADINGDATA);
2882         CLEAR_CALLED(Obj_OnProgress_ENDDOWNLOADDATA);
2883         CHECK_CALLED(Obj_OnProgress_CLASSIDAVAILABLE);
2884         CHECK_CALLED(Obj_OnProgress_BEGINSYNCOPERATION);
2885         CHECK_CALLED(Obj_OnProgress_ENDSYNCOPERATION);
2886         CHECK_CALLED(OnObjectAvailable);
2887         CHECK_CALLED(Obj_OnStopBinding);
2888     }
2889
2890     ok(IMoniker_Release(mon) == 0, "mon should be destroyed here\n");
2891     if(test_protocol != HTTP_TEST || emulate_protocol || !(bindf & BINDF_ASYNCHRONOUS))
2892         ok(IBindCtx_Release(bctx) == 0, "bctx should be destroyed here\n");
2893     else
2894         IBindCtx_Release(bctx);
2895
2896     if(emulate_protocol)
2897         CoRevokeClassObject(regid);
2898
2899     if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
2900         http_is_first = FALSE;
2901 }
2902
2903 static void test_URLDownloadToFile(DWORD prot, BOOL emul)
2904 {
2905     BOOL res;
2906     HRESULT hres;
2907
2908     init_bind_test(prot, BINDTEST_FILEDWLAPI | (emul ? BINDTEST_EMULATE : 0), TYMED_FILE);
2909
2910     SET_EXPECT(GetBindInfo);
2911     SET_EXPECT(QueryInterface_IInternetProtocol);
2912     if(!emulate_protocol) {
2913         SET_EXPECT(QueryInterface_IServiceProvider);
2914         SET_EXPECT(QueryService_IInternetProtocol);
2915     }
2916     SET_EXPECT(OnStartBinding);
2917     if(emulate_protocol) {
2918         if(is_urlmon_protocol(test_protocol))
2919             SET_EXPECT(SetPriority);
2920         SET_EXPECT(Start);
2921         SET_EXPECT(UnlockRequest);
2922     }else {
2923         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST) {
2924             SET_EXPECT(QueryInterface_IHttpNegotiate);
2925             SET_EXPECT(BeginningTransaction);
2926             SET_EXPECT(QueryInterface_IHttpNegotiate2);
2927             SET_EXPECT(GetRootSecurityId);
2928             SET_EXPECT(QueryInterface_IWindowForBindingUI);
2929             SET_EXPECT(OnProgress_CONNECTING);
2930         }
2931         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == FILE_TEST)
2932             SET_EXPECT(OnProgress_SENDINGREQUEST);
2933         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST) {
2934             SET_EXPECT(QueryInterface_IHttpNegotiate);
2935             SET_EXPECT(OnResponse);
2936         }
2937         SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
2938         SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
2939         if(test_protocol == FILE_TEST)
2940             SET_EXPECT(OnProgress_CACHEFILENAMEAVAILABLE);
2941         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
2942             SET_EXPECT(OnProgress_DOWNLOADINGDATA);
2943         SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
2944         SET_EXPECT(OnStopBinding);
2945     }
2946
2947     hres = URLDownloadToFileW(NULL, test_protocol == FILE_TEST ? file_url : urls[test_protocol],
2948             dwl_htmlW, 0, (IBindStatusCallback*)&bsc);
2949     ok(hres == S_OK, "URLDownloadToFile failed: %08x\n", hres);
2950
2951     CHECK_CALLED(GetBindInfo);
2952     CHECK_CALLED(QueryInterface_IInternetProtocol);
2953     if(!emulate_protocol) {
2954         CHECK_CALLED(QueryInterface_IServiceProvider);
2955         CHECK_CALLED(QueryService_IInternetProtocol);
2956     }
2957     CHECK_CALLED(OnStartBinding);
2958     if(emulate_protocol) {
2959         if(is_urlmon_protocol(test_protocol))
2960             CHECK_CALLED(SetPriority);
2961         CHECK_CALLED(Start);
2962         CHECK_CALLED(UnlockRequest);
2963     }else {
2964         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST) {
2965             CHECK_CALLED(QueryInterface_IHttpNegotiate);
2966             CHECK_CALLED(BeginningTransaction);
2967             if (have_IHttpNegotiate2)
2968             {
2969                 CHECK_CALLED(QueryInterface_IHttpNegotiate2);
2970                 CHECK_CALLED(GetRootSecurityId);
2971             }
2972             CLEAR_CALLED(QueryInterface_IWindowForBindingUI);
2973             CLEAR_CALLED(OnProgress_CONNECTING);
2974         }
2975         if(test_protocol == FILE_TEST)
2976             CHECK_CALLED(OnProgress_SENDINGREQUEST);
2977         else if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
2978             CLEAR_CALLED(OnProgress_SENDINGREQUEST); /* not called by IE7 */
2979         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST) {
2980             CLEAR_CALLED(QueryInterface_IHttpNegotiate);
2981             CHECK_CALLED(OnResponse);
2982         }
2983         CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
2984         CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
2985         if(test_protocol == FILE_TEST)
2986             CHECK_CALLED(OnProgress_CACHEFILENAMEAVAILABLE);
2987         if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST)
2988             CLEAR_CALLED(OnProgress_DOWNLOADINGDATA);
2989         CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
2990         CHECK_CALLED(OnStopBinding);
2991     }
2992
2993     res = DeleteFileA(dwl_htmlA);
2994     ok(res, "DeleteFile failed: %u\n", GetLastError());
2995
2996     if(prot != FILE_TEST || emul)
2997         return;
2998
2999     hres = URLDownloadToFileW(NULL, urls[test_protocol], dwl_htmlW, 0, NULL);
3000     ok(hres == S_OK, "URLDownloadToFile failed: %08x\n", hres);
3001
3002     res = DeleteFileA(dwl_htmlA);
3003     ok(res, "DeleteFile failed: %u\n", GetLastError());
3004 }
3005
3006 static void set_file_url(char *path)
3007 {
3008     CHAR file_urlA[INTERNET_MAX_URL_LENGTH];
3009     CHAR INDEX_HTMLA[MAX_PATH];
3010
3011     lstrcpyA(file_urlA, "file:///");
3012     lstrcatA(file_urlA, path);
3013     MultiByteToWideChar(CP_ACP, 0, file_urlA, -1, file_url, INTERNET_MAX_URL_LENGTH);
3014
3015     lstrcpyA(INDEX_HTMLA, "file://");
3016     lstrcatA(INDEX_HTMLA, path);
3017     MultiByteToWideChar(CP_ACP, 0, INDEX_HTMLA, -1, INDEX_HTML, MAX_PATH);
3018 }
3019
3020 static void create_file(void)
3021 {
3022     HANDLE file;
3023     DWORD size;
3024     CHAR path[MAX_PATH];
3025
3026     static const char html_doc[] = "<HTML></HTML>";
3027
3028     file = CreateFileA(wszIndexHtmlA, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
3029             FILE_ATTRIBUTE_NORMAL, NULL);
3030     ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
3031     if(file == INVALID_HANDLE_VALUE)
3032         return;
3033
3034     WriteFile(file, html_doc, sizeof(html_doc)-1, &size, NULL);
3035     CloseHandle(file);
3036
3037     GetCurrentDirectoryA(MAX_PATH, path);
3038     lstrcatA(path, "\\");
3039     lstrcatA(path, wszIndexHtmlA);
3040     set_file_url(path);
3041 }
3042
3043 static void create_cache_file(void)
3044 {
3045     char buf[6500], curdir[MAX_PATH];
3046     HANDLE file;
3047     DWORD size;
3048
3049     file = CreateFileA(test_txtA, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
3050             FILE_ATTRIBUTE_NORMAL, NULL);
3051     ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
3052     if(file == INVALID_HANDLE_VALUE)
3053         return;
3054
3055     memset(buf, 'X', sizeof(buf));
3056     WriteFile(file, buf, sizeof(buf), &size, NULL);
3057     CloseHandle(file);
3058
3059     memset(curdir, 0, sizeof(curdir));
3060     GetCurrentDirectoryA(MAX_PATH, curdir);
3061     lstrcatA(curdir, "\\");
3062     lstrcatA(curdir, test_txtA);
3063
3064     MultiByteToWideChar(CP_ACP, 0, curdir, -1, cache_file_name, MAX_PATH);
3065 }
3066
3067 static void test_ReportResult(HRESULT exhres)
3068 {
3069     IMoniker *mon = NULL;
3070     IBindCtx *bctx = NULL;
3071     IUnknown *unk = (void*)0xdeadbeef;
3072     HRESULT hres;
3073
3074     init_bind_test(ABOUT_TEST, BINDTEST_EMULATE, TYMED_ISTREAM);
3075     binding_hres = exhres;
3076
3077     hres = CreateURLMoniker(NULL, ABOUT_BLANK, &mon);
3078     ok(hres == S_OK, "CreateURLMoniker failed: %08x\n", hres);
3079
3080     SET_EXPECT(QueryInterface_IServiceProvider);
3081     hres = CreateAsyncBindCtx(0, (IBindStatusCallback*)&bsc, NULL, &bctx);
3082     ok(hres == S_OK, "CreateAsyncBindCtx failed: %08x\n\n", hres);
3083     CHECK_CALLED(QueryInterface_IServiceProvider);
3084
3085     SET_EXPECT(QueryInterface_IBindStatusCallbackEx);
3086     SET_EXPECT(GetBindInfo);
3087     SET_EXPECT(QueryInterface_IInternetProtocol);
3088     SET_EXPECT(OnStartBinding);
3089     if(is_urlmon_protocol(test_protocol))
3090         SET_EXPECT(SetPriority);
3091     SET_EXPECT(Start);
3092
3093     hres = IMoniker_BindToStorage(mon, bctx, NULL, &IID_IStream, (void**)&unk);
3094     if(SUCCEEDED(exhres))
3095         ok(hres == S_OK || hres == MK_S_ASYNCHRONOUS, "BindToStorage failed: %08x\n", hres);
3096     else
3097         ok(hres == exhres || hres == MK_S_ASYNCHRONOUS,
3098            "BindToStorage failed: %08x, expected %08x or MK_S_ASYNCHRONOUS\n", hres, exhres);
3099
3100     CLEAR_CALLED(QueryInterface_IBindStatusCallbackEx); /* IE 8 */
3101     CHECK_CALLED(GetBindInfo);
3102     CHECK_CALLED(QueryInterface_IInternetProtocol);
3103     CHECK_CALLED(OnStartBinding);
3104     if(is_urlmon_protocol(test_protocol))
3105         CHECK_CALLED(SetPriority);
3106     CHECK_CALLED(Start);
3107
3108     ok(unk == NULL, "unk=%p\n", unk);
3109
3110     IBindCtx_Release(bctx);
3111     IMoniker_Release(mon);
3112 }
3113
3114 static void test_BindToStorage_fail(void)
3115 {
3116     IMoniker *mon = NULL;
3117     IBindCtx *bctx = NULL;
3118     IUnknown *unk;
3119     HRESULT hres;
3120
3121     hres = CreateURLMoniker(NULL, ABOUT_BLANK, &mon);
3122     ok(hres == S_OK, "CreateURLMoniker failed: %08x\n", hres);
3123     if(FAILED(hres))
3124         return;
3125
3126     hres = pCreateAsyncBindCtxEx(NULL, 0, NULL, NULL, &bctx, 0);
3127     ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08x\n", hres);
3128
3129     hres = IMoniker_BindToStorage(mon, bctx, NULL, &IID_IStream, (void**)&unk);
3130     ok(hres == MK_E_SYNTAX || hres == INET_E_DATA_NOT_AVAILABLE,
3131        "hres=%08x, expected MK_E_SYNTAX or INET_E_DATA_NOT_AVAILABLE\n", hres);
3132
3133     IBindCtx_Release(bctx);
3134
3135     IMoniker_Release(mon);
3136
3137     test_ReportResult(E_NOTIMPL);
3138     test_ReportResult(S_FALSE);
3139 }
3140
3141 static void test_StdURLMoniker(void)
3142 {
3143     IMoniker *mon, *async_mon;
3144     LPOLESTR display_name;
3145     HRESULT hres;
3146
3147     hres = CoCreateInstance(&IID_IInternet, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
3148             &IID_IMoniker, (void**)&mon);
3149     ok(hres == S_OK, "Could not create IInternet instance: %08x\n", hres);
3150     if(FAILED(hres))
3151         return;
3152
3153     hres = IMoniker_QueryInterface(mon, &IID_IAsyncMoniker, (void**)&async_mon);
3154     ok(hres == S_OK, "Could not get IAsyncMoniker iface: %08x\n", hres);
3155     ok(mon == async_mon, "mon != async_mon\n");
3156     IMoniker_Release(async_mon);
3157
3158     hres = IMoniker_GetDisplayName(mon, NULL, NULL, &display_name);
3159     ok(hres == E_OUTOFMEMORY, "GetDisplayName failed: %08x, expected E_OUTOFMEMORY\n", hres);
3160
3161     if(pCreateUri) {
3162       IUriContainer *uri_container;
3163       IUri *uri;
3164
3165       hres = IMoniker_QueryInterface(mon, &IID_IUriContainer, (void**)&uri_container);
3166       ok(hres == S_OK, "Coud not get IUriMoniker iface: %08x\n", hres);
3167
3168
3169       uri = (void*)0xdeadbeef;
3170       hres = IUriContainer_GetIUri(uri_container, &uri);
3171       ok(hres == S_FALSE, "GetIUri failed: %08x\n", hres);
3172       ok(!uri, "uri = %p, expected NULL\n", uri);
3173
3174       IUriContainer_Release(uri_container);
3175     }
3176
3177     IMoniker_Release(mon);
3178 }
3179
3180 static void register_protocols(void)
3181 {
3182     IInternetSession *session;
3183     HRESULT hres;
3184
3185     static const WCHAR winetestW[] = {'w','i','n','e','t','e','s','t',0};
3186
3187     hres = CoInternetGetSession(0, &session, 0);
3188     ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
3189     if(FAILED(hres))
3190         return;
3191
3192     hres = IInternetSession_RegisterNameSpace(session, &protocol_cf, &IID_NULL,
3193             winetestW, 0, NULL, 0);
3194     ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
3195
3196     IInternetSession_Release(session);
3197 }
3198
3199 START_TEST(url)
3200 {
3201     HMODULE hurlmon;
3202
3203     hurlmon = GetModuleHandle("urlmon.dll");
3204     pCreateAsyncBindCtxEx = (void*) GetProcAddress(hurlmon, "CreateAsyncBindCtxEx");
3205
3206     if(!GetProcAddress(hurlmon, "CompareSecurityIds")) {
3207         win_skip("Too old IE\n");
3208         return;
3209     }
3210
3211     pCreateUri = (void*) GetProcAddress(hurlmon, "CreateUri");
3212     if(!pCreateUri)
3213         win_skip("IUri not supported\n");
3214
3215     complete_event = CreateEvent(NULL, FALSE, FALSE, NULL);
3216     complete_event2 = CreateEvent(NULL, FALSE, FALSE, NULL);
3217     thread_id = GetCurrentThreadId();
3218     create_file();
3219     create_cache_file();
3220     register_protocols();
3221
3222     test_create();
3223
3224     trace("test CreateAsyncBindCtx...\n");
3225     test_CreateAsyncBindCtx();
3226
3227     trace("test CreateAsyncBindCtxEx...\n");
3228     test_CreateAsyncBindCtxEx();
3229
3230     trace("test RegisterBindStatusCallback...\n");
3231     if(test_RegisterBindStatusCallback()) {
3232         trace("test BindToStorage failures...\n");
3233         test_BindToStorage_fail();
3234
3235         trace("synchronous http test (COM not initialised)...\n");
3236         test_BindToStorage(HTTP_TEST, 0, TYMED_ISTREAM);
3237
3238         CoInitialize(NULL);
3239
3240         trace("test StdURLMoniker...\n");
3241         test_StdURLMoniker();
3242
3243         trace("synchronous http test...\n");
3244         test_BindToStorage(HTTP_TEST, 0, TYMED_ISTREAM);
3245
3246         trace("emulated synchronous http test (to file)...\n");
3247         test_BindToStorage(HTTP_TEST, BINDTEST_EMULATE, TYMED_FILE);
3248
3249         trace("synchronous http test (to object)...\n");
3250         test_BindToObject(HTTP_TEST, 0);
3251
3252         trace("emulated synchronous http test (with cache)...\n");
3253         test_BindToStorage(HTTP_TEST, BINDTEST_EMULATE|BINDTEST_USE_CACHE, TYMED_ISTREAM);
3254
3255         trace("emulated synchronous http test (with cache, no read)...\n");
3256         test_BindToStorage(HTTP_TEST, BINDTEST_EMULATE|BINDTEST_USE_CACHE|BINDTEST_NO_CALLBACK_READ, TYMED_ISTREAM);
3257
3258         trace("synchronous http test (with cache, no read)...\n");
3259         test_BindToStorage(HTTP_TEST, BINDTEST_USE_CACHE|BINDTEST_NO_CALLBACK_READ, TYMED_ISTREAM);
3260
3261         trace("synchronous file test...\n");
3262         test_BindToStorage(FILE_TEST, 0, TYMED_ISTREAM);
3263
3264         trace("emulated synchronous file test (to file)...\n");
3265         test_BindToStorage(FILE_TEST, BINDTEST_EMULATE, TYMED_FILE);
3266
3267         trace("synchronous file test (to object)...\n");
3268         test_BindToObject(FILE_TEST, 0);
3269
3270         trace("file test (no callback)...\n");
3271         test_BindToStorage(FILE_TEST, BINDTEST_NO_CALLBACK, TYMED_ISTREAM);
3272
3273         bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
3274
3275         trace("about test (no read)...\n");
3276         test_BindToStorage(ABOUT_TEST, BINDTEST_NO_CALLBACK_READ, TYMED_ISTREAM);
3277
3278         trace("http test...\n");
3279         test_BindToStorage(HTTP_TEST, 0, TYMED_ISTREAM);
3280
3281         trace("http test (to file)...\n");
3282         test_BindToStorage(HTTP_TEST, 0, TYMED_FILE);
3283
3284         trace("http test (to object)...\n");
3285         test_BindToObject(HTTP_TEST, 0);
3286
3287         trace("http test (short response)...\n");
3288         http_is_first = TRUE;
3289         test_BindToStorage(HTTP_TEST, BINDTEST_HTTPRESPONSE, TYMED_ISTREAM);
3290
3291         trace("http test (short response, to object)...\n");
3292         test_BindToObject(HTTP_TEST, 0);
3293
3294         trace("emulated http test...\n");
3295         test_BindToStorage(HTTP_TEST, BINDTEST_EMULATE, TYMED_ISTREAM);
3296
3297         trace("emulated http test (to object)...\n");
3298         test_BindToObject(HTTP_TEST, BINDTEST_EMULATE);
3299
3300         trace("emulated http test (to object, redirect)...\n");
3301         test_BindToObject(HTTP_TEST, BINDTEST_EMULATE|BINDTEST_REDIRECT);
3302
3303         trace("emulated http test (to file)...\n");
3304         test_BindToStorage(HTTP_TEST, BINDTEST_EMULATE, TYMED_FILE);
3305
3306         trace("emulated http test (redirect)...\n");
3307         test_BindToStorage(HTTP_TEST, BINDTEST_EMULATE|BINDTEST_REDIRECT, TYMED_ISTREAM);
3308
3309         trace("emulated http test (with cache)...\n");
3310         test_BindToStorage(HTTP_TEST, BINDTEST_EMULATE|BINDTEST_USE_CACHE, TYMED_ISTREAM);
3311
3312         trace("winetest test (no callback)...\n");
3313         test_BindToStorage(WINETEST_TEST, BINDTEST_EMULATE|BINDTEST_NO_CALLBACK|BINDTEST_USE_CACHE, TYMED_ISTREAM);
3314
3315         trace("asynchronous https test...\n");
3316         test_BindToStorage(HTTPS_TEST, 0, TYMED_ISTREAM);
3317
3318         trace("emulated https test...\n");
3319         test_BindToStorage(HTTPS_TEST, BINDTEST_EMULATE, TYMED_ISTREAM);
3320
3321         trace("about test...\n");
3322         test_BindToStorage(ABOUT_TEST, 0, TYMED_ISTREAM);
3323
3324         trace("about test (to file)...\n");
3325         test_BindToStorage(ABOUT_TEST, 0, TYMED_FILE);
3326
3327         trace("about test (to object)...\n");
3328         test_BindToObject(ABOUT_TEST, 0);
3329
3330         trace("emulated about test...\n");
3331         test_BindToStorage(ABOUT_TEST, BINDTEST_EMULATE, TYMED_ISTREAM);
3332
3333         trace("emulated about test (to file)...\n");
3334         test_BindToStorage(ABOUT_TEST, BINDTEST_EMULATE, TYMED_FILE);
3335
3336         trace("emulated about test (to object)...\n");
3337         test_BindToObject(ABOUT_TEST, BINDTEST_EMULATE);
3338
3339         trace("file test...\n");
3340         test_BindToStorage(FILE_TEST, 0, TYMED_ISTREAM);
3341
3342         trace("file test (to file)...\n");
3343         test_BindToStorage(FILE_TEST, 0, TYMED_FILE);
3344
3345         trace("file test (to object)...\n");
3346         test_BindToObject(FILE_TEST, 0);
3347
3348         trace("emulated file test...\n");
3349         test_BindToStorage(FILE_TEST, BINDTEST_EMULATE, TYMED_ISTREAM);
3350
3351         trace("emulated file test (to file)...\n");
3352         test_BindToStorage(FILE_TEST, BINDTEST_EMULATE, TYMED_FILE);
3353
3354         trace("emulated file test (to object)...\n");
3355         test_BindToObject(FILE_TEST, BINDTEST_EMULATE);
3356
3357         trace("emulated its test...\n");
3358         test_BindToStorage(ITS_TEST, BINDTEST_EMULATE, TYMED_ISTREAM);
3359
3360         trace("emulated its test (to file)...\n");
3361         test_BindToStorage(ITS_TEST, BINDTEST_EMULATE, TYMED_FILE);
3362
3363         trace("emulated mk test...\n");
3364         test_BindToStorage(MK_TEST, BINDTEST_EMULATE, TYMED_ISTREAM);
3365
3366         trace("test URLDownloadToFile for file protocol...\n");
3367         test_URLDownloadToFile(FILE_TEST, FALSE);
3368
3369         trace("test URLDownloadToFile for emulated file protocol...\n");
3370         test_URLDownloadToFile(FILE_TEST, TRUE);
3371
3372         trace("test URLDownloadToFile for http protocol...\n");
3373         test_URLDownloadToFile(HTTP_TEST, FALSE);
3374
3375         trace("test emulated http abort...\n");
3376         test_BindToStorage(HTTP_TEST, BINDTEST_EMULATE|BINDTEST_ABORT, TYMED_ISTREAM);
3377
3378         bindf |= BINDF_NOWRITECACHE;
3379
3380         trace("ftp test...\n");
3381         test_BindToStorage(FTP_TEST, 0, TYMED_ISTREAM);
3382
3383         trace("test failures...\n");
3384         test_BindToStorage_fail();
3385
3386         bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE;
3387         only_check_prot_args = TRUE; /* Fail after checking arguments to Protocol_Start */
3388
3389         trace("check emulated http protocol arguments...\n");
3390         test_BindToStorage(HTTP_TEST, BINDTEST_EMULATE, TYMED_ISTREAM);
3391     }
3392
3393     DeleteFileA(wszIndexHtmlA);
3394     DeleteFileA(test_txtA);
3395     CloseHandle(complete_event);
3396     CloseHandle(complete_event2);
3397     CoUninitialize();
3398 }