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