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