dsound: Call waveInUnPrepareHeader and waveInPrepareHeader when submitting new buffer.
[wine/multimedia.git] / dlls / urlmon / tests / url.c
blob57126692edf4eab9fc21f7d151a16d76a2b4c79a
1 /*
2 * UrlMon URL tests
4 * Copyright 2004 Kevin Koltzau
5 * Copyright 2004 Jacek Caban
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.
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.
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
22 #include <stdarg.h>
24 #define COBJMACROS
25 #define CONST_VTABLE
27 #include "windef.h"
28 #include "winbase.h"
29 #include "urlmon.h"
30 #include "wininet.h"
32 #include "wine/test.h"
34 #define DEFINE_EXPECT(func) \
35 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
37 #define SET_EXPECT(func) \
38 expect_ ## func = TRUE
40 #define CHECK_EXPECT(func) \
41 do { \
42 ok(expect_ ##func, "unexpected call " #func "\n"); \
43 expect_ ## func = FALSE; \
44 called_ ## func = TRUE; \
45 }while(0)
47 #define CHECK_EXPECT2(func) \
48 do { \
49 ok(expect_ ##func, "unexpected call " #func "\n"); \
50 called_ ## func = TRUE; \
51 }while(0)
53 #define CHECK_CALLED(func) \
54 do { \
55 ok(called_ ## func, "expected " #func "\n"); \
56 expect_ ## func = called_ ## func = FALSE; \
57 }while(0)
59 #define CHECK_NOT_CALLED(func) \
60 do { \
61 ok(!called_ ## func, "unexpected " #func "\n"); \
62 expect_ ## func = called_ ## func = FALSE; \
63 }while(0)
65 #define CLEAR_CALLED(func) \
66 expect_ ## func = called_ ## func = FALSE
68 DEFINE_EXPECT(QueryInterface_IServiceProvider);
69 DEFINE_EXPECT(QueryInterface_IHttpNegotiate);
70 DEFINE_EXPECT(BeginningTransaction);
71 DEFINE_EXPECT(OnResponse);
72 DEFINE_EXPECT(QueryInterface_IHttpNegotiate2);
73 DEFINE_EXPECT(GetRootSecurityId);
74 DEFINE_EXPECT(GetBindInfo);
75 DEFINE_EXPECT(OnStartBinding);
76 DEFINE_EXPECT(OnProgress_FINDINGRESOURCE);
77 DEFINE_EXPECT(OnProgress_CONNECTING);
78 DEFINE_EXPECT(OnProgress_SENDINGREQUEST);
79 DEFINE_EXPECT(OnProgress_MIMETYPEAVAILABLE);
80 DEFINE_EXPECT(OnProgress_BEGINDOWNLOADDATA);
81 DEFINE_EXPECT(OnProgress_DOWNLOADINGDATA);
82 DEFINE_EXPECT(OnProgress_ENDDOWNLOADDATA);
83 DEFINE_EXPECT(OnStopBinding);
84 DEFINE_EXPECT(OnDataAvailable);
85 DEFINE_EXPECT(Start);
86 DEFINE_EXPECT(Read);
87 DEFINE_EXPECT(LockRequest);
88 DEFINE_EXPECT(Terminate);
89 DEFINE_EXPECT(UnlockRequest);
91 static const WCHAR TEST_URL_1[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g','/','\0'};
92 static const WCHAR TEST_PART_URL_1[] = {'/','t','e','s','t','/','\0'};
94 static const WCHAR WINE_ABOUT_URL[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.',
95 'o','r','g','/','s','i','t','e','/','a','b','o','u','t',0};
96 static const WCHAR SHORT_RESPONSE_URL[] =
97 {'h','t','t','p',':','/','/','c','r','o','s','s','o','v','e','r','.',
98 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m','/',
99 'p','o','s','t','t','e','s','t','.','p','h','p',0};
100 static const WCHAR ABOUT_BLANK[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
101 static WCHAR INDEX_HTML[MAX_PATH];
102 static const WCHAR ITS_URL[] =
103 {'i','t','s',':','t','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l',0};
104 static const WCHAR MK_URL[] = {'m','k',':','@','M','S','I','T','S','t','o','r','e',':',
105 't','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l',0};
109 static const WCHAR wszIndexHtml[] = {'i','n','d','e','x','.','h','t','m','l',0};
111 static BOOL stopped_binding = FALSE, emulate_protocol = FALSE,
112 data_available = FALSE, http_is_first = TRUE;
113 static DWORD read = 0, bindf = 0;
114 static CHAR mime_type[512];
116 static LPCWSTR urls[] = {
117 WINE_ABOUT_URL,
118 ABOUT_BLANK,
119 INDEX_HTML,
120 ITS_URL,
121 MK_URL
124 static enum {
125 HTTP_TEST,
126 ABOUT_TEST,
127 FILE_TEST,
128 ITS_TEST,
129 MK_TEST
130 } test_protocol;
132 static enum {
133 BEFORE_DOWNLOAD,
134 DOWNLOADING,
135 END_DOWNLOAD
136 } download_state;
138 static void test_CreateURLMoniker(LPCWSTR url1, LPCWSTR url2)
140 HRESULT hr;
141 IMoniker *mon1 = NULL;
142 IMoniker *mon2 = NULL;
144 hr = CreateURLMoniker(NULL, url1, &mon1);
145 ok(SUCCEEDED(hr), "failed to create moniker: 0x%08x\n", hr);
146 if(SUCCEEDED(hr)) {
147 hr = CreateURLMoniker(mon1, url2, &mon2);
148 ok(SUCCEEDED(hr), "failed to create moniker: 0x%08x\n", hr);
150 if(mon1) IMoniker_Release(mon1);
151 if(mon2) IMoniker_Release(mon2);
154 static void test_create(void)
156 test_CreateURLMoniker(TEST_URL_1, TEST_PART_URL_1);
159 static HRESULT WINAPI Protocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
161 if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) {
162 *ppv = iface;
163 return S_OK;
166 *ppv = NULL;
167 return E_NOINTERFACE;
170 static ULONG WINAPI Protocol_AddRef(IInternetProtocol *iface)
172 return 2;
175 static ULONG WINAPI Protocol_Release(IInternetProtocol *iface)
177 return 1;
180 static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
181 IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo,
182 DWORD grfPI, DWORD dwReserved)
184 BINDINFO bindinfo, bi = {sizeof(bi), 0};
185 DWORD bindf, bscf = BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION;
186 WCHAR null_char = 0;
187 HRESULT hres;
189 static const WCHAR wszTextHtml[] = {'t','e','x','t','/','h','t','m','l',0};
191 CHECK_EXPECT(Start);
193 read = 0;
195 ok(szUrl && !lstrcmpW(szUrl, urls[test_protocol]), "wrong url\n");
196 ok(pOIProtSink != NULL, "pOIProtSink == NULL\n");
197 ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n");
198 ok(grfPI == 0, "grfPI=%d, expected 0\n", grfPI);
199 ok(dwReserved == 0, "dwReserved=%d, expected 0\n", dwReserved);
201 memset(&bindinfo, 0, sizeof(bindinfo));
202 bindinfo.cbSize = sizeof(bindinfo);
203 hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &bindf, &bindinfo);
204 ok(hres == S_OK, "GetBindInfo failed: %08x\n", hres);
206 if(test_protocol == FILE_TEST || test_protocol == MK_TEST) {
207 ok(bindf == (BINDF_ASYNCHRONOUS|BINDF_ASYNCSTORAGE|BINDF_PULLDATA
208 |BINDF_FROMURLMON),
209 "bindf=%08x\n", bindf);
210 }else {
211 ok(bindf == (BINDF_ASYNCHRONOUS|BINDF_ASYNCSTORAGE|BINDF_PULLDATA|
212 BINDF_FROMURLMON|BINDF_NEEDFILE),
213 "bindf=%08x\n", bindf);
216 ok(!memcmp(&bindinfo, &bi, sizeof(bindinfo)), "wrong bindinfo\n");
218 switch(test_protocol) {
219 case MK_TEST:
220 hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
221 BINDSTATUS_DIRECTBIND, NULL);
222 ok(hres == S_OK,
223 "ReportProgress(BINDSTATUS_SENDINGREQUEST) failed: %08x\n", hres);
225 case FILE_TEST:
226 case ITS_TEST:
227 SET_EXPECT(OnProgress_SENDINGREQUEST);
228 hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
229 BINDSTATUS_SENDINGREQUEST, &null_char);
230 ok(hres == S_OK,
231 "ReportProgress(BINDSTATUS_SENDINGREQUEST) failed: %08x\n", hres);
232 CHECK_CALLED(OnProgress_SENDINGREQUEST);
233 default:
234 break;
237 if(test_protocol == FILE_TEST) {
238 hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
239 BINDSTATUS_CACHEFILENAMEAVAILABLE, &null_char);
240 ok(hres == S_OK,
241 "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres);
243 SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
244 hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
245 BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE, wszTextHtml);
246 ok(hres == S_OK,
247 "ReportProgress(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE) failed: %08x\n", hres);
248 CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
249 }else {
250 hres = IInternetProtocolSink_ReportProgress(pOIProtSink,
251 BINDSTATUS_MIMETYPEAVAILABLE, wszTextHtml);
252 ok(hres == S_OK,
253 "ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE) failed: %08x\n", hres);
256 if(test_protocol == ABOUT_TEST)
257 bscf |= BSCF_DATAFULLYAVAILABLE;
258 if(test_protocol == ITS_TEST)
259 bscf = BSCF_FIRSTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE;
261 SET_EXPECT(Read);
262 if(test_protocol != FILE_TEST && test_protocol != MK_TEST)
263 SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
264 SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
265 SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
266 SET_EXPECT(LockRequest);
267 SET_EXPECT(OnDataAvailable);
268 SET_EXPECT(OnStopBinding);
270 hres = IInternetProtocolSink_ReportData(pOIProtSink, bscf, 13, 13);
271 ok(hres == S_OK, "ReportData failed: %08x\n", hres);
273 CHECK_CALLED(Read);
274 if(test_protocol != FILE_TEST && test_protocol != MK_TEST)
275 CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
276 CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
277 CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
278 CHECK_CALLED(LockRequest);
279 CHECK_CALLED(OnDataAvailable);
280 CHECK_CALLED(OnStopBinding);
282 if(test_protocol == ITS_TEST) {
283 SET_EXPECT(Read);
284 hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_BEGINDOWNLOADDATA, NULL);
285 ok(hres == S_OK, "ReportProgress(BINDSTATUS_BEGINDOWNLOADDATA) failed: %08x\n", hres);
286 CHECK_CALLED(Read);
289 SET_EXPECT(Terminate);
290 hres = IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);
291 ok(hres == S_OK, "ReportResult failed: %08x\n", hres);
292 CHECK_CALLED(Terminate);
294 return S_OK;
297 static HRESULT WINAPI Protocol_Continue(IInternetProtocol *iface,
298 PROTOCOLDATA *pProtocolData)
300 ok(0, "unexpected call\n");
301 return E_NOTIMPL;
304 static HRESULT WINAPI Protocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
305 DWORD dwOptions)
307 ok(0, "unexpected call\n");
308 return E_NOTIMPL;
311 static HRESULT WINAPI Protocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
313 CHECK_EXPECT(Terminate);
314 ok(dwOptions == 0, "dwOptions=%d, expected 0\n", dwOptions);
315 return S_OK;
318 static HRESULT WINAPI Protocol_Suspend(IInternetProtocol *iface)
320 ok(0, "unexpected call\n");
321 return E_NOTIMPL;
324 static HRESULT WINAPI Protocol_Resume(IInternetProtocol *iface)
326 ok(0, "unexpected call\n");
327 return E_NOTIMPL;
330 static HRESULT WINAPI Protocol_Read(IInternetProtocol *iface, void *pv,
331 ULONG cb, ULONG *pcbRead)
333 static const char data[] = "<HTML></HTML>";
335 CHECK_EXPECT2(Read);
337 if(read) {
338 *pcbRead = 0;
339 return S_FALSE;
342 ok(pv != NULL, "pv == NULL\n");
343 ok(cb != 0, "cb == 0\n");
344 ok(pcbRead != NULL, "pcbRead == NULL\n");
345 if(pcbRead) {
346 ok(*pcbRead == 0, "*pcbRead=%d, expected 0\n", *pcbRead);
347 read += *pcbRead = sizeof(data)-1;
349 if(pv)
350 memcpy(pv, data, sizeof(data));
352 return S_OK;
355 static HRESULT WINAPI Protocol_Seek(IInternetProtocol *iface,
356 LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
358 ok(0, "unexpected call\n");
359 return E_NOTIMPL;
362 static HRESULT WINAPI Protocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
364 CHECK_EXPECT(LockRequest);
365 return S_OK;
368 static HRESULT WINAPI Protocol_UnlockRequest(IInternetProtocol *iface)
370 CHECK_EXPECT(UnlockRequest);
371 return S_OK;
374 static const IInternetProtocolVtbl ProtocolVtbl = {
375 Protocol_QueryInterface,
376 Protocol_AddRef,
377 Protocol_Release,
378 Protocol_Start,
379 Protocol_Continue,
380 Protocol_Abort,
381 Protocol_Terminate,
382 Protocol_Suspend,
383 Protocol_Resume,
384 Protocol_Read,
385 Protocol_Seek,
386 Protocol_LockRequest,
387 Protocol_UnlockRequest
390 static IInternetProtocol Protocol = { &ProtocolVtbl };
392 static HRESULT WINAPI HttpNegotiate_QueryInterface(IHttpNegotiate2 *iface, REFIID riid, void **ppv)
394 if(IsEqualGUID(&IID_IUnknown, riid)
395 || IsEqualGUID(&IID_IHttpNegotiate, riid)
396 || IsEqualGUID(&IID_IHttpNegotiate2, riid)) {
397 *ppv = iface;
398 return S_OK;
401 ok(0, "unexpected call\n");
402 return E_NOINTERFACE;
405 static ULONG WINAPI HttpNegotiate_AddRef(IHttpNegotiate2 *iface)
407 return 2;
410 static ULONG WINAPI HttpNegotiate_Release(IHttpNegotiate2 *iface)
412 return 1;
415 static HRESULT WINAPI HttpNegotiate_BeginningTransaction(IHttpNegotiate2 *iface, LPCWSTR szURL,
416 LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
418 CHECK_EXPECT(BeginningTransaction);
420 ok(!lstrcmpW(szURL, urls[test_protocol]), "szURL != urls[test_protocol]\n");
421 ok(!dwReserved, "dwReserved=%d, expected 0\n", dwReserved);
422 ok(pszAdditionalHeaders != NULL, "pszAdditionalHeaders == NULL\n");
423 if(pszAdditionalHeaders)
424 ok(*pszAdditionalHeaders == NULL, "*pszAdditionalHeaders != NULL\n");
426 return S_OK;
429 static HRESULT WINAPI HttpNegotiate_OnResponse(IHttpNegotiate2 *iface, DWORD dwResponseCode,
430 LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders)
432 CHECK_EXPECT(OnResponse);
434 ok(dwResponseCode == 200, "dwResponseCode=%d, expected 200\n", dwResponseCode);
435 ok(szResponseHeaders != NULL, "szResponseHeaders == NULL\n");
436 ok(szRequestHeaders == NULL, "szRequestHeaders != NULL\n");
437 /* Note: in protocol.c tests, OnResponse pszAdditionalRequestHeaders _is_ NULL */
438 ok(pszAdditionalRequestHeaders != NULL, "pszAdditionalHeaders == NULL\n");
439 if(pszAdditionalRequestHeaders)
440 ok(*pszAdditionalRequestHeaders == NULL, "*pszAdditionalHeaders != NULL\n");
442 return S_OK;
445 static HRESULT WINAPI HttpNegotiate_GetRootSecurityId(IHttpNegotiate2 *iface,
446 BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
448 static const BYTE sec_id[] = {'h','t','t','p',':','t','e','s','t',1,0,0,0};
450 CHECK_EXPECT(GetRootSecurityId);
452 ok(!dwReserved, "dwReserved=%ld, expected 0\n", dwReserved);
453 ok(pbSecurityId != NULL, "pbSecurityId == NULL\n");
454 ok(pcbSecurityId != NULL, "pcbSecurityId == NULL\n");
456 if(pcbSecurityId) {
457 ok(*pcbSecurityId == 512, "*pcbSecurityId=%d, expected 512\n", *pcbSecurityId);
458 *pcbSecurityId = sizeof(sec_id);
461 if(pbSecurityId)
462 memcpy(pbSecurityId, sec_id, sizeof(sec_id));
464 return E_FAIL;
467 static IHttpNegotiate2Vtbl HttpNegotiateVtbl = {
468 HttpNegotiate_QueryInterface,
469 HttpNegotiate_AddRef,
470 HttpNegotiate_Release,
471 HttpNegotiate_BeginningTransaction,
472 HttpNegotiate_OnResponse,
473 HttpNegotiate_GetRootSecurityId
476 static IHttpNegotiate2 HttpNegotiate = { &HttpNegotiateVtbl };
478 static HRESULT WINAPI statusclb_QueryInterface(IBindStatusCallback *iface, REFIID riid, void **ppv)
480 if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
481 if(emulate_protocol) {
482 *ppv = &Protocol;
483 return S_OK;
484 }else {
485 return E_NOINTERFACE;
488 else if (IsEqualGUID(&IID_IServiceProvider, riid))
490 CHECK_EXPECT(QueryInterface_IServiceProvider);
492 else if (IsEqualGUID(&IID_IHttpNegotiate, riid))
494 CHECK_EXPECT(QueryInterface_IHttpNegotiate);
495 *ppv = &HttpNegotiate;
496 return S_OK;
498 else if (IsEqualGUID(&IID_IHttpNegotiate2, riid))
500 CHECK_EXPECT(QueryInterface_IHttpNegotiate2);
501 *ppv = &HttpNegotiate;
502 return S_OK;
505 return E_NOINTERFACE;
508 static ULONG WINAPI statusclb_AddRef(IBindStatusCallback *iface)
510 return 2;
513 static ULONG WINAPI statusclb_Release(IBindStatusCallback *iface)
515 return 1;
518 static HRESULT WINAPI statusclb_OnStartBinding(IBindStatusCallback *iface, DWORD dwReserved,
519 IBinding *pib)
521 HRESULT hres;
522 IMoniker *mon;
524 CHECK_EXPECT(OnStartBinding);
526 ok(pib != NULL, "pib should not be NULL\n");
528 hres = IBinding_QueryInterface(pib, &IID_IMoniker, (void**)&mon);
529 ok(hres == E_NOINTERFACE, "IBinding should not have IMoniker interface\n");
530 if(SUCCEEDED(hres))
531 IMoniker_Release(mon);
533 return S_OK;
536 static HRESULT WINAPI statusclb_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
538 ok(0, "unexpected call\n");
539 return E_NOTIMPL;
542 static HRESULT WINAPI statusclb_OnLowResource(IBindStatusCallback *iface, DWORD reserved)
544 ok(0, "unexpected call\n");
545 return E_NOTIMPL;
548 static HRESULT WINAPI statusclb_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
549 ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
551 switch(ulStatusCode) {
552 case BINDSTATUS_FINDINGRESOURCE:
553 CHECK_EXPECT(OnProgress_FINDINGRESOURCE);
554 break;
555 case BINDSTATUS_CONNECTING:
556 CHECK_EXPECT(OnProgress_CONNECTING);
557 break;
558 case BINDSTATUS_SENDINGREQUEST:
559 CHECK_EXPECT(OnProgress_SENDINGREQUEST);
560 break;
561 case BINDSTATUS_MIMETYPEAVAILABLE:
562 CHECK_EXPECT(OnProgress_MIMETYPEAVAILABLE);
563 ok(download_state == BEFORE_DOWNLOAD, "Download state was %d, expected BEFORE_DOWNLOAD\n",
564 download_state);
565 WideCharToMultiByte(CP_ACP, 0, szStatusText, -1, mime_type, sizeof(mime_type)-1, NULL, NULL);
566 break;
567 case BINDSTATUS_BEGINDOWNLOADDATA:
568 CHECK_EXPECT(OnProgress_BEGINDOWNLOADDATA);
569 ok(szStatusText != NULL, "szStatusText == NULL\n");
570 if(szStatusText)
571 ok(!lstrcmpW(szStatusText, urls[test_protocol]), "wrong szStatusText\n");
572 ok(download_state == BEFORE_DOWNLOAD, "Download state was %d, expected BEFORE_DOWNLOAD\n",
573 download_state);
574 download_state = DOWNLOADING;
575 break;
576 case BINDSTATUS_DOWNLOADINGDATA:
577 CHECK_EXPECT2(OnProgress_DOWNLOADINGDATA);
578 ok(download_state == DOWNLOADING, "Download state was %d, expected DOWNLOADING\n",
579 download_state);
580 break;
581 case BINDSTATUS_ENDDOWNLOADDATA:
582 CHECK_EXPECT(OnProgress_ENDDOWNLOADDATA);
583 ok(szStatusText != NULL, "szStatusText == NULL\n");
584 if(szStatusText)
585 ok(!lstrcmpW(szStatusText, urls[test_protocol]), "wrong szStatusText\n");
586 ok(download_state == DOWNLOADING, "Download state was %d, expected DOWNLOADING\n",
587 download_state);
588 download_state = END_DOWNLOAD;
589 break;
590 case BINDSTATUS_CACHEFILENAMEAVAILABLE:
591 ok(szStatusText != NULL, "szStatusText == NULL\n");
592 if(szStatusText && test_protocol == FILE_TEST)
593 ok(!lstrcmpW(INDEX_HTML+7, szStatusText), "wrong szStatusText\n");
594 break;
595 default:
596 todo_wine { ok(0, "unexpexted code %d\n", ulStatusCode); }
598 return S_OK;
601 static HRESULT WINAPI statusclb_OnStopBinding(IBindStatusCallback *iface, HRESULT hresult, LPCWSTR szError)
603 CHECK_EXPECT(OnStopBinding);
605 /* ignore DNS failure */
606 if (hresult != HRESULT_FROM_WIN32(ERROR_INTERNET_NAME_NOT_RESOLVED))
608 ok(SUCCEEDED(hresult), "Download failed: %08x\n", hresult);
609 ok(szError == NULL, "szError should be NULL\n");
611 stopped_binding = TRUE;
613 return S_OK;
616 static HRESULT WINAPI statusclb_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo)
618 DWORD cbSize;
620 CHECK_EXPECT(GetBindInfo);
622 *grfBINDF = bindf;
623 cbSize = pbindinfo->cbSize;
624 memset(pbindinfo, 0, cbSize);
625 pbindinfo->cbSize = cbSize;
627 return S_OK;
630 static HRESULT WINAPI statusclb_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
631 DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
633 HRESULT hres;
634 DWORD readed;
635 BYTE buf[512];
636 CHAR clipfmt[512];
638 CHECK_EXPECT2(OnDataAvailable);
639 ok(download_state == DOWNLOADING || download_state == END_DOWNLOAD,
640 "Download state was %d, expected DOWNLOADING or END_DOWNLOAD\n",
641 download_state);
642 data_available = TRUE;
644 ok(pformatetc != NULL, "pformatetx == NULL\n");
645 if(pformatetc) {
646 if (mime_type[0]) todo_wine {
647 clipfmt[0] = 0;
648 ok(GetClipboardFormatName(pformatetc->cfFormat, clipfmt, sizeof(clipfmt)-1),
649 "GetClipboardFormatName failed, error %d\n", GetLastError());
650 ok(!lstrcmp(clipfmt, mime_type), "clipformat != mime_type, \"%s\" != \"%s\"\n",
651 clipfmt, mime_type);
652 } else {
653 ok(pformatetc->cfFormat == 0, "clipformat=%x\n", pformatetc->cfFormat);
655 ok(pformatetc->ptd == NULL, "ptd = %p\n", pformatetc->ptd);
656 ok(pformatetc->dwAspect == 1, "dwAspect=%u\n", pformatetc->dwAspect);
657 ok(pformatetc->lindex == -1, "lindex=%d\n", pformatetc->lindex);
658 ok(pformatetc->tymed == TYMED_ISTREAM, "tymed=%u\n", pformatetc->tymed);
661 ok(pstgmed != NULL, "stgmeg == NULL\n");
662 if(pstgmed) {
663 ok(pstgmed->tymed == TYMED_ISTREAM, "tymed=%u\n", pstgmed->tymed);
664 ok(U(*pstgmed).pstm != NULL, "pstm == NULL\n");
665 ok(pstgmed->pUnkForRelease != NULL, "pUnkForRelease == NULL\n");
668 if(U(*pstgmed).pstm) {
669 do hres = IStream_Read(U(*pstgmed).pstm, buf, 512, &readed);
670 while(hres == S_OK);
671 ok(hres == S_FALSE || hres == E_PENDING, "IStream_Read returned %08x\n", hres);
674 return S_OK;
677 static HRESULT WINAPI statusclb_OnObjectAvailable(IBindStatusCallback *iface, REFIID riid, IUnknown *punk)
679 ok(0, "unexpected call\n");
680 return E_NOTIMPL;
683 static const IBindStatusCallbackVtbl BindStatusCallbackVtbl = {
684 statusclb_QueryInterface,
685 statusclb_AddRef,
686 statusclb_Release,
687 statusclb_OnStartBinding,
688 statusclb_GetPriority,
689 statusclb_OnLowResource,
690 statusclb_OnProgress,
691 statusclb_OnStopBinding,
692 statusclb_GetBindInfo,
693 statusclb_OnDataAvailable,
694 statusclb_OnObjectAvailable
697 static IBindStatusCallback bsc = { &BindStatusCallbackVtbl };
699 static void test_CreateAsyncBindCtx(void)
701 IBindCtx *bctx = (IBindCtx*)0x0ff00ff0;
702 IUnknown *unk;
703 HRESULT hres;
704 ULONG ref;
705 BIND_OPTS bindopts;
707 hres = CreateAsyncBindCtx(0, NULL, NULL, &bctx);
708 ok(hres == E_INVALIDARG, "CreateAsyncBindCtx failed. expected: E_INVALIDARG, got: %08x\n", hres);
709 ok(bctx == (IBindCtx*)0x0ff00ff0, "bctx should not be changed\n");
711 hres = CreateAsyncBindCtx(0, NULL, NULL, NULL);
712 ok(hres == E_INVALIDARG, "CreateAsyncBindCtx failed. expected: E_INVALIDARG, got: %08x\n", hres);
714 SET_EXPECT(QueryInterface_IServiceProvider);
715 hres = CreateAsyncBindCtx(0, &bsc, NULL, &bctx);
716 ok(SUCCEEDED(hres), "CreateAsyncBindCtx failed: %08x\n", hres);
717 todo_wine CHECK_CALLED(QueryInterface_IServiceProvider);
719 bindopts.cbStruct = sizeof(bindopts);
720 hres = IBindCtx_GetBindOptions(bctx, &bindopts);
721 ok(SUCCEEDED(hres), "IBindCtx_GetBindOptions failed: %08x\n", hres);
722 ok(bindopts.grfFlags == BIND_MAYBOTHERUSER,
723 "bindopts.grfFlags = %08x, expected: BIND_MAYBOTHERUSER\n", bindopts.grfFlags);
724 ok(bindopts.grfMode == (STGM_READWRITE | STGM_SHARE_EXCLUSIVE),
725 "bindopts.grfMode = %08x, expected: STGM_READWRITE | STGM_SHARE_EXCLUSIVE\n",
726 bindopts.grfMode);
727 ok(bindopts.dwTickCountDeadline == 0,
728 "bindopts.dwTickCountDeadline = %08x, expected: 0\n", bindopts.dwTickCountDeadline);
730 hres = IBindCtx_QueryInterface(bctx, &IID_IAsyncBindCtx, (void**)&unk);
731 ok(hres == E_NOINTERFACE, "QueryInterface(IID_IAsyncBindCtx) failed: %08x, expected E_NOINTERFACE\n", hres);
732 if(SUCCEEDED(hres))
733 IUnknown_Release(unk);
735 ref = IBindCtx_Release(bctx);
736 ok(ref == 0, "bctx should be destroyed here\n");
739 static void test_CreateAsyncBindCtxEx(void)
741 IBindCtx *bctx = NULL, *bctx_arg = NULL;
742 IUnknown *unk;
743 BIND_OPTS bindopts;
744 HRESULT hres;
746 hres = CreateAsyncBindCtxEx(NULL, 0, NULL, NULL, NULL, 0);
747 ok(hres == E_INVALIDARG, "CreateAsyncBindCtx failed: %08x, expected E_INVALIDARG\n", hres);
749 hres = CreateAsyncBindCtxEx(NULL, 0, NULL, NULL, &bctx, 0);
750 ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08x\n", hres);
752 if(SUCCEEDED(hres)) {
753 bindopts.cbStruct = sizeof(bindopts);
754 hres = IBindCtx_GetBindOptions(bctx, &bindopts);
755 ok(SUCCEEDED(hres), "IBindCtx_GetBindOptions failed: %08x\n", hres);
756 ok(bindopts.grfFlags == BIND_MAYBOTHERUSER,
757 "bindopts.grfFlags = %08x, expected: BIND_MAYBOTHERUSER\n", bindopts.grfFlags);
758 ok(bindopts.grfMode == (STGM_READWRITE | STGM_SHARE_EXCLUSIVE),
759 "bindopts.grfMode = %08x, expected: STGM_READWRITE | STGM_SHARE_EXCLUSIVE\n",
760 bindopts.grfMode);
761 ok(bindopts.dwTickCountDeadline == 0,
762 "bindopts.dwTickCountDeadline = %08x, expected: 0\n", bindopts.dwTickCountDeadline);
764 IBindCtx_Release(bctx);
767 CreateBindCtx(0, &bctx_arg);
768 hres = CreateAsyncBindCtxEx(NULL, 0, NULL, NULL, &bctx, 0);
769 ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08x\n", hres);
771 if(SUCCEEDED(hres)) {
772 bindopts.cbStruct = sizeof(bindopts);
773 hres = IBindCtx_GetBindOptions(bctx, &bindopts);
774 ok(SUCCEEDED(hres), "IBindCtx_GetBindOptions failed: %08x\n", hres);
775 ok(bindopts.grfFlags == BIND_MAYBOTHERUSER,
776 "bindopts.grfFlags = %08x, expected: BIND_MAYBOTHERUSER\n", bindopts.grfFlags);
777 ok(bindopts.grfMode == (STGM_READWRITE | STGM_SHARE_EXCLUSIVE),
778 "bindopts.grfMode = %08x, expected: STGM_READWRITE | STGM_SHARE_EXCLUSIVE\n",
779 bindopts.grfMode);
780 ok(bindopts.dwTickCountDeadline == 0,
781 "bindopts.dwTickCountDeadline = %08x, expected: 0\n", bindopts.dwTickCountDeadline);
783 IBindCtx_Release(bctx);
786 IBindCtx_Release(bctx_arg);
788 SET_EXPECT(QueryInterface_IServiceProvider);
789 hres = CreateAsyncBindCtxEx(NULL, 0, &bsc, NULL, &bctx, 0);
790 ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08x\n", hres);
791 todo_wine CHECK_CALLED(QueryInterface_IServiceProvider);
793 hres = IBindCtx_QueryInterface(bctx, &IID_IAsyncBindCtx, (void**)&unk);
794 ok(hres == S_OK, "QueryInterface(IID_IAsyncBindCtx) failed: %08x\n", hres);
795 if(SUCCEEDED(hres))
796 IUnknown_Release(unk);
798 if(SUCCEEDED(hres))
799 IBindCtx_Release(bctx);
802 static void test_BindToStorage(int protocol, BOOL emul)
804 IMoniker *mon;
805 HRESULT hres;
806 LPOLESTR display_name;
807 IBindCtx *bctx;
808 MSG msg;
809 IBindStatusCallback *previousclb;
810 IUnknown *unk = (IUnknown*)0x00ff00ff;
811 IBinding *bind;
813 test_protocol = protocol;
814 emulate_protocol = emul;
815 download_state = BEFORE_DOWNLOAD;
816 stopped_binding = FALSE;
817 data_available = FALSE;
818 mime_type[0] = 0;
820 SET_EXPECT(QueryInterface_IServiceProvider);
821 hres = CreateAsyncBindCtx(0, &bsc, NULL, &bctx);
822 ok(SUCCEEDED(hres), "CreateAsyncBindCtx failed: %08x\n\n", hres);
823 if(FAILED(hres))
824 return;
825 todo_wine CHECK_CALLED(QueryInterface_IServiceProvider);
827 SET_EXPECT(QueryInterface_IServiceProvider);
828 hres = RegisterBindStatusCallback(bctx, &bsc, &previousclb, 0);
829 ok(SUCCEEDED(hres), "RegisterBindStatusCallback failed: %08x\n", hres);
830 ok(previousclb == &bsc, "previousclb(%p) != sclb(%p)\n", previousclb, &bsc);
831 todo_wine CHECK_CALLED(QueryInterface_IServiceProvider);
832 if(previousclb)
833 IBindStatusCallback_Release(previousclb);
835 hres = CreateURLMoniker(NULL, urls[test_protocol], &mon);
836 ok(SUCCEEDED(hres), "failed to create moniker: %08x\n", hres);
837 if(FAILED(hres)) {
838 IBindCtx_Release(bctx);
839 return;
842 if(test_protocol == FILE_TEST && INDEX_HTML[7] == '/')
843 memmove(INDEX_HTML+7, INDEX_HTML+8, lstrlenW(INDEX_HTML+7)*sizeof(WCHAR));
845 hres = IMoniker_QueryInterface(mon, &IID_IBinding, (void**)&bind);
846 ok(hres == E_NOINTERFACE, "IMoniker should not have IBinding interface\n");
847 if(SUCCEEDED(hres))
848 IBinding_Release(bind);
850 hres = IMoniker_GetDisplayName(mon, bctx, NULL, &display_name);
851 ok(hres == S_OK, "GetDisplayName failed %08x\n", hres);
852 ok(!lstrcmpW(display_name, urls[test_protocol]), "GetDisplayName got wrong name\n");
854 SET_EXPECT(QueryInterface_IServiceProvider);
855 SET_EXPECT(GetBindInfo);
856 SET_EXPECT(OnStartBinding);
857 if(emulate_protocol) {
858 SET_EXPECT(Start);
859 SET_EXPECT(UnlockRequest);
860 }else {
861 if(test_protocol == HTTP_TEST) {
862 SET_EXPECT(QueryInterface_IHttpNegotiate);
863 SET_EXPECT(BeginningTransaction);
864 SET_EXPECT(QueryInterface_IHttpNegotiate2);
865 SET_EXPECT(GetRootSecurityId);
866 SET_EXPECT(OnProgress_FINDINGRESOURCE);
867 SET_EXPECT(OnProgress_CONNECTING);
869 if(test_protocol == HTTP_TEST || test_protocol == FILE_TEST)
870 SET_EXPECT(OnProgress_SENDINGREQUEST);
871 if(test_protocol == HTTP_TEST)
872 SET_EXPECT(OnResponse);
873 SET_EXPECT(OnProgress_MIMETYPEAVAILABLE);
874 SET_EXPECT(OnProgress_BEGINDOWNLOADDATA);
875 if(test_protocol == HTTP_TEST)
876 SET_EXPECT(OnProgress_DOWNLOADINGDATA);
877 SET_EXPECT(OnProgress_ENDDOWNLOADDATA);
878 SET_EXPECT(OnDataAvailable);
879 SET_EXPECT(OnStopBinding);
882 hres = IMoniker_BindToStorage(mon, bctx, NULL, &IID_IStream, (void**)&unk);
883 if (test_protocol == HTTP_TEST && hres == HRESULT_FROM_WIN32(ERROR_INTERNET_NAME_NOT_RESOLVED))
885 trace( "Network unreachable, skipping tests\n" );
886 return;
888 if (!SUCCEEDED(hres)) return;
890 if((bindf & BINDF_ASYNCHRONOUS) && !data_available) {
891 ok(hres == MK_S_ASYNCHRONOUS, "IMoniker_BindToStorage failed: %08x\n", hres);
892 ok(unk == NULL, "istr should be NULL\n");
893 }else {
894 ok(hres == S_OK, "IMoniker_BindToStorage failed: %08x\n", hres);
895 ok(unk != NULL, "unk == NULL\n");
897 if(unk)
898 IUnknown_Release(unk);
900 while((bindf & BINDF_ASYNCHRONOUS) &&
901 !stopped_binding && GetMessage(&msg,NULL,0,0)) {
902 TranslateMessage(&msg);
903 DispatchMessage(&msg);
906 todo_wine CHECK_NOT_CALLED(QueryInterface_IServiceProvider);
907 CHECK_CALLED(GetBindInfo);
908 CHECK_CALLED(OnStartBinding);
909 if(emulate_protocol) {
910 CHECK_CALLED(Start);
911 CHECK_CALLED(UnlockRequest);
912 }else {
913 if(test_protocol == HTTP_TEST) {
914 CHECK_CALLED(QueryInterface_IHttpNegotiate);
915 CHECK_CALLED(BeginningTransaction);
916 /* QueryInterface_IHttpNegotiate2 and GetRootSecurityId
917 * called on WinXP but not on Win98 */
918 CLEAR_CALLED(QueryInterface_IHttpNegotiate2);
919 CLEAR_CALLED(GetRootSecurityId);
920 if(http_is_first) {
921 CHECK_CALLED(OnProgress_FINDINGRESOURCE);
922 CHECK_CALLED(OnProgress_CONNECTING);
923 }else todo_wine {
924 CHECK_NOT_CALLED(OnProgress_FINDINGRESOURCE);
925 CHECK_NOT_CALLED(OnProgress_CONNECTING);
928 if(test_protocol == HTTP_TEST || test_protocol == FILE_TEST)
929 CHECK_CALLED(OnProgress_SENDINGREQUEST);
930 if(test_protocol == HTTP_TEST)
931 CHECK_CALLED(OnResponse);
932 CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE);
933 CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA);
934 if(test_protocol == HTTP_TEST)
935 CLEAR_CALLED(OnProgress_DOWNLOADINGDATA);
936 CHECK_CALLED(OnProgress_ENDDOWNLOADDATA);
937 CHECK_CALLED(OnDataAvailable);
938 CHECK_CALLED(OnStopBinding);
941 ok(IMoniker_Release(mon) == 0, "mon should be destroyed here\n");
942 ok(IBindCtx_Release(bctx) == 0, "bctx should be destroyed here\n");
944 if(test_protocol == HTTP_TEST)
945 http_is_first = FALSE;
948 static void set_file_url(void)
950 int len;
952 static const WCHAR wszFile[] = {'f','i','l','e',':','/','/'};
954 memcpy(INDEX_HTML, wszFile, sizeof(wszFile));
955 len = sizeof(wszFile)/sizeof(WCHAR);
956 INDEX_HTML[len++] = '/';
957 len += GetCurrentDirectoryW(sizeof(INDEX_HTML)/sizeof(WCHAR)-len, INDEX_HTML+len);
958 INDEX_HTML[len++] = '\\';
959 memcpy(INDEX_HTML+len, wszIndexHtml, sizeof(wszIndexHtml));
962 static void create_file(void)
964 HANDLE file;
965 DWORD size;
967 static const char html_doc[] = "<HTML></HTML>";
969 file = CreateFileW(wszIndexHtml, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
970 FILE_ATTRIBUTE_NORMAL, NULL);
971 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
972 if(file == INVALID_HANDLE_VALUE)
973 return;
975 WriteFile(file, html_doc, sizeof(html_doc)-1, &size, NULL);
976 CloseHandle(file);
978 set_file_url();
981 static void test_BindToStorage_fail(void)
983 IMoniker *mon = NULL;
984 IBindCtx *bctx = NULL;
985 IUnknown *unk;
986 HRESULT hres;
988 hres = CreateURLMoniker(NULL, ABOUT_BLANK, &mon);
989 ok(hres == S_OK, "CreateURLMoniker failed: %08x\n", hres);
990 if(FAILED(hres))
991 return;
993 hres = CreateAsyncBindCtxEx(NULL, 0, NULL, NULL, &bctx, 0);
994 ok(hres == S_OK, "CreateAsyncBindCtxEx failed: %08x\n", hres);
996 hres = IMoniker_BindToStorage(mon, bctx, NULL, &IID_IStream, (void**)&unk);
997 ok(hres == MK_E_SYNTAX, "hres=%08x, expected INET_E_SYNTAX\n", hres);
999 IBindCtx_Release(bctx);
1001 IMoniker_Release(mon);
1004 START_TEST(url)
1006 test_create();
1007 test_CreateAsyncBindCtx();
1008 test_CreateAsyncBindCtxEx();
1010 trace("synchronous http test...\n");
1011 test_BindToStorage(HTTP_TEST, FALSE);
1013 trace("synchronous file test...\n");
1014 create_file();
1015 test_BindToStorage(FILE_TEST, FALSE);
1016 DeleteFileW(wszIndexHtml);
1018 bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA;
1020 trace("http test...\n");
1021 test_BindToStorage(HTTP_TEST, FALSE);
1023 trace("http test (short response)...\n");
1024 http_is_first = TRUE;
1025 urls[HTTP_TEST] = SHORT_RESPONSE_URL;
1026 test_BindToStorage(HTTP_TEST, FALSE);
1028 trace("about test...\n");
1029 CoInitialize(NULL);
1030 test_BindToStorage(ABOUT_TEST, FALSE);
1031 CoUninitialize();
1033 trace("emulated about test...\n");
1034 test_BindToStorage(ABOUT_TEST, TRUE);
1036 trace("file test...\n");
1037 create_file();
1038 test_BindToStorage(FILE_TEST, FALSE);
1039 DeleteFileW(wszIndexHtml);
1041 trace("emulated file test...\n");
1042 set_file_url();
1043 test_BindToStorage(FILE_TEST, TRUE);
1045 trace("emulated its test...\n");
1046 test_BindToStorage(ITS_TEST, TRUE);
1048 trace("emulated mk test...\n");
1049 test_BindToStorage(MK_TEST, TRUE);
1051 test_BindToStorage_fail();