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