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