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