urlmon: Added ibind argument handling in CreateAsyncBindCtx.
[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 CONST_VTABLE
27
28 #include "windef.h"
29 #include "winbase.h"
30 #include "urlmon.h"
31 #include "wininet.h"
32 #include "mshtml.h"
33
34 #include "wine/test.h"
35
36 #define DEFINE_EXPECT(func) \
37     static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
38
39 #define SET_EXPECT(func) \
40     expect_ ## func = TRUE
41
42 #define CHECK_EXPECT2(func) \
43     do { \
44         ok(expect_ ##func, "unexpected call " #func "\n"); \
45         called_ ## func = TRUE; \
46     }while(0)
47
48 #define CHECK_EXPECT(func) \
49     do { \
50         CHECK_EXPECT2(func); \
51         expect_ ## func = FALSE; \
52     }while(0)
53
54 #define CHECK_CALLED(func) \
55     do { \
56         ok(called_ ## func, "expected " #func "\n"); \
57         expect_ ## func = called_ ## func = FALSE; \
58     }while(0)
59
60 #define CHECK_NOT_CALLED(func) \
61     do { \
62         ok(!called_ ## func, "unexpected " #func "\n"); \
63         expect_ ## func = called_ ## func = FALSE; \
64     }while(0)
65
66 #define CLEAR_CALLED(func) \
67     expect_ ## func = called_ ## func = FALSE
68
69 DEFINE_EXPECT(QueryInterface_IServiceProvider);
70 DEFINE_EXPECT(QueryInterface_IHttpNegotiate);
71 DEFINE_EXPECT(QueryInterface_IBindStatusCallback);
72 DEFINE_EXPECT(QueryInterface_IBindStatusCallbackHolder);
73 DEFINE_EXPECT(QueryInterface_IInternetBindInfo);
74 DEFINE_EXPECT(QueryInterface_IAuthenticate);
75 DEFINE_EXPECT(QueryInterface_IInternetProtocol);
76 DEFINE_EXPECT(QueryService_IAuthenticate);
77 DEFINE_EXPECT(QueryService_IInternetProtocol);
78 DEFINE_EXPECT(QueryService_IInternetBindInfo);
79 DEFINE_EXPECT(BeginningTransaction);
80 DEFINE_EXPECT(OnResponse);
81 DEFINE_EXPECT(QueryInterface_IHttpNegotiate2);
82 DEFINE_EXPECT(GetRootSecurityId);
83 DEFINE_EXPECT(GetBindInfo);
84 DEFINE_EXPECT(OnStartBinding);
85 DEFINE_EXPECT(OnProgress_FINDINGRESOURCE);
86 DEFINE_EXPECT(OnProgress_CONNECTING);
87 DEFINE_EXPECT(OnProgress_SENDINGREQUEST);
88 DEFINE_EXPECT(OnProgress_MIMETYPEAVAILABLE);
89 DEFINE_EXPECT(OnProgress_BEGINDOWNLOADDATA);
90 DEFINE_EXPECT(OnProgress_DOWNLOADINGDATA);
91 DEFINE_EXPECT(OnProgress_ENDDOWNLOADDATA);
92 DEFINE_EXPECT(OnProgress_CLASSIDAVAILABLE);
93 DEFINE_EXPECT(OnProgress_BEGINSYNCOPERATION);
94 DEFINE_EXPECT(OnProgress_ENDSYNCOPERATION);
95 DEFINE_EXPECT(OnStopBinding);
96 DEFINE_EXPECT(OnDataAvailable);
97 DEFINE_EXPECT(OnObjectAvailable);
98 DEFINE_EXPECT(Start);
99 DEFINE_EXPECT(Read);
100 DEFINE_EXPECT(LockRequest);
101 DEFINE_EXPECT(Terminate);
102 DEFINE_EXPECT(UnlockRequest);
103 DEFINE_EXPECT(Continue);
104
105 static const WCHAR TEST_URL_1[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g','/','\0'};
106 static const WCHAR TEST_PART_URL_1[] = {'/','t','e','s','t','/','\0'};
107
108 static const WCHAR WINE_ABOUT_URL[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.',
109                                        'o','r','g','/','s','i','t','e','/','a','b','o','u','t',0};
110 static const WCHAR SHORT_RESPONSE_URL[] =
111         {'h','t','t','p',':','/','/','c','r','o','s','s','o','v','e','r','.',
112          'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m','/',
113          'p','o','s','t','t','e','s','t','.','p','h','p',0};
114 static const WCHAR ABOUT_BLANK[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
115 static WCHAR INDEX_HTML[MAX_PATH];
116 static const WCHAR ITS_URL[] =
117     {'i','t','s',':','t','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l',0};
118 static const WCHAR MK_URL[] = {'m','k',':','@','M','S','I','T','S','t','o','r','e',':',
119     't','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l',0};
120
121 static const WCHAR wszTextHtml[] = {'t','e','x','t','/','h','t','m','l',0};
122
123 static WCHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
124
125 static const WCHAR wszWineHQSite[] =
126     {'w','w','w','.','w','i','n','e','h','q','.','o','r','g',0};
127 static const WCHAR wszWineHQIP[] =
128     {'2','0','9','.','3','2','.','1','4','1','.','3',0};
129 static const WCHAR wszIndexHtml[] = {'i','n','d','e','x','.','h','t','m','l',0};
130
131 static BOOL stopped_binding = FALSE, emulate_protocol = FALSE,
132     data_available = FALSE, http_is_first = TRUE;
133 static DWORD read = 0, bindf = 0, prot_state = 0, thread_id;
134 static CHAR mime_type[512];
135 static IInternetProtocolSink *protocol_sink = NULL;
136 static HANDLE complete_event, complete_event2;
137
138 extern IID IID_IBindStatusCallbackHolder;
139
140 static LPCWSTR urls[] = {
141     WINE_ABOUT_URL,
142     ABOUT_BLANK,
143     INDEX_HTML,
144     ITS_URL,
145     MK_URL
146 };
147
148 static enum {
149     HTTP_TEST,
150     ABOUT_TEST,
151     FILE_TEST,
152     ITS_TEST,
153     MK_TEST
154 } test_protocol;
155
156 static enum {
157     BEFORE_DOWNLOAD,
158     DOWNLOADING,
159     END_DOWNLOAD
160 } download_state;
161
162 static const char *debugstr_guid(REFIID riid)
163 {
164     static char buf[50];
165
166     sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
167             riid->Data1, riid->Data2, riid->Data3, riid->Data4[0],
168             riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4],
169             riid->Data4[5], riid->Data4[6], riid->Data4[7]);
170
171     return buf;
172 }
173
174 static void test_CreateURLMoniker(LPCWSTR url1, LPCWSTR url2)
175 {
176     HRESULT hr;
177     IMoniker *mon1 = NULL;
178     IMoniker *mon2 = NULL;
179
180     hr = CreateURLMoniker(NULL, url1, &mon1);
181     ok(SUCCEEDED(hr), "failed to create moniker: 0x%08x\n", hr);
182     if(SUCCEEDED(hr)) {
183         hr = CreateURLMoniker(mon1, url2, &mon2);
184         ok(SUCCEEDED(hr), "failed to create moniker: 0x%08x\n", hr);
185     }
186     if(mon1) IMoniker_Release(mon1);
187     if(mon2) IMoniker_Release(mon2);
188 }
189
190 static void test_create(void)
191 {
192     test_CreateURLMoniker(TEST_URL_1, TEST_PART_URL_1);
193 }
194
195 static HRESULT WINAPI Protocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
196 {
197     if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
198         *ppv = iface;
199         return S_OK;
200     }
201
202     *ppv = NULL;
203     return E_NOINTERFACE;
204 }
205
206 static ULONG WINAPI Protocol_AddRef(IInternetProtocol *iface)
207 {
208     return 2;
209 }
210
211 static ULONG WINAPI Protocol_Release(IInternetProtocol *iface)
212 {
213     return 1;
214 }
215
216 static DWORD WINAPI thread_proc(PVOID arg)
217 {
218     PROTOCOLDATA protocoldata;
219     HRESULT hres;
220
221     SET_EXPECT(OnProgress_FINDINGRESOURCE);
222     hres = IInternetProtocolSink_ReportProgress(protocol_sink,
223             BINDSTATUS_FINDINGRESOURCE, wszWineHQSite);
224     ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
225     WaitForSingleObject(complete_event, INFINITE);
226     CHECK_CALLED(OnProgress_FINDINGRESOURCE);
227
228     SET_EXPECT(OnProgress_CONNECTING);
229     hres = IInternetProtocolSink_ReportProgress(protocol_sink,
230             BINDSTATUS_CONNECTING, wszWineHQIP);
231     ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
232     WaitForSingleObject(complete_event, INFINITE);
233     CHECK_CALLED(OnProgress_CONNECTING);
234
235     SET_EXPECT(OnProgress_SENDINGREQUEST);
236     hres = IInternetProtocolSink_ReportProgress(protocol_sink,
237             BINDSTATUS_SENDINGREQUEST, NULL);
238     ok(hres == S_OK, "ReportProgress failed: %08x\n", hres);
239     WaitForSingleObject(complete_event, INFINITE);
240     CHECK_CALLED(OnProgress_SENDINGREQUEST);
241
242     SET_EXPECT(Continue);
243     prot_state = 1;
244     hres = IInternetProtocolSink_Switch(protocol_sink, &protocoldata);
245     ok(hres == S_OK, "Switch failed: %08x\n", hres);
246     WaitForSingleObject(complete_event, INFINITE);
247     CHECK_CALLED(Continue);
248     CHECK_CALLED(Read);
249     CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
250     CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
251     CHECK_CALLED(LockRequest);
252     CHECK_CALLED(OnDataAvailable);
253
254     SET_EXPECT(Continue);
255     prot_state = 2;
256     hres = IInternetProtocolSink_Switch(protocol_sink, &protocoldata);
257     ok(hres == S_OK, "Switch failed: %08x\n", hres);
258     WaitForSingleObject(complete_event, INFINITE);
259     CHECK_CALLED(Continue);
260     CHECK_CALLED(Read);
261     CHECK_CALLED(OnProgress_DOWNLOADINGDATA);
262     CHECK_CALLED(OnDataAvailable);
263
264     SET_EXPECT(Continue);
265     prot_state = 2;
266     hres = IInternetProtocolSink_Switch(protocol_sink, &protocoldata);
267     ok(hres == S_OK, "Switch failed: %08x\n", hres);
268     WaitForSingleObject(complete_event, INFINITE);
269     CHECK_CALLED(Continue);
270     CHECK_CALLED(Read);
271     CHECK_CALLED(OnProgress_DOWNLOADINGDATA);
272     CHECK_CALLED(OnDataAvailable);
273
274     SET_EXPECT(Continue);
275     prot_state = 3;
276     hres = IInternetProtocolSink_Switch(protocol_sink, &protocoldata);
277     ok(hres == S_OK, "Switch failed: %08x\n", hres);
278     WaitForSingleObject(complete_event, INFINITE);
279     CHECK_CALLED(Continue);
280     CHECK_CALLED(Read);
281     CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
282     CHECK_CALLED(OnDataAvailable);
283     CHECK_CALLED(OnStopBinding);
284
285     SetEvent(complete_event2);
286
287     return 0;
288 }
289
290 static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
291         IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
292         DWORD grfPI, DWORD dwReserved)
293 {
294     BINDINFO bindinfo, bi = {sizeof(bi), 0};
295     DWORD bindf, bscf = BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION;
296     WCHAR null_char = 0;
297     HRESULT hres;
298
299     CHECK_EXPECT(Start);
300
301     read = 0;
302
303     ok(szUrl && !lstrcmpW(szUrl, urls[test_protocol]), "wrong url\n");
304     ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
305     ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
306     ok(grfPI == 0, "grfPI=%d, expected 0\n", grfPI);
307     ok(dwReserved == 0, "dwReserved=%d, expected 0\n", dwReserved);
308
309     memset(&bindinfo, 0, sizeof(bindinfo));
310     bindinfo.cbSize = sizeof(bindinfo);
311     hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &bindf, &bindinfo);
312     ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
313
314     if(test_protocol == FILE_TEST || test_protocol == MK_TEST || test_protocol == HTTP_TEST) {
315         ok(bindf == (BINDF_ASYNCHRONOUS|BINDF_ASYNCSTORAGE|BINDF_PULLDATA
316                      |BINDF_FROMURLMON),
317            "bindf=%08x\n", bindf);
318     }else {
319         ok(bindf == (BINDF_ASYNCHRONOUS|BINDF_ASYNCSTORAGE|BINDF_PULLDATA|
320                      BINDF_FROMURLMON|BINDF_NEEDFILE),
321            "bindf=%08x\n", bindf);
322     }
323
324     ok(!memcmp(&bindinfo, &bi, sizeof(bindinfo)), "wrong bindinfo\n");
325
326     switch(test_protocol) {
327     case MK_TEST:
328         hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
329                 BINDSTATUS_DIRECTBIND, NULL);
330         ok(hres == S_OK,
331            "ReportProgress(BINDSTATUS_SENDINGREQUEST) failed: %08x\n", hres);
332
333     case FILE_TEST:
334     case ITS_TEST:
335         SET_EXPECT(OnProgress_SENDINGREQUEST);
336         hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
337                 BINDSTATUS_SENDINGREQUEST, &null_char);
338         ok(hres == S_OK,
339            "ReportProgress(BINDSTATUS_SENDINGREQUEST) failed: %08x\n", hres);
340         CHECK_CALLED(OnProgress_SENDINGREQUEST);
341     default:
342         break;
343     }
344
345     if(test_protocol == HTTP_TEST) {
346         IServiceProvider *service_provider;
347         IHttpNegotiate *http_negotiate;
348         IHttpNegotiate2 *http_negotiate2;
349         LPWSTR ua = (LPWSTR)0xdeadbeef, accept_mimes[256];
350         LPWSTR additional_headers = (LPWSTR)0xdeadbeef;
351         BYTE sec_id[100];
352         DWORD fetched = 256, size = 100;
353
354         static const WCHAR wszMimes[] = {'*','/','*',0};
355
356         SET_EXPECT(QueryInterface_IInternetBindInfo);
357         SET_EXPECT(QueryService_IInternetBindInfo);
358         hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_USER_AGENT,
359                                                &ua, 1, &fetched);
360         todo_wine {
361         CHECK_CALLED(QueryInterface_IInternetBindInfo);
362         CHECK_CALLED(QueryService_IInternetBindInfo);
363         }
364         ok(hres == E_NOINTERFACE,
365            "GetBindString(BINDSTRING_USER_AGETNT) failed: %08x\n", hres);
366         ok(fetched == 256, "fetched = %d, expected 254\n", fetched);
367         ok(ua == (LPWSTR)0xdeadbeef, "ua =  %p\n", ua);
368
369         hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_ACCEPT_MIMES,
370                                                accept_mimes, 256, &fetched);
371         ok(hres == S_OK,
372            "GetBindString(BINDSTRING_ACCEPT_MIMES) failed: %08x\n", hres);
373         ok(fetched == 1, "fetched = %d, expected 1\n", fetched);
374         ok(!lstrcmpW(wszMimes, accept_mimes[0]), "unexpected mimes\n");
375
376         hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_ACCEPT_MIMES,
377                                                NULL, 256, &fetched);
378         ok(hres == E_INVALIDARG,
379            "GetBindString(BINDSTRING_ACCEPT_MIMES) failed: %08x\n", hres);
380
381         hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_ACCEPT_MIMES,
382                                                accept_mimes, 256, NULL);
383         ok(hres == E_INVALIDARG,
384            "GetBindString(BINDSTRING_ACCEPT_MIMES) failed: %08x\n", hres);
385
386         hres = IInternetBindInfo_QueryInterface(pOIBindInfo, &IID_IServiceProvider,
387                                                 (void**)&service_provider);
388         ok(hres == S_OK, "QueryInterface failed: %08x\n", hres);
389
390         SET_EXPECT(QueryInterface_IHttpNegotiate);
391         hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
392                 &IID_IHttpNegotiate, (void**)&http_negotiate);
393         CHECK_CALLED(QueryInterface_IHttpNegotiate);
394         ok(hres == S_OK, "QueryService failed: %08x\n", hres);
395
396         SET_EXPECT(BeginningTransaction);
397         hres = IHttpNegotiate_BeginningTransaction(http_negotiate, urls[test_protocol],
398                                                    NULL, 0, &additional_headers);
399         CHECK_CALLED(BeginningTransaction);
400         IHttpNegotiate_Release(http_negotiate);
401         ok(hres == S_OK, "BeginningTransction failed: %08x\n", hres);
402         ok(additional_headers == NULL, "additional_headers=%p\n", additional_headers);
403
404         SET_EXPECT(QueryInterface_IHttpNegotiate2);
405         hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate2,
406                 &IID_IHttpNegotiate2, (void**)&http_negotiate2);
407         CHECK_CALLED(QueryInterface_IHttpNegotiate2);
408         ok(hres == S_OK, "QueryService failed: %08x\n", hres);
409
410         size = 512;
411         SET_EXPECT(GetRootSecurityId);
412         hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, sec_id, &size, 0);
413         CHECK_CALLED(GetRootSecurityId);
414         IHttpNegotiate2_Release(http_negotiate2);
415         ok(hres == E_FAIL, "GetRootSecurityId failed: %08x, expected E_FAIL\n", hres);
416         ok(size == 13, "size=%d\n", size);
417
418         IServiceProvider_Release(service_provider);
419
420         IInternetProtocolSink_AddRef(pOIProtSink);
421         protocol_sink = pOIProtSink;
422         CreateThread(NULL, 0, thread_proc, NULL, 0, NULL);
423
424         return S_OK;
425     }
426
427     if(test_protocol == FILE_TEST) {
428         hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
429                 BINDSTATUS_CACHEFILENAMEAVAILABLE, &null_char);
430         ok(hres == S_OK,
431            "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
432
433         SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
434         hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
435                 BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE, wszTextHtml);
436         ok(hres == S_OK,
437            "ReportProgress(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE) failed: %08x\n", hres);
438         CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
439     }else {
440         hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
441                 BINDSTATUS_MIMETYPEAVAILABLE, wszTextHtml);
442         ok(hres == S_OK,
443            "ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE) failed: %08x\n", hres);
444     }
445
446     if(test_protocol == ABOUT_TEST)
447         bscf |= BSCF_DATAFULLYAVAILABLE;
448     if(test_protocol == ITS_TEST)
449         bscf = BSCF_FIRSTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE;
450
451     SET_EXPECT(Read);
452     if(test_protocol != FILE_TEST && test_protocol != MK_TEST)
453         SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
454     SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
455     SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
456     SET_EXPECT(LockRequest);
457     SET_EXPECT(OnDataAvailable);
458     SET_EXPECT(OnStopBinding);
459
460     hres = IInternetProtocolSink_ReportData(pOIProtSink, bscf, 13, 13);
461     ok(hres == S_OK, "ReportData failed: %08x\n", hres);
462
463     CHECK_CALLED(Read);
464     if(test_protocol != FILE_TEST && test_protocol != MK_TEST)
465         CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
466     CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
467     CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
468     CHECK_CALLED(LockRequest);
469     CHECK_CALLED(OnDataAvailable);
470     CHECK_CALLED(OnStopBinding);
471
472     if(test_protocol == ITS_TEST) {
473         SET_EXPECT(Read);
474         hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_BEGINDOWNLOADDATA, NULL);
475         ok(hres == S_OK, "ReportProgress(BINDSTATUS_BEGINDOWNLOADDATA) failed: %08x\n", hres);
476         CHECK_CALLED(Read);
477     }
478
479     SET_EXPECT(Terminate);
480     hres = IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);
481     ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
482     CHECK_CALLED(Terminate);
483
484     return S_OK;
485 }
486
487 static HRESULT WINAPI Protocol_Continue(IInternetProtocol *iface,
488         PROTOCOLDATA *pProtocolData)
489 {
490     DWORD bscf = 0;
491     HRESULT hres;
492
493     CHECK_EXPECT(Continue);
494
495     ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
496
497     ok(pProtocolData != NULL, "pProtocolData == NULL\n");
498     if(!pProtocolData)
499         return S_OK;
500
501     switch(prot_state) {
502     case 1: {
503         IServiceProvider *service_provider;
504         IHttpNegotiate *http_negotiate;
505         static WCHAR header[] = {'?',0};
506
507         hres = IInternetProtocolSink_QueryInterface(protocol_sink, &IID_IServiceProvider,
508                                                     (void**)&service_provider);
509         ok(hres == S_OK, "Could not get IServiceProvicder\n");
510
511         hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
512                                              &IID_IHttpNegotiate, (void**)&http_negotiate);
513         ok(hres == S_OK, "Could not get IHttpNegotiate\n");
514
515         SET_EXPECT(OnResponse);
516         hres = IHttpNegotiate_OnResponse(http_negotiate, 200, header, NULL, NULL);
517         CHECK_CALLED(OnResponse);
518         IHttpNegotiate_Release(http_negotiate);
519         ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
520
521         hres = IInternetProtocolSink_ReportProgress(protocol_sink,
522                 BINDSTATUS_MIMETYPEAVAILABLE, wszTextHtml);
523         ok(hres == S_OK,
524            "ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE) failed: %08x\n", hres);
525
526         bscf |= BSCF_FIRSTDATANOTIFICATION;
527         break;
528     }
529     case 2:
530     case 3:
531         bscf = BSCF_INTERMEDIATEDATANOTIFICATION;
532         break;
533     }
534
535     hres = IInternetProtocolSink_ReportData(protocol_sink, bscf, 100, 400);
536     ok(hres == S_OK, "ReportData failed: %08x\n", hres);
537
538     SET_EXPECT(Read);
539     switch(prot_state) {
540     case 1:
541         SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
542         SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
543         SET_EXPECT(LockRequest);
544         break;
545     case 2:
546         SET_EXPECT(OnProgress_DOWNLOADINGDATA);
547         break;
548     case 3:
549         SET_EXPECT(OnProgress_DOWNLOADINGDATA);
550         SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
551     }
552     SET_EXPECT(OnDataAvailable);
553     if(prot_state == 3)
554         SET_EXPECT(OnStopBinding);
555
556     return S_OK;
557 }
558
559 static HRESULT WINAPI Protocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
560         DWORD dwOptions)
561 {
562     ok(0, "unexpected call\n");
563     return E_NOTIMPL;
564 }
565
566 static HRESULT WINAPI Protocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
567 {
568     CHECK_EXPECT(Terminate);
569
570     ok(dwOptions == 0, "dwOptions=%d, expected 0\n", dwOptions);
571
572     if(protocol_sink) {
573         IInternetProtocolSink_Release(protocol_sink);
574         protocol_sink = NULL;
575     }
576
577     return S_OK;
578 }
579
580 static HRESULT WINAPI Protocol_Suspend(IInternetProtocol *iface)
581 {
582     ok(0, "unexpected call\n");
583     return E_NOTIMPL;
584 }
585
586 static HRESULT WINAPI Protocol_Resume(IInternetProtocol *iface)
587 {
588     ok(0, "unexpected call\n");
589     return E_NOTIMPL;
590 }
591
592 static HRESULT WINAPI Protocol_Read(IInternetProtocol *iface, void *pv,
593         ULONG cb, ULONG *pcbRead)
594 {
595     static const char data[] = "<HTML></HTML>";
596
597     CHECK_EXPECT2(Read);
598
599     if(test_protocol == HTTP_TEST) {
600         HRESULT hres;
601
602         static BOOL pending = TRUE;
603
604         pending = !pending;
605
606         switch(prot_state) {
607         case 1:
608         case 2:
609             if(pending) {
610                 *pcbRead = 10;
611                 memset(pv, '?', 10);
612                 return E_PENDING;
613             }else {
614                 memset(pv, '?', cb);
615                 *pcbRead = cb;
616                 read++;
617                 return S_OK;
618             }
619         case 3:
620             prot_state++;
621
622             *pcbRead = 0;
623
624             hres = IInternetProtocolSink_ReportData(protocol_sink,
625                     BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION, 2000, 2000);
626             ok(hres == S_OK, "ReportData failed: %08x\n", hres);
627
628             hres = IInternetProtocolSink_ReportResult(protocol_sink, S_OK, 0, NULL);
629             ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
630
631             return S_FALSE;
632         case 4:
633             *pcbRead = 0;
634             return S_FALSE;
635         }
636     }
637
638     if(read) {
639         *pcbRead = 0;
640         return S_FALSE;
641     }
642
643     ok(pv != NULL, "pv == NULL\n");
644     ok(cb != 0, "cb == 0\n");
645     ok(pcbRead != NULL, "pcbRead == NULL\n");
646     if(pcbRead) {
647         ok(*pcbRead == 0, "*pcbRead=%d, expected 0\n", *pcbRead);
648         read += *pcbRead = sizeof(data)-1;
649     }
650     if(pv)
651         memcpy(pv, data, sizeof(data));
652
653     return S_OK;
654 }
655
656 static HRESULT WINAPI Protocol_Seek(IInternetProtocol *iface,
657         LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
658 {
659     ok(0, "unexpected call\n");
660     return E_NOTIMPL;
661 }
662
663 static HRESULT WINAPI Protocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
664 {
665     CHECK_EXPECT(LockRequest);
666     return S_OK;
667 }
668
669 static HRESULT WINAPI Protocol_UnlockRequest(IInternetProtocol *iface)
670 {
671     CHECK_EXPECT(UnlockRequest);
672     return S_OK;
673 }
674
675 static const IInternetProtocolVtbl ProtocolVtbl = {
676     Protocol_QueryInterface,
677     Protocol_AddRef,
678     Protocol_Release,
679     Protocol_Start,
680     Protocol_Continue,
681     Protocol_Abort,
682     Protocol_Terminate,
683     Protocol_Suspend,
684     Protocol_Resume,
685     Protocol_Read,
686     Protocol_Seek,
687     Protocol_LockRequest,
688     Protocol_UnlockRequest
689 };
690
691 static IInternetProtocol Protocol = { &ProtocolVtbl };
692
693 static HRESULT WINAPI HttpNegotiate_QueryInterface(IHttpNegotiate2 *iface, REFIID riid, void **ppv)
694 {
695     if(IsEqualGUID(&IID_IUnknown, riid)
696             || IsEqualGUID(&IID_IHttpNegotiate, riid)
697             || IsEqualGUID(&IID_IHttpNegotiate2, riid)) {
698         *ppv = iface;
699         return S_OK;
700     }
701
702     ok(0, "unexpected call\n");
703     return E_NOINTERFACE;
704 }
705
706 static ULONG WINAPI HttpNegotiate_AddRef(IHttpNegotiate2 *iface)
707 {
708     return 2;
709 }
710
711 static ULONG WINAPI HttpNegotiate_Release(IHttpNegotiate2 *iface)
712 {
713     return 1;
714 }
715
716 static HRESULT WINAPI HttpNegotiate_BeginningTransaction(IHttpNegotiate2 *iface, LPCWSTR szURL,
717         LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
718 {
719     CHECK_EXPECT(BeginningTransaction);
720
721     ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
722
723     ok(!lstrcmpW(szURL, urls[test_protocol]), "szURL != urls[test_protocol]\n");
724     ok(!dwReserved, "dwReserved=%d, expected 0\n", dwReserved);
725     ok(pszAdditionalHeaders != NULL, "pszAdditionalHeaders == NULL\n");
726     if(pszAdditionalHeaders)
727         ok(*pszAdditionalHeaders == NULL, "*pszAdditionalHeaders != NULL\n");
728
729     return S_OK;
730 }
731
732 static HRESULT WINAPI HttpNegotiate_OnResponse(IHttpNegotiate2 *iface, DWORD dwResponseCode,
733         LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders)
734 {
735     CHECK_EXPECT(OnResponse);
736
737     ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
738
739     ok(dwResponseCode == 200, "dwResponseCode=%d, expected 200\n", dwResponseCode);
740     ok(szResponseHeaders != NULL, "szResponseHeaders == NULL\n");
741     ok(szRequestHeaders == NULL, "szRequestHeaders != NULL\n");
742     /* Note: in protocol.c tests, OnResponse pszAdditionalRequestHeaders _is_ NULL */
743     ok(pszAdditionalRequestHeaders != NULL, "pszAdditionalHeaders == NULL\n");
744     if(pszAdditionalRequestHeaders)
745         ok(*pszAdditionalRequestHeaders == NULL, "*pszAdditionalHeaders != NULL\n");
746
747     return S_OK;
748 }
749
750 static HRESULT WINAPI HttpNegotiate_GetRootSecurityId(IHttpNegotiate2 *iface,
751         BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
752 {
753     static const BYTE sec_id[] = {'h','t','t','p',':','t','e','s','t',1,0,0,0};
754
755     CHECK_EXPECT(GetRootSecurityId);
756
757     ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
758
759     ok(!dwReserved, "dwReserved=%ld, expected 0\n", dwReserved);
760     ok(pbSecurityId != NULL, "pbSecurityId == NULL\n");
761     ok(pcbSecurityId != NULL, "pcbSecurityId == NULL\n");
762
763     if(pbSecurityId == (void*)0xdeadbeef)
764         return E_NOTIMPL;
765
766     if(pcbSecurityId) {
767         ok(*pcbSecurityId == 512, "*pcbSecurityId=%d, expected 512\n", *pcbSecurityId);
768         *pcbSecurityId = sizeof(sec_id);
769     }
770
771     if(pbSecurityId)
772         memcpy(pbSecurityId, sec_id, sizeof(sec_id));
773
774     return E_FAIL;
775 }
776
777 static IHttpNegotiate2Vtbl HttpNegotiateVtbl = {
778     HttpNegotiate_QueryInterface,
779     HttpNegotiate_AddRef,
780     HttpNegotiate_Release,
781     HttpNegotiate_BeginningTransaction,
782     HttpNegotiate_OnResponse,
783     HttpNegotiate_GetRootSecurityId
784 };
785
786 static IHttpNegotiate2 HttpNegotiate = { &HttpNegotiateVtbl };
787
788 static HRESULT WINAPI ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
789 {
790     ok(0, "unexpected call\n");
791     return E_NOINTERFACE;
792 }
793
794 static ULONG WINAPI ServiceProvider_AddRef(IServiceProvider *iface)
795 {
796     return 2;
797 }
798
799 static ULONG WINAPI ServiceProvider_Release(IServiceProvider *iface)
800 {
801     return 1;
802 }
803
804 static HRESULT WINAPI ServiceProvider_QueryService(IServiceProvider *iface,
805         REFGUID guidService, REFIID riid, void **ppv)
806 {
807     if(IsEqualGUID(&IID_IAuthenticate, guidService)) {
808         CHECK_EXPECT(QueryService_IAuthenticate);
809         return E_NOTIMPL;
810     }
811
812     if(IsEqualGUID(&IID_IInternetProtocol, guidService)) {
813         CHECK_EXPECT2(QueryService_IInternetProtocol);
814         return E_NOTIMPL;
815     }
816
817     if(IsEqualGUID(&IID_IInternetBindInfo, guidService)) {
818         CHECK_EXPECT(QueryService_IInternetBindInfo);
819         return E_NOTIMPL;
820     }
821
822     ok(0, "unexpected service %s\n", debugstr_guid(guidService));
823     return E_NOINTERFACE;
824 }
825
826 static IServiceProviderVtbl ServiceProviderVtbl = {
827     ServiceProvider_QueryInterface,
828     ServiceProvider_AddRef,
829     ServiceProvider_Release,
830     ServiceProvider_QueryService
831 };
832
833 static IServiceProvider ServiceProvider = { &ServiceProviderVtbl };
834
835 static HRESULT WINAPI statusclb_QueryInterface(IBindStatusCallback *iface, REFIID riid, void **ppv)
836 {
837     ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
838
839     if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
840         CHECK_EXPECT2(QueryInterface_IInternetProtocol);
841         if(emulate_protocol) {
842             *ppv = &Protocol;
843             return S_OK;
844         }else {
845             return E_NOINTERFACE;
846         }
847     }
848     else if (IsEqualGUID(&IID_IServiceProvider, riid))
849     {
850         CHECK_EXPECT2(QueryInterface_IServiceProvider);
851         *ppv = &ServiceProvider;
852         return S_OK;
853     }
854     else if (IsEqualGUID(&IID_IHttpNegotiate, riid))
855     {
856         CHECK_EXPECT(QueryInterface_IHttpNegotiate);
857         *ppv = &HttpNegotiate;
858         return S_OK;
859     }
860     else if (IsEqualGUID(&IID_IHttpNegotiate2, riid))
861     {
862         CHECK_EXPECT(QueryInterface_IHttpNegotiate2);
863         *ppv = &HttpNegotiate;
864         return S_OK;
865     }
866     else if (IsEqualGUID(&IID_IAuthenticate, riid))
867     {
868         CHECK_EXPECT(QueryInterface_IAuthenticate);
869         return E_NOINTERFACE;
870     }
871     else if(IsEqualGUID(&IID_IBindStatusCallback, riid))
872     {
873         CHECK_EXPECT2(QueryInterface_IBindStatusCallback);
874         *ppv = iface;
875         return S_OK;
876     }
877     else if(IsEqualGUID(&IID_IBindStatusCallbackHolder, riid))
878     {
879         CHECK_EXPECT2(QueryInterface_IBindStatusCallbackHolder);
880         return E_NOINTERFACE;
881     }
882     else if(IsEqualGUID(&IID_IInternetBindInfo, riid))
883     {
884         /* TODO */
885         CHECK_EXPECT2(QueryInterface_IInternetBindInfo);
886     }
887     else
888     {
889         ok(0, "unexpected interface %s\n", debugstr_guid(riid));
890     }
891
892     return E_NOINTERFACE;
893 }
894
895 static ULONG WINAPI statusclb_AddRef(IBindStatusCallback *iface)
896 {
897     return 2;
898 }
899
900 static ULONG WINAPI statusclb_Release(IBindStatusCallback *iface)
901 {
902     return 1;
903 }
904
905 static HRESULT WINAPI statusclb_OnStartBinding(IBindStatusCallback *iface, DWORD dwReserved,
906         IBinding *pib)
907 {
908     HRESULT hres;
909     IMoniker *mon;
910
911     CHECK_EXPECT(OnStartBinding);
912
913     ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
914
915     ok(pib != NULL, "pib should not be NULL\n");
916     ok(dwReserved == 0xff, "dwReserved=%x\n", dwReserved);
917
918     if(pib == (void*)0xdeadbeef)
919         return S_OK;
920
921     hres = IBinding_QueryInterface(pib, &IID_IMoniker, (void**)&mon);
922     ok(hres == E_NOINTERFACE, "IBinding should not have IMoniker interface\n");
923     if(SUCCEEDED(hres))
924         IMoniker_Release(mon);
925
926     return S_OK;
927 }
928
929 static HRESULT WINAPI statusclb_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
930 {
931     ok(0, "unexpected call\n");
932     return E_NOTIMPL;
933 }
934
935 static HRESULT WINAPI statusclb_OnLowResource(IBindStatusCallback *iface, DWORD reserved)
936 {
937     ok(0, "unexpected call\n");
938     return E_NOTIMPL;
939 }
940
941 static HRESULT WINAPI statusclb_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
942         ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
943 {
944     ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
945
946     switch(ulStatusCode) {
947     case BINDSTATUS_FINDINGRESOURCE:
948         CHECK_EXPECT(OnProgress_FINDINGRESOURCE);
949         if((bindf & BINDF_ASYNCHRONOUS) && emulate_protocol)
950             SetEvent(complete_event);
951         break;
952     case BINDSTATUS_CONNECTING:
953         CHECK_EXPECT(OnProgress_CONNECTING);
954         if((bindf & BINDF_ASYNCHRONOUS) && emulate_protocol)
955             SetEvent(complete_event);
956         break;
957     case BINDSTATUS_SENDINGREQUEST:
958         CHECK_EXPECT(OnProgress_SENDINGREQUEST);
959         if((bindf & BINDF_ASYNCHRONOUS) && emulate_protocol)
960             SetEvent(complete_event);
961         break;
962     case BINDSTATUS_MIMETYPEAVAILABLE:
963         CHECK_EXPECT(OnProgress_MIMETYPEAVAILABLE);
964         ok(download_state == BEFORE_DOWNLOAD, "Download state was %d, expected BEFORE_DOWNLOAD\n",
965            download_state);
966         WideCharToMultiByte(CP_ACP, 0, szStatusText, -1, mime_type, sizeof(mime_type)-1, NULL, NULL);
967         break;
968     case BINDSTATUS_BEGINDOWNLOADDATA:
969         CHECK_EXPECT(OnProgress_BEGINDOWNLOADDATA);
970         ok(szStatusText != NULL, "szStatusText == NULL\n");
971         if(szStatusText)
972             ok(!lstrcmpW(szStatusText, urls[test_protocol]), "wrong szStatusText\n");
973         ok(download_state == BEFORE_DOWNLOAD, "Download state was %d, expected BEFORE_DOWNLOAD\n",
974            download_state);
975         download_state = DOWNLOADING;
976         break;
977     case BINDSTATUS_DOWNLOADINGDATA:
978         CHECK_EXPECT2(OnProgress_DOWNLOADINGDATA);
979         ok(download_state == DOWNLOADING, "Download state was %d, expected DOWNLOADING\n",
980            download_state);
981         break;
982     case BINDSTATUS_ENDDOWNLOADDATA:
983         CHECK_EXPECT(OnProgress_ENDDOWNLOADDATA);
984         ok(szStatusText != NULL, "szStatusText == NULL\n");
985         if(szStatusText)
986             ok(!lstrcmpW(szStatusText, urls[test_protocol]), "wrong szStatusText\n");
987         ok(download_state == DOWNLOADING, "Download state was %d, expected DOWNLOADING\n",
988            download_state);
989         download_state = END_DOWNLOAD;
990         break;
991     case BINDSTATUS_CACHEFILENAMEAVAILABLE:
992         ok(szStatusText != NULL, "szStatusText == NULL\n");
993         if(szStatusText && test_protocol == FILE_TEST)
994             ok(!lstrcmpW(INDEX_HTML+7, szStatusText), "wrong szStatusText\n");
995         break;
996     case BINDSTATUS_CLASSIDAVAILABLE:
997     {
998         CLSID clsid;
999         HRESULT hr;
1000         CHECK_EXPECT(OnProgress_CLASSIDAVAILABLE);
1001         hr = CLSIDFromString((LPOLESTR)szStatusText, &clsid);
1002         ok(hr == S_OK, "CLSIDFromString failed with error 0x%08x\n", hr);
1003         ok(IsEqualCLSID(&clsid, &CLSID_HTMLDocument),
1004             "Expected clsid to be CLSID_HTMLDocument instead of {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
1005             clsid.Data1, clsid.Data2, clsid.Data3,
1006             clsid.Data4[0], clsid.Data4[1], clsid.Data4[2], clsid.Data4[3],
1007             clsid.Data4[4], clsid.Data4[5], clsid.Data4[6], clsid.Data4[7]);
1008         break;
1009     }
1010     case BINDSTATUS_BEGINSYNCOPERATION:
1011         CHECK_EXPECT(OnProgress_BEGINSYNCOPERATION);
1012         ok(szStatusText == NULL, "Expected szStatusText to be NULL\n");
1013         break;
1014     case BINDSTATUS_ENDSYNCOPERATION:
1015         CHECK_EXPECT(OnProgress_ENDSYNCOPERATION);
1016         ok(szStatusText == NULL, "Expected szStatusText to be NULL\n");
1017         break;
1018     default:
1019         ok(0, "unexpexted code %d\n", ulStatusCode);
1020     };
1021     return S_OK;
1022 }
1023
1024 static HRESULT WINAPI statusclb_OnStopBinding(IBindStatusCallback *iface, HRESULT hresult, LPCWSTR szError)
1025 {
1026     CHECK_EXPECT(OnStopBinding);
1027
1028     ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
1029
1030     stopped_binding = TRUE;
1031
1032     /* ignore DNS failure */
1033     if (hresult == HRESULT_FROM_WIN32(ERROR_INTERNET_NAME_NOT_RESOLVED))
1034         return S_OK;
1035
1036     ok(hresult == S_OK, "binding failed: %08x\n", hresult);
1037     ok(szError == NULL, "szError should be NULL\n");
1038
1039     if(test_protocol == HTTP_TEST && emulate_protocol) {
1040         SetEvent(complete_event);
1041         WaitForSingleObject(complete_event2, INFINITE);
1042     }
1043
1044     return S_OK;
1045 }
1046
1047 static HRESULT WINAPI statusclb_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
1048 {
1049     DWORD cbSize;
1050
1051     CHECK_EXPECT(GetBindInfo);
1052
1053     ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
1054
1055     *grfBINDF = bindf;
1056     cbSize = pbindinfo->cbSize;
1057     memset(pbindinfo, 0, cbSize);
1058     pbindinfo->cbSize = cbSize;
1059
1060     return S_OK;
1061 }
1062
1063 static HRESULT WINAPI statusclb_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
1064         DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
1065 {
1066     HRESULT hres;
1067     DWORD readed;
1068     BYTE buf[512];
1069     CHAR clipfmt[512];
1070
1071     CHECK_EXPECT2(OnDataAvailable);
1072
1073     ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId());
1074
1075     ok(download_state == DOWNLOADING || download_state == END_DOWNLOAD,
1076        "Download state was %d, expected DOWNLOADING or END_DOWNLOAD\n",
1077        download_state);
1078     data_available = TRUE;
1079
1080     ok(pformatetc != NULL, "pformatetx == NULL\n");
1081     if(pformatetc) {
1082         if (mime_type[0]) {
1083             clipfmt[0] = 0;
1084             ok(GetClipboardFormatName(pformatetc->cfFormat, clipfmt, sizeof(clipfmt)-1),
1085                "GetClipboardFormatName failed, error %d\n", GetLastError());
1086             ok(!lstrcmp(clipfmt, mime_type), "clipformat != mime_type, \"%s\" != \"%s\"\n",
1087                clipfmt, mime_type);
1088         } else {
1089             ok(pformatetc->cfFormat == 0, "clipformat=%x\n", pformatetc->cfFormat);
1090         }
1091         ok(pformatetc->ptd == NULL, "ptd = %p\n", pformatetc->ptd);
1092         ok(pformatetc->dwAspect == 1, "dwAspect=%u\n", pformatetc->dwAspect);
1093         ok(pformatetc->lindex == -1, "lindex=%d\n", pformatetc->lindex);
1094         ok(pformatetc->tymed == TYMED_ISTREAM, "tymed=%u\n", pformatetc->tymed);
1095     }
1096
1097     ok(pstgmed != NULL, "stgmeg == NULL\n");
1098     if(pstgmed) {
1099         ok(pstgmed->tymed == TYMED_ISTREAM, "tymed=%u\n", pstgmed->tymed);
1100         ok(U(*pstgmed).pstm != NULL, "pstm == NULL\n");
1101         ok(pstgmed->pUnkForRelease != NULL, "pUnkForRelease == NULL\n");
1102     }
1103
1104     if(grfBSCF & BSCF_FIRSTDATANOTIFICATION) {
1105         hres = IStream_Write(U(*pstgmed).pstm, buf, 10, NULL);
1106         ok(hres == STG_E_ACCESSDENIED,
1107            "Write failed: %08x, expected STG_E_ACCESSDENIED\n", hres);
1108
1109         hres = IStream_Commit(U(*pstgmed).pstm, 0);
1110         ok(hres == E_NOTIMPL, "Commit failed: %08x, expected E_NOTIMPL\n", hres);
1111
1112         hres = IStream_Revert(U(*pstgmed).pstm);
1113         ok(hres == E_NOTIMPL, "Revert failed: %08x, expected E_NOTIMPL\n", hres);
1114     }
1115
1116     ok(U(*pstgmed).pstm != NULL, "U(*pstgmed).pstm == NULL\n");
1117
1118     if(U(*pstgmed).pstm) {
1119         do hres = IStream_Read(U(*pstgmed).pstm, buf, 512, &readed);
1120         while(hres == S_OK);
1121         ok(hres == S_FALSE || hres == E_PENDING, "IStream_Read returned %08x\n", hres);
1122     }
1123
1124     if(test_protocol == HTTP_TEST && emulate_protocol && prot_state < 4)
1125         SetEvent(complete_event);
1126
1127     return S_OK;
1128 }
1129
1130 static HRESULT WINAPI statusclb_OnObjectAvailable(IBindStatusCallback *iface, REFIID riid, IUnknown *punk)
1131 {
1132     CHECK_EXPECT(OnObjectAvailable);
1133     return S_OK;
1134 }
1135
1136 static const IBindStatusCallbackVtbl BindStatusCallbackVtbl = {
1137     statusclb_QueryInterface,
1138     statusclb_AddRef,
1139     statusclb_Release,
1140     statusclb_OnStartBinding,
1141     statusclb_GetPriority,
1142     statusclb_OnLowResource,
1143     statusclb_OnProgress,
1144     statusclb_OnStopBinding,
1145     statusclb_GetBindInfo,
1146     statusclb_OnDataAvailable,
1147     statusclb_OnObjectAvailable
1148 };
1149
1150 static IBindStatusCallback bsc = { &BindStatusCallbackVtbl };
1151
1152 static void test_CreateAsyncBindCtx(void)
1153 {
1154     IBindCtx *bctx = (IBindCtx*)0x0ff00ff0;
1155     IUnknown *unk;
1156     HRESULT hres;
1157     ULONG ref;
1158     BIND_OPTS bindopts;
1159
1160     hres = CreateAsyncBindCtx(0, NULL, NULL, &bctx);
1161     ok(hres == E_INVALIDARG, "CreateAsyncBindCtx failed. expected: E_INVALIDARG, got: %08x\n", hres);
1162     ok(bctx == (IBindCtx*)0x0ff00ff0, "bctx should not be changed\n");
1163
1164     hres = CreateAsyncBindCtx(0, NULL, NULL, NULL);
1165     ok(hres == E_INVALIDARG, "CreateAsyncBindCtx failed. expected: E_INVALIDARG, got: %08x\n", hres);
1166
1167     SET_EXPECT(QueryInterface_IServiceProvider);
1168     hres = CreateAsyncBindCtx(0, &bsc, NULL, &bctx);
1169     ok(hres == S_OK, "CreateAsyncBindCtx failed: %08x\n", hres);
1170     CHECK_CALLED(QueryInterface_IServiceProvider);
1171
1172     bindopts.cbStruct = sizeof(bindopts);
1173     hres = IBindCtx_GetBindOptions(bctx, &bindopts);
1174     ok(SUCCEEDED(hres), "IBindCtx_GetBindOptions failed: %08x\n", hres);
1175     ok(bindopts.grfFlags == BIND_MAYBOTHERUSER,
1176                 "bindopts.grfFlags = %08x, expected: BIND_MAYBOTHERUSER\n", bindopts.grfFlags);
1177     ok(bindopts.grfMode == (STGM_READWRITE | STGM_SHARE_EXCLUSIVE),
1178                 "bindopts.grfMode = %08x, expected: STGM_READWRITE | STGM_SHARE_EXCLUSIVE\n",
1179                 bindopts.grfMode);
1180     ok(bindopts.dwTickCountDeadline == 0,
1181                 "bindopts.dwTickCountDeadline = %08x, expected: 0\n", bindopts.dwTickCountDeadline);
1182
1183     hres = IBindCtx_QueryInterface(bctx, &IID_IAsyncBindCtx, (void**)&unk);
1184     ok(hres == E_NOINTERFACE, "QueryInterface(IID_IAsyncBindCtx) failed: %08x, expected E_NOINTERFACE\n", hres);
1185     if(SUCCEEDED(hres))
1186         IUnknown_Release(unk);
1187
1188     ref = IBindCtx_Release(bctx);
1189     ok(ref == 0, "bctx should be destroyed here\n");
1190 }
1191
1192 static void test_CreateAsyncBindCtxEx(void)
1193 {
1194     IBindCtx *bctx = NULL, *bctx2 = NULL, *bctx_arg = NULL;
1195     IUnknown *unk;
1196     BIND_OPTS bindopts;
1197     HRESULT hres;
1198
1199     static WCHAR testW[] = {'t','e','s','t',0};
1200
1201     hres = CreateAsyncBindCtxEx(NULL, 0, NULL, NULL, NULL, 0);
1202     ok(hres == E_INVALIDARG, "CreateAsyncBindCtx failed: %08x, expected E_INVALIDARG\n", hres);
1203
1204     hres = CreateAsyncBindCtxEx(NULL, 0, NULL, NULL, &bctx, 0);
1205     ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08x\n", hres);
1206
1207     if(SUCCEEDED(hres)) {
1208         bindopts.cbStruct = sizeof(bindopts);
1209         hres = IBindCtx_GetBindOptions(bctx, &bindopts);
1210         ok(SUCCEEDED(hres), "IBindCtx_GetBindOptions failed: %08x\n", hres);
1211         ok(bindopts.grfFlags == BIND_MAYBOTHERUSER,
1212                 "bindopts.grfFlags = %08x, expected: BIND_MAYBOTHERUSER\n", bindopts.grfFlags);
1213         ok(bindopts.grfMode == (STGM_READWRITE | STGM_SHARE_EXCLUSIVE),
1214                 "bindopts.grfMode = %08x, expected: STGM_READWRITE | STGM_SHARE_EXCLUSIVE\n",
1215                 bindopts.grfMode);
1216         ok(bindopts.dwTickCountDeadline == 0,
1217                 "bindopts.dwTickCountDeadline = %08x, expected: 0\n", bindopts.dwTickCountDeadline);
1218
1219         IBindCtx_Release(bctx);
1220     }
1221
1222     CreateBindCtx(0, &bctx_arg);
1223     hres = CreateAsyncBindCtxEx(NULL, 0, NULL, NULL, &bctx, 0);
1224     ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08x\n", hres);
1225
1226     if(SUCCEEDED(hres)) {
1227         bindopts.cbStruct = sizeof(bindopts);
1228         hres = IBindCtx_GetBindOptions(bctx, &bindopts);
1229         ok(SUCCEEDED(hres), "IBindCtx_GetBindOptions failed: %08x\n", hres);
1230         ok(bindopts.grfFlags == BIND_MAYBOTHERUSER,
1231                 "bindopts.grfFlags = %08x, expected: BIND_MAYBOTHERUSER\n", bindopts.grfFlags);
1232         ok(bindopts.grfMode == (STGM_READWRITE | STGM_SHARE_EXCLUSIVE),
1233                 "bindopts.grfMode = %08x, expected: STGM_READWRITE | STGM_SHARE_EXCLUSIVE\n",
1234                 bindopts.grfMode);
1235         ok(bindopts.dwTickCountDeadline == 0,
1236                 "bindopts.dwTickCountDeadline = %08x, expected: 0\n", bindopts.dwTickCountDeadline);
1237
1238         IBindCtx_Release(bctx);
1239     }
1240
1241     IBindCtx_Release(bctx_arg);
1242
1243     SET_EXPECT(QueryInterface_IServiceProvider);
1244     hres = CreateAsyncBindCtxEx(NULL, 0, &bsc, NULL, &bctx, 0);
1245     ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08x\n", hres);
1246     CHECK_CALLED(QueryInterface_IServiceProvider);
1247
1248     hres = IBindCtx_QueryInterface(bctx, &IID_IAsyncBindCtx, (void**)&unk);
1249     ok(hres == S_OK, "QueryInterface(IID_IAsyncBindCtx) failed: %08x\n", hres);
1250     if(SUCCEEDED(hres))
1251         IUnknown_Release(unk);
1252
1253     IBindCtx_Release(bctx);
1254
1255     hres = CreateBindCtx(0, &bctx2);
1256     ok(hres == S_OK, "CreateBindCtx failed: %08x\n", hres);
1257
1258     hres = CreateAsyncBindCtxEx(bctx2, 0, NULL, NULL, &bctx, 0);
1259     ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08x\n", hres);
1260
1261     hres = IBindCtx_RegisterObjectParam(bctx2, testW, (IUnknown*)&Protocol);
1262     ok(hres == S_OK, "RegisterObjectParam failed: %08x\n", hres);
1263
1264     hres = IBindCtx_GetObjectParam(bctx, testW, &unk);
1265     ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres);
1266     ok(unk == (IUnknown*)&Protocol, "unexpected unk %p\n", unk);
1267
1268     IBindCtx_Release(bctx);
1269     IBindCtx_Release(bctx2);
1270 }
1271
1272 static void test_bscholder(IBindStatusCallback *holder)
1273 {
1274     IServiceProvider *serv_prov;
1275     IHttpNegotiate *http_negotiate, *http_negotiate_serv;
1276     IHttpNegotiate2 *http_negotiate2, *http_negotiate2_serv;
1277     IAuthenticate *authenticate, *authenticate_serv;
1278     IInternetProtocol *protocol;
1279     BINDINFO bindinfo = {sizeof(bindinfo)};
1280     LPWSTR wstr;
1281     DWORD dw;
1282     HRESULT hres;
1283
1284     static const WCHAR emptyW[] = {0};
1285
1286     hres = IBindStatusCallback_QueryInterface(holder, &IID_IServiceProvider, (void**)&serv_prov);
1287     ok(hres == S_OK, "Could not get IServiceProvider interface: %08x\n", hres);
1288
1289     dw = 0xdeadbeef;
1290     SET_EXPECT(GetBindInfo);
1291     hres = IBindStatusCallback_GetBindInfo(holder, &dw, &bindinfo);
1292     ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
1293     CHECK_CALLED(GetBindInfo);
1294
1295     SET_EXPECT(OnStartBinding);
1296     hres = IBindStatusCallback_OnStartBinding(holder, 0, (void*)0xdeadbeef);
1297     ok(hres == S_OK, "OnStartBinding failed: %08x\n", hres);
1298     CHECK_CALLED(OnStartBinding);
1299
1300     hres = IBindStatusCallback_QueryInterface(holder, &IID_IHttpNegotiate, (void**)&http_negotiate);
1301     ok(hres == S_OK, "Could not get IHttpNegotiate interface: %08x\n", hres);
1302
1303     wstr = (void*)0xdeadbeef;
1304     hres = IHttpNegotiate_BeginningTransaction(http_negotiate, urls[test_protocol], (void*)0xdeadbeef, 0xff, &wstr);
1305     ok(hres == S_OK, "BeginningTransaction failed: %08x\n", hres);
1306     ok(wstr == NULL, "wstr = %p\n", wstr);
1307
1308     SET_EXPECT(QueryInterface_IHttpNegotiate);
1309     hres = IServiceProvider_QueryService(serv_prov, &IID_IHttpNegotiate, &IID_IHttpNegotiate,
1310                                          (void**)&http_negotiate_serv);
1311     ok(hres == S_OK, "Could not get IHttpNegotiate service: %08x\n", hres);
1312     CHECK_CALLED(QueryInterface_IHttpNegotiate);
1313
1314     ok(http_negotiate == http_negotiate_serv, "http_negotiate != http_negotiate_serv\n");
1315
1316     wstr = (void*)0xdeadbeef;
1317     SET_EXPECT(BeginningTransaction);
1318     hres = IHttpNegotiate_BeginningTransaction(http_negotiate_serv, urls[test_protocol], emptyW, 0, &wstr);
1319     CHECK_CALLED(BeginningTransaction);
1320     ok(hres == S_OK, "BeginningTransaction failed: %08x\n", hres);
1321     ok(wstr == NULL, "wstr = %p\n", wstr);
1322
1323     IHttpNegotiate_Release(http_negotiate_serv);
1324
1325     hres = IServiceProvider_QueryService(serv_prov, &IID_IHttpNegotiate, &IID_IHttpNegotiate,
1326                                          (void**)&http_negotiate_serv);
1327     ok(hres == S_OK, "Could not get IHttpNegotiate service: %08x\n", hres);
1328     ok(http_negotiate == http_negotiate_serv, "http_negotiate != http_negotiate_serv\n");
1329     IHttpNegotiate_Release(http_negotiate_serv);
1330
1331     hres = IBindStatusCallback_QueryInterface(holder, &IID_IHttpNegotiate2, (void**)&http_negotiate2);
1332     ok(hres == S_OK, "Could not get IHttpNegotiate2 interface: %08x\n", hres);
1333
1334     hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, (void*)0xdeadbeef, (void*)0xdeadbeef, 0);
1335     ok(hres == E_FAIL, "GetRootSecurityId failed: %08x\n", hres);
1336
1337     IHttpNegotiate_Release(http_negotiate2);
1338
1339     SET_EXPECT(QueryInterface_IHttpNegotiate2);
1340     hres = IServiceProvider_QueryService(serv_prov, &IID_IHttpNegotiate2, &IID_IHttpNegotiate2,
1341                                          (void**)&http_negotiate2_serv);
1342     ok(hres == S_OK, "Could not get IHttpNegotiate2 service: %08x\n", hres);
1343     CHECK_CALLED(QueryInterface_IHttpNegotiate2);
1344     ok(http_negotiate2 == http_negotiate2_serv, "http_negotiate != http_negotiate_serv\n");
1345
1346     SET_EXPECT(GetRootSecurityId);
1347     hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, (void*)0xdeadbeef, (void*)0xdeadbeef, 0);
1348     ok(hres == E_NOTIMPL, "GetRootSecurityId failed: %08x\n", hres);
1349     CHECK_CALLED(GetRootSecurityId);
1350
1351     IHttpNegotiate_Release(http_negotiate2_serv);
1352
1353     SET_EXPECT(OnProgress_FINDINGRESOURCE);
1354     hres = IBindStatusCallback_OnProgress(holder, 0, 0, BINDSTATUS_FINDINGRESOURCE, NULL);
1355     ok(hres == S_OK, "OnProgress failed: %08x\n", hres);
1356     CHECK_CALLED(OnProgress_FINDINGRESOURCE);
1357
1358     SET_EXPECT(OnResponse);
1359     wstr = (void*)0xdeadbeef;
1360     hres = IHttpNegotiate_OnResponse(http_negotiate, 200, emptyW, NULL, NULL);
1361     ok(hres == S_OK, "OnResponse failed: %08x\n", hres);
1362     CHECK_CALLED(OnResponse);
1363
1364     IHttpNegotiate_Release(http_negotiate);
1365
1366     hres = IBindStatusCallback_QueryInterface(holder, &IID_IAuthenticate, (void**)&authenticate);
1367     ok(hres == S_OK, "Could not get IAuthenticate interface: %08x\n", hres);
1368
1369     SET_EXPECT(QueryInterface_IAuthenticate);
1370     SET_EXPECT(QueryService_IAuthenticate);
1371     hres = IServiceProvider_QueryService(serv_prov, &IID_IAuthenticate, &IID_IAuthenticate,
1372                                          (void**)&authenticate_serv);
1373     ok(hres == S_OK, "Could not get IAuthenticate service: %08x\n", hres);
1374     CHECK_CALLED(QueryInterface_IAuthenticate);
1375     CHECK_CALLED(QueryService_IAuthenticate);
1376     ok(authenticate == authenticate_serv, "authenticate != authenticate_serv\n");
1377     IAuthenticate_Release(authenticate_serv);
1378
1379     hres = IServiceProvider_QueryService(serv_prov, &IID_IAuthenticate, &IID_IAuthenticate,
1380                                          (void**)&authenticate_serv);
1381     ok(hres == S_OK, "Could not get IAuthenticate service: %08x\n", hres);
1382     ok(authenticate == authenticate_serv, "authenticate != authenticate_serv\n");
1383
1384     IAuthenticate_Release(authenticate);
1385     IAuthenticate_Release(authenticate_serv);
1386
1387     SET_EXPECT(OnStopBinding);
1388     hres = IBindStatusCallback_OnStopBinding(holder, S_OK, NULL);
1389     ok(hres == S_OK, "OnStopBinding failed: %08x\n", hres);
1390     CHECK_CALLED(OnStopBinding);
1391
1392     SET_EXPECT(QueryInterface_IInternetProtocol);
1393     SET_EXPECT(QueryService_IInternetProtocol);
1394     hres = IServiceProvider_QueryService(serv_prov, &IID_IInternetProtocol, &IID_IInternetProtocol,
1395                                          (void**)&protocol);
1396     ok(hres == E_NOINTERFACE, "QueryService(IInternetProtocol) failed: %08x\n", hres);
1397     CHECK_CALLED(QueryInterface_IInternetProtocol);
1398     CHECK_CALLED(QueryService_IInternetProtocol);
1399
1400     IServiceProvider_Release(serv_prov);
1401 }
1402
1403 static void test_RegisterBindStatusCallback(void)
1404 {
1405     IBindStatusCallback *prevbsc, *clb;
1406     IBindCtx *bindctx;
1407     IUnknown *unk;
1408     HRESULT hres;
1409
1410     hres = CreateBindCtx(0, &bindctx);
1411     ok(hres == S_OK, "BindCtx failed: %08x\n", hres);
1412
1413     SET_EXPECT(QueryInterface_IServiceProvider);
1414
1415     hres = IBindCtx_RegisterObjectParam(bindctx, BSCBHolder, (IUnknown*)&bsc);
1416     ok(hres == S_OK, "RegisterObjectParam failed: %08x\n", hres);
1417
1418     SET_EXPECT(QueryInterface_IBindStatusCallback);
1419     SET_EXPECT(QueryInterface_IBindStatusCallbackHolder);
1420     prevbsc = (void*)0xdeadbeef;
1421     hres = RegisterBindStatusCallback(bindctx, &bsc, &prevbsc, 0);
1422     ok(hres == S_OK, "RegisterBindStatusCallback failed: %08x\n", hres);
1423     ok(prevbsc == &bsc, "prevbsc=%p\n", prevbsc);
1424     CHECK_CALLED(QueryInterface_IBindStatusCallback);
1425     CHECK_CALLED(QueryInterface_IBindStatusCallbackHolder);
1426
1427     CHECK_CALLED(QueryInterface_IServiceProvider);
1428
1429     hres = IBindCtx_GetObjectParam(bindctx, BSCBHolder, &unk);
1430     ok(hres == S_OK, "GetObjectParam failed: %08x\n", hres);
1431
1432     hres = IUnknown_QueryInterface(unk, &IID_IBindStatusCallback, (void**)&clb);
1433     IUnknown_Release(unk);
1434     ok(hres == S_OK, "QueryInterface(IID_IBindStatusCallback) failed: %08x\n", hres);
1435     ok(clb != &bsc, "bsc == clb\n");
1436
1437     test_bscholder(clb);
1438
1439     IBindStatusCallback_Release(clb);
1440
1441     hres = RevokeBindStatusCallback(bindctx, &bsc);
1442     ok(hres == S_OK, "RevokeBindStatusCallback failed: %08x\n", hres);
1443
1444     unk = (void*)0xdeadbeef;
1445     hres = IBindCtx_GetObjectParam(bindctx, BSCBHolder, &unk);
1446     ok(hres == E_FAIL, "GetObjectParam failed: %08x\n", hres);
1447     ok(unk == NULL, "unk != NULL\n");
1448
1449     if(unk)
1450         IUnknown_Release(unk);
1451
1452     hres = RevokeBindStatusCallback(bindctx, (void*)0xdeadbeef);
1453     ok(hres == S_OK, "RevokeBindStatusCallback failed: %08x\n", hres);
1454
1455     hres = RevokeBindStatusCallback(NULL, (void*)0xdeadbeef);
1456     ok(hres == E_INVALIDARG, "RevokeBindStatusCallback failed: %08x\n", hres);
1457
1458     hres = RevokeBindStatusCallback(bindctx, NULL);
1459     ok(hres == E_INVALIDARG, "RevokeBindStatusCallback failed: %08x\n", hres);
1460
1461     IBindCtx_Release(bindctx);
1462 }
1463
1464 static void test_BindToStorage(int protocol, BOOL emul)
1465 {
1466     IMoniker *mon;
1467     HRESULT hres;
1468     LPOLESTR display_name;
1469     IBindCtx *bctx;
1470     MSG msg;
1471     IBindStatusCallback *previousclb;
1472     IUnknown *unk = (IUnknown*)0x00ff00ff;
1473     IBinding *bind;
1474
1475     test_protocol = protocol;
1476     emulate_protocol = emul;
1477     download_state = BEFORE_DOWNLOAD;
1478     stopped_binding = FALSE;
1479     data_available = FALSE;
1480     mime_type[0] = 0;
1481
1482     SET_EXPECT(QueryInterface_IServiceProvider);
1483     hres = CreateAsyncBindCtx(0, &bsc, NULL, &bctx);
1484     ok(hres == S_OK, "CreateAsyncBindCtx failed: %08x\n\n", hres);
1485     CHECK_CALLED(QueryInterface_IServiceProvider);
1486     if(FAILED(hres))
1487         return;
1488
1489     SET_EXPECT(QueryInterface_IServiceProvider);
1490     hres = RegisterBindStatusCallback(bctx, &bsc, &previousclb, 0);
1491     ok(hres == S_OK, "RegisterBindStatusCallback failed: %08x\n", hres);
1492     ok(previousclb == &bsc, "previousclb(%p) != sclb(%p)\n", previousclb, &bsc);
1493     CHECK_CALLED(QueryInterface_IServiceProvider);
1494     if(previousclb)
1495         IBindStatusCallback_Release(previousclb);
1496
1497     hres = CreateURLMoniker(NULL, urls[test_protocol], &mon);
1498     ok(SUCCEEDED(hres), "failed to create moniker: %08x\n", hres);
1499     if(FAILED(hres)) {
1500         IBindCtx_Release(bctx);
1501         return;
1502     }
1503
1504     if(test_protocol == FILE_TEST && INDEX_HTML[7] == '/')
1505         memmove(INDEX_HTML+7, INDEX_HTML+8, lstrlenW(INDEX_HTML+7)*sizeof(WCHAR));
1506
1507     hres = IMoniker_QueryInterface(mon, &IID_IBinding, (void**)&bind);
1508     ok(hres == E_NOINTERFACE, "IMoniker should not have IBinding interface\n");
1509     if(SUCCEEDED(hres))
1510         IBinding_Release(bind);
1511
1512     hres = IMoniker_GetDisplayName(mon, bctx, NULL, &display_name);
1513     ok(hres == S_OK, "GetDisplayName failed %08x\n", hres);
1514     ok(!lstrcmpW(display_name, urls[test_protocol]), "GetDisplayName got wrong name\n");
1515     CoTaskMemFree(display_name);
1516
1517     SET_EXPECT(GetBindInfo);
1518     SET_EXPECT(QueryInterface_IInternetProtocol);
1519     if(!emulate_protocol)
1520         SET_EXPECT(QueryService_IInternetProtocol);
1521     SET_EXPECT(OnStartBinding);
1522     if(emulate_protocol) {
1523         SET_EXPECT(Start);
1524         if(test_protocol == HTTP_TEST)
1525             SET_EXPECT(Terminate);
1526         SET_EXPECT(UnlockRequest);
1527     }else {
1528         if(test_protocol == HTTP_TEST) {
1529             SET_EXPECT(QueryInterface_IHttpNegotiate);
1530             SET_EXPECT(BeginningTransaction);
1531             SET_EXPECT(QueryInterface_IHttpNegotiate2);
1532             SET_EXPECT(GetRootSecurityId);
1533             SET_EXPECT(OnProgress_FINDINGRESOURCE);
1534             SET_EXPECT(OnProgress_CONNECTING);
1535         }
1536         if(test_protocol == HTTP_TEST || test_protocol == FILE_TEST)
1537             SET_EXPECT(OnProgress_SENDINGREQUEST);
1538         if(test_protocol == HTTP_TEST)
1539             SET_EXPECT(OnResponse);
1540         SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
1541         SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
1542         if(test_protocol == HTTP_TEST)
1543             SET_EXPECT(OnProgress_DOWNLOADINGDATA);
1544         SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
1545         SET_EXPECT(OnDataAvailable);
1546         SET_EXPECT(OnStopBinding);
1547     }
1548
1549     hres = IMoniker_BindToStorage(mon, bctx, NULL, &IID_IStream, (void**)&unk);
1550     if (test_protocol == HTTP_TEST && hres == HRESULT_FROM_WIN32(ERROR_INTERNET_NAME_NOT_RESOLVED))
1551     {
1552         trace( "Network unreachable, skipping tests\n" );
1553         return;
1554     }
1555     if (!SUCCEEDED(hres)) return;
1556
1557     if((bindf & BINDF_ASYNCHRONOUS) && !data_available) {
1558         ok(hres == MK_S_ASYNCHRONOUS, "IMoniker_BindToStorage failed: %08x\n", hres);
1559         ok(unk == NULL, "istr should be NULL\n");
1560     }else {
1561         ok(hres == S_OK, "IMoniker_BindToStorage failed: %08x\n", hres);
1562         ok(unk != NULL, "unk == NULL\n");
1563     }
1564     if(unk)
1565         IUnknown_Release(unk);
1566
1567     while((bindf & BINDF_ASYNCHRONOUS) &&
1568           !stopped_binding && GetMessage(&msg,NULL,0,0)) {
1569         TranslateMessage(&msg);
1570         DispatchMessage(&msg);
1571     }
1572
1573     CHECK_CALLED(GetBindInfo);
1574     CHECK_CALLED(QueryInterface_IInternetProtocol);
1575     if(!emulate_protocol)
1576         CHECK_CALLED(QueryService_IInternetProtocol);
1577     CHECK_CALLED(OnStartBinding);
1578     if(emulate_protocol) {
1579         CHECK_CALLED(Start);
1580         if(test_protocol == HTTP_TEST)
1581             CHECK_CALLED(Terminate);
1582         CHECK_CALLED(UnlockRequest);
1583     }else {
1584         if(test_protocol == HTTP_TEST) {
1585             CHECK_CALLED(QueryInterface_IHttpNegotiate);
1586             CHECK_CALLED(BeginningTransaction);
1587             /* QueryInterface_IHttpNegotiate2 and GetRootSecurityId
1588              * called on WinXP but not on Win98 */
1589             CLEAR_CALLED(QueryInterface_IHttpNegotiate2);
1590             CLEAR_CALLED(GetRootSecurityId);
1591             if(http_is_first) {
1592                 CHECK_CALLED(OnProgress_FINDINGRESOURCE);
1593                 CHECK_CALLED(OnProgress_CONNECTING);
1594             }else todo_wine {
1595                 CHECK_NOT_CALLED(OnProgress_FINDINGRESOURCE);
1596                 CHECK_NOT_CALLED(OnProgress_CONNECTING);
1597             }
1598         }
1599         if(test_protocol == HTTP_TEST || test_protocol == FILE_TEST)
1600             CHECK_CALLED(OnProgress_SENDINGREQUEST);
1601         if(test_protocol == HTTP_TEST)
1602             CHECK_CALLED(OnResponse);
1603         CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
1604         CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
1605         if(test_protocol == HTTP_TEST)
1606             CLEAR_CALLED(OnProgress_DOWNLOADINGDATA);
1607         CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
1608         CHECK_CALLED(OnDataAvailable);
1609         CHECK_CALLED(OnStopBinding);
1610     }
1611
1612     ok(IMoniker_Release(mon) == 0, "mon should be destroyed here\n");
1613     ok(IBindCtx_Release(bctx) == 0, "bctx should be destroyed here\n");
1614
1615     if(test_protocol == HTTP_TEST)
1616         http_is_first = FALSE;
1617 }
1618
1619 static void test_BindToObject(int protocol, BOOL emul)
1620 {
1621     IMoniker *mon;
1622     HRESULT hres;
1623     LPOLESTR display_name;
1624     IBindCtx *bctx;
1625     MSG msg;
1626     IUnknown *unk = (IUnknown*)0x00ff00ff;
1627     IBinding *bind;
1628
1629     test_protocol = protocol;
1630     emulate_protocol = emul;
1631     download_state = BEFORE_DOWNLOAD;
1632     stopped_binding = FALSE;
1633     data_available = FALSE;
1634     mime_type[0] = 0;
1635
1636     SET_EXPECT(QueryInterface_IServiceProvider);
1637     hres = CreateAsyncBindCtx(0, &bsc, NULL, &bctx);
1638     ok(SUCCEEDED(hres), "CreateAsyncBindCtx failed: %08x\n\n", hres);
1639     if(FAILED(hres))
1640         return;
1641     CHECK_CALLED(QueryInterface_IServiceProvider);
1642
1643     hres = CreateURLMoniker(NULL, urls[test_protocol], &mon);
1644     ok(SUCCEEDED(hres), "failed to create moniker: %08x\n", hres);
1645     if(FAILED(hres)) {
1646         IBindCtx_Release(bctx);
1647         return;
1648     }
1649
1650     if(test_protocol == FILE_TEST && INDEX_HTML[7] == '/')
1651         memmove(INDEX_HTML+7, INDEX_HTML+8, lstrlenW(INDEX_HTML+7)*sizeof(WCHAR));
1652
1653     hres = IMoniker_QueryInterface(mon, &IID_IBinding, (void**)&bind);
1654     ok(hres == E_NOINTERFACE, "IMoniker should not have IBinding interface\n");
1655     if(SUCCEEDED(hres))
1656         IBinding_Release(bind);
1657
1658     hres = IMoniker_GetDisplayName(mon, bctx, NULL, &display_name);
1659     ok(hres == S_OK, "GetDisplayName failed %08x\n", hres);
1660     ok(!lstrcmpW(display_name, urls[test_protocol]), "GetDisplayName got wrong name\n");
1661
1662     SET_EXPECT(GetBindInfo);
1663     SET_EXPECT(QueryInterface_IInternetProtocol);
1664     if(!emulate_protocol)
1665         SET_EXPECT(QueryService_IInternetProtocol);
1666     SET_EXPECT(OnStartBinding);
1667     if(emulate_protocol) {
1668         SET_EXPECT(Start);
1669         SET_EXPECT(UnlockRequest);
1670     }else {
1671         if(test_protocol == HTTP_TEST) {
1672             SET_EXPECT(QueryInterface_IHttpNegotiate);
1673             SET_EXPECT(BeginningTransaction);
1674             SET_EXPECT(QueryInterface_IHttpNegotiate2);
1675             SET_EXPECT(GetRootSecurityId);
1676             SET_EXPECT(OnProgress_FINDINGRESOURCE);
1677             SET_EXPECT(OnProgress_CONNECTING);
1678         }
1679         if(test_protocol == HTTP_TEST || test_protocol == FILE_TEST)
1680             SET_EXPECT(OnProgress_SENDINGREQUEST);
1681         if(test_protocol == HTTP_TEST)
1682             SET_EXPECT(OnResponse);
1683         SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
1684         SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
1685         if(test_protocol == HTTP_TEST)
1686             SET_EXPECT(OnProgress_DOWNLOADINGDATA);
1687         SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
1688         SET_EXPECT(OnProgress_CLASSIDAVAILABLE);
1689         SET_EXPECT(OnProgress_BEGINSYNCOPERATION);
1690         SET_EXPECT(OnProgress_ENDSYNCOPERATION);
1691         SET_EXPECT(OnObjectAvailable);
1692         SET_EXPECT(OnStopBinding);
1693     }
1694
1695     hres = IMoniker_BindToObject(mon, bctx, NULL, &IID_IUnknown, (void**)&unk);
1696     if (test_protocol == HTTP_TEST && hres == HRESULT_FROM_WIN32(ERROR_INTERNET_NAME_NOT_RESOLVED))
1697     {
1698         trace( "Network unreachable, skipping tests\n" );
1699         return;
1700     }
1701     todo_wine ok(SUCCEEDED(hres), "IMoniker_BindToObject failed with error 0x%08x\n", hres);
1702     /* no point testing the calls if binding didn't even work */
1703     if (!SUCCEEDED(hres)) return;
1704
1705     if((bindf & BINDF_ASYNCHRONOUS)) {
1706         ok(hres == MK_S_ASYNCHRONOUS, "IMoniker_BindToStorage failed: %08x\n", hres);
1707         ok(unk == NULL, "istr should be NULL\n");
1708     }else {
1709         ok(hres == S_OK, "IMoniker_BindToStorage failed: %08x\n", hres);
1710         ok(unk != NULL, "unk == NULL\n");
1711     }
1712     if(unk)
1713         IUnknown_Release(unk);
1714
1715     while((bindf & BINDF_ASYNCHRONOUS) &&
1716           !stopped_binding && GetMessage(&msg,NULL,0,0)) {
1717         TranslateMessage(&msg);
1718         DispatchMessage(&msg);
1719     }
1720
1721     CHECK_CALLED(GetBindInfo);
1722     CHECK_CALLED(QueryInterface_IInternetProtocol);
1723     if(!emulate_protocol)
1724         CHECK_CALLED(QueryService_IInternetProtocol);
1725     CHECK_CALLED(OnStartBinding);
1726     if(emulate_protocol) {
1727         CHECK_CALLED(Start);
1728         CHECK_CALLED(UnlockRequest);
1729     }else {
1730         if(test_protocol == HTTP_TEST) {
1731             CHECK_CALLED(QueryInterface_IHttpNegotiate);
1732             CHECK_CALLED(BeginningTransaction);
1733             /* QueryInterface_IHttpNegotiate2 and GetRootSecurityId
1734              * called on WinXP but not on Win98 */
1735             CLEAR_CALLED(QueryInterface_IHttpNegotiate2);
1736             CLEAR_CALLED(GetRootSecurityId);
1737             if(http_is_first) {
1738                 CHECK_CALLED(OnProgress_FINDINGRESOURCE);
1739                 CHECK_CALLED(OnProgress_CONNECTING);
1740             }else todo_wine {
1741                 CHECK_NOT_CALLED(OnProgress_FINDINGRESOURCE);
1742                 CHECK_NOT_CALLED(OnProgress_CONNECTING);
1743             }
1744         }
1745         if(test_protocol == HTTP_TEST || test_protocol == FILE_TEST)
1746             CHECK_CALLED(OnProgress_SENDINGREQUEST);
1747         if(test_protocol == HTTP_TEST)
1748             CHECK_CALLED(OnResponse);
1749         CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
1750         CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
1751         if(test_protocol == HTTP_TEST)
1752             CLEAR_CALLED(OnProgress_DOWNLOADINGDATA);
1753         CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
1754         CHECK_CALLED(OnProgress_CLASSIDAVAILABLE);
1755         CHECK_CALLED(OnProgress_BEGINSYNCOPERATION);
1756         CHECK_CALLED(OnProgress_ENDSYNCOPERATION);
1757         CHECK_CALLED(OnObjectAvailable);
1758         CHECK_CALLED(OnStopBinding);
1759     }
1760
1761     ok(IMoniker_Release(mon) == 0, "mon should be destroyed here\n");
1762     ok(IBindCtx_Release(bctx) == 0, "bctx should be destroyed here\n");
1763
1764     if(test_protocol == HTTP_TEST)
1765         http_is_first = FALSE;
1766 }
1767
1768 static void set_file_url(void)
1769 {
1770     int len;
1771
1772     static const WCHAR wszFile[] = {'f','i','l','e',':','/','/'};
1773
1774     memcpy(INDEX_HTML, wszFile, sizeof(wszFile));
1775     len = sizeof(wszFile)/sizeof(WCHAR);
1776     INDEX_HTML[len++] = '/';
1777     len += GetCurrentDirectoryW(sizeof(INDEX_HTML)/sizeof(WCHAR)-len, INDEX_HTML+len);
1778     INDEX_HTML[len++] = '\\';
1779     memcpy(INDEX_HTML+len, wszIndexHtml, sizeof(wszIndexHtml));
1780 }
1781
1782 static void create_file(void)
1783 {
1784     HANDLE file;
1785     DWORD size;
1786
1787     static const char html_doc[] = "<HTML></HTML>";
1788
1789     file = CreateFileW(wszIndexHtml, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
1790             FILE_ATTRIBUTE_NORMAL, NULL);
1791     ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError());
1792     if(file == INVALID_HANDLE_VALUE)
1793         return;
1794
1795     WriteFile(file, html_doc, sizeof(html_doc)-1, &size, NULL);
1796     CloseHandle(file);
1797
1798     set_file_url();
1799 }
1800
1801 static void test_BindToStorage_fail(void)
1802 {
1803     IMoniker *mon = NULL;
1804     IBindCtx *bctx = NULL;
1805     IUnknown *unk;
1806     HRESULT hres;
1807
1808     hres = CreateURLMoniker(NULL, ABOUT_BLANK, &mon);
1809     ok(hres == S_OK, "CreateURLMoniker failed: %08x\n", hres);
1810     if(FAILED(hres))
1811         return;
1812
1813     hres = CreateAsyncBindCtxEx(NULL, 0, NULL, NULL, &bctx, 0);
1814     ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08x\n", hres);
1815
1816     hres = IMoniker_BindToStorage(mon, bctx, NULL, &IID_IStream, (void**)&unk);
1817     ok(hres == MK_E_SYNTAX, "hres=%08x, expected INET_E_SYNTAX\n", hres);
1818
1819     IBindCtx_Release(bctx);
1820
1821     IMoniker_Release(mon);
1822 }
1823
1824 START_TEST(url)
1825 {
1826     complete_event = CreateEvent(NULL, FALSE, FALSE, NULL);
1827     complete_event2 = CreateEvent(NULL, FALSE, FALSE, NULL);
1828     thread_id = GetCurrentThreadId();
1829
1830     test_create();
1831     test_CreateAsyncBindCtx();
1832     test_CreateAsyncBindCtxEx();
1833     test_RegisterBindStatusCallback();
1834
1835     trace("synchronous http test (COM not initialised)...\n");
1836     test_BindToStorage(HTTP_TEST, FALSE);
1837     test_BindToStorage_fail();
1838
1839     CoInitialize(NULL);
1840
1841     trace("synchronous http test...\n");
1842     test_BindToStorage(HTTP_TEST, FALSE);
1843     test_BindToObject(HTTP_TEST, FALSE);
1844
1845     trace("synchronous file test...\n");
1846     create_file();
1847     test_BindToStorage(FILE_TEST, FALSE);
1848     test_BindToObject(FILE_TEST, FALSE);
1849     DeleteFileW(wszIndexHtml);
1850
1851     bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
1852
1853     trace("http test...\n");
1854     test_BindToStorage(HTTP_TEST, FALSE);
1855     test_BindToObject(HTTP_TEST, FALSE);
1856
1857     trace("http test (short response)...\n");
1858     http_is_first = TRUE;
1859     urls[HTTP_TEST] = SHORT_RESPONSE_URL;
1860     test_BindToStorage(HTTP_TEST, FALSE);
1861     test_BindToObject(HTTP_TEST, FALSE);
1862
1863     trace("emulated http test...\n");
1864     test_BindToStorage(HTTP_TEST, TRUE);
1865
1866     trace("about test...\n");
1867     test_BindToStorage(ABOUT_TEST, FALSE);
1868     test_BindToObject(ABOUT_TEST, FALSE);
1869
1870     trace("emulated about test...\n");
1871     test_BindToStorage(ABOUT_TEST, TRUE);
1872
1873     trace("file test...\n");
1874     create_file();
1875     test_BindToStorage(FILE_TEST, FALSE);
1876     test_BindToObject(FILE_TEST, FALSE);
1877     DeleteFileW(wszIndexHtml);
1878
1879     trace("emulated file test...\n");
1880     set_file_url();
1881     test_BindToStorage(FILE_TEST, TRUE);
1882
1883     trace("emulated its test...\n");
1884     test_BindToStorage(ITS_TEST, TRUE);
1885
1886     trace("emulated mk test...\n");
1887     test_BindToStorage(MK_TEST, TRUE);
1888
1889     test_BindToStorage_fail();
1890
1891     CloseHandle(complete_event);
1892     CloseHandle(complete_event2);
1893     CoUninitialize();
1894 }