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