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